.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/wallets/stretching/plot_03_brain_wallet_drain.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_wallets_stretching_plot_03_brain_wallet_drain.py: The brain-wallet drain (Vasek et al., 2016) =========================================== A brain wallet's private key is the SHA-256 of a passphrase, .. math:: k = \mathrm{SHA256}(\text{passphrase}), so nothing needs to be stored. But anyone can hash the same passphrase. Marie Vasek, Joseph Bonneau, Ryan Castellucci, Cameron Keith and Tyler Moore searched the Bitcoin chain for brain wallets and found that thieves had precomputed the keys of dictionaries, quotations and leaked passwords, and emptied most funded brain wallets, many within minutes, often racing one another. There is no salt and no stretching, and a phrase a person chooses has far less entropy than a random key. Here thieves with precomputed tables sweep a population of brain wallets. .. GENERATED FROM PYTHON SOURCE LINES 22-26 .. code-block:: Python import matplotlib.pyplot as plt import blockchainkit as bk .. GENERATED FROM PYTHON SOURCE LINES 27-29 The most famous brain wallet ---------------------------- .. GENERATED FROM PYTHON SOURCE LINES 29-43 .. code-block:: Python key = bk.wallets.brain_wallet_key("password") address = bk.wallets.brain_wallet_address("password") print("SHA256('password') =", hex(key)) print("address:", address) assert bk.wallets.crack_brain_wallet(address, bk.wallets.PHRASEBOOK) == "password" # A random 12-word phrase is out of reach of any dictionary. strong = bk.wallets.entropy_to_mnemonic(bytes(range(16))) assert ( bk.wallets.crack_brain_wallet(bk.wallets.brain_wallet_address(strong), bk.wallets.PHRASEBOOK) is None ) .. rst-class:: sphx-glr-script-out .. code-block:: none SHA256('password') = 0x5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 address: 16ga2uqnF1NqpAuQeeg7sTCAdtDUwDyJav .. GENERATED FROM PYTHON SOURCE LINES 44-47 Thieves racing to sweep deposits -------------------------------- Three thieves: a fast one with most of the phrasebook, and two slower ones. .. GENERATED FROM PYTHON SOURCE LINES 47-64 .. code-block:: Python thieves = [(0.7, 2.0), (0.5, 10.0), (0.3, 50.0)] drain = bk.wallets.simulate_brain_drain(300, weak_share=0.4, thieves=thieves, seed=2016) print(f"{drain.wallets} wallets, {drain.weak} with a common phrase, {drain.drained} drained") print("wallets taken by each thief:", drain.hauls) assert drain.drained <= drain.weak and drain.hauls[0] == max(drain.hauls) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4)) ax1.hist(drain.delays, bins=range(1, max(drain.delays) + 2), color="#dc2626") ax1.set(xlabel="blocks from deposit to theft", ylabel="wallets") ax1.set_title("Most weak wallets are swept at once") ax2.bar(["fast", "medium", "slow"], drain.hauls, color="#64748b") ax2.set(ylabel="wallets drained") ax2.set_title("The fastest table wins the race") fig.tight_layout() plt.show() .. image-sg:: /api/gallery/wallets/stretching/images/sphx_glr_plot_03_brain_wallet_drain_001.png :alt: Most weak wallets are swept at once, The fastest table wins the race :srcset: /api/gallery/wallets/stretching/images/sphx_glr_plot_03_brain_wallet_drain_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none 300 wallets, 106 with a common phrase, 98 drained wallets taken by each thief: (69, 24, 5) .. GENERATED FROM PYTHON SOURCE LINES 65-71 Exercise -------- Brain wallets that stretched their passphrase, such as WarpWallet with scrypt and PBKDF2, slowed each guess. Why does that still not save a passphrase from the phrasebook? A worked solution is in :doc:`/exercises/wallets`. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 2.324 seconds) .. _sphx_glr_download_api_gallery_wallets_stretching_plot_03_brain_wallet_drain.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/wallets/stretching/plot_03_brain_wallet_drain.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_03_brain_wallet_drain.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_03_brain_wallet_drain.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_03_brain_wallet_drain.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_