secp256k1

Pure Haskell cryptographic primitives on the secp256k1 elliptic curve.
git clone git://git.ppad.tech/secp256k1.git
Log | Files | Refs | LICENSE

commit 67319e9b56763bafcfa3e41d5a876d851fd70128
parent 411122f32984e59a08dcfa74c6522a4f4d896cd3
Author: Jared Tobin <jared@jtobin.io>
Date:   Fri,  5 Apr 2024 18:17:25 +0400

lib: basic ECDSA sign skeleton

Diffstat:
Mlib/Crypto/Secp256k1.hs | 19++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/lib/Crypto/Secp256k1.hs b/lib/Crypto/Secp256k1.hs @@ -413,7 +413,7 @@ unroll i = case i of bits2int :: BS.ByteString -> Integer bits2int bs = let (fromIntegral -> blen) = BS.length bs * 8 - (fromIntegral -> qlen) = _CURVE_N_LEN + (fromIntegral -> qlen) = _CURVE_N_LEN -- RFC6979 notation del = blen - qlen in if del > 0 then roll bs `I.integerShiftR` del @@ -430,12 +430,21 @@ int2octets i = pad (unroll i) where bits2octets :: BS.ByteString -> BS.ByteString bits2octets bs = let z1 = bits2int bs - z2 = let d = z1 - _CURVE_N - in if d < 0 - then z1 - else d + z2 = modN z1 in int2octets z2 +-- XX handle low-s +sign :: BS.ByteString -> Integer -> Integer -> (Integer, Integer) +sign (modN . bits2int -> h) k x = + let kg = mul _CURVE_G k + Affine (modN -> r) _ = affine kg + s = case modinv k (fromIntegral _CURVE_N) of + Nothing -> error "ppad-secp256k1 (sign): bad k value" + Just kinv -> modN (modN (h + modN (x * r)) * kinv) + in if r == 0 + then error "ppad-secp256k1 (sign): <negligible probability outcome>" + else (r, s) + -- XX test test_h1 :: BS.ByteString