commit f67d1cc5897496eb8ea32b582264f85c02c2418d
parent 78a07bfdf80a67cb2f132c805b7decf333365033
Author: Jared Tobin <jared@jtobin.io>
Date: Thu, 13 Mar 2025 13:58:33 +0400
lib: ecdh implementation
Diffstat:
1 file changed, 24 insertions(+), 0 deletions(-)
diff --git a/lib/Crypto/Curve/Secp256k1.hs b/lib/Crypto/Curve/Secp256k1.hs
@@ -42,6 +42,9 @@ module Crypto.Curve.Secp256k1 (
-- * Serializing
, serialize_point
+ -- * ECDH
+ , ecdh
+
-- * BIP0340 Schnorr signatures
, sign_schnorr
, verify_schnorr
@@ -1236,3 +1239,24 @@ _verify_ecdsa_unrestricted _mul (SHA256.hash -> h) p (ECDSA r s)
in v == r
{-# INLINE _verify_ecdsa_unrestricted #-}
+-- ecdh -----------------------------------------------------------------------
+
+-- SEC1-v2 3.3.1
+
+-- | Compute a shared secret, given a secret key and public secp256k1 point,
+-- via Elliptic Curve Diffie-Hellman (ECDH).
+--
+-- The shared secret is the SHA256 hash of the compressed secp256k1
+-- point obtained by scalar multiplication.
+ecdh
+ :: Integer -- ^ secret key
+ -> Projective -- ^ public key
+ -> BS.ByteString -- ^ shared secret
+ecdh _SECRET pub
+ | not (ge _SECRET) = error "ppad-secp256k1 (ecdh): invalid secret key"
+ | otherwise =
+ let pt = mul pub _SECRET
+ in if pt == _CURVE_ZERO
+ then error "ppad-secp256k1 (ecdh): invalid public key"
+ else SHA256.hash (serialize_point pt)
+