Hi Libertaad, nice to meet you!
Nice to meet you too!
What you say is only partially true: since Mersenne Twister is not a Cryptographically-Strong Pseudorandom number generator (CSPRNG) there is the possibility that the possible pre-images could be computed to maximize some statistical properties of the Mersenne Twister output. The advantage might be subtle, but it could be done, in theory.
My suggestion is to use a client_seed much longer (say 80 bits) and a CSPRNG.
A key reason that we went with Mersenne Twister for the reshuffle phase was because we place a lot of value on the reference implementation. We wanted an accessible reference implementation, that any of our end users could run. This meant it had to be in javascript. We didn't want to just have this awesome provably fair shuffling algorithm, but make it basically impossible for any of our end-users to truly verify anything.
We also didn't want to re-implement any PRNG's in javascript, because this would defeat the goal of having a simple reference implementation. Our reference implementation is less than 100 lines of code, but it does rely on an existing
Mersenne Twister implementation.
Great! But the problem is that the user has to manually check the shuffles every time. There should be a way to automate the checks, but in a way the the checking code is not sent by the server, but given by the user. An interfase between the web page and a local application.
I believe that a great way for a savvy user to do this on their own would be through a greasemonkey script. This is possible since bitZino is an HTML5 app. Since greasemonkey scripts are in javascript, the user could even use our reference implementation if they desired
There are (possibly) two other problems with your protocol:
1) The origin of the code that choses the client_seed:
I haven´t seen the page, but I doubt the user can provide the random seed manually in an edit box.
If not, then the server-sended client-side javaScript code could choose the number in a predictable way, and the user has no way to find it.
A "fake" webpage could be sent with a probability of 1/10, so the user chances of finding it while reviewing the source code is low.
bitZino actually does allow you to edit the client_seed if you so desire (you can see the interface for yourself if you'd like with a play money table at
https://bitzino.com/blackjack). While it would be possible for us to send down fake javascript on occasion to generate client_seeds that favored us, we would be guaranteed to eventually be caught if we did this.
This avenue of attack could also be stopped in its tracks by the user running a greasemonkey script which always submitted their own client_seed. In this way, the user would never be depending on the javascript on the page to generate the seed for them.
2) The way the client_seed random is chosen:
Again, I haven´t seen the source code of the webpage where the client_seed is chosen. (I haven´t played in your site) but I guess it has some javaScript code that calls Math.random(), which is not cryptographically secure and so it´s predictable.
How do you compute the client_seed ? You should use a CSPRNG, such as the one provided by SJCL namespace sjcl.random (I haven´t tested it myself)
Could you post the source code of the webpage where the client_seed is chosen ?
We are indeed using Math.random() to generate the seed.
The source code, if you're curious (it creates a 24 character base-62 string):
function setRandomClientSeed() {
var a = [];
for(var i = 0; i < 24; i++) {
var val = Math.floor(Math.random() * 62);
val += 48;
if (val > 57) { val += 7; }
if (val > 90) { val += 6; }
a.push(val);
}
$('#client_seed_input').val(String.fromCharCode.apply(null, a));
}
Once again though, the user could utilize a greasemonkey script to create their own seed, and therefore not rely on the page javascript for security at all.
We did think about making this whole algorithm greasemonkey script from the beginning - which would have satisfied all of your issues regarding the server sending down tainted JS. The reason we chose not to do this primarily as a greasemonkey script was once again about accessibility. We wanted 100% of our users to be able to verify their hands if they chose to. I still may make a greasemonkey verifier, but I think it would actually be better if the greasemonkey verifier came from the community, rather than from us.