secp256k1

Pure Haskell Schnorr, ECDSA on the elliptic curve secp256k1 (docs.ppad.tech/secp256k1).
git clone git://git.ppad.tech/secp256k1.git
Log | Files | Refs | README | LICENSE

commit 42fbbc0e8493c5c1981427e7493a3fa0b2822872
parent 70d13a6fd3e9549507f83ee1e9168b135d03bee3
Author: Jared Tobin <jared@jtobin.io>
Date:   Fri, 18 Oct 2024 15:27:06 +0400

meta: readme

Diffstat:
MREADME.md | 52+++++++++++++++++++++++++++++++++++++++-------------
Mlib/Crypto/Curve/Secp256k1.hs | 2++
2 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/README.md b/README.md @@ -40,24 +40,50 @@ Haddocks (API documentation, etc.) are hosted at ## Security -This library is in a **pre-release** state. It ultimately aims at the -maximum security achievable in a garbage-collected language under an -optimizing compiler such as GHC, in which strict constant-timeness can -be [challenging to achieve][const], but we're not there quite yet. +This library aims at the maximum security achievable in a +garbage-collected language under an optimizing compiler such as GHC, in +which strict constant-timeness can be [challenging to achieve][const]. The Schnorr implementation within has been tested against the [official BIP0340 vectors][ut340], and ECDSA has been tested against the relevant [Wycheproof vectors][wyche], so their implementations are likely to be accurate and safe from attacks targeting e.g. faulty nonce generation or -malicious inputs for signature parameters. - -However, the signature schemes are **not** implemented so as to be -constant-time (or constant-allocation) with respect to secrets, and no -effort has yet been made to quantify the degree to which they deviate -from that. Perhaps obviously: you shouldn't deploy the implementations -within in any situation where they can easily be used as an oracle to -construct a [timing attack][timea], and you shouldn't give sophisticated -malicious actors [access to your computer][flurl]. +malicious inputs for signature parameters. Timing-sensitive operations, +e.g. elliptic curve scalar multiplication, have been explicitly written +so as to execute algorithmically in time constant with respect to secret +data: + +``` + benchmarking schnorr/sign_schnorr (small secret) + time 5.388 ms (5.345 ms .. 5.438 ms) + 1.000 R² (0.999 R² .. 1.000 R²) + mean 5.429 ms (5.410 ms .. 5.449 ms) + std dev 58.14 μs (48.93 μs .. 68.69 μs) + + benchmarking schnorr/sign_schnorr (large secret) + time 5.364 ms (5.324 ms .. 5.410 ms) + 0.999 R² (0.999 R² .. 1.000 R²) + mean 5.443 ms (5.414 ms .. 5.486 ms) + std dev 102.1 μs (74.16 μs .. 146.4 μs) + + benchmarking ecdsa/sign_ecdsa (small secret) + time 1.740 ms (1.726 ms .. 1.753 ms) + 1.000 R² (0.999 R² .. 1.000 R²) + mean 1.752 ms (1.744 ms .. 1.761 ms) + std dev 32.33 μs (26.12 μs .. 43.34 μs) + + benchmarking ecdsa/sign_ecdsa (large secret) + time 1.748 ms (1.731 ms .. 1.766 ms) + 0.999 R² (0.998 R² .. 0.999 R²) + mean 1.756 ms (1.743 ms .. 1.771 ms) + std dev 48.99 μs (40.83 μs .. 62.77 μs) +``` + +Despite all that, take reasonable security precautions as appropriate. +You probably shouldn't deploy the implementations within in any +situation where they could easily be used as an oracle to construct a +[timing attack][timea], and you shouldn't give sophisticated malicious +actors [access to your computer][flurl]. If you discover any vulnerabilities, please disclose them via security@ppad.tech. diff --git a/lib/Crypto/Curve/Secp256k1.hs b/lib/Crypto/Curve/Secp256k1.hs @@ -151,6 +151,8 @@ roll32 bs = word256_to_integer $! (go 0 0 0 0 0) where in go acc0 acc1 acc2 ((acc3 `B.shiftL` 8) .|. b) (j + 1) {-# INLINE roll32 #-} +-- XX surely there's a better way to do this + -- big-endian bytestring encoding unroll :: Integer -> BS.ByteString unroll i = case i of