Our current scheme for private information involves committing to player hands and the card remaining in player decks (via a (to be salted) Merkle root) and then proving changes to these roots via zk proofs. We also use on-chain randomness to select random cards and prove in the zk proof that the correct cards were drawn from the deck.
This has the advantage of being relatively simple and not require extra infrastructure. The disadvantage is that it limits us in terms of gameplay: game often have mechanism that manipulate the deck, such as "look at the three top cards of your deck and put them back in any order". The current zk scheme does not allow us to do this (or we need to special case for every potential effect, and it gets really complicated and expensive really fast).
An alternative exists in the form of zkShuffle, an implementation of "mental poker" by the team at p0x Labs.
I wrote some twitter threads on both system:
But in brief, mental poker thresholds encrypt every card by all players (both in our case). I encrypt then shuffle, pass the shuffled deck to you, then you encrypt and shuffle. The result is a deck where nobody knows what card is where. To reveal a card publicly, all parties need to collaborate. To reveal a card only to player X, all players except X decrypt publicly, and X decrypts privately.
This system allows any card system we want BUT comes with the problem that both players need to collaborate when revealing a card. This could mean extra on-chain latency or an off-chain component (server or p2p) to aggregate the descriptions. In practice though, the El Gamal encryption scheme is expensive to compute on-chain and so zkShuffle uses zero-knowledge proof to prove the El Gamal decryption on-chain instead (also maybe there is no way to tell that a ciphertext was decrypted with the right private key? I really have no idea how El Gamal works).
But anyway, all that work has been by the good folks at p0x Labs, who are also making their system available as open source software. The tech was used to implement https://zkholdem.xyz. Some resources:
The goal of this issue is to investigate the use of zkShuffle as applied to 0xFable. No better way to learn than by doing, so basically, reimplement the system with zkShuffle — in particular, its current state with the demo game loop (draw, play creatures, attack, defend) which only needs zk for drawing & playing.