TL;DR: 999dice is not provably fair at all, but they hide is so well, you'd never actually know it.
Stupid-long version:
I'd like to start with some background. I'm involved in the crypto community, have been mining and trading bitcoin for a very long time. (Well, very long being a relative term.) I'm a programmer, I enjoy math, and few things give me more joy than figuring out a math/programming puzzle. I've also dabbled with gambling my entire adult life. Not addicted to it by any stretch of the imagination. Losing is frustrating and ruins the joy of it. The joy I get from it is figuring out how it works, and making it work to my advantage. Card counting? Sure, sometimes. That's a bit boring however. Let it Ride is my favorite game to play for fun. Being able to increase your bet (or reduce your losses) depending on how your hand plays out? Oh, that’s fun. (Yes, I'm aware the house edge is about 3.5% or so on Let it Ride, and card counting doesn't do much good, but at a table in a casino, when the other players realize there's an advantage to sharing their hands with each other, that changes the odds a little).
Anyway - I wrote the above just to give a little background on where I'm coming from. Naturally, being a lover of all things crypto, I eventually gravitated towards sites like primedice and satoshidice and not too long ago, 999dice.com caught my attention. .1% house edge? Wow. That’s not bad. And since it's based on cryptography, you can't accuse them of cheating, like I'm sure all the online casinos engage in.
So I start betting there, and I'm doing ok. Up 10-20 BTC some days, then I lose it, then back up a little. Yes, my bankroll for playing games is large. If you were in the chat rooms while I was playing, before I realized that the setting to disable announcing your bets in chat, you probably saw some of my bets. My auto-assigned name there was Euphantes, or something similar. My account has been deleted so I cannot access it to check. (Login names do not = chat names on 999dice.com). But shortly after my winnings went up and down, I started losing. Very badly. Against all odds it was loss after loss after loss. Last I looked my main account was down 108 BTC.
So I decide that I'm switching to an automated system based off of their API. Loving programming, I whip up a simple (which quickly became not so simple) internal webpage that had two functions, testing and live. In testing mode, I could run simulations and see how different strategies would net the largest wins with the lowest risk in the shortest amount of time.
After this post, as a reply I want to post something long winded, but worth reading, on betting systems, "luck" and how math proves the first worthless and ruins any concept of the second. It was originally here, but became too long and made this post more technical than I intended. Anyway, moving on...
Knowing you cannot beat math, I try a few different techniques to try and have the lowest risk, with the largest payouts, quickly so I can get in and out before math nails me. I run these strategies through my simulator, which uses truly random numbers generated by random.org. For anyone unfamiliar, random.org provides random numbers that are generated by encoding atmospheric noise generated by (if memory serves correctly) a radio tuned to a null station, static. The static is digitally encoded as, basically, a wav file, and bits are extracted to form random numbers. You cannot get more truly random than that.
So I test my strategies over and over, to the tune of 1, 10, 100 million rolls each, so I know how and when they go broke.
And I start betting.
And without fail, my betting strategies that produced reasonable results in my simulator failed miserably when put to actual use. My god. How horrific is my luck?! (Using the term loosely, of course). I try, and try. I change my win percentage. I change my risk factor (betting higher limits to decrease the odds I max out). I lower my starting bet. I find other ways that produce a few bitcoin per betting run, with a reasonable risk. And I then bet them, for real. And lose again.
What. The. Hell?!
So I then think, I need to actually validate this site's 'provably fair' betting. And that’s when I saw it.
Before I get to that, the site is intentionally misleading. The method the hash is generated states that the formula is server seed + client seed + bet number is then double hashed and other stuff is done. The first code example (in a language hardly anyone actually uses) does not add the "bet number”. The second (which is written to be compiled in a Microsoft .net environment - how many bitcoiners work in .net as opposed to Linux/g++/etc.?) example does.
The first example does no endian reversing of the bytes, the second does.
Nowhere is the bet number explained. What is the bet number? The bet ID? Makes sense it is...? If you place a bet and then click on the resulting roll in the bet results window, you get to a verification page, which shows under the # sign (indicating number) a 0, and then next to that is the word "Number" and under that is the bet ID. So what the hell is the bet number? Is it the number under the number symbol? The number under the word number? Do we reverse the bits? Do we USE the bet number at all? The code example the site says they actually USE doesn't even use the bet number, whatever the heck it is. The page is, I believe, intentionally ambiguous.
I emailed the admin for clarification, and he did clarify. And since the page has always been written like that, I will assume that NO ONE has EVER actually bothered to verify a bet there, independently. Which is sad. Or if they have, they also needed clarification, and the admin intentionally never actually clarified the page.
Just wanted to point out what I believe to be intentional misleading information. For anyone who wants to actually verify, the bet number is the bet sequence number - always 0, unless you are doing a multibet, in which case it starts at 0 and goes up to 199. The client seed, and the bet number are reverse-endian, for some reason, also not clearly explained on the site. Using that information I WAS able to verify bets.
What? I was able to? Then they aren't cheating, right?
Bullcrap they aren't.
Go to most dice sites. They publicly show the hash of the day, and on the next day they show the seed that generated that hash. You can hash the seed to yesterday's hash, and use the seed plus the other info to validate every roll you made the day before.
Some sites change the seed with every bet, to make it impossible to find the seed and cheat the site. Satoshidice does this, and shows you the hash on screen with every bet.
999dice APPEARS to show you the hash, but does not.
Where is the hash for your next bet on 999dice? It's on the provably fair tab. Click it. Show me where the hash is.
What? You can't see it? Oh, right, YOU NEED TO CLICK A BUTTON TO SHOW IT.
** PLEASE, READ THE NEXT THREE PARAGRAPHS VERY CAREFULLY. This is how 999dice is stealing thousands of your bitcoin. **
Until you click that button, you cannot see the hash. If you NEVER click that button, that seed, and the hash that is generated from it, can be WHATEVER THE HELL 999dice wants and needs the seed to be. Are you on a big winning streak, and feeling lucky, and place a huge bet? Are you on a horrifically bad martingale losing streak, doubling your 5 satoshi bet all the way up to 3.35 bitcoin and praying to god you don't lose AGAIN? **DID YOU CLICK THE BUTTON TO GET THE HASH BEFORE YOU BET?**
No? Oh, ok then - sorry - you lost the roll. I guess it was just really bad luck. Do you want to validate that it was actually a losing roll and make sure we aren't cheating? Ok, here's the server seed we used, right there on the hard to find and not explained how to get there validation page, you can use that with the client seed and the bet number and you can validate and see clearly that it all matches up. See? We aren't cheating.
Wait, hold on a second... how the hell do you know that seed wasn't created AFTER you clicked the bet button and the site decided it was time for you to lose? YOU CAN'T. SUCK IT. It is utterly impossible. Because since there's a new hash with every bet, if you didn't request the hash before that crippling losing bet, piss off loser, you can't prove a thing. Once you click bet, if you didn’t copy/screenshot the hash that proves they did not generate the seed AFTER you clicked bet, it's gone. With no way to EVER. PROVE. ANYTHING.
Remember in the title how I said "and exactly why I'm positive you won't believe me"? Here's why:
You decide you want to catch the cheating jackass. So you place some bets, requesting the seed before each bet. And EVERY single roll matches up. Every bet you make, hashed out on your own computer, is legit. You win some, you lose some, but they are all, absolutely, positively, PROVEN beyond any shadow of a doubt to be provably fair and impossible to cheat. LEE-GIT.
Well, shit. You thought you were going to catch him.
And THAT is why his system is elegantly, beautifully, genius-level brilliant. When you click that button, the server KNOWS you are going to be validating the seed. The server KNOWS it can't cheat this roll. The server KNOWS you might validate the bet, you have the hash, it HAS to use the seed it promised it would use - it can't risk cheating and you catching it red handed.
Wanna see something REALLY slick? Open the laughably fair tab. Click the "get server seed" button. Look at it. See the hash? Don't change tabs. Watch the hash. Click bet. (Get some doge from the faucet or something). Did you see the seed change to the new one?
NO. You did NOT see it change to the new one - because the BUTTON REAPPEARED FORCING YOU TO CLICK IT FOR **EVERY** BET!
You click it, you copy the hash, you make a bet, you validate the seed, and the hash disappears. And you have to click the button again. The button on the tab which hides your bet results, the chat room, everything.
Who is going to place 100 bets on the site, clicking the button, copying and pasting the hash, then betting, then making sure the seed for that bet actually hashes out to match the copied hash, then doing it all over again?
NO ONE.
And that is EXACTLY why no one reading this will believe a word I am saying. Because anyone who tries to validate their bets will always have them validated 100% of the time, until they stop validating, and then they have absolutely NO way at all to know if they are being cheated or not. It is absolutely, beautifully, elegant, "politicians around the world would be envious and proud"-level deniability. No one can EVER prove he is actually cheating. Ever. And he can ALWAYS prove he is not. Always. Because he can cheat you out of every bet you make, UNTIL you explicitly TELL him, "I am watching you." And once you tell the server you're watching, it knows it can't cheat. Until you get tired of clicking that button before every bet.
The API refuses to tell you the hash also, unless you intentionally ask for it before betting. Slowing down your bets by half, which is annoying because you are likely using the API to speed your bets up. But really, who actually uses the API?
Want to know how Satoshidice's API works? First, you start a betting session by sending a command. That returns the server hash.
Then, AS A REQUIREMENT TO PLACE THE BET, you absolutely MUST send that hash you just got back to the server as a parameter to the bet function, to PROVE you have seen the hash. Let me reiterate that: you can NOT place an API bet with satoshidice without PROVING to them that you've seen and have recorded the hash.
Then the result of the bet returns the hash for the next bet you make, which, again, you're not allowed to place until you again prove that you have the new hash.
Satoshidice forces you to see and confirm you have the hash. 999dice makes it an annoyance to get.
So after losing 108 BTC on my main account, and another 99 or so on my API account - yes, I lost 207 BTC on 999dice, and after making over 8 million bets to the tune of a total of about 92,000 BTC in total bets (thereabouts), I was NEVER up more than 20, and then only briefly at the beginning, and then it was loss after loss after loss, I retrofitted my API script to send the API call to request the seed before every bet, and every time a bet was lost, it hashed everything out to ensure the site was not cheating.
After doing that, forcing 999dice.com to play fair and preventing it from cheating, in a span of 14 hours in which I had 3 betting sessions (deposit, bet, withdraw, go do something else for a while), I won back 61 bitcoin, the first two being deposits of 40 BTC each and quitting/withdrawing after I was up between 25-30 BTC each, the last being a deposit of just 4 BTC and quitting when I was at 7.3. My betting strategies (risk X amount to win Y bitcoin on every press of the go button, with a risk of Z, and quit after I am up a set amount) that worked on the simulator suddenly worked on the site. My colossal and mathematically improbable losing streaks suddenly stopped, and I was winning back my stolen bitcoin.
Then I received this email (my personally identifying information XXX'ed out)
-----
Return-Path:
admin@999dice.comReceived: from imap11-2.ox.privateemail.com (imap11-2.ox.privateemail.com [192.64.116.199])
by XXXX (8.14.4/8.14.4) with ESMTP id t15NFufU015721
for <XXXX>; Thu, 5 Feb 2015 18:15:57 -0500
Received: from localhost (localhost [127.0.0.1])
by mail.privateemail.com (Postfix) with ESMTP id D0307880314
for <XXXX>; Thu, 5 Feb 2015 18:15:55 -0500 (EST)
X-Virus-Scanned: Debian amavisd-new at imap11.ox.privateemail.com
Received: from mail.privateemail.com ([127.0.0.1])
by localhost (imap11.ox.privateemail.com [127.0.0.1]) (amavisd-new, port 10024)
with LMTP id dMVUR-J0gp5g for <XXXX>;
Thu, 5 Feb 2015 18:15:55 -0500 (EST)
Received: from [192.168.0.185] (kaputte.li [194.150.168.95])
(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))
(No client certificate requested)
by mail.privateemail.com (Postfix) with ESMTPSA id 84C2B880289
for <XXXX>; Thu, 5 Feb 2015 18:15:54 -0500 (EST)
Message-ID: <
54D3F9B0.6040603@999dice.com> (sfid-20150205_181558_975973_AC99148C)
Date: Thu, 05 Feb 2015 23:16:00 +0000
From: "99.9% Dice Support"
admin@999dice.comMIME-Version: 1.0
To: XXXX
Subject: Re: Followup
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
XXXX,
*PLEASE MAKE NO FURTHER DEPOSITS*
I am glad to see that my email got through. My email provider was having
troubles all day. I was not sure that it had, because I saw your bets
pop back up in the chat room. There's a pending withdrawal of 7.3 BTC or
so, which I will release after clicking "Send" on this email.
If I see further deposits, they'll be seized. If they're on new/stealthy
accounts that you think I won't know about, they'll still be seized -
please don't test what you can get away with - you'll lose your money.
You have no remaining balances on your account - everything that is
yours will have been paid out within a couple minutes of this email
being sent. I wish you the best of luck earning back what you've lost -
but it will have to be elsewhere - not on this website.
Jake
-----------
(Side note: Why does the admin of a legitimate site need to use privateemail.com and access said site through tor? Odd, that)
Yep. I figure out how the cheating works, and how to avoid it, I TELL him I've figured his scam out, I start winning back my lost bitcoin, and unsurprisingly, I am banned from the site.
There were many back and forth emails. When I first discovered the scam I went ballistic and demanded he return my stolen 207 bitcoin, or I'd make it my life's work to see his site shut down. I explained how the bet ID could be faked, and how the site could cheat by having to request the hash. He politely replied that I was mistaken about how the bet ID was part of the hash (I thought it was the bet ID, not the bet number which I explained above). He ignored my second accusation.
I wrote back and said ok, you're right, thanks for clearing that up about the bet ID/bet number issue, but still, you can cheat by knowing when we're looking at the hash. He ignored this email.
So I started doing testing. I ran the API, using doge, and made over 1 million bets at a 95% win chance, and my final numbers were a 95.0172% win ratio (or something close). Which sure seems like the site is legit... except that although I had a 95% win ratio, I was still down more then I should have been.
How is that possible? Because the site only needs to make you lose a few extra times on larger bets to really punch your wallet, and that would never truly affect your win percentage when you're making a million rolls. It's especially bad with martingale strategy. 49.95% odds, 1 million rolls, you can have a 49.96% win result, yet be down hundreds of bitcoin, if you won a lot of 1st rolls, and the rolls that were faked were the ones where you're at the end of the run and betting 35 bitcoin. Fake just 10 rolls out of 10000 and you bring a 49.95% win ratio down to 49.85%, something that is perfectly within the bounds of random chance. Yet 10 faked rolls could cost you 350 bitcoin if they are timed just right.
So I email him and say that I ran tests and it appears the site MIGHT not be cheating, but, I still don't trust it and I'd like an explanation.
I am ignored.
So I retrofit my script to pull the hash, and I win 61 bitcoin in 14 hours.
And then get an email that I am banned and all deposits will be CONFISCATED.
The reason he states for the ban is that I lost a lot of bitcoin, and went crazy screaming at him and calling him a cheater, and threatening extortion and going "mafia style" on him. In the chat room last night he even claimed I threatened his life. Absolutely not true. I demanded my stolen coin back or I'd do my best to expose him and ruin him/his site. So then he saw me betting again, and was afraid that if I lost again, that I'd blow up at him again.
Let's be clear here - by his own admission - the reason I was given that I was not only banned, but any deposits I made would be confiscated, was because he "was afraid" that I'd lose again, and send him meany face emails.
What? Seriously?
It had nothing to do with the still, until this day, ignored accusations about cheating and theft? I even went so far as to say in an email, "All you had to do was say, 'Oh, crap, you're right! The way I have users request the hash really COULD be seen as cheating, and since I'm honest, I'd never want that, so I'll fix that right away. I am so sorry it came off that way!" and it would have shot my theory down. That never happened. EVERY time I directly asked him to explain, that question was ignored.
Late last night I was trying to warn some people in the chat, and as I was being repeatedly banned, I sent him an email asking if he was working hard tonight banning every tor window I could open, and all he needed to do was return my bitcoin and fix the site and I'd leave it be.
He responded that he's sorry I lost money, and before I do anything rash, he thinks I should wait a week or two to calm down before taking any action. "The site isn’t going anywhere and isn’t changing in two weeks".
What? Really? Take TWO WEEKS to "calm down"? How batshit crazy do you need to be to take TWO WEEKS to calm down?
My ex-wife once very inappropriately yelled at and went off on my son and said hurtful things to him, and I went absolutely nuts on her, having one of the largest fights we ever had, and even then I didn't need two weeks to calm down.
And to specifically state that the site isn't changing in two weeks? How about - how about - let's examine this... how about I wait two weeks so that you can make modifications to the site and any accusations can be ignored?
However, at the end of the day, I have absolutely zero proof of what I claim. The site is designed in such a way that it's impossible to prove. It's genius, really. And that's why I doubt anyone will actually take this seriously. They will talk about it in the chat room, the admin will blow it off and say how the crazy guy was mad he lost 200 bitcoin, he'll say I threatened his life and god knows what else, and be chatty and friendly, and people will ignore it. And continue to be stolen from.
But I'll close with the following scenario.
You suspect that your wife is cheating on you with your boss. The bed is way too rumpled when you get home, and she's putting off that vibe. Your boss makes snarky comments here and there, but nothing you can ever prove. But in your gut you know it's happening, but you can't prove a thing.
They both deny it and say you're being paranoid.
You WANT to catch them and prove it's happening, but in order to leave work and not get fired, you have to let your boss know you're leaving the office mid-day. You have to tell him that you won't be at your desk, and your boss knows that you might be going home. And every time you do... everything is perfect. You never catch anyone. In fact your wife is ready for you to come home, everything spotless and pristine, exactly how you'd expect it to be if nothing was going on.
People, please... when you have to inform the person who's cheating you that you are watching them, you will NEVER catch them. And when they know it's impossible for you to check on them, they can do whatever they want.
Do your own due diligence. Place bets. Notice how you always seem to lose that crucial bet. Then take the time to record the hash and see if your luck changes. The best part about all this is that by posting this, the admin may well turn off the cheat mode so that even non-hash-checked rolls are legitimate, so no one can prove otherwise. Which I guess is a victory if it stops the cheating.
Decide for yourselves, but don't be stupid and blatantly trust a site that hides the hash, makes you tell them you're looking, and provides deceptive information for calculating the hash yourself.