bip39

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

commit 18ef0d3507eed7359ea33f04ae7364bd4e82929e
parent 5df28ff6a5a6fe5b1f73ffabb651d31c150d852b
Author: Jared Tobin <jared@jtobin.io>
Date:   Sat, 10 Jan 2026 22:36:52 +0400

lib: use new hmac api

Diffstat:
Mflake.lock | 68+++++++++++++++++++++++++++++++++-----------------------------------
Mlib/Crypto/KDF/BIP39.hs | 9+++++++--
Mppad-bip39.cabal | 8++++----
3 files changed, 44 insertions(+), 41 deletions(-)

diff --git a/flake.lock b/flake.lock @@ -93,11 +93,11 @@ ] }, "locked": { - "lastModified": 1767898767, - "narHash": "sha256-PAhxa5UvbGJn3vpPUvwlohV5KUTWAz112At/Z386tBc=", + "lastModified": 1768067273, + "narHash": "sha256-W5K8Q9KUGlKD5Ky0hOclThFHLzd7Ybike9Yr8yubTNA=", "ref": "master", - "rev": "08cb6bf5b24a730e8101110e4cbbc8a95788751e", - "revCount": 33, + "rev": "1babbd97abf0a6163657676396b8eedf4fdf4105", + "revCount": 34, "type": "git", "url": "git://git.ppad.tech/base58.git" }, @@ -124,6 +124,7 @@ ], "ppad-base58": "ppad-base58", "ppad-fixed": "ppad-fixed", + "ppad-hmac-drbg": "ppad-hmac-drbg", "ppad-nixpkgs": [ "ppad-nixpkgs" ], @@ -137,11 +138,11 @@ ] }, "locked": { - "lastModified": 1767898967, - "narHash": "sha256-OL0SQ0dgPiQGdjes/JcDRreQWGse3GFz27WDoIVPn2U=", + "lastModified": 1768069865, + "narHash": "sha256-JGHu694nYWmVZihz+oZ7N+pxzmWQJSnM4ogwefBiCL4=", "ref": "master", - "rev": "b71c03bf56aaffbbc3f6c677ce7feb6b45a4e00d", - "revCount": 67, + "rev": "568a4346be1f4c69f82d6ef54a7114af5ed69851", + "revCount": 69, "type": "git", "url": "git://git.ppad.tech/bip32.git" }, @@ -189,45 +190,39 @@ "inputs": { "flake-utils": [ "ppad-bip32", - "ppad-secp256k1", "ppad-hmac-drbg", "ppad-nixpkgs", "flake-utils" ], "nixpkgs": [ "ppad-bip32", - "ppad-secp256k1", "ppad-hmac-drbg", "ppad-nixpkgs", "nixpkgs" ], "ppad-base16": [ "ppad-bip32", - "ppad-secp256k1", "ppad-base16" ], "ppad-nixpkgs": [ "ppad-bip32", - "ppad-secp256k1", "ppad-nixpkgs" ], "ppad-sha256": [ "ppad-bip32", - "ppad-secp256k1", "ppad-sha256" ], "ppad-sha512": [ "ppad-bip32", - "ppad-secp256k1", "ppad-sha512" ] }, "locked": { - "lastModified": 1767897885, - "narHash": "sha256-DLSpSE5sV94K6I2Hj05SlkEIoU46dfi7AT6dmoiIaVA=", + "lastModified": 1768057958, + "narHash": "sha256-Csrv+J0WnGankFhvEMQsHnLd3h8zVpmTKV5WaHD5LoM=", "ref": "master", - "rev": "c754b88c59d0a3f759368a99b949400f08e16b79", - "revCount": 56, + "rev": "c6487458ef620c4f83bdbc7494f5f48c989133b6", + "revCount": 62, "type": "git", "url": "git://git.ppad.tech/hmac-drbg.git" }, @@ -283,11 +278,11 @@ ] }, "locked": { - "lastModified": 1767898485, - "narHash": "sha256-odC4S8JnWalZDxrpDA9vlpYo77CYn2kMKSClamT7QPk=", + "lastModified": 1768067908, + "narHash": "sha256-kX6H0UFkbuzC6WTWtF/8f4f/L/1xc76uqHDnnlD2+2E=", "ref": "master", - "rev": "66bd7e9057a23e88690c9db65c4648d18198e8b4", - "revCount": 19, + "rev": "e887914a0000c11ff662c1fdc96f893a40326e7e", + "revCount": 21, "type": "git", "url": "git://git.ppad.tech/pbkdf.git" }, @@ -357,7 +352,10 @@ "ppad-bip32", "ppad-fixed" ], - "ppad-hmac-drbg": "ppad-hmac-drbg", + "ppad-hmac-drbg": [ + "ppad-bip32", + "ppad-hmac-drbg" + ], "ppad-nixpkgs": [ "ppad-bip32", "ppad-nixpkgs" @@ -372,11 +370,11 @@ ] }, "locked": { - "lastModified": 1767898470, - "narHash": "sha256-/BG30iSsiAKFW8edGrEBd34BcR+s1ab8XqrwWC9wHVs=", + "lastModified": 1768069596, + "narHash": "sha256-S98vYYeuLkLLfUozc/YraIEBX4uWrIS5V14hkN2xyk0=", "ref": "master", - "rev": "10254053c384b05b4a528c7c4884705e046ce331", - "revCount": 239, + "rev": "ee40b39f69f79e77ce50ca9be31e0e4679839b8a", + "revCount": 243, "type": "git", "url": "git://git.ppad.tech/secp256k1.git" }, @@ -406,11 +404,11 @@ ] }, "locked": { - "lastModified": 1767897559, - "narHash": "sha256-UabcPqE4O+h1HHv02LjanjuorRS91OODqk0ek55VrmQ=", + "lastModified": 1768045644, + "narHash": "sha256-8+jLaYRN8iX6NmyotE7DvjfjUIT8I0KOchgcP7uq7Vo=", "ref": "master", - "rev": "528d9cf07ca756fb5422cab174849fe0708620d0", - "revCount": 111, + "rev": "4716cd5b4e673e9cb66e4e5e427e5464a7c10977", + "revCount": 116, "type": "git", "url": "git://git.ppad.tech/sha256.git" }, @@ -440,11 +438,11 @@ ] }, "locked": { - "lastModified": 1767897585, - "narHash": "sha256-QxLlHu8+tGKZ9aOKFnVOqNwEn+LCuNF27kY2dxOCYxo=", + "lastModified": 1768045869, + "narHash": "sha256-ySqv5fQRz+/9X54yXCuck2QnGyuIqRLpRzanh+Ehl88=", "ref": "master", - "rev": "428e2e09c345a0cb255d9aab432606308872c014", - "revCount": 38, + "rev": "0fbaba3c091692622744d30016e36ca6b726a819", + "revCount": 42, "type": "git", "url": "git://git.ppad.tech/sha512.git" }, diff --git a/lib/Crypto/KDF/BIP39.hs b/lib/Crypto/KDF/BIP39.hs @@ -63,6 +63,11 @@ fi :: (Integral a, Num b) => a -> b fi = fromIntegral {-# INLINE fi #-} +hmac_sha512 :: BS.ByteString -> BS.ByteString -> BS.ByteString +hmac_sha512 k b = case SHA512.hmac k b of + SHA512.MAC mac -> mac +{-# INLINE hmac_sha512 #-} + -- | A BIP39 wordlist. newtype Wordlist = Wordlist (PA.Array T.Text) @@ -166,7 +171,7 @@ _seed wlist mnem pass = do guard (_valid wlist mnem) let salt = TE.encodeUtf8 ("mnemonic" <> ICU.nfkd pass) norm = TE.encodeUtf8 (ICU.nfkd mnem) - PBKDF.derive SHA512.hmac norm salt 2048 64 + PBKDF.derive hmac_sha512 norm salt 2048 64 {-# INLINE _seed #-} -- | Derive a master seed from a provided mnemonic and passphrase. @@ -186,7 +191,7 @@ seed_unsafe mnem pass = do guard (length (T.words mnem) `elem` [12, 15, 18, 21, 24]) let salt = TE.encodeUtf8 ("mnemonic" <> ICU.nfkd pass) norm = TE.encodeUtf8 (ICU.nfkd mnem) - PBKDF.derive SHA512.hmac norm salt 2048 64 + PBKDF.derive hmac_sha512 norm salt 2048 64 -- | Validate a mnemonic against the default English wordlist. -- diff --git a/ppad-bip39.cabal b/ppad-bip39.cabal @@ -1,6 +1,6 @@ cabal-version: 3.0 name: ppad-bip39 -version: 0.3.1 +version: 0.3.2 synopsis: BIP39 mnemonic codes. license: MIT license-file: LICENSE @@ -47,9 +47,9 @@ library build-depends: base >= 4.9 && < 5 , bytestring >= 0.9 && < 0.13 - , ppad-pbkdf >= 0.2.1 && < 0.3 - , ppad-sha256 >= 0.2.4 && < 0.3 - , ppad-sha512 >= 0.1.4 && < 0.2 + , ppad-pbkdf >= 0.2.2 && < 0.3 + , ppad-sha256 >= 0.3 && < 0.4 + , ppad-sha512 >= 0.2 && < 0.3 , primitive >= 0.8 && < 0.10 , text >= 2.1 && < 2.2 , text-icu >= 0.8 && < 0.9