commit 9603f1e4a327c3007df36f7afdc16954eefcf314
parent edf681f4a679a52118d0c750572e3efb5b9439f3
Author: Jared Tobin <jared@jtobin.io>
Date: Mon, 25 Nov 2024 15:40:04 +0400
lib: add wnaf-powered derive_pub
Diffstat:
3 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/bench/Main.hs b/bench/Main.hs
@@ -92,14 +92,19 @@ mul_wnaf = env setup $ \ ~(tex, x) ->
pure (tex, int)
derive_pub :: Benchmark
-derive_pub = env setup $ \x ->
+derive_pub = env setup $ \ ~(tex, x) ->
bgroup "derive_pub" [
bench "sk = 2" $ nf S.derive_pub 2
, bench "sk = 2 ^ 255 - 19" $ nf S.derive_pub x
+ , bench "wnaf, sk = 2" $ nf (S.derive_pub' tex) 2
+ , bench "wnaf, sk = 2 ^ 255 - 19" $ nf (S.derive_pub' tex) x
]
where
- setup = pure . S.parse_int256 $ B16.decodeLenient
- "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
+ setup = do
+ let !tex = S.precompute
+ !int = S.parse_int256 $ B16.decodeLenient
+ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
+ pure (tex, int)
schnorr :: Benchmark
schnorr = env setup $ \ ~(tex, big) ->
diff --git a/lib/Crypto/Curve/Secp256k1.hs b/lib/Crypto/Curve/Secp256k1.hs
@@ -24,6 +24,7 @@ module Crypto.Curve.Secp256k1 (
-- * secp256k1 points
Pub
, derive_pub
+ , derive_pub'
-- * Parsing
, parse_int256
@@ -680,6 +681,22 @@ derive_pub _SECRET
mul _CURVE_G _SECRET
{-# NOINLINE derive_pub #-}
+-- | The same as 'derive_pub', except uses a 'Context' to optimise
+-- internal calculations.
+--
+-- >>> import qualified System.Entropy as E
+-- >>> sk <- fmap parse_int256 (E.getEntropy 32)
+-- >>> let !tex = precompute
+-- >>> derive_pub' tex sk
+-- "<secp256k1 point>"
+derive_pub' :: Context -> Integer -> Pub
+derive_pub' tex _SECRET
+ | not (ge _SECRET) =
+ error "ppad-secp256k1 (derive_pub): invalid secret key"
+ | otherwise =
+ mul_wnaf tex _SECRET
+{-# NOINLINE derive_pub' #-}
+
-- parsing --------------------------------------------------------------------
-- | Parse a positive 256-bit 'Integer', /e.g./ a Schnorr or ECDSA
diff --git a/test/Main.hs b/test/Main.hs
@@ -69,7 +69,6 @@ parse_point_tests = testGroup "parse_point tests" [
render :: Show a => a -> String
render = filter (`notElem` ("\"" :: String)) . show
--- XX replace these with something non-stupid
parse_point_test_p :: TestTree
parse_point_test_p = testCase (render p_hex) $
case parse_point (B16.decodeLenient p_hex) of
@@ -88,7 +87,6 @@ parse_point_test_r = testCase (render r_hex) $
Nothing -> assertFailure "bad parse"
Just r -> assertEqual mempty r_pro r
--- XX also make less dumb
add_tests :: TestTree
add_tests = testGroup "ec addition" [
add_test_pq