bip39

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

commit 529610bf27eba2778e304d4641a4f7063c9c1e2c
parent 5066ce757a89ccd67eded3dbc8d8a2f5b79c426f
Author: Jared Tobin <jared@jtobin.io>
Date:   Thu, 27 Feb 2025 17:39:04 +0400

lib: docs

Diffstat:
MCHANGELOG | 6++++++
Mlib/Crypto/KDF/BIP39.hs | 45+++++++++++++++++++++++++++++++++------------
2 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG @@ -0,0 +1,6 @@ +# Changelog + +- 0.1.0 (2025-02-27) + * Initial release. + + diff --git a/lib/Crypto/KDF/BIP39.hs b/lib/Crypto/KDF/BIP39.hs @@ -1,14 +1,26 @@ +{-# OPTIONS_HADDOCK prune #-} {-# LANGUAGE BinaryLiterals #-} {-# LANGUAGE NumericUnderscores #-} {-# LANGUAGE OverloadedStrings #-} +-- | +-- Module: Crypto.HDKey.BIP32 +-- Copyright: (c) 2025 Jared Tobin +-- License: MIT +-- Maintainer: Jared Tobin <jared@ppad.tech> +-- +-- [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) +-- mnemonic codes for deterministic key generation, supporting wordlists in +-- multiple languages. + module Crypto.KDF.BIP39 ( - Mnemonic(..) - , mnemonic - , _mnemonic + -- * Mnemonic and seed construction + mnemonic , seed - -- wordlists + -- * Alternative wordlists + , _mnemonic + , Wordlist(..) , english , chinese_traditional , chinese_simplified @@ -37,19 +49,23 @@ import qualified Data.Text.Encoding as TE import qualified Data.Text.ICU.Normalize2 as ICU import System.IO.Unsafe (unsafePerformIO) --- XX get rid of this type -newtype Mnemonic = Mnemonic BS.ByteString - deriving Eq - -instance Show Mnemonic where - show (Mnemonic bs) = show bs - +-- | A BIP39 wordlist. newtype Wordlist = Wordlist (PA.Array T.Text) fi :: (Integral a, Num b) => a -> b fi = fromIntegral {-# INLINE fi #-} +-- | Generate a BIP39 mnemonic from some entropy. +-- +-- The entropy must be at least 128 bits long, at most 256 bits long, +-- and its length must be a multiple of 32 bits. Providing invalid +-- entropy will result in an 'ErrorCall' exception. +-- +-- >>> import qualified System.Entropy as E +-- >>> trop <- E.getEntropy 16 +-- >>> mnemonic trop +-- "coral maze mimic half fat breeze thought club give brass bone snake" mnemonic :: BS.ByteString -> T.Text mnemonic = _mnemonic english @@ -91,7 +107,12 @@ words wlist bs = L.unfoldr coalg (bs, 0, 0) where Nothing {-# INLINE words #-} --- XX check that this is a valid mnemonic! +-- | Derive a master seed from a provided mnemonic and passphrase. +-- +-- >>> let mnem = "coral maze mimic half fat breeze thought club give brass bone snake" +-- >> let pass = "hunter2" +-- >>> seed mnem pass +-- <512-bit long seed> seed :: T.Text -> T.Text -> BS.ByteString seed mnem pass = PBKDF.derive SHA512.hmac bs salt 2048 64 where salt = TE.encodeUtf8 ("mnemonic" <> ICU.nfkd pass)