csecp256k1

Haskell FFI bindings to bitcoin-core/secp256k1 (docs.ppad.tech/csecp256k1).
git clone git://git.ppad.tech/csecp256k1.git
Log | Files | Refs | README | LICENSE

commit 8a319e392574efd217faf929059d2707e8876a07
parent 8ebed96021830cf3b8b965dd29378044fa636179
Author: Jared Tobin <jared@jtobin.io>
Date:   Thu,  7 Nov 2024 16:36:44 +0400

test: bip340 vectors passing

.. with the exception of those using arbitrary-size messages, which we're
not supporting at present.

Diffstat:
Metc/bip-0340-test-vectors.csv | 4----
Mtest/BIP340.hs | 56++++++++++++++++++++++----------------------------------
Mtest/Main.hs | 4++--
3 files changed, 24 insertions(+), 40 deletions(-)

diff --git a/etc/bip-0340-test-vectors.csv b/etc/bip-0340-test-vectors.csv @@ -14,7 +14,3 @@ index,secret key,public key,aux_rand,message,signature,verification result,comme 12,,DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F69E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B,FALSE,sig[0:32] is equal to field size 13,,DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E177769FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141,FALSE,sig[32:64] is equal to curve order 14,,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC30,,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E17776969E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B,FALSE,public key is not a valid X coordinate because it exceeds the field size -15,0340034003400340034003400340034003400340034003400340034003400340,778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117,0000000000000000000000000000000000000000000000000000000000000000,,71535DB165ECD9FBBC046E5FFAEA61186BB6AD436732FCCC25291A55895464CF6069CE26BF03466228F19A3A62DB8A649F2D560FAC652827D1AF0574E427AB63,TRUE,message of size 0 (added 2022-12) -16,0340034003400340034003400340034003400340034003400340034003400340,778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117,0000000000000000000000000000000000000000000000000000000000000000,11,08A20A0AFEF64124649232E0693C583AB1B9934AE63B4C3511F3AE1134C6A303EA3173BFEA6683BD101FA5AA5DBC1996FE7CACFC5A577D33EC14564CEC2BACBF,TRUE,message of size 1 (added 2022-12) -17,0340034003400340034003400340034003400340034003400340034003400340,778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117,0000000000000000000000000000000000000000000000000000000000000000,0102030405060708090A0B0C0D0E0F1011,5130F39A4059B43BC7CAC09A19ECE52B5D8699D1A71E3C52DA9AFDB6B50AC370C4A482B77BF960F8681540E25B6771ECE1E5A37FD80E5A51897C5566A97EA5A5,TRUE,message of size 17 (added 2022-12) -18,0340034003400340034003400340034003400340034003400340034003400340,778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117,0000000000000000000000000000000000000000000000000000000000000000,99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999,403B12B0D8555A344175EA7EC746566303321E5DBFA8BE6F091635163ECA79A8585ED3E3170807E7C03B720FC54C7B23897FCBA0E9D0B4A06894CFD249F22367,TRUE,message of size 100 (added 2022-12) diff --git a/test/BIP340.hs b/test/BIP340.hs @@ -13,20 +13,9 @@ import Crypto.Curve.Secp256k1 import qualified Data.Attoparsec.ByteString.Char8 as AT import qualified Data.ByteString as BS import qualified Data.ByteString.Base16 as B16 -import qualified GHC.Num.Integer as I import Test.Tasty import Test.Tasty.HUnit --- XX make a test prelude instead of copying/pasting these things everywhere - -fi :: (Integral a, Num b) => a -> b -fi = fromIntegral -{-# INLINE fi #-} - -roll :: BS.ByteString -> Integer -roll = BS.foldl' unstep 0 where - unstep a (fi -> b) = (a `I.integerShiftL` 8) `I.integerOr` b - data Case = Case { c_index :: !Int , c_sk :: !BS.ByteString @@ -38,29 +27,28 @@ data Case = Case { , c_comment :: !BS.ByteString } deriving Show -execute = undefined - --- execute :: Context -> Case -> TestTree --- execute tex Case {..} = testCase ("bip0340 " <> show c_index) $ do --- pub <- try (parse_xonly tex (B16.decodeLenient c_pk)) --- case pub of --- Left _ -> assertBool mempty (not c_res) --- Right pk -> do --- if c_sk == mempty --- then do -- no signature; test verification --- ver <- verify_schnorr tex pk c_msg c_sig --- if c_res --- then assertBool mempty ver --- else assertBool mempty (not ver) --- -- XX test pubkey derivation from sk --- else do -- signature present; test sig too --- let sk = roll c_sk --- sig <- sign_schnorr tex c_msg sk c_aux --- ver <- verify_schnorr tex pk c_msg sig --- assertEqual mempty c_sig sig --- if c_res --- then assertBool mempty ver --- else assertBool mempty (not ver) +execute :: Context -> Case -> TestTree +execute tex Case {..} = testCase ("bip0340 " <> show c_index) $ do + par <- try (parse_xonly tex (B16.decodeLenient c_pk)) + :: IO (Either Secp256k1Exception XOnlyPub) + case par of + Left _ -> assertBool mempty (not c_res) + Right (XOnlyPub pub) -> do + let pk = Pub pub + if c_sk == mempty + then do -- no signature; test verification + ver <- verify_schnorr tex pk c_msg c_sig + if c_res + then assertBool mempty ver + else assertBool mempty (not ver) + -- XX test pubkey derivation from sk + else do -- signature present; test sig too + sig <- sign_schnorr tex c_msg c_sk c_aux + ver <- verify_schnorr tex pk c_msg sig + assertEqual mempty c_sig sig + if c_res + then assertBool mempty ver + else assertBool mempty (not ver) header :: AT.Parser () header = do diff --git a/test/Main.hs b/test/Main.hs @@ -5,7 +5,7 @@ module Main where import Crypto.Curve.Secp256k1 import qualified Data.Aeson as A -import qualified Data.Attoparsec.ByteString.Char8 as AT +import qualified Data.Attoparsec.ByteString as AT import qualified Data.ByteString as BS import qualified Data.Text.IO as TIO import Test.Tasty @@ -31,7 +31,7 @@ main = do defaultMain $ testGroup "ppad-csecp256k1" [ units , wycheproof_ecdsa_verify_tests "(ecdsa, sha256, low-s)" tree - -- , testGroup "bip0340 vectors (schnorr)" (fmap BIP340.execute bip) + , testGroup "bip0340 vectors (schnorr)" (fmap (BIP340.execute tex) bip) ] wycheproof_ecdsa_verify_tests :: String -> [TestTree] -> TestTree