edicted Blog Banner

edicted

Draw() RNG Shortcut

deck-poker-rng-random.jpg

So what is the point of this post?

Yesterday I talked about how random numbers don't really exist. Our perception of random events simply stems from ignorance due to the complexity of the system we are engaging with. However, this time around I'd like to focus on something a bit more specific: Can we create pseudo random numbers on the blockchain?

Creating a decentralized deck of cards on the blockchain is shockingly complicated because of the complexities of generating random numbers online while also making sure they are not exposed to the opponent. The logistics are seemingly insurmountable:

  1. Draw a card from the deck without anyone seeing.
  2. Be able to prove which card you drew without the ability to lie.
  3. Make sure that the card you drew hasn't already been drawn from the deck while simultaneously making sure that nobody else's cards are exposed.

#3 is the ultimate sticking point.

It's one thing to draw a card from the deck and keep that information safe from prying eyes, but the amount of complexity required to make sure that card hasn't already been drawn from the deck is just ridiculous. How is it even possible? Surely with some math-ninja Zero-Knowledge magic it is technically achievable.

However, I'm told that these zero-knowledge strategies are too slow and inefficient to create an acceptable UX. If players have to wait an unacceptable amount of time for every Draw() from the deck... they simply aren't going to play. Poker games need to clip along quickly at around 1 hand per minute. If ZK-proofs aren't fast enough to accommodate this pace then they become worthless on a practical level.

But what if...

The sticking point on a decentralized deck of cards is that a card can only be drawn from the deck one time... so what if we just changed the rules to allow duplicate cards to be drawn? This fixes all of our problems and turns a very complex solution into a quite simple one that doesn't even require zero-knowledge.

How?

Each player/client generates a temporary password for the card they are going to draw from the deck. On a technical level the player can choose any password they like but on a practical level it would probably be something like a 12-word crypto seed that can create infinite secure passwords automatically during the game.

Then each player masks their password with a hash and posts that hash to chain (or just sends directly to the other players p2p). Now each player's card draw is locked in and can't be changed, as finding a new password that matched the hash of the password would be just as difficult as cracking encryption directly.

All of the players now broadcast a number that keeps their opponents honest. This number will be included into the algorithm that draws from the deck. Essentially every player in the game will change (shuffle) which cards will be chosen for every other player. Every number added to the pile completely changes the RNG, ensuring that none of the players at the table can collude against the others.

Once the shuffle-RNG from the opponents has been submitted, players will be able to figure out what card they got from the deck. The client accomplishes this by feeding the private password and the public shuffle-RNG numbers into an algorithm, which will tell them what card they draw(). No one else knows what the card is because the password is still masked by a hash or a public key (which gets revealed later [or not] at the appropriate time).

or not

In many cases the winner of the hand won't even have to reveal their cards or password because they won due to everyone else folding. However, should it get to the end and hands need to be revealed to see who wins, the client will simply broadcast the private password which in turn allows everyone in the game to validate the hash and confirm who has which cards.

Of course the language I'm using here assumes that the game being played is poker (more specifically Texas Hold'em), but something like this could also be adapted to other popular casino games like Blackjack. In fact, a system like this makes even more logical sense for Blackjack than it does for poker because Blackjack already uses multiple decks at the same time; it is already possible for 2 players to pull the same card on the same round.

This system I'm describing would be synonymous with using an infinite amount of decks, with every card always having a 1/52 chance of being pulled from said virtual deck. An implementation like this makes it literally impossible to count cards to get an edge against the dealer. However, such a decentralized system can also allow any player to be the dealer, and a totally fair game of blackjack could be played by allowing the dealer to rotate around the table just like it would in a poker game.

Draw() cards in advance.

There's also no reason why card's can't be drawn for rounds that haven't even happened yet. Theoretically this applies to a ZK solution as well. If ZK is too slow there are ways to speed rounds up by shuffling up and dealing out hands while the current hand is being played, with the frontend only revealing that data when it's appropriate.

Collusion

The step that allows players to shuffle everyone else's picks is just as important as all the other steps. If two players decide to cheat, say player 1 and 3, then player 3 could just wait for everyone to shuffle the cards and then manipulate the numbers to allow player 1 to draw whatever card they wanted. Even worse, when the card in question is shared between all players this problem is even more pronounced.

It's pretty obvious that in addition to protecting their own cards, the shuffle() function of all players also has to be password protected. This adds an extra necessary step, but considering how much back and forth chatter is required for zero-knowledge implementation, I'm guessing this solution would be exponentially faster than decentralized decks that insist on hammering a square peg into a round hole by not allowing card duplicates.

What do we lose?

A lot of the strategy behind card games is the knowledge that there are no duplicates. A good example of this is when a flush is the best possible hand in Texas Holdem, so anyone that has an Ace-high flush knows for a 100% fact that they're going to win. These kinds of statistics and strategies are lost when duplicates are allowed. Still, I think it's more than worth it to create the duplicate version if only to build up a community before working on the more difficult implementation.

Wait is this even random?

This solution to RNG card drawing isn't really random at all, is it? It's hardly even pseudo random. Rather, all card draws are simply password protected by all the players involved. Is "password protected" really random? Certainly it's robust enough to create an even and unpredictable distribution, which fits the definition of random. However, it is obviously a very unconventional way of going about it. Since when has randomness ever been achieved by mashing passwords together?

Conclusion

Does this idea have any merit whatsoever? Honestly I really have no clue. To be honest it's not even a new idea and I have code floating around here somewhere that even worked on a basic level. It uses JavaScript Math.random() and SHA-256 hashes so it's not particularly secure, but then again a prototype doesn't really have to be. If I recall the code I wrote for this actually worked for a small side project I was working on (basic rock/paper/scissors clone). I'll have to go dig it up one of these days and get back to work.

The main theme of this post is that we need to stop getting stuck within our rigid viewpoint of how things should work. Adapting a deck of cards to decentralized blockchain is completely non-trivial because we have to prove to all parties that the card being drawn haven't already been drawn without actually revealing any of the cards in question.

If we allow duplicates to be drawn from the deck all this complexity falls away and becomes a much more basic multi-sig style solution rather than zero-knowledge. Sure: it won't be exactly the same, but it will be good enough to work. Isn't that what crypto and decentralization is all about?


Return from Draw() RNG Shortcut to edicted's Web3 Blog

Draw() RNG Shortcut was published on and last updated on 06 May 2023.