.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/crypto/commitments/plot_01_coin_flipping.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_crypto_commitments_plot_01_coin_flipping.py: Coin flipping by telephone: hash commitments (Blum 1981) ======================================================== Alice and Bob, on the phone, want a fair coin toss. If Alice calls first, Bob can lie. Blum's fix: Alice *commits* to her call, Bob announces the coin, then Alice opens the commitment. A commitment must be binding (Alice cannot change her call) and hiding (Bob cannot read it early). What to look for ---------------- A salted hash commitment opens only to the committed value. Without a secret salt, Bob can hash both possible calls and read Alice's choice: a commitment to a guessable value needs randomness to hide it. The history behind this experiment: :doc:`/history/crypto_breakthroughs`. .. GENERATED FROM PYTHON SOURCE LINES 21-23 Commit, reveal, verify ---------------------- .. GENERATED FROM PYTHON SOURCE LINES 23-36 .. code-block:: Python import matplotlib.pyplot as plt import blockchainkit as bk salt = bytes(range(32)) # A real salt comes from secrets.token_bytes(32). commitment = bk.crypto.commit(b"heads", salt) bob_coin = b"tails" # Bob announces after seeing only the commitment. assert bk.crypto.verify_commitment(commitment, b"heads", salt) assert not bk.crypto.verify_commitment(commitment, b"tails", salt) # Binding. print( "Alice called heads; the coin was", bob_coin.decode(), "-> Bob wins, and Alice cannot deny it" ) .. rst-class:: sphx-glr-script-out .. code-block:: none Alice called heads; the coin was tails -> Bob wins, and Alice cannot deny it .. GENERATED FROM PYTHON SOURCE LINES 37-39 Why the salt matters -------------------- .. GENERATED FROM PYTHON SOURCE LINES 39-44 .. code-block:: Python unsalted = bk.crypto.sha256(b"heads") guesses = {call: bk.crypto.sha256(call) for call in (b"heads", b"tails")} recovered = next(call for call, h in guesses.items() if h == unsalted) assert recovered == b"heads" # Bob reads the call: no hiding without a salt. .. GENERATED FROM PYTHON SOURCE LINES 45-49 A thousand fair flips --------------------- The coin is the XOR of Alice's committed bit and Bob's bit: fair if either party is honest. .. GENERATED FROM PYTHON SOURCE LINES 49-65 .. code-block:: Python from random import Random rng = Random(1981) outcomes = [] for _ in range(1000): alice_bit, alice_salt = bytes([rng.getrandbits(1)]), rng.randbytes(32) sealed = bk.crypto.commit(alice_bit, alice_salt) # Sent first. bob_bit = rng.getrandbits(1) # Bob replies without being able to read it. assert bk.crypto.verify_commitment(sealed, alice_bit, alice_salt) # Then Alice opens. outcomes.append(alice_bit[0] ^ bob_bit) fig, ax = plt.subplots(figsize=(6, 3.5)) ax.bar(["0", "1"], [outcomes.count(0), outcomes.count(1)], color="#2563eb") ax.set(ylabel="flips", title="XOR of a committed bit and a reply") fig.tight_layout() assert 430 < outcomes.count(1) < 570 .. image-sg:: /api/gallery/crypto/commitments/images/sphx_glr_plot_01_coin_flipping_001.png :alt: XOR of a committed bit and a reply :srcset: /api/gallery/crypto/commitments/images/sphx_glr_plot_01_coin_flipping_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 66-72 Exercise -------- Commitments are everywhere in this package: name where a Schnorr signature commits before seeing a challenge, and where a block commits to its transactions. Why does a commitment scheme need *both* properties for the coin toss to be fair? .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.089 seconds) .. _sphx_glr_download_api_gallery_crypto_commitments_plot_01_coin_flipping.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../../lite/lab/index.html?path=api/gallery/crypto/commitments/plot_01_coin_flipping.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_01_coin_flipping.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_01_coin_flipping.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_01_coin_flipping.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_