commit aae76295f8d86754de5a4560e4d6c7f2213ac5e6
parent 5873f4b163896cd7b7197c9d9f5fb3683a9e8aaa
Author: Jared Tobin <jared@jtobin.io>
Date: Tue, 17 Jun 2025 14:47:52 +0400
lib: make parse_int256 total
Diffstat:
3 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/bench/Main.hs b/bench/Main.hs
@@ -28,6 +28,11 @@ main = defaultMain [
, ecdh
]
+parse_int256 :: BS.ByteString -> Integer
+parse_int256 bs = case S.parse_int256 bs of
+ Nothing -> error "bang"
+ Just s -> s
+
remQ :: Benchmark
remQ = env setup $ \x ->
bgroup "remQ (remainder modulo _CURVE_Q)" [
@@ -35,7 +40,7 @@ remQ = env setup $ \x ->
, bench "remQ (2 ^ 255 - 19)" $ nf S.remQ x
]
where
- setup = pure . S.parse_int256 $ B16.decodeLenient
+ setup = pure . parse_int256 $ B16.decodeLenient
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
parse_point :: Benchmark
@@ -48,8 +53,8 @@ parse_point = bgroup "parse_point" [
parse_integer :: Benchmark
parse_integer = env setup $ \ ~(small, big) ->
bgroup "parse_int256" [
- bench "parse_int256 (small)" $ nf S.parse_int256 small
- , bench "parse_int256 (big)" $ nf S.parse_int256 big
+ bench "parse_int256 (small)" $ nf parse_int256 small
+ , bench "parse_int256 (big)" $ nf parse_int256 big
]
where
setup = do
@@ -73,7 +78,7 @@ mul = env setup $ \x ->
, bench "(2 ^ 255 - 19) G" $ nf (S.mul S._CURVE_G) x
]
where
- setup = pure . S.parse_int256 $ B16.decodeLenient
+ setup = pure . parse_int256 $ B16.decodeLenient
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
precompute :: Benchmark
@@ -88,7 +93,7 @@ mul_wnaf = env setup $ \ ~(tex, x) ->
where
setup = do
let !tex = S.precompute
- !int = S.parse_int256 $ B16.decodeLenient
+ !int = parse_int256 $ B16.decodeLenient
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
pure (tex, int)
@@ -103,7 +108,7 @@ derive_pub = env setup $ \ ~(tex, x) ->
where
setup = do
let !tex = S.precompute
- !int = S.parse_int256 $ B16.decodeLenient
+ !int = parse_int256 $ B16.decodeLenient
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
pure (tex, int)
@@ -120,7 +125,7 @@ schnorr = env setup $ \ ~(tex, big) ->
where
setup = do
let !tex = S.precompute
- !int = S.parse_int256 $ B16.decodeLenient
+ !int = parse_int256 $ B16.decodeLenient
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
pure (tex, int)
@@ -137,7 +142,7 @@ ecdsa = env setup $ \ ~(tex, big, pub, msg, sig) ->
where
setup = do
let !tex = S.precompute
- big = S.parse_int256 $ B16.decodeLenient
+ big = parse_int256 $ B16.decodeLenient
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
Just pub = S.derive_pub big
msg = "i approve of this message"
@@ -203,7 +208,7 @@ t = case S.parse_point t_bs of
Just !pt -> pt
s_sk :: Integer
-s_sk = S.parse_int256 . B16.decodeLenient $
+s_sk = parse_int256 . B16.decodeLenient $
"B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF"
s_sig :: BS.ByteString
diff --git a/bench/Weight.hs b/bench/Weight.hs
@@ -15,6 +15,11 @@ instance NFData S.Affine
instance NFData S.ECDSA
instance NFData S.Context
+parse_int :: BS.ByteString -> Integer
+parse_int bs = case S.parse_int256 bs of
+ Nothing -> error "bang"
+ Just v -> v
+
big :: Integer
big = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed
@@ -42,8 +47,8 @@ remQ = W.wgroup "remQ" $ do
parse_int256 :: W.Weigh ()
parse_int256 = W.wgroup "parse_int256" $ do
- W.func' "parse_int256 (small)" S.parse_int256 (BS.replicate 32 0x00)
- W.func' "parse_int256 (big)" S.parse_int256 (BS.replicate 32 0xFF)
+ W.func' "parse_int (small)" parse_int (BS.replicate 32 0x00)
+ W.func' "parse_int (big)" parse_int (BS.replicate 32 0xFF)
add :: W.Weigh ()
add = W.wgroup " add" $ do
@@ -108,7 +113,7 @@ ecdh = W.wgroup "ecdh" $ do
"bd02b9dfc8ef760708950bd972f2dc244893b61b6b46c3b19be1b2da7b034ac5"
s_sk :: Integer
-s_sk = S.parse_int256 . B16.decodeLenient $
+s_sk = parse_int . B16.decodeLenient $
"B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF"
s_sig :: BS.ByteString
diff --git a/lib/Crypto/Curve/Secp256k1.hs b/lib/Crypto/Curve/Secp256k1.hs
@@ -703,11 +703,10 @@ derive_pub' = mul_wnaf
-- >>> import qualified Data.ByteString as BS
-- >>> parse_int256 (BS.replicate 32 0xFF)
-- <2^256 - 1>
-parse_int256 :: BS.ByteString -> Integer
-parse_int256 bs
- | BS.length bs /= 32 =
- error "ppad-secp256k1 (parse_int256): requires exactly 32-byte input"
- | otherwise = roll32 bs
+parse_int256 :: BS.ByteString -> Maybe Integer
+parse_int256 bs = do
+ guard (BS.length bs == 32)
+ pure $! roll32 bs
-- | Parse compressed secp256k1 point (33 bytes), uncompressed point (65
-- bytes), or BIP0340-style point (32 bytes).