commit 132ef47e2561f28f401583132658dae17a62852f
parent 8305a24530f35a6d6c9f50012ef50a0a6e1ba97c
Author: Jared Tobin <jared@jtobin.io>
Date: Fri, 18 Oct 2024 16:55:43 +0400
lib: s/derive_public/derive_pub, bench stuff
Diffstat:
3 files changed, 58 insertions(+), 16 deletions(-)
diff --git a/README.md b/README.md
@@ -38,6 +38,43 @@ A sample GHCi session:
Haddocks (API documentation, etc.) are hosted at
[docs.ppad.tech/secp256k1][hadoc].
+## Performance
+
+The aim is best-in-class performance for pure, highly-auditable Haskell
+code.
+
+Current benchmark figures on my mid-2020 MacBook Air look like (use
+`cabal bench` to run the benchmark suite):
+
+```
+ benchmarking schnorr/sign_schnorr
+ time 5.663 ms (5.618 ms .. 5.714 ms)
+ 0.999 R² (0.999 R² .. 1.000 R²)
+ mean 5.683 ms (5.652 ms .. 5.715 ms)
+ std dev 98.56 μs (78.45 μs .. 127.0 μs)
+
+ benchmarking schnorr/verify_schnorr
+ time 2.323 ms (2.301 ms .. 2.360 ms)
+ 0.999 R² (0.997 R² .. 0.999 R²)
+ mean 2.342 ms (2.328 ms .. 2.363 ms)
+ std dev 57.68 μs (43.66 μs .. 86.22 μs)
+ variance introduced by outliers: 11% (moderately inflated)
+
+ benchmarking ecdsa/sign_ecdsa
+ time 1.756 ms (1.741 ms .. 1.774 ms)
+ 0.999 R² (0.998 R² .. 1.000 R²)
+ mean 1.773 ms (1.760 ms .. 1.788 ms)
+ std dev 45.40 μs (35.58 μs .. 57.52 μs)
+ variance introduced by outliers: 13% (moderately inflated)
+
+ benchmarking ecdsa/verify_ecdsa
+ time 2.300 ms (2.270 ms .. 2.331 ms)
+ 0.998 R² (0.997 R² .. 0.999 R²)
+ mean 2.318 ms (2.297 ms .. 2.345 ms)
+ std dev 81.45 μs (65.15 μs .. 105.2 μs)
+ variance introduced by outliers: 21% (moderately inflated)
+```
+
## Security
This library aims at the maximum security achievable in a
diff --git a/bench/Main.hs b/bench/Main.hs
@@ -20,7 +20,7 @@ main = defaultMain [
parse_point
, add
, mul
- , derive_public
+ , derive_pub
, schnorr
, ecdsa
]
@@ -63,11 +63,11 @@ mul = env setup $ \x ->
setup = pure . S.parse_int256 $ B16.decodeLenient
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
-derive_public :: Benchmark
-derive_public = env setup $ \x ->
- bgroup "derive_public" [
- bench "sk = 2" $ nf S.derive_public 2
- , bench "sk = 2 ^ 255 - 19" $ nf S.derive_public x
+derive_pub :: Benchmark
+derive_pub = env setup $ \x ->
+ bgroup "derive_pub" [
+ bench "sk = 2" $ nf S.derive_pub 2
+ , bench "sk = 2 ^ 255 - 19" $ nf S.derive_pub x
]
where
setup = pure . S.parse_int256 $ B16.decodeLenient
@@ -85,15 +85,20 @@ schnorr = env setup $ \big ->
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
ecdsa :: Benchmark
-ecdsa = env setup $ \big ->
+ecdsa = env setup $ \ ~(big, pub, msg, sig) ->
bgroup "ecdsa" [
bench "sign_ecdsa (small)" $ nf (S.sign_ecdsa 2) s_msg
, bench "sign_ecdsa (large)" $ nf (S.sign_ecdsa big) s_msg
- -- , bench "verify_ecdsa" $ nf (S.verify_ecdsa e_msg t) e_sig -- XX inputs
+ , bench "verify_ecdsa" $ nf (S.verify_ecdsa msg pub) sig
]
where
- setup = pure . S.parse_int256 $ B16.decodeLenient
- "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
+ setup = do
+ let big = S.parse_int256 $ B16.decodeLenient
+ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
+ pub = S.derive_pub big
+ msg = "i approve of this message"
+ sig = S.sign_ecdsa big s_msg
+ pure (big, pub, msg, sig)
p_bs :: BS.ByteString
p_bs = B16.decodeLenient
diff --git a/lib/Crypto/Curve/Secp256k1.hs b/lib/Crypto/Curve/Secp256k1.hs
@@ -43,7 +43,7 @@ module Crypto.Curve.Secp256k1 (
, double
, mul
, mul_unsafe
- , derive_public
+ , derive_pub
-- Coordinate systems and transformations
, Affine(..)
@@ -580,15 +580,15 @@ mul_unsafe p n
--
-- >>> import qualified System.Entropy as E
-- >>> sk <- fmap parse_int256 (E.getEntropy 32)
--- >>> derive_public sk
+-- >>> derive_pub sk
-- "<secp256k1 point>"
-derive_public :: Integer -> Pub
-derive_public _SECRET
+derive_pub :: Integer -> Pub
+derive_pub _SECRET
| not (ge _SECRET) =
- error "ppad-secp256k1 (derive_public): invalid secret key"
+ error "ppad-secp256k1 (derive_pub): invalid secret key"
| otherwise =
mul _CURVE_G _SECRET
-{-# NOINLINE derive_public #-}
+{-# NOINLINE derive_pub #-}
-- parsing --------------------------------------------------------------------