SDK - Shuffle
Hide card information and ensure card security.
Environment
Language: javascript/typescript
Overview
Almost all multi-player card games require a fair and unpredictable shuffling mechanism. Simply using random numbers on the chain cannot meet this demand. Therefore, Zypher provides Shuffle solution, and the usage process is as follows.
graph LR;
Start(["N Players join game \n with their own public keys"])
Aggregate["Aggregate N public keys \n to generate a shared key"]
Mask["Mask the deck \n by the shared key"]
Shuffle{{"All players \n shuffle the deck"}}
CollectOtherRevealTokens["Collect reveal tokens (N-1) \n from other players"]
ClientUnmask["Player can check the card locally"]
CollectAllevealTokens["Collect all reveal tokens (N)"]
ChainUnmask["Everybody can check the card on chain"]
Start --> Aggregate
subgraph Shuffling
Aggregate --> Mask --> Shuffle
end
subgraph Revealing
Shuffle --> CollectOtherRevealTokens --> ClientUnmask
Shuffle --> CollectAllevealTokens --> ChainUnmask
endInclude:
The beginning of the game
All players provide their own public key, which is used to generate the game aggregated key for the game.
We use the aggregated key to mask the originally public cards into a deck dedicated to the game.
Shuffling stage
Each player takes turns shuffling the deck and updating the deck based on the previous deck state.
When updating the deck, we will use the ZK mechanism to ensure that players have the ability to disrupt the deck based on our rules.
opening stage
For the card whose result is to be displayed, the correct card content can be displayed by gathering the reveal tokens of all players.
When submitting reveal tokens, the contract can ensure that each player provides the tokens that comply with the rules through the ZK mechanism.
If only a single player wants to see his hand, other players need to calculate the corresponding token of their hand and give it to that player.
If the card is to be fully disclosed, all players will hand over the corresponding tokens to the contract, and the card will be confirmed through on-chain calculations.
Below we use a standard game process to demonstrate how to use the Shuffle solution we provide at each stage.
Installation
We package the WASM and types used on the front-end and the verifier interfaces used on the contract, and upload to NPM packages. It can be downloaded to the development environment through npm:
For the contract part, please select the verifiers address from the table below:
opBNB Testnet
ShuffleVerifier (20)
0x1De814F9A303253288fa9195C6e7aae7cabB6670
opBNB Testnet
ShuffleVerifier (52)
0xfbDF4217a3959cE4D3c39b240959c800e3c9E640
opBNB Testnet
RevealVerifier
0x8d084e5c212834456c07Cef2c1e2a258fF04b5eb
Arbitrum Sepolia Testnet
ShuffleVerifier (20)
0x.....
Arbitrum Sepolia Testnet
ShuffleVerifier (52)
0x.....
Arbitrum Sepolia Testnet
RevealVerifier
0x.....
Game Starts
At the beginning of the game, each player provides his or her public key. After having the public keys of all players, the contract can calculate the game aggregated key specific to the game.
Players provide their key.pkxy to the contract to generate the encryption key for the game.
After all players have provided public keys, the game aggregated key can be generated through ZgRevealVerifier::aggregateKeys on the contract:
Mask the Game Deck
Now, players can obtain the game aggregated key specific to the current game from the contract, and the first player to shuffle the deck needs to mask the entire deck with the game key before shuffling the deck.
We do this part on the client side:
After the first player has masked the deck, he can shuffle the deck directly locally, and we continue to the next section.
Shuffle the Game Deck
If it is the first player to shuffle the cards, we directly adjust the result of the previous step to the same specifications as the contract. If it is the second player or later, the deck will be shuffled directly with the deck found on the contract.
When the client completes the shuffling, the previous and new deck, proof and pkc are submitting to the contract to verify and update the deck.
Submit ZK Reveal Tokens
After all players have shuffled the deck, if player want the "value" of any card, they must collect the ZK information (reveal token) provided by all other players to unlock it.
When players submit card reveal tokens, they can ensure their correctness with the Reveal Verifier we provide:
To generate the ZK reveal token of any card, it can be calculated on the client side using the player's secret key:
When the contract receives the ZK reveal token and proof, it can be verified online instantly:
After collecting a sufficient number of reveal tokens, player will get the card's "value".
Reveal Card
There are two calculation methods, one is calculated on the client side, and the other is calculated on the contract:
Local:
Through reveal tokens provided by other players, player can locally reveal cards whose results only player can see:
Public in the contract:
All players provide reveal tokens, and the contract reveals the card through Reveal Verifier:
Through the above two methods, the common card shuffling and opening process can be achieved.
Last updated
Was this helpful?