bip39

BIP39 mnemonic codes in Haskell (docs.ppad.tech/bip39).
git clone git://git.ppad.tech/bip39.git
Log | Files | Refs | README | LICENSE

README.md (4839B)


      1 # bip39
      2 
      3 [![](https://img.shields.io/hackage/v/ppad-bip39?color=blue)](https://hackage.haskell.org/package/ppad-bip39)
      4 ![](https://img.shields.io/badge/license-MIT-brightgreen)
      5 [![](https://img.shields.io/badge/haddock-bip39-lightblue)](https://docs.ppad.tech/bip39)
      6 
      7 An implementation of [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) mnemonics for deterministic key generation.
      8 
      9 ## Usage
     10 
     11 A sample GHCi session:
     12 
     13 ```
     14   > -- pragma and bip32/TIO imports not required; just for illustration
     15   > :set -XOverloadedStrings
     16   > import qualified Crypto.HDKey.BIP32 as BIP32
     17   > import qualified Data.Text.IO as TIO
     18   >
     19   > import Crypto.KDF.BIP39
     20   >
     21   > -- bring your own entropy, e.g. via System.Entropy
     22   > -- for now we'll use an ultra-secret source
     23   > let trop = "my ultra secret entropy!"
     24   >
     25   > -- use 'mnemonic' to create a BIP39 mnemonic
     26   > let mnem = mnemonic trop
     27   > mnem
     28   "hope simple bubble suggest elbow correct limb hole gloom nasty fringe dolphin finger demand situate unlock junior autumn"
     29   >
     30   > -- you can use other wordlists; the bip39 'defaults' are included
     31   > -- to supply an alternative one, use '_mnemonic' (with a leading underscore)
     32   > let fr_mnem = _mnemonic french trop
     33   > let jp_mnem = _mnemonic japanese trop
     34   >
     35   > TIO.putStrLn fr_mnem
     36   frivole reculer bilingue secouer diriger chose ingérer frémir fatal luxueux étonnant défiler éolien crayon réflexe tournage hélium appareil
     37   >
     38   > TIO.putStrLn jp_mnem
     39   ずあん はんらん えんえん へいしゃ けむし きかんしゃ そめる しんせいじ したて ちきゅう さとし けいたい こんだて ぐうせい ひかく もちろん せんげん いやがる
     40   >
     41   > -- use 'seed' to create a seed
     42   > let master_seed = seed mnem mempty
     43   >
     44   > -- the second argument is a passphrase, which can be arbitrary UTF-8
     45   > let phrase_seed = seed jp_mnem "㍍ガバヴァぱばぐゞちぢ十人十色"
     46   >
     47   > -- use a seed to derive a bip32 hd wallet
     48   > let hd_wallet = BIP32.master phrase_seed
     49 ```
     50 
     51 ## Documentation
     52 
     53 Haddocks (API documentation, etc.) are hosted at
     54 [docs.ppad.tech/bip39](https://docs.ppad.tech/bip39).
     55 
     56 ## Security
     57 
     58 This library aims at the maximum security achievable in a
     59 garbage-collected language under an optimizing compiler such as GHC, in
     60 which strict constant-timeness can be [challenging to achieve][const].
     61 
     62 The implementation within passes the official [BIP39 test
     63 vectors](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki#test-vectors)
     64 for every "default" wordlist, including the additional
     65 Japanese vectors with heavily-normalized passphrases.
     66 
     67 This library differs somewhat from most *ppad* libraries
     68 as it includes a somewhat-nonstandard dependency, namely
     69 [text-icu](https://hackage.haskell.org/package/text-icu), which wraps
     70 the [International Components for Unicode](https://icu.unicode.org/)
     71 library that is required for UTF8 normalization.
     72 
     73 *text-icu* itself is venerable, is maintained by the Haskell Libraries
     74 Committee on [GitHub](https://github.com/haskell/text-icu), and its FFI
     75 code is simple and easy to audit. The alternatives to including it would
     76 probably be either only to support English wordlists, or to vendor the
     77 icu4c dependency ourselves and create our own FFI bindings to the NFKD
     78 normalization code we care about. The latter may be something I look to
     79 do in a future release.
     80 
     81 If you discover any vulnerabilities, please disclose them via
     82 security@ppad.tech.
     83 
     84 ## Performance
     85 
     86 The aim is best-in-class performance for pure, highly-auditable Haskell
     87 code.
     88 
     89 Current benchmark figures on my mid-2020 MacBook Air look like (use
     90 `cabal bench` to run the benchmark suite):
     91 
     92 ```
     93   benchmarking ppad-bip39/mnemonic
     94   time                 4.222 μs   (4.055 μs .. 4.380 μs)
     95                        0.992 R²   (0.990 R² .. 0.995 R²)
     96   mean                 4.220 μs   (4.118 μs .. 4.332 μs)
     97   std dev              366.1 ns   (318.3 ns .. 427.9 ns)
     98   variance introduced by outliers: 84% (severely inflated)
     99 
    100   benchmarking ppad-bip39/seed
    101   time                 12.91 ms   (12.64 ms .. 13.35 ms)
    102                        0.994 R²   (0.989 R² .. 0.997 R²)
    103   mean                 12.87 ms   (12.62 ms .. 13.16 ms)
    104   std dev              699.8 μs   (568.8 μs .. 938.4 μs)
    105   variance introduced by outliers: 25% (moderately inflated)
    106 ```
    107 
    108 ## Development
    109 
    110 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a
    111 development shell with:
    112 
    113 ```
    114 $ nix develop
    115 ```
    116 
    117 Then do e.g.:
    118 
    119 ```
    120 $ cabal repl ppad-bip39
    121 ```
    122 
    123 to get a REPL for the main library.
    124 
    125 [nixos]: https://nixos.org/
    126 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html
    127 [const]: https://www.chosenplaintext.ca/articles/beginners-guide-constant-time-cryptography.html
    128 [secp]: https://git.ppad.tech/secp256k1