bip32

Pure Haskell BIP32 hierarchical deterministic wallets (docs.ppad.tech/bip32).
git clone git://git.ppad.tech/bip32.git
Log | Files | Refs | README | LICENSE

commit 9696a67e84a765c53c4636cad30ce900b358520a
parent bc489462835f853d58970fc53d5ce359932eacc5
Author: Jared Tobin <jared@jtobin.io>
Date:   Thu, 19 Jun 2025 16:55:29 +0400

lib: use updated secp256k1 api

Diffstat:
Mflake.lock | 16++++++++--------
Mlib/Crypto/HDKey/BIP32.hs | 24+++++++++++++-----------
2 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/flake.lock b/flake.lock @@ -85,11 +85,11 @@ ] }, "locked": { - "lastModified": 1740802926, - "narHash": "sha256-STkzNGx6DakFA+3tZVXurxEU/rEHtkcylNueyh3jLl4=", + "lastModified": 1750335817, + "narHash": "sha256-XReE3NMudmbpWgvMGwvsMt5SO3DkKYFYVLvsh5waDRg=", "ref": "master", - "rev": "66e9deb21aaf7910ed44363a5c72e29d05e9e15d", - "revCount": 23, + "rev": "10c667ad8dc7583407fd1545259dc140497e2b17", + "revCount": 27, "type": "git", "url": "git://git.ppad.tech/base58.git" }, @@ -216,11 +216,11 @@ ] }, "locked": { - "lastModified": 1741950137, - "narHash": "sha256-9NTMZ+WSZ+81Ys9RBkLqDo06ZPo0hgcCAwvy8ehbDIA=", + "lastModified": 1750336608, + "narHash": "sha256-hNTKr/dkUjiWkqg0qzCl+hVrY51Xc6lkmC3QnpBs5cg=", "ref": "master", - "rev": "f179ea0c298a8d9d0bc20649003554e5d22939b7", - "revCount": 155, + "rev": "0216aa125e71d3e23f890084bb80345a7cb13e2f", + "revCount": 171, "type": "git", "url": "git://git.ppad.tech/secp256k1.git" }, diff --git a/lib/Crypto/HDKey/BIP32.hs b/lib/Crypto/HDKey/BIP32.hs @@ -142,10 +142,11 @@ instance Extended XPub where in RIPEMD160.hash (SHA256.hash ser) instance Extended XPrv where - identifier (XPrv (X sec _)) = - let p = Secp256k1.mul Secp256k1._CURVE_G sec - ser = Secp256k1.serialize_point p - in RIPEMD160.hash (SHA256.hash ser) + identifier (XPrv (X sec _)) = case Secp256k1.mul Secp256k1._CURVE_G sec of + Nothing -> error "ppad-bip32 (identifier): evil extended key" + Just p -> + let ser = Secp256k1.serialize_point p + in RIPEMD160.hash (SHA256.hash ser) -- internal key derivation functions------------------------------------------- @@ -175,9 +176,9 @@ ckd_priv _xprv@(XPrv (X sec cod)) i = else XPrv (X ki ci) where dat | hardened i = BS.singleton 0x00 <> ser256 sec <> ser32 i - | otherwise = - let p = Secp256k1.mul Secp256k1._CURVE_G sec - in Secp256k1.serialize_point p <> ser32 i + | otherwise = case Secp256k1.mul Secp256k1._CURVE_G sec of + Nothing -> error "ppad-bip32 (ckd_priv): evil extended key" + Just p -> Secp256k1.serialize_point p <> ser32 i -- public parent key -> public child key ckd_pub :: XPub -> Word32 -> Maybe XPub @@ -188,16 +189,17 @@ ckd_pub _xpub@(XPub (X pub cod)) i l = SHA512.hmac cod dat (il, ci) = BS.splitAt 32 l pil = parse256 il -- safe due to 512-bit hmac - ki = Secp256k1.mul_unsafe Secp256k1._CURVE_G pil `Secp256k1.add` pub + pt <- Secp256k1.mul_unsafe Secp256k1._CURVE_G pil + let ki = pt `Secp256k1.add` pub if pil >= Secp256k1._CURVE_Q || ki == Secp256k1._CURVE_ZERO -- negl then ckd_pub _xpub (succ i) else pure (XPub (X ki ci)) -- private parent key -> public child key n :: XPrv -> XPub -n (XPrv (X sec cod)) = - let p = Secp256k1.mul Secp256k1._CURVE_G sec - in XPub (X p cod) +n (XPrv (X sec cod)) = case Secp256k1.mul Secp256k1._CURVE_G sec of + Nothing -> error "ppad-bip32 (n): evil extended key" + Just p -> XPub (X p cod) -- hierarchical deterministic keys --------------------------------------------