.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/crypto/hashing/plot_04_sha256_avalanche.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_hashing_plot_04_sha256_avalanche.py: SHA-256 and the avalanche effect (FIPS 180-2, 2002) =================================================== SHA-256 became the standardized hash behind Bitcoin's block hashes, addresses, and Merkle trees. A good hash behaves like a random function: flipping one input bit flips each output bit with probability one half. What to look for ---------------- Flip every bit of a message in turn. The number of changed output bits clusters around 128 of 256, following a Binomial(256, 1/2) distribution. This is useful intuition, not a proof of collision or preimage resistance. The history behind this experiment: :doc:`/history/crypto_breakthroughs`. See :doc:`/exercises/crypto` for a worked solution to the exercise. .. GENERATED FROM PYTHON SOURCE LINES 21-36 .. code-block:: Python import blockchainkit as bk from blockchainkit.crypto.visualizers import plot_hamming_distances message = b"blockchainkit: a reproducible experiment" digest = bk.crypto.sha256(message) assert digest.hex() == bk.crypto.merkle_damgard_sha256(message).hex() distances = [] for bit in range(len(message) * 8): flipped = bytearray(message) flipped[bit // 8] ^= 1 << (bit % 8) distances.append(bk.crypto.hamming_distance(digest, bk.crypto.sha256(bytes(flipped)))) mean = sum(distances) / len(distances) assert 120 < mean < 136 print("Mean changed digest bits:", mean, "out of 256") .. rst-class:: sphx-glr-script-out .. code-block:: none Mean changed digest bits: 127.66875 out of 256 .. GENERATED FROM PYTHON SOURCE LINES 37-40 .. code-block:: Python ax = plot_hamming_distances(distances) ax.figure.tight_layout() .. image-sg:: /api/gallery/crypto/hashing/images/sphx_glr_plot_04_sha256_avalanche_001.png :alt: Avalanche: about half the output bits change :srcset: /api/gallery/crypto/hashing/images/sphx_glr_plot_04_sha256_avalanche_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 41-46 Exercise -------- Hash only the first byte of each digest and find collisions. Compare the number of trials to the birthday estimate. Why is this not an attack on the full SHA-256 output? .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.152 seconds) .. _sphx_glr_download_api_gallery_crypto_hashing_plot_04_sha256_avalanche.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/hashing/plot_04_sha256_avalanche.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_04_sha256_avalanche.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_04_sha256_avalanche.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_04_sha256_avalanche.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_