revisiting preventing rigged dice rolls in online play

An earlier thread asked whether Vassal had any protection against rigged dice rolls during online play. The conclusion there was that this was impossible to protect against without a 3rd-party dice roller.

But I wonder if the following approach might work. Suppose two copies of Vassal are communicating with each other. User1, using Vassal1, initiates a dice roll.

Vassal1 transmits an encrypted, randomly-generated Seed1 to Vassal2. I’m not an expert in cryptography by any means but it seems to me that the seed may need to be “padded” in a way that would authenticate the value on decryption. For example, it could consist of a series of randomly-selected dictionary words. (There are probably better ways to confirm that decryption has been performed using the correct key.)

Vassal2 responds to Vassal1 with an unencrypted, randomly-generated Seed2. Vassal1 then combines the two seeds to deterministically generate a die roll. Vassal1 sends the die roll back to Vassal2 along with the key to decrypt Seed1. Vassal2 decrypts Seed1, authenticates it (in my example, by confirming that the padding decrypts into dictionary words), and confirms that the combination of the two seeds generates the same value reported by Vassal1.

Comment?

(This is based on a primitive method a friend and I used some 20 years ago for PBeM. If I recall correctly, we’d each provide several series of d6 rolls in text files, encrypt them and send them to the other person. When a set of die rolls was needed, we’d exchange keys for a given pair of text files. Authentication was based on the fact that decrypting a text file with the wrong key would generate a series of nonsense characters. The actual die rolls would be generated by rotating each number from file1 by the corresponding number in file2. E.g., if n1 in file1 was 5 and n1 in file2 was 3, the die roll would be 2.)

I think it seems solid, but yes, surely there is a better way to verify that you’ve been given the correct key by Vassal1.
However, supposing this was implemented exactly as stated - even if some clever person could figure out a way to circumvent it, say, if they discovered a way to generate multiple valid keys for their original encrypted message - if they then dug into the source and recompiled a modified version of Vassal to implement their hack - then I would say, let them have it. I mean, geez!
I feel the same way about die rolls in Vassal as is, however. I imagine you could probably make a personal die roller just by throwing a button onto a custom version of the module, without even cracking the hood on the Vassal engine itself - but I mean, when your buddies notice you get an awful lot of high rolls, they’re probably not going to want to play with you all that much.
So in other words, I think it’s a fantastic solution, but if I were a developer I honestly probably wouldn’t bother all that much. But then I’m pretty lazy, so who knows?

-Seth

Thanks, I realize this may sound like straining at a gnat and swallowing a camel to some, but it’s been a concern for some users; see the thread I linked and this one as well. Especially for tournaments, I think everyone would be more comfortable if the integrity of die-rolling could be guaranteed.

Also, I’m hoping that some developer will see this as an interesting challenge worth implementing just for the sake of it. Sadly, I don’t have the skills.

With respect to authenticating the key, while (again) I’m sure there are already well-proven methods available, another idea would be to generate a random key of sufficient length, and then use the key itself as the “padding” for the encrypted seed. I assume/suspect that it would be very hard to create a encrypted message that decrypts into (payloadA + keyA) if decrypted with keyA, and (payloadB + keyB) if decrypted with keyB. Of course, this will only work if using the key as the “padding” doesn’t make the key easy to guess, but again, I suspect it wouldn’t.

However, enough speculation from me on that point. Hopefully someone who really understands cryptography could suggest an appropriate method.

Thus spake ewilen:

An earlier thread[1] asked whether Vassal had any protection against
rigged dice rolls during online play. The conclusion there was that this
was impossible to protect against without a 3rd-party dice roller.

But I wonder if the following approach might work. Suppose two copies of
Vassal are communicating with each other. User1, using Vassal1,
initiates a dice roll.

Vassal1 transmits an encrypted, randomly-generated Seed1 to Vassal2. I’m
not an expert in cryptography by any means but it seems to me that the
seed may need to be “padded” in a way that would authenticate the value
on decryption. For example, it could consist of a series of
randomly-selected dictionary words. (There are probably better ways to
confirm that decryption has been performed using the correct key.)

Vassal2 responds to Vassal1 with an unencrypted, randomly-generated
Seed2. Vassal1 then combines the two seeds to deterministically generate
a die roll. Vassal1 sends the die roll back to Vassal2 along with the
key to decrypt Seed1. Vassal2 decrypts Seed1, authenticates it (in my
example, by confirming that the padding decrypts into dictionary words),
and confirms that the combination of the two seeds generates the same
value reported by Vassal1.

Comment?

Using a salt which is not random makes this much less secure than it
could be.

I had forgotten that it was possible to do this, thanks for reminding
me:

Each party chooses a secret number in 0,…,n-1, appends a salt, hashes
that, and tells every other party the hash. Then, each party reveals his
number and salt, which permits everyone to verify the hashes. Finally,
sum the numbers modulo n and add 1 to get a result in 1,…,n.

The security of this depends on the security of the hash function, the
quality of the RNGs the parties use, and the length of the salt. If I
can generate a hash collision, then I can choose from among two
different secret numbers to reveal. We can always devise a perfect hash
function (one with no collisions), but we can’t guarantee it will be
one which is one-way. The less salt we use, the less likely there will
be a collision, but the more likely that an attacker could brute-force
the hash function. With enough rolls, it would be possbile to guess
the seed or some internal state of a PRNG that someone uses for
generating their salt, which could also help you guess the salt.

Finally, this method requires O(n^2) messages to be passed among n
players. The only way that a player can be certain (supposing that a
secure hash function and RNG are used) that a roll was not fudged by the
other players is to provide input himself, even for rolls to which he is
not a party. In a 6-player game, there would have to be 2*36 = 72
messages passed in order to ensure the integrity of a single die roll.

As a further consequence of this, certain kinds of secret rolls become
impossble. I know I’ve played at least one game where I have a choice
whether to make a particular roll, but my opponent is privy neither to
the result nor to whether I’ve even made the roll before the game ends.
If this roll is not an interrupt, then I could simply announce a hash at
every possible opportunity to take the roll, but hash in whether I was
in fact taking the roll. Then my opponent could anounce his hash and
secret number, and I could announce mine at the end of the game. That
would work, but could be unbelievably tedious if the roll was something
that could be done at many different points in play. If, however, the
roll was an interrupt, I see no way at all of generating such rolls
using this method without leaking information that a roll had occurred.

So, to sum up:

  1. We could implement this using SHA1 and a cryptographic-quality PRNG.

  2. This would not scale well to large games with many separate
    occasions for dice rolling. Consider running a Car Wars game with
    a large area and 20 players. Every single roll would require 800
    messages to be sent over the network if you pass messages peer-to-peer.
    You could reduce this by pasing all messages via a trusted third party,
    but if you have trusted third party, why not just have them roll for
    you?

I’ll consider implementing this in VASSAL 4, but there needs to be a
limit on the number of clients which will provide input for any given
roll.


J.

On Jan 22, 2012, at 6:15 PM, Joel Uckelman wrote:

I’ll consider implementing this in VASSAL 4, but there needs to be a
limit on the number of clients which will provide input for any given
roll.

I would think that the internet die roller integration would be a more useful approach to dealing with this problem.

Thus spake Thomas Russ:

On Jan 22, 2012, at 6:15 PM, Joel Uckelman wrote:

I’ll consider implementing this in VASSAL 4, but there needs to be a
limit on the number of clients which will provide input for any given
roll.

I would think that the internet die roller integration would be a more useful
approach to dealing with this problem.

They don’t solve the same set of problems. An internet dice roller works
for PBEM, the distributed method doesn’t. The distributed method
potentially uses more bandwidth, but it’s bandwidth between users, not
between a single roller and all users.


J.

Can anybody point me to a few examples of Internet dice rollers that work for PBEM?

Thanks much.

Thus spake lmnop:

An internet dice roller works for PBEM

Can anybody point me to a few examples of Internet dice rollers that
work for PBEM?

There’s this one, which I run:

dice.nomic.net/email.html


J.

what if:

a script hosted on the 'net were to generate the dice rolls, along with a hash key of the packet.

when a die roll is requested, along with the request, connection info for each connected instance of Vassal is also sent

said roll and hash key would be transmitted independently to and stored in a log file with each connected instance of Vassal.

the only ways to circumvent that might be to hack the hosting server (probably more effort than it is worth for most) or to intercept the packets and modify them before they are logged. not much anyone can do about the former during a game, but the latter can be easily checked during or after the game with a comparison-check of the logged rolls and hash keys.

Thus spake nijineko:

what if:

a script hosted on the 'net were to generate the dice rolls, along with
a hash key of the packet.

when a die roll is requested, along with the request, connection info
for each connected instance of Vassal is also sent

said roll and hash key would be transmitted independently to and stored
in a log file with each connected instance of Vassal.

the only ways to circumvent that might be to hack the hosting server
(probably more effort than it is worth for most) or to intercept the
packets and modify them before they are logged. not much anyone can do
about the former during a game, but the latter can be easily checked
during or after the game with a comparison-check of the logged rolls and
hash keys.

This is not so different from what I devised some years ago:

Each game gets a UUID. A running hash is kept for the UUID, which is
returned with each roll. If the hash of the previous hash concatenated
with the next roll does not equal the next hash, then you know the
sequence of rolls has been tampered with.


J.