-
-
Save NostrCasino/a9d6c31510f00c32deff8214261e7bd9 to your computer and use it in GitHub Desktop.
Verifiable protocol for 3 card poker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
3_card_poker@nostrcasino.com, poker on Nostr! | |
npub: npub1hsl3xg22txclek63k6arwzjkydymzmea0y3fnxcffv7rylrysavq249hap | |
You can verify the fairness and result of the game from this python | |
script. | |
In order to ensure it's a fair game, we follow the following protocol: | |
1. You start a game by posting `@3_card_poker pair_plus_wager_amount ante_wager_amount` | |
2. We generate a seed, and share the hash of the seed (`seed_hash`) with you (along with a lightning invoice for pair_plus_wager_amount + ante_wager_amount) | |
3. You pay the invoice, then respond with 'deal' | |
4. We use the signature from your response (that we couldn't know ahead of time) | |
as a random input to deal the cards in the code below. | |
5. We deal your cards face up, and you're able to decide if you want to 'play' or 'fold'. | |
If you fold, the game is over and we share the seed (and your original comment signature for convenience) | |
so that you can verify the fairness of the game | |
If you choose 'play', you have to match the ante wager, so another invoice will be provided. | |
6. If you choose 'play' in step 5, after you pay the invoice, you can comment 'paid', | |
and the dealers cards will be turned face up. Winnings will be paid out if applicable. | |
And Finally, the seed (and your original comment signature for convenience) | |
so that you can verify the fairness of the game | |
""" | |
import hashlib | |
import hmac | |
# fill in the following variables from your game | |
seed_hash = ... # shared in step 2 | |
seed = ... # shared in step 5 or 6 | |
signature = ... # shared in step 5 or 6 | |
# first, verify that the seed_hash really comes from the seed | |
def verify_seed_hash(seed, seed_hash): | |
computed_seed_hash = hashlib.sha256(seed).hexdigest() | |
if seed_hash == computed_seed_hash: | |
print("We verified that the seed_hash comes from the seed!") | |
else: | |
print("The seed_hash does not come from the seed, something is wrong!") | |
def hmac_substring_to_card(hmac_substring, precision, deck): | |
int_max = 16 ** precision - 1 | |
int_result = int.from_bytes(bytes.fromhex( | |
hmac_substring), byteorder="big", signed=False) | |
num_cards = len(deck) | |
card_index = int(num_cards * int_result / int_max) | |
dealt_card = deck[card_index] | |
new_deck = [x for x in deck if x != dealt_card] | |
return dealt_card, new_deck | |
def deal_cards(seed, signature): | |
precision = 14 | |
deck = ['2s', '2h', '2c', '2d', | |
'3s', '3h', '3c', '3d', | |
'4s', '4h', '4c', '4d', | |
'5s', '5h', '5c', '5d', | |
'6s', '6h', '6c', '6d', | |
'7s', '7h', '7c', '7d', | |
'8s', '8h', '8c', '8d', | |
'9s', '9h', '9c', '9d', | |
'10s', '10h', '10c', '10d', | |
'Js', 'Jh', 'Jc', 'Jd', | |
'Qs', 'Qh', 'Qc', 'Qd', | |
'Ks', 'Kh', 'Kc', 'Kd', | |
'As', 'Ah', 'Ac', 'Ad'] | |
signature_bytes = bytes.fromhex(signature) | |
computed_hmac = hmac.new(signature_bytes, msg=seed, | |
digestmod=hashlib.sha512).hexdigest() | |
# take a subset of the computed hmac | |
hmac_substring = computed_hmac[precision - 1::-1] | |
cards_dealt = [] | |
for _ in range(6): | |
dealt_card, deck = hmac_substring_to_card( | |
hmac_substring, precision, deck) | |
cards_dealt.append(dealt_card) | |
signature_bytes = hashlib.sha256(signature_bytes).digest() | |
seed = hashlib.sha256(seed).digest() | |
computed_hmac = hmac.new( | |
signature_bytes, msg=seed, digestmod=hashlib.sha512).hexdigest() | |
# take a subset of the computed hmac | |
hmac_substring = computed_hmac[precision - 1::-1] | |
player_cards = cards_dealt[::2] | |
dealer_cards = cards_dealt[1::2] | |
return player_cards, dealer_cards | |
# The following steps verify that it was a fair game! | |
verify_seed_hash(seed, seed_hash) | |
player_cards, dealer_cards = deal_cards(seed, signature) | |
print(f"The player was dealt {player_cards}") | |
print(f"The dealer was dealt {dealer_cards}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment