CypherPoker v2.0, here we come!

Good news, everyone!

After lots of pondering, prodding, and poking I’m finally ready to move forward on CypherPoker. With this next version we will see a complete product, ready for wagering using cryptocurrencies, connected via the anonymous Tor network, and verified using Ethereum smart contracts. And I have some ideas for a nicer user interface too.

By way of explaining what’s taken me so damn long, here are some of the things that have been keeping me up late at night:

  1. Creating a math library for Ethereum (smart contracts) to deal with the size of numbers that can be used in CypherPoker.
  2. Handling dropouts in games with more than two players.
  3. Playing with multiple cryptocurrencies such as Bitcoin, Dogecoin, etc.

Although the solutions aren’t the ideal ones I was looking for, I believe I’ve hit a nice enough balance for me to put my nose back to the grindstone and finally complete a fully-functional version. Barring any major interruptions or unforeseen problems I’m aiming to have CypherPoker v2.0 ready by early to mid October.

The Math Library

A while ago I announced that I was working on an arbitrary-length integer math library for Ethereum, written in the Solidity smart contract language. There’s an explanation of why this is necessary in an earlier post on this blog but the short version is essentially that we need very large numbers in order to provide adequate security for the game (otherwise it’s feasible for someone to run through all the possible numeric combinations and crack the encryption).

However, this isn’t a straightforward process, especially given that Solidity is a rather rudimentary language. For example, in JavaScript and ActionScript we can easily convert between different types of data like numbers and character strings but in Solidity no such functionality exists natively within the language. This makes just the process of converting to and from the arbitrary-length number format challenging, and we haven’t even started to do math with the numbers yet.

While this library will continue to be developed, I wanted to speed things up a bit so I decided that it would be somewhat easier to work within Solidity’s 256-bit limit and have each player encrypt values multiple times instead just once using larger numbers. Although the security is not exactly equivalent, a one-pass 1024-bit encryption can be achieved by encrypting a each value 4 times with 4 unique keys (since 4 x 256=1024).

The commutative nature of the cryptosystem ensures that each player can encrypt values as many times as they like so while one player may choose to encrypt 3 times another player may choose 6x encryption. As long as the decryptions match the encryptions everything will work correctly.

My hesitation in taking this approach was grounded in my understanding of the security of the RSA cryptosystem. There are two major points, however, that give me confidence:

  1. SRA uses no public key. Keypairs are kept private and by my estimates there are roughly 2253 of them for any given 256-bit modulus.
  2. Values may be encrypted an arbitrary number of times with any valid keypairs.

Updating the game engine to work this way should be fairly straightforward and this approach will make the smart contracts much easier to code. I’d like to see a rigorous cryptanalysis done on this approach but it looks like a good interim solution.

Dropout Handling

This has been a topic I’ve been wrestling with quite extensively and it looks like there are really only two reasonable approaches, each with its own unique drawbacks.

In order to illustrate why the first approach – the existing dropout/re-keying protocol –  isn’t ideal let’s imagine that you’re involved in a 3-player game; it’s you against 2 colluding players. Something similar to the Rochambeau protocol will minimize the possibility of colluding players being paired up but for this illustration let’s say that this is the composition of the current game.

Now let’s say the community/public cards so far are A♠ 7♣ 7♠, you’ve been dealt 2♠ 5♦, colluder 1 has A♥ 6♥, and colluder 2 has been dealt 7♥ 3♦. With 43 cards remaining in the deck, colluder 1 has a 1/43 chance, or 2.3%, of drawing that final seven to make a full house. On the river, colluder 1 will have a 1/42 chance (2.4%) or drawing that other seven.

Because they’re communicating, colluder 2 knows what his partner is holding and so he drops out of the game by disconnecting. The process that this kicks off has the effect of returning the dropped-out player’s cards back to the deck so that the chance of drawing another seven for colluder 1 are now 2/43 (4.65%). On the river this increases to 2/42 (4.76%). Of course this doesn’t guarantee that colluder 1 will actually get a seven, and perhaps I may be holding a seven so the odds are smaller, but either way this increases their chances of making a wining hand.

The second approach to dealing with dropouts is to simply return the bets for the current hand and deal a new one for the remaining players. The advantage that may be gained here is that disgruntled players and colluders get a do-over while taking a peek at your strategy but at the cost of allowing further collusion and potentially more since the dropped-out player’s buy-in or pot contributions would remain in the game. Of course, this could also be frustrating if you have a particularly good hand and a player drops out.

It’s important to note that this isn’t an issue with two-player or heads-up games, and what constitutes a dropout will be configurable so truly accidental disconnects needn’t necessarily be penalized (reconnect within 5 minutes, for example). Nevertheless, both of these multiplayer strategies have their advantages and drawbacks so for that reason the option of which one to use will be included with each game and enforced by the associated smart contract(s).

I’ve gone over my archive of literature on the topic to see if anyone has managed to successfully address dropouts and it seems that the approach I’ve taken is essentially it, at least for the time being. There are slightly more elegant ways to handle dropouts and dealing of cards in general but they all have the effect of returning the dropped-out player’s cards back to the live deck; anything else would involve knowing, or being able to deduce, which cards a player is holding (yikes!)

I’ve also explored the field of zero-knowledge proofs which, although they’ll make great additions to the suite of cryptographic proofs available for verifying the game, don’t allow us to extrapolate information about which cards should or should not remain in the deck after a dropout. Again, this would have the effect of allowing other players a peek at a certain player’s cards.

Among other considerations I’ve thought about ways to split the pot when a player drops out but these either increase advantages for colluding players or introduce unfair awards. For example, it would make sense for a  colluder to drop out if his partner received two pocket aces — the highest verifiable hand possible with only two cards and therefore the winner. If we adjust the pot split based on what may have been dealt in the rest of the hand it would be extremely unfair to the player who was actually holding the highest combination.

Another consideration I’d discussed on the CypherPoker slack was to introduce some sort of insurance that each player would add in addition to the pot. To ensure that players don’t feel cheated it would make sense that each player remaining after a dropout would be awarded with the maximum possible pot for the game. For example, if the buy-in for a three-player game is 1 BTC the winner should receive 3 BTC at the end. In order to cover this amount each player’s dropout insurance would be 3 BTC in addition to their 1 BTC buy-in (total of 4 BTC). Should a player drop out, the remaining two players take back their 1 BTC buy-ins and receive an even split of the dropped-out player’s insurance+buy-in, or 2 BTC each. Clearly the problem here is that the insurance quickly grows as the number of players increases — hopefully our network connection doesn’t tank during a game!

As it stands, the best approach at this time is simply to use one of the aforementioned solutions with a basic reputation system. A player’s reputation would consist of the number of successfully completed games, stored in a smart contract, so that when you’re looking for players you would have some indication of your opponent’s reliability.

Cryptocurrency Support

One of the features that got people excited about CypherPoker was the potential to play using Bitcoin and other cryptocurrencies. Since smart contracts running on Ethereum are funded by Ether it made sense to point out the fact that direct play using this cryptocurrency would likely be the easiest approach. Although I’ve never ruled out using cryptocurrencies like Bitcoin, I’ve since done more investigation and I’ve concluded that there’s really no reason why CypherPoker can’t support most of the major cryptocoins via services like ShapeShift.

Naturally, there are fees associated with converting from one cryptocurrency to another but ShapeShift’s API should allow good integration with CypherPoker while making the mechanics mostly invisible to the player. The process should be fairly straightforward: exchange from the source cryptocurrency to Ether, wait for the confirmation, play, exchange winnings back to source cryptocurrency for withdrawal. In this context, having more permanent “play wallets” on the Ethereum blockchain would make sense in order to minimize the exchange costs.

Anonymity

With the development of the Golden Faucet 3-reel slot demonstration game I have a much better idea of how anonymity will be implemented in CypherPoker.

In terms of a personal identifier (for reputation, for example), the only information that a player will need will be a valid cryptocurrency address of some sort.

The CypherPoker client will initially launch Tor as an invisible background process and create a .onion service that will act as a communication end-point. Each CypherPoker software installation will act as both a HTTP(s) server and client so there will be no exits to the public internet. Furthermore, because the protocol stack is strictly controlled there will be no information leakage, such as might happen through generic HTTP headers via traditional web browsers/servers.

Once the .onion service has been deployed the CypherPoker software will publish its details, along with the associated cryptocurrency address, to the Ethereum blockchain. Third-party services, which can also operate over Tor, can also fulfill this function in order to reduce initial costs to players (since each smart contract interaction has a small cost associated with it).

Using such player introduction services, available players can discover and connect directly to each other. Of course, if players already know each others’ .onion addresses they can connect directly, entirely bypassing any sort of introduction service. If anonymity and privacy are not a concern, players may even connect directly to each others’ IPs, and the RTMFP protocol will remain for players who want to play locally over LANs / WLANs or tether connections.

The CypherPoker software will run the Ethereum client in the background in order to interact directly with the blockchain and smart contracts, and additional clients such as Bitcoin will also run invisibly in the background in order to interact directly with various cryptocurrency wallets.

This separation between the core CypherPoker game software and the various clients means that they (clients) can operate as external proxy services for players who can’t or don’t want to run the full stack on their machines. For example, the CypherPoker game software can operate on a mobile device while interacting with Tor, Ethereum, and Bitcoin clients running on a more powerful desktop PC. This PC may operate remotely and can be provided as a third-party service similar to cryptocurrency web wallets.

Finally, the I2P network handles anonymization and hidden/private sites very similarly to Tor and so it makes an excellent candidate as a secondary way to enable privacy and anonymity for players. Mixing up messages across multiple networks can help to bring player anonymity and privacy to a whole new level.


With everything I’ve described here I think we’re looking at a solid foundation for the first, fully-functional version of CypherPoker. As always I expect improvements, revisions, and bug fixes, but we’re now at the point where we’re ready to move beyond a proof-of-concept. Now is the time to get involved! Join the slack, comment on the subreddit, drop me a comment here (or email me at patrick (at) cypherpoker [dot] org), and keep an eye on the cypherpoker.org site for updates.

Add Comment

Required fields are marked *. Your email address will not be published.