secp256k1

Pure Haskell Schnorr, ECDSA on the elliptic curve secp256k1 (docs.ppad.tech/secp256k1).
git clone git://git.ppad.tech/secp256k1.git
Log | Files | Refs | README | LICENSE

commit 0f9b63c031e7f26b8b235f7633fbe90b85cc913e
parent 10254053c384b05b4a528c7c4884705e046ce331
Author: Jared Tobin <jared@jtobin.io>
Date:   Sat, 10 Jan 2026 19:38:37 +0400

lib: use new hmac-drbg api, reorder haddocks

Diffstat:
Mlib/Crypto/Curve/Secp256k1.hs | 46+++++++++++++++++++++++++++++-----------------
Mppad-secp256k1.cabal | 6+++---
2 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/lib/Crypto/Curve/Secp256k1.hs b/lib/Crypto/Curve/Secp256k1.hs @@ -30,9 +30,13 @@ -- on the elliptic curve secp256k1. module Crypto.Curve.Secp256k1 ( - -- * Field and group parameters - _CURVE_Q - , _CURVE_P + -- * Parsing + parse_int256 + , parse_point + , parse_sig + + -- * Serializing + , serialize_point -- * secp256k1 points , Pub @@ -43,14 +47,6 @@ module Crypto.Curve.Secp256k1 ( , ge , fe - -- * Parsing - , parse_int256 - , parse_point - , parse_sig - - -- * Serializing - , serialize_point - -- * ECDH , ecdh @@ -86,6 +82,10 @@ module Crypto.Curve.Secp256k1 ( , mul_vartime , mul_wnaf + -- * Field and group parameters + , _CURVE_Q + , _CURVE_P + -- Coordinate systems and transformations , Affine(..) , Projective(..) @@ -301,10 +301,16 @@ xor = BS.packZipWith B.xor -- constants ------------------------------------------------------------------ -- | secp256k1 field prime. +-- +-- >>> _CURVE_P +-- 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F _CURVE_P :: Wider _CURVE_P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F -- | secp256k1 group order. +-- +-- >>> _CURVE_Q +-- 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 _CURVE_Q :: Wider _CURVE_Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 @@ -372,7 +378,7 @@ instance Eq Projective where !y2z1 = by * az in CT.decide (CT.and (C.eq x1z2 x2z1) (C.eq y1z2 y2z1)) --- | An ECC-flavoured alias for a secp256k1 point. +-- | A public key, i.e. secp256k1 point. type Pub = Projective -- Convert to affine coordinates. @@ -1255,10 +1261,13 @@ _sign_ecdsa _mul ty hf _SECRET m = runST $ do -- RFC6979 sec 3.3a let entropy = int2octets _SECRET nonce = bits2octets h - drbg <- DRBG.new SHA256.hmac entropy nonce mempty + drbg <- DRBG.new hmac entropy nonce mempty -- RFC6979 sec 2.4 sign_loop drbg where + hmac k b = case SHA256.hmac k b of + SHA256.MAC mac -> mac + d = S.to _SECRET hm = S.to (bits2int h) h = case hf of @@ -1289,10 +1298,13 @@ gen_k :: DRBG.DRBG s -> ST s Wider gen_k g = loop g where loop drbg = do bytes <- DRBG.gen mempty (fi _CURVE_Q_BYTES) drbg - let can = bits2int bytes - case W.cmp_vartime can _CURVE_Q of - LT -> pure can - _ -> loop drbg -- 2 ^ -128 probability + case bytes of + Left {} -> error "ppad-secp256k1: internal error (please report a bug!)" + Right bs -> do + let can = bits2int bs + case W.cmp_vartime can _CURVE_Q of + LT -> pure can + _ -> loop drbg -- 2 ^ -128 probability {-# INLINE gen_k #-} -- | Verify a "low-s" ECDSA signature for the provided message and diff --git a/ppad-secp256k1.cabal b/ppad-secp256k1.cabal @@ -1,6 +1,6 @@ cabal-version: 3.0 name: ppad-secp256k1 -version: 0.5.2 +version: 0.5.3 synopsis: Schnorr signatures, ECDSA, and ECDH on the elliptic curve secp256k1 license: MIT @@ -36,8 +36,8 @@ library build-depends: base >= 4.9 && < 5 , bytestring >= 0.9 && < 0.13 - , ppad-hmac-drbg >= 0.1.3 && < 0.2 - , ppad-sha256 >= 0.2.4 && < 0.3 + , ppad-hmac-drbg >= 0.2.1 && < 0.3 + , ppad-sha256 >= 0.3 && < 0.4 , ppad-fixed >= 0.1.3 && < 0.2 , primitive >= 0.8 && < 0.10