packages feed

secp256k1 0.1.11 → 0.2.0

raw patch · 25 files changed

+4625/−57 lines, 25 filesdep +binarydep +largeword

Dependencies added: binary, largeword

Files

+ contrib/lax_der_parsing.h view
@@ -0,0 +1,191 @@+/**********************************************************************+ * Copyright (c) 2015 Pieter Wuille                                   *+ * Distributed under the MIT software license, see the accompanying   *+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*+ **********************************************************************/++/* This file contains a code snippet that parses DER with various errors and+ * violations. This is not a part of the library itself, because the allowed+ * violations are chosen arbitrarily and do not follow or establish any+ * standard.+ *+ * In many places it matters that different implementations do not only accept+ * the same set of valid signatures, but also reject the same set of signatures.+ * The only means to accomplish that is by strictly obeying a standard, and not+ * accepting anything else.+ *+ * Nonetheless, sometimes there is a need for compatibility with systems that+ * use signatures which do not strictly obey DER. The snippet below shows how+ * certain violations are easily supported. You may need to adapt it.+ *+ * Do not use this for new systems. Use well-defined DER or compact signatures+ * instead if you have the choice (see secp256k1_ecdsa_signature_parse_der and+ * secp256k1_ecdsa_signature_parse_compact).+ *+ * The supported violations are:+ * - All numbers are parsed as nonnegative integers, even though X.609-0207+ *   section 8.3.3 specifies that integers are always encoded as two's+ *   complement.+ * - Integers can have length 0, even though section 8.3.1 says they can't.+ * - Integers with overly long padding are accepted, violation section+ *   8.3.2.+ * - 127-byte long length descriptors are accepted, even though section+ *   8.1.3.5.c says that they are not.+ * - Trailing garbage data inside or after the signature is ignored.+ * - The length descriptor of the sequence is ignored.+ *+ * Compared to for example OpenSSL, many violations are NOT supported:+ * - Using overly long tag descriptors for the sequence or integers inside,+ *   violating section 8.1.2.2.+ * - Encoding primitive integers as constructed values, violating section+ *   8.3.1.+ */++#ifndef _SECP256K1_CONTRIB_LAX_DER_PARSING_H_+#define _SECP256K1_CONTRIB_LAX_DER_PARSING_H_++#include <string.h>+#include <secp256k1.h>++static int secp256k1_ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen);++static int secp256k1_ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {+    size_t rpos, rlen, spos, slen;+    size_t pos = 0;+    size_t lenbyte;+    unsigned char tmpsig[64] = {0};+    int overflow = 0;++    /* Hack to initialize sig with a correctly-parsed but invalid signature. */+    secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);++    /* Sequence tag byte */+    if (pos == inputlen || input[pos] != 0x30) {+        return 0;+    }+    pos++;++    /* Sequence length bytes */+    if (pos == inputlen) {+        return 0;+    }+    lenbyte = input[pos++];+    if (lenbyte & 0x80) {+        lenbyte -= 0x80;+        if (pos + lenbyte > inputlen) {+            return 0;+        }+        pos += lenbyte;+    }++    /* Integer tag byte for R */+    if (pos == inputlen || input[pos] != 0x02) {+        return 0;+    }+    pos++;++    /* Integer length for R */+    if (pos == inputlen) {+        return 0;+    }+    lenbyte = input[pos++];+    if (lenbyte & 0x80) {+        lenbyte -= 0x80;+        if (pos + lenbyte > inputlen) {+            return 0;+        }+        while (lenbyte > 0 && input[pos] == 0) {+            pos++;+            lenbyte--;+        }+        if (lenbyte >= sizeof(size_t)) {+            return 0;+        }+        rlen = 0;+        while (lenbyte > 0) {+            rlen = (rlen << 8) + input[pos];+            pos++;+            lenbyte--;+        }+    } else {+        rlen = lenbyte;+    }+    if (rlen > inputlen - pos) {+        return 0;+    }+    rpos = pos;+    pos += rlen;++    /* Integer tag byte for S */+    if (pos == inputlen || input[pos] != 0x02) {+        return 0;+    }+    pos++;++    /* Integer length for S */+    if (pos == inputlen) {+        return 0;+    }+    lenbyte = input[pos++];+    if (lenbyte & 0x80) {+        lenbyte -= 0x80;+        if (pos + lenbyte > inputlen) {+            return 0;+        }+        while (lenbyte > 0 && input[pos] == 0) {+            pos++;+            lenbyte--;+        }+        if (lenbyte >= sizeof(size_t)) {+            return 0;+        }+        slen = 0;+        while (lenbyte > 0) {+            slen = (slen << 8) + input[pos];+            pos++;+            lenbyte--;+        }+    } else {+        slen = lenbyte;+    }+    if (slen > inputlen - pos) {+        return 0;+    }+    spos = pos;+    pos += slen;++    /* Ignore leading zeroes in R */+    while (rlen > 0 && input[rpos] == 0) {+        rlen--;+        rpos++;+    }+    /* Copy R value */+    if (rlen > 32) {+        overflow = 1;+    } else {+        memcpy(tmpsig + 32 - rlen, input + rpos, rlen);+    }++    /* Ignore leading zeroes in S */+    while (slen > 0 && input[spos] == 0) {+        slen--;+        spos++;+    }+    /* Copy S value */+    if (slen > 32) {+        overflow = 1;+    } else {+        memcpy(tmpsig + 64 - slen, input + spos, slen);+    }++    if (!overflow) {+        overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);+    }+    if (overflow) {+        memset(tmpsig, 0, 64);+        secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);+    }+    return 1;+}++#endif
+ haskell/cbits/lax_der.c view
@@ -0,0 +1,8 @@+#include "haskell/include/lax_der.h"++int lax_der_parse(+        const secp256k1_context* ctx,+        secp256k1_ecdsa_signature* sig,+        const unsigned char *input, size_t inputlen) {+    return secp256k1_ecdsa_signature_parse_der_lax(ctx, sig, input, inputlen);+}
+ haskell/include/lax_der.h view
@@ -0,0 +1,6 @@+#include "contrib/lax_der_parsing.h"++int lax_der_parse(+        const secp256k1_context* ctx,+        secp256k1_ecdsa_signature* sig,+        const unsigned char *input, size_t inputlen);
haskell/src/Crypto/Secp256k1.hs view
@@ -20,13 +20,11 @@ , secKey, getSecKey   -- * Public Key , PubKey, importPubKey, exportPubKey-  -- ** Raw Public Key-, unsafePubKey, getPubKey   -- * Signature-, Sig, importSig, exportSig-, signMsg, verifySig-  -- ** Raw Signature-, unsafeSig, getSig+, Sig, CompactSig(..)+, importSig, laxImportSig, exportSig+, exportCompactSig, importCompactSig+, signMsg, verifySig, normalizeSig   -- * Addition & Multiplication , Tweak, tweak, getTweak , tweakAddSecKey, tweakMulSecKey@@ -155,7 +153,7 @@     fm1 == fm2 = getMsg fm1 == getMsg fm2  instance Eq Sig where-    fg1 == fg2 = getSig fg1 == getSig fg2+    fg1 == fg2 = exportCompactSig fg1 == exportCompactSig fg2  instance Eq SecKey where     fk1 == fk2 = getSecKey fk1 == getSecKey fk2@@ -185,23 +183,15 @@             else return $ Nothing     | otherwise = Nothing --- | Create internal public key from raw 64-byte 'ByteString'. Unsafe!-unsafePubKey :: ByteString -> Maybe PubKey-unsafePubKey bs-    | BS.length bs == 64 = unsafePerformIO $ do-        fp <- mallocForeignPtr-        withForeignPtr fp $ \p -> poke p (PubKey64 bs)-        return $ Just $ PubKey fp-    | otherwise = Nothing---- | Create internal signature from raw 64-byte 'ByteString'. Unsafe!-unsafeSig :: ByteString -> Maybe Sig-unsafeSig bs-    | BS.length bs == 64 = unsafePerformIO $ do-        fp <- mallocForeignPtr-        withForeignPtr fp $ \p -> poke p (Sig64 bs)-        return $ Just $ Sig fp-    | otherwise = Nothing+-- | Convert signature to a normalized lower-S form. Boolean value 'True'+-- indicates that the signature was normalized, 'False' indicates that it was+-- already normal.+normalizeSig :: Sig -> (Sig, Bool)+normalizeSig (Sig fg) = unsafePerformIO $ do+    fg' <- mallocForeignPtr+    ret <- withForeignPtr fg $ \pg -> withForeignPtr fg' $ \pg' ->+        ecdsa_signature_normalize ctx pg' pg+    return (Sig fg', isSuccess ret)  -- | Create internal tweak data from 32-byte 'ByteString'. tweak :: ByteString -> Maybe Tweak@@ -220,10 +210,6 @@ getPubKey :: PubKey -> ByteString getPubKey (PubKey fp) = getPubKey64 $ unsafePerformIO $ withForeignPtr fp peek --- | Get 64-byte internal signature representation.-getSig :: Sig -> ByteString-getSig (Sig fg) = getSig64 $ unsafePerformIO $ withForeignPtr fg peek- -- | Get 32-byte message. getMsg :: Msg -> ByteString getMsg (Msg fm) = getMsg32 $ unsafePerformIO $ withForeignPtr fm $ peek@@ -243,21 +229,46 @@ -- | Encode public key as DER.  First argument 'True' for compressed output. exportPubKey :: Bool -> PubKey -> ByteString exportPubKey compress (PubKey pub) = unsafePerformIO $-    withForeignPtr pub $ \p -> alloca $ \l -> allocaBytes 65 $ \o -> do-        poke l 65+    withForeignPtr pub $ \p -> alloca $ \l -> allocaBytes z $ \o -> do+        poke l (fromIntegral z)         ret <- ec_pubkey_serialize ctx o l p c         unless (isSuccess ret) $ error "could not serialize public key"         n <- peek l         packByteString (o, n)   where     c = if compress then compressed else uncompressed+    z = if compress then 33 else 65 +-- | Get compact signature.+exportCompactSig :: Sig -> CompactSig+exportCompactSig (Sig fg) = unsafePerformIO $+    withForeignPtr fg $ \pg -> alloca $ \pc -> do+        ret <- ecdsa_signature_serialize_compact ctx pc pg+        unless (isSuccess ret) $ error "Could not obtain compact signature"+        peek pc+ -- | Read DER-encoded signature.+importCompactSig :: CompactSig -> Maybe Sig+importCompactSig c = unsafePerformIO $ alloca $ \pc -> do+    poke pc c+    fg <- mallocForeignPtr+    ret <- withForeignPtr fg $ \pg -> ecdsa_signature_parse_compact ctx pg pc+    if isSuccess ret then return $ Just $ Sig fg else return Nothing++-- | Read DER-encoded signature. importSig :: ByteString -> Maybe Sig importSig bs = unsafePerformIO $     useByteString bs $ \(b, l) -> do         fg <- mallocForeignPtr         ret <- withForeignPtr fg $ \g -> ecdsa_signature_parse_der ctx g b l+        if isSuccess ret then return $ Just $ Sig fg else return Nothing++-- | Relaxed DER parsing. Allows certain DER errors and violations.+laxImportSig :: ByteString -> Maybe Sig+laxImportSig bs = unsafePerformIO $+    useByteString bs $ \(b, l) -> do+        fg <- mallocForeignPtr+        ret <- withForeignPtr fg $ \g -> lax_der_parse ctx g b l         if isSuccess ret then return $ Just $ Sig fg else return Nothing  -- | Encode signature as DER.
haskell/src/Crypto/Secp256k1/Internal.hs view
@@ -12,13 +12,16 @@ module Crypto.Secp256k1.Internal where  import           Control.Monad-+import           Data.Binary            (get, put)+import           Data.Binary.Get        (runGet)+import           Data.Binary.Put        (runPut) import           Data.ByteString        (ByteString, packCStringLen)-import           Data.ByteString.Unsafe (unsafeUseAsCStringLen)-+import           Data.ByteString.Lazy   (fromStrict, toStrict)+import           Data.ByteString.Unsafe (unsafePackCStringLen,+                                         unsafeUseAsCStringLen)+import           Data.LargeWord         (LargeKey (LargeKey), Word256) import           Foreign import           Foreign.C- import           System.Entropy import           System.IO.Unsafe @@ -33,6 +36,13 @@ newtype Sig64 = Sig64 { getSig64 :: ByteString }     deriving (Read, Show, Eq, Ord) +data CompactSig =+    CompactSig+        { getCompactSigR :: Word256+        , getCompactSigS :: Word256+        }+    deriving (Show, Eq, Ord)+ newtype Seed32 = Seed32 { getSeed32 :: ByteString }     deriving (Read, Show, Eq, Ord) @@ -103,6 +113,18 @@     poke p (Sig64 k) = useByteString k $         \(b, _) -> copyArray (castPtr p) b 64 +instance Storable CompactSig where+    sizeOf _ = 64+    alignment _ = 1+    peek p = do+        bs <- unsafePackCStringLen (castPtr p, 64)+        let LargeKey r s = runGet get (fromStrict bs)+        return $ CompactSig r s+    poke p (CompactSig r s) = useByteString bs $+        \(b, _) -> copyArray (castPtr p) b 64+      where+        bs = toStrict $ runPut $ put (LargeKey r s)+ instance Storable Msg32 where     sizeOf _ = 32     alignment _ = 1@@ -212,6 +234,15 @@     -> IO Ret  foreign import ccall+    "secp256k1.h secp256k1_ecdsa_signature_parse_compact"+    ecdsa_signature_parse_compact+    :: Ptr Ctx+    -> Ptr Sig64+    -> Ptr CompactSig+    -> IO Ret+++foreign import ccall     "secp256k1.h secp256k1_ecdsa_signature_parse_der"     ecdsa_signature_parse_der     :: Ptr Ctx@@ -230,12 +261,37 @@     -> IO Ret  foreign import ccall+    "secp256k1.h secp256k1_ecdsa_signature_serialize_compact"+    ecdsa_signature_serialize_compact+    :: Ptr Ctx+    -> Ptr CompactSig+    -> Ptr Sig64+    -> IO Ret++foreign import ccall     "secp256k1.h secp256k1_ecdsa_verify"     ecdsa_verify     :: Ptr Ctx     -> Ptr Sig64     -> Ptr Msg32     -> Ptr PubKey64+    -> IO Ret++foreign import ccall+    "secp256k1.h secp256k1_ecdsa_signature_normalize"+    ecdsa_signature_normalize+    :: Ptr Ctx+    -> Ptr Sig64 -- | output+    -> Ptr Sig64 -- | input+    -> IO Ret++foreign import ccall+    "lax_der.h lax_der_parse"+    lax_der_parse+    :: Ptr Ctx+    -> Ptr Sig64+    -> Ptr CUChar+    -> CSize     -> IO Ret  -- TODO:
haskell/test/Crypto/Secp256k1/Internal/Tests.hs view
@@ -29,7 +29,9 @@         [ testCase "Parse public key"         ec_pubkey_parse_test         , testCase "Serialize public key"     ec_pubkey_serialize_test         , testCase "Storable public key"      pubkey_storable_test+        , testCase "Storable signature"       signature_storable_test         , testCase "Parse DER signature"      ecdsa_signature_parse_der_test+        , testCase "Lax parse DER signature"  lax_der_parse_test         , testCase "Serialize DER signature"  ecdsa_signature_serialize_der_test         ]     , testGroup "Signatures"@@ -136,6 +138,27 @@     der = fst $ B16.decode         "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705" +signature_storable_test :: Assertion+signature_storable_test = do+    (sig, ret) <- liftIO $ do+        x <- context_create verify+        g <- alloca $ \pc -> alloca $ \pg -> do+            poke pc cpt+            ret <- ecdsa_signature_parse_compact x pg (castPtr pc)+            unless (isSuccess ret) $ error "failed to parse signature"+            peek pg+        alloca $ \pc -> alloca $ \pg -> do+            poke pg g+            ret <- ecdsa_signature_serialize_compact x pc pg+            c <- peek pc+            return (c, ret)+    assertBool "successful serialization" (isSuccess ret)+    assertEqual "signatures match" cpt sig+  where+    cpt = CompactSig+        0xf502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37fb22+        0x6f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e3045+ ecdsa_signature_parse_der_test :: Assertion ecdsa_signature_parse_der_test = do     ret <- liftIO $ useAsCStringLen der $ \(d, dl) -> alloca $ \s -> do@@ -147,6 +170,17 @@         "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\         \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\         \45"++lax_der_parse_test :: Assertion+lax_der_parse_test = do+    ret <- liftIO $ useAsCStringLen der $ \(d, dl) -> alloca $ \s -> do+        x <- context_create verify+        lax_der_parse x s (castPtr d) (fromIntegral dl)+    assertBool "parsed signature successfully" $ isSuccess ret+  where+    der = fst $ B16.decode $+        "30450220f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37fb\+        \2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e3045"  ecdsa_signature_serialize_der_test :: Assertion ecdsa_signature_serialize_der_test = do
haskell/test/Crypto/Secp256k1/Tests.hs view
@@ -13,10 +13,13 @@     [ testGroup "Signing"         [ testProperty "Signing messages" signMsgTest         , testProperty "Bad signatures" badSignatureTest+        , testProperty "Normalize signatures" normalizeSigTest         ]     , testGroup "Serialization"         [ testProperty "Serialize public key" serializePubKeyTest-        , testProperty "Serialize signature" serializeSigTest+        , testProperty "Serialize DER signature" serializeSigTest+        , testProperty "Serialize lax DER signature" serializeLaxSigTest+        , testProperty "Serialize compact signature" serializeCompactSigTest         , testProperty "Serialize secret key" serializeSecKeyTest         ]     , testGroup "Tweaks"@@ -34,11 +37,14 @@     fg = signMsg fk fm  badSignatureTest :: (Msg, SecKey, PubKey) -> Bool-badSignatureTest (fm, fk, fp) =-    not $ verifySig fp fg fm-  where+badSignatureTest (fm, fk, fp) = not $ verifySig fp fg fm where     fg = signMsg fk fm +normalizeSigTest :: (Msg, SecKey) -> Bool+normalizeSigTest (fm, fk) = norm == False && sig == fg where+    fg = signMsg fk fm+    (sig, norm) = normalizeSig fg+ serializePubKeyTest :: (PubKey, Bool) -> Bool serializePubKeyTest (fp, b) =     case importPubKey $ exportPubKey b fp of@@ -48,6 +54,22 @@ serializeSigTest :: (Msg, SecKey) -> Bool serializeSigTest (fm, fk) =     case importSig $ exportSig fg of+        Just fg' -> fg == fg'+        Nothing -> False+  where+    fg = signMsg fk fm++serializeLaxSigTest :: (Msg, SecKey) -> Bool+serializeLaxSigTest (fm, fk) =+    case laxImportSig $ exportSig fg of+        Just fg' -> fg == fg'+        Nothing -> False+  where+    fg = signMsg fk fm++serializeCompactSigTest :: (Msg, SecKey) -> Bool+serializeCompactSigTest (fm, fk) =+    case importCompactSig $ exportCompactSig fg of         Just fg' -> fg == fg'         Nothing -> False   where
secp256k1.cabal view
@@ -1,5 +1,5 @@ name:                secp256k1-version:             0.1.11+version:             0.2.0 synopsis:            secp256k1 bindings for Haskell description:         Please see README.md homepage:            http://github.com/haskoin/secp256k1#readme@@ -11,38 +11,54 @@ category:            Crypto build-type:          Custom extra-source-files:-    configure.ac-    autogen.sh-    libsecp256k1.pc.in     Makefile.am     README.md     TODO+    autogen.sh+    configure.ac+    libsecp256k1.pc.in     build-aux/m4/ax_prog_cc_for_build.m4     build-aux/m4/bitcoin_secp.m4+    contrib/lax_der_parsing.h+    include/secp256k1.h+    include/secp256k1_ecdh.h+    include/secp256k1_recovery.h+    include/secp256k1_schnorr.h     src/field_impl.h     src/field.h+    src/bench_sign.c     src/scalar_impl.h     src/ecmult_gen.h     src/scalar_4x64_impl.h     src/field_5x52_int128_impl.h     src/eckey_impl.h+    src/java/org_bitcoin_NativeSecp256k1.c+    src/java/org/bitcoin/NativeSecp256k1.java+    src/java/org_bitcoin_NativeSecp256k1.h+    src/tests.c     src/testrand_impl.h     src/testrand.h     src/scalar_8x32.h     src/eckey.h     src/hash.h     src/field_5x52_impl.h+    src/bench_internal.c     src/ecmult_const_impl.h+    src/bench_recover.c     src/field_5x52_asm_impl.h     src/scalar_4x64.h     src/num_gmp.h+    src/libsecp256k1-config.h.in     src/modules/schnorr/schnorr.h     src/modules/schnorr/tests_impl.h+    src/modules/schnorr/Makefile.am.include     src/modules/schnorr/main_impl.h     src/modules/schnorr/schnorr_impl.h     src/modules/recovery/tests_impl.h+    src/modules/recovery/Makefile.am.include     src/modules/recovery/main_impl.h     src/modules/ecdh/tests_impl.h+    src/modules/ecdh/Makefile.am.include     src/modules/ecdh/main_impl.h     src/bench.h     src/ecdsa_impl.h@@ -57,17 +73,20 @@     src/ecdsa.h     src/group.h     src/num.h+    src/stamp-h1+    src/bench_verify.c     src/util.h     src/num_gmp_impl.h     src/ecmult_const.h+    src/bench_ecdh.c     src/basic-config.h     src/scalar.h+    src/gen_context.c     src/scalar_8x32_impl.h     src/ecmult.h-    include/secp256k1_recovery.h-    include/secp256k1_schnorr.h-    include/secp256k1.h-    include/secp256k1_ecdh.h+    src/bench_schnorr_verify.c+    haskell/include/lax_der.h+    stack.yaml cabal-version:       >=1.10  library@@ -75,17 +94,19 @@     exposed-modules:     Crypto.Secp256k1                        , Crypto.Secp256k1.Internal     build-depends:       base >= 4.8 && < 5-                       , QuickCheck+                       , base16-bytestring+                       , binary                        , bytestring-                       , mtl                        , entropy+                       , largeword+                       , mtl+                       , QuickCheck                        , string-conversions-                       , base16-bytestring     default-language:    Haskell2010     ghc-options:         -Wall     cc-options:          -DHAVE_CONFIG_H-    c-sources:           src/secp256k1.c-    include-dirs:        .+    c-sources:           src/secp256k1.c, haskell/cbits/lax_der.c+    include-dirs:        ., include, haskell/include  test-suite secp256k1-test     type:                exitcode-stdio-1.0@@ -94,17 +115,17 @@     other-modules:       Crypto.Secp256k1.Tests                        , Crypto.Secp256k1.Internal.Tests     build-depends:       base-                       , secp256k1+                       , base16-bytestring+                       , bytestring+                       , cryptohash+                       , entropy                        , HUnit+                       , mtl                        , QuickCheck+                       , secp256k1                        , test-framework                        , test-framework-hunit                        , test-framework-quickcheck2-                       , base16-bytestring-                       , cryptohash-                       , bytestring-                       , mtl-                       , entropy     ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N     default-language:    Haskell2010 
+ src/bench_ecdh.c view
@@ -0,0 +1,53 @@+/**********************************************************************+ * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra                  *+ * Distributed under the MIT software license, see the accompanying   *+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*+ **********************************************************************/++#include <string.h>++#include "include/secp256k1.h"+#include "include/secp256k1_ecdh.h"+#include "util.h"+#include "bench.h"++typedef struct {+    secp256k1_context *ctx;+    secp256k1_pubkey point;+    unsigned char scalar[32];+} bench_ecdh_t;++static void bench_ecdh_setup(void* arg) {+    int i;+    bench_ecdh_t *data = (bench_ecdh_t*)arg;+    const unsigned char point[] = {+        0x03,+        0x54, 0x94, 0xc1, 0x5d, 0x32, 0x09, 0x97, 0x06,+        0xc2, 0x39, 0x5f, 0x94, 0x34, 0x87, 0x45, 0xfd,+        0x75, 0x7c, 0xe3, 0x0e, 0x4e, 0x8c, 0x90, 0xfb,+        0xa2, 0xba, 0xd1, 0x84, 0xf8, 0x83, 0xc6, 0x9f+    };++    data->ctx = secp256k1_context_create(0);+    for (i = 0; i < 32; i++) {+        data->scalar[i] = i + 1;+    }+    CHECK(secp256k1_ec_pubkey_parse(data->ctx, &data->point, point, sizeof(point)) == 1);+}++static void bench_ecdh(void* arg) {+    int i;+    unsigned char res[32];+    bench_ecdh_t *data = (bench_ecdh_t*)arg;++    for (i = 0; i < 20000; i++) {+        CHECK(secp256k1_ecdh(data->ctx, res, &data->point, data->scalar) == 1);+    }+}++int main(void) {+    bench_ecdh_t data;++    run_benchmark("ecdh", bench_ecdh, bench_ecdh_setup, NULL, &data, 10, 20000);+    return 0;+}
+ src/bench_internal.c view
@@ -0,0 +1,354 @@+/**********************************************************************+ * Copyright (c) 2014-2015 Pieter Wuille                              *+ * Distributed under the MIT software license, see the accompanying   *+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*+ **********************************************************************/+#include <stdio.h>++#include "include/secp256k1.h"++#include "util.h"+#include "hash_impl.h"+#include "num_impl.h"+#include "field_impl.h"+#include "group_impl.h"+#include "scalar_impl.h"+#include "ecmult_const_impl.h"+#include "ecmult_impl.h"+#include "bench.h"+#include "secp256k1.c"++typedef struct {+    secp256k1_scalar scalar_x, scalar_y;+    secp256k1_fe fe_x, fe_y;+    secp256k1_ge ge_x, ge_y;+    secp256k1_gej gej_x, gej_y;+    unsigned char data[64];+    int wnaf[256];+} bench_inv_t;++void bench_setup(void* arg) {+    bench_inv_t *data = (bench_inv_t*)arg;++    static const unsigned char init_x[32] = {+        0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13,+        0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35,+        0x3b, 0x3d, 0x43, 0x47, 0x49, 0x4f, 0x53, 0x59,+        0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71, 0x7f, 0x83+    };++    static const unsigned char init_y[32] = {+        0x82, 0x83, 0x85, 0x87, 0x8b, 0x8d, 0x81, 0x83,+        0x97, 0xad, 0xaf, 0xb5, 0xb9, 0xbb, 0xbf, 0xc5,+        0xdb, 0xdd, 0xe3, 0xe7, 0xe9, 0xef, 0xf3, 0xf9,+        0x11, 0x15, 0x17, 0x1b, 0x1d, 0xb1, 0xbf, 0xd3+    };++    secp256k1_scalar_set_b32(&data->scalar_x, init_x, NULL);+    secp256k1_scalar_set_b32(&data->scalar_y, init_y, NULL);+    secp256k1_fe_set_b32(&data->fe_x, init_x);+    secp256k1_fe_set_b32(&data->fe_y, init_y);+    CHECK(secp256k1_ge_set_xo_var(&data->ge_x, &data->fe_x, 0));+    CHECK(secp256k1_ge_set_xo_var(&data->ge_y, &data->fe_y, 1));+    secp256k1_gej_set_ge(&data->gej_x, &data->ge_x);+    secp256k1_gej_set_ge(&data->gej_y, &data->ge_y);+    memcpy(data->data, init_x, 32);+    memcpy(data->data + 32, init_y, 32);+}++void bench_scalar_add(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 2000000; i++) {+        secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);+    }+}++void bench_scalar_negate(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 2000000; i++) {+        secp256k1_scalar_negate(&data->scalar_x, &data->scalar_x);+    }+}++void bench_scalar_sqr(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 200000; i++) {+        secp256k1_scalar_sqr(&data->scalar_x, &data->scalar_x);+    }+}++void bench_scalar_mul(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 200000; i++) {+        secp256k1_scalar_mul(&data->scalar_x, &data->scalar_x, &data->scalar_y);+    }+}++#ifdef USE_ENDOMORPHISM+void bench_scalar_split(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 20000; i++) {+        secp256k1_scalar l, r;+        secp256k1_scalar_split_lambda(&l, &r, &data->scalar_x);+        secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);+    }+}+#endif++void bench_scalar_inverse(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 2000; i++) {+        secp256k1_scalar_inverse(&data->scalar_x, &data->scalar_x);+        secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);+    }+}++void bench_scalar_inverse_var(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 2000; i++) {+        secp256k1_scalar_inverse_var(&data->scalar_x, &data->scalar_x);+        secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);+    }+}++void bench_field_normalize(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 2000000; i++) {+        secp256k1_fe_normalize(&data->fe_x);+    }+}++void bench_field_normalize_weak(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 2000000; i++) {+        secp256k1_fe_normalize_weak(&data->fe_x);+    }+}++void bench_field_mul(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 200000; i++) {+        secp256k1_fe_mul(&data->fe_x, &data->fe_x, &data->fe_y);+    }+}++void bench_field_sqr(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 200000; i++) {+        secp256k1_fe_sqr(&data->fe_x, &data->fe_x);+    }+}++void bench_field_inverse(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 20000; i++) {+        secp256k1_fe_inv(&data->fe_x, &data->fe_x);+        secp256k1_fe_add(&data->fe_x, &data->fe_y);+    }+}++void bench_field_inverse_var(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 20000; i++) {+        secp256k1_fe_inv_var(&data->fe_x, &data->fe_x);+        secp256k1_fe_add(&data->fe_x, &data->fe_y);+    }+}++void bench_field_sqrt_var(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 20000; i++) {+        secp256k1_fe_sqrt_var(&data->fe_x, &data->fe_x);+        secp256k1_fe_add(&data->fe_x, &data->fe_y);+    }+}++void bench_group_double_var(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 200000; i++) {+        secp256k1_gej_double_var(&data->gej_x, &data->gej_x, NULL);+    }+}++void bench_group_add_var(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 200000; i++) {+        secp256k1_gej_add_var(&data->gej_x, &data->gej_x, &data->gej_y, NULL);+    }+}++void bench_group_add_affine(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 200000; i++) {+        secp256k1_gej_add_ge(&data->gej_x, &data->gej_x, &data->ge_y);+    }+}++void bench_group_add_affine_var(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 200000; i++) {+        secp256k1_gej_add_ge_var(&data->gej_x, &data->gej_x, &data->ge_y, NULL);+    }+}++void bench_ecmult_wnaf(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 20000; i++) {+        secp256k1_ecmult_wnaf(data->wnaf, 256, &data->scalar_x, WINDOW_A);+        secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);+    }+}++void bench_wnaf_const(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;++    for (i = 0; i < 20000; i++) {+        secp256k1_wnaf_const(data->wnaf, data->scalar_x, WINDOW_A);+        secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);+    }+}+++void bench_sha256(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;+    secp256k1_sha256_t sha;++    for (i = 0; i < 20000; i++) {+        secp256k1_sha256_initialize(&sha);+        secp256k1_sha256_write(&sha, data->data, 32);+        secp256k1_sha256_finalize(&sha, data->data);+    }+}++void bench_hmac_sha256(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;+    secp256k1_hmac_sha256_t hmac;++    for (i = 0; i < 20000; i++) {+        secp256k1_hmac_sha256_initialize(&hmac, data->data, 32);+        secp256k1_hmac_sha256_write(&hmac, data->data, 32);+        secp256k1_hmac_sha256_finalize(&hmac, data->data);+    }+}++void bench_rfc6979_hmac_sha256(void* arg) {+    int i;+    bench_inv_t *data = (bench_inv_t*)arg;+    secp256k1_rfc6979_hmac_sha256_t rng;++    for (i = 0; i < 20000; i++) {+        secp256k1_rfc6979_hmac_sha256_initialize(&rng, data->data, 64);+        secp256k1_rfc6979_hmac_sha256_generate(&rng, data->data, 32);+    }+}++void bench_context_verify(void* arg) {+    int i;+    (void)arg;+    for (i = 0; i < 20; i++) {+        secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_VERIFY));+    }+}++void bench_context_sign(void* arg) {+    int i;+    (void)arg;+    for (i = 0; i < 200; i++) {+        secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_SIGN));+    }+}+++int have_flag(int argc, char** argv, char *flag) {+    char** argm = argv + argc;+    argv++;+    if (argv == argm) {+        return 1;+    }+    while (argv != NULL && argv != argm) {+        if (strcmp(*argv, flag) == 0) {+            return 1;+        }+        argv++;+    }+    return 0;+}++int main(int argc, char **argv) {+    bench_inv_t data;+    if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "add")) run_benchmark("scalar_add", bench_scalar_add, bench_setup, NULL, &data, 10, 2000000);+    if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, 10, 2000000);+    if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "sqr")) run_benchmark("scalar_sqr", bench_scalar_sqr, bench_setup, NULL, &data, 10, 200000);+    if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "mul")) run_benchmark("scalar_mul", bench_scalar_mul, bench_setup, NULL, &data, 10, 200000);+#ifdef USE_ENDOMORPHISM+    if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "split")) run_benchmark("scalar_split", bench_scalar_split, bench_setup, NULL, &data, 10, 20000);+#endif+    if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse", bench_scalar_inverse, bench_setup, NULL, &data, 10, 2000);+    if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse_var", bench_scalar_inverse_var, bench_setup, NULL, &data, 10, 2000);++    if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize", bench_field_normalize, bench_setup, NULL, &data, 10, 2000000);+    if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize_weak", bench_field_normalize_weak, bench_setup, NULL, &data, 10, 2000000);+    if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqr")) run_benchmark("field_sqr", bench_field_sqr, bench_setup, NULL, &data, 10, 200000);+    if (have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, 200000);+    if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, 20000);+    if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, 10, 20000);+    if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt_var", bench_field_sqrt_var, bench_setup, NULL, &data, 10, 20000);++    if (have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, 10, 200000);+    if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, 200000);+    if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, 200000);+    if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, 200000);++    if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("wnaf_const", bench_wnaf_const, bench_setup, NULL, &data, 10, 20000);+    if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000);++    if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, 20000);+    if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, 10, 20000);+    if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "rng6979")) run_benchmark("hash_rfc6979_hmac_sha256", bench_rfc6979_hmac_sha256, bench_setup, NULL, &data, 10, 20000);++    if (have_flag(argc, argv, "context") || have_flag(argc, argv, "verify")) run_benchmark("context_verify", bench_context_verify, bench_setup, NULL, &data, 10, 20);+    if (have_flag(argc, argv, "context") || have_flag(argc, argv, "sign")) run_benchmark("context_sign", bench_context_sign, bench_setup, NULL, &data, 10, 200);++    return 0;+}
+ src/bench_recover.c view
@@ -0,0 +1,60 @@+/**********************************************************************+ * Copyright (c) 2014-2015 Pieter Wuille                              *+ * Distributed under the MIT software license, see the accompanying   *+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*+ **********************************************************************/++#include "include/secp256k1.h"+#include "include/secp256k1_recovery.h"+#include "util.h"+#include "bench.h"++typedef struct {+    secp256k1_context *ctx;+    unsigned char msg[32];+    unsigned char sig[64];+} bench_recover_t;++void bench_recover(void* arg) {+    int i;+    bench_recover_t *data = (bench_recover_t*)arg;+    secp256k1_pubkey pubkey;+    unsigned char pubkeyc[33];++    for (i = 0; i < 20000; i++) {+        int j;+        size_t pubkeylen = 33;+        secp256k1_ecdsa_recoverable_signature sig;+        CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(data->ctx, &sig, data->sig, i % 2));+        CHECK(secp256k1_ecdsa_recover(data->ctx, &pubkey, &sig, data->msg));+        CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED));+        for (j = 0; j < 32; j++) {+            data->sig[j + 32] = data->msg[j];    /* Move former message to S. */+            data->msg[j] = data->sig[j];         /* Move former R to message. */+            data->sig[j] = pubkeyc[j + 1];       /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */+        }+    }+}++void bench_recover_setup(void* arg) {+    int i;+    bench_recover_t *data = (bench_recover_t*)arg;++    for (i = 0; i < 32; i++) {+        data->msg[i] = 1 + i;+    }+    for (i = 0; i < 64; i++) {+        data->sig[i] = 65 + i;+    }+}++int main(void) {+    bench_recover_t data;++    data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);++    run_benchmark("ecdsa_recover", bench_recover, bench_recover_setup, NULL, &data, 10, 20000);++    secp256k1_context_destroy(data.ctx);+    return 0;+}
+ src/bench_schnorr_verify.c view
@@ -0,0 +1,73 @@+/**********************************************************************+ * Copyright (c) 2014 Pieter Wuille                                   *+ * Distributed under the MIT software license, see the accompanying   *+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*+ **********************************************************************/++#include <stdio.h>+#include <string.h>++#include "include/secp256k1.h"+#include "include/secp256k1_schnorr.h"+#include "util.h"+#include "bench.h"++typedef struct {+    unsigned char key[32];+    unsigned char sig[64];+    unsigned char pubkey[33];+    size_t pubkeylen;+} benchmark_schnorr_sig_t;++typedef struct {+    secp256k1_context *ctx;+    unsigned char msg[32];+    benchmark_schnorr_sig_t sigs[64];+    int numsigs;+} benchmark_schnorr_verify_t;++static void benchmark_schnorr_init(void* arg) {+    int i, k;+    benchmark_schnorr_verify_t* data = (benchmark_schnorr_verify_t*)arg;++    for (i = 0; i < 32; i++) {+        data->msg[i] = 1 + i;+    }+    for (k = 0; k < data->numsigs; k++) {+        secp256k1_pubkey pubkey;+        for (i = 0; i < 32; i++) {+            data->sigs[k].key[i] = 33 + i + k;+        }+        secp256k1_schnorr_sign(data->ctx, data->sigs[k].sig, data->msg, data->sigs[k].key, NULL, NULL);+        data->sigs[k].pubkeylen = 33;+        CHECK(secp256k1_ec_pubkey_create(data->ctx, &pubkey, data->sigs[k].key));+        CHECK(secp256k1_ec_pubkey_serialize(data->ctx, data->sigs[k].pubkey, &data->sigs[k].pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED));+    }+}++static void benchmark_schnorr_verify(void* arg) {+    int i;+    benchmark_schnorr_verify_t* data = (benchmark_schnorr_verify_t*)arg;++    for (i = 0; i < 20000 / data->numsigs; i++) {+        secp256k1_pubkey pubkey;+        data->sigs[0].sig[(i >> 8) % 64] ^= (i & 0xFF);+        CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->sigs[0].pubkey, data->sigs[0].pubkeylen));+        CHECK(secp256k1_schnorr_verify(data->ctx, data->sigs[0].sig, data->msg, &pubkey) == ((i & 0xFF) == 0));+        data->sigs[0].sig[(i >> 8) % 64] ^= (i & 0xFF);+    }+}++++int main(void) {+    benchmark_schnorr_verify_t data;++    data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);++    data.numsigs = 1;+    run_benchmark("schnorr_verify", benchmark_schnorr_verify, benchmark_schnorr_init, NULL, &data, 10, 20000);++    secp256k1_context_destroy(data.ctx);+    return 0;+}
+ src/bench_sign.c view
@@ -0,0 +1,56 @@+/**********************************************************************+ * Copyright (c) 2014 Pieter Wuille                                   *+ * Distributed under the MIT software license, see the accompanying   *+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*+ **********************************************************************/++#include "include/secp256k1.h"+#include "util.h"+#include "bench.h"++typedef struct {+    secp256k1_context* ctx;+    unsigned char msg[32];+    unsigned char key[32];+} bench_sign_t;++static void bench_sign_setup(void* arg) {+    int i;+    bench_sign_t *data = (bench_sign_t*)arg;++    for (i = 0; i < 32; i++) {+        data->msg[i] = i + 1;+    }+    for (i = 0; i < 32; i++) {+        data->key[i] = i + 65;+    }+}++static void bench_sign(void* arg) {+    int i;+    bench_sign_t *data = (bench_sign_t*)arg;++    unsigned char sig[74];+    for (i = 0; i < 20000; i++) {+        size_t siglen = 74;+        int j;+        secp256k1_ecdsa_signature signature;+        CHECK(secp256k1_ecdsa_sign(data->ctx, &signature, data->msg, data->key, NULL, NULL));+        CHECK(secp256k1_ecdsa_signature_serialize_der(data->ctx, sig, &siglen, &signature));+        for (j = 0; j < 32; j++) {+            data->msg[j] = sig[j];+            data->key[j] = sig[j + 32];+        }+    }+}++int main(void) {+    bench_sign_t data;++    data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);++    run_benchmark("ecdsa_sign", bench_sign, bench_sign_setup, NULL, &data, 10, 20000);++    secp256k1_context_destroy(data.ctx);+    return 0;+}
+ src/bench_verify.c view
@@ -0,0 +1,67 @@+/**********************************************************************+ * Copyright (c) 2014 Pieter Wuille                                   *+ * Distributed under the MIT software license, see the accompanying   *+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*+ **********************************************************************/++#include <stdio.h>+#include <string.h>++#include "include/secp256k1.h"+#include "util.h"+#include "bench.h"++typedef struct {+    secp256k1_context *ctx;+    unsigned char msg[32];+    unsigned char key[32];+    unsigned char sig[72];+    size_t siglen;+    unsigned char pubkey[33];+    size_t pubkeylen;+} benchmark_verify_t;++static void benchmark_verify(void* arg) {+    int i;+    benchmark_verify_t* data = (benchmark_verify_t*)arg;++    for (i = 0; i < 20000; i++) {+        secp256k1_pubkey pubkey;+        secp256k1_ecdsa_signature sig;+        data->sig[data->siglen - 1] ^= (i & 0xFF);+        data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);+        data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);+        CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1);+        CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1);+        CHECK(secp256k1_ecdsa_verify(data->ctx, &sig, data->msg, &pubkey) == (i == 0));+        data->sig[data->siglen - 1] ^= (i & 0xFF);+        data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);+        data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);+    }+}++int main(void) {+    int i;+    secp256k1_pubkey pubkey;+    secp256k1_ecdsa_signature sig;+    benchmark_verify_t data;++    data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);++    for (i = 0; i < 32; i++) {+        data.msg[i] = 1 + i;+    }+    for (i = 0; i < 32; i++) {+        data.key[i] = 33 + i;+    }+    data.siglen = 72;+    CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL));+    CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig));+    CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key));+    CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);++    run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000);++    secp256k1_context_destroy(data.ctx);+    return 0;+}
+ src/gen_context.c view
@@ -0,0 +1,74 @@+/**********************************************************************+ * Copyright (c) 2013, 2014, 2015 Thomas Daede, Cory Fields           *+ * Distributed under the MIT software license, see the accompanying   *+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*+ **********************************************************************/++#define USE_BASIC_CONFIG 1++#include "basic-config.h"+#include "include/secp256k1.h"+#include "field_impl.h"+#include "scalar_impl.h"+#include "group_impl.h"+#include "ecmult_gen_impl.h"++static void default_error_callback_fn(const char* str, void* data) {+    (void)data;+    fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str);+    abort();+}++static const secp256k1_callback default_error_callback = {+    default_error_callback_fn,+    NULL+};++int main(int argc, char **argv) {+    secp256k1_ecmult_gen_context ctx;+    int inner;+    int outer;+    FILE* fp;++    (void)argc;+    (void)argv;++    fp = fopen("src/ecmult_static_context.h","w");+    if (fp == NULL) {+        fprintf(stderr, "Could not open src/ecmult_static_context.h for writing!\n");+        return -1;+    }+    +    fprintf(fp, "#ifndef _SECP256K1_ECMULT_STATIC_CONTEXT_\n");+    fprintf(fp, "#define _SECP256K1_ECMULT_STATIC_CONTEXT_\n");+    fprintf(fp, "#include \"group.h\"\n");+    fprintf(fp, "#define SC SECP256K1_GE_STORAGE_CONST\n");+    fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_static_context[64][16] = {\n");++    secp256k1_ecmult_gen_context_init(&ctx);+    secp256k1_ecmult_gen_context_build(&ctx, &default_error_callback);+    for(outer = 0; outer != 64; outer++) {+        fprintf(fp,"{\n");+        for(inner = 0; inner != 16; inner++) {+            fprintf(fp,"    SC(%uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu)", SECP256K1_GE_STORAGE_CONST_GET((*ctx.prec)[outer][inner]));+            if (inner != 15) {+                fprintf(fp,",\n");+            } else {+                fprintf(fp,"\n");+            }+        }+        if (outer != 63) {+            fprintf(fp,"},\n");+        } else {+            fprintf(fp,"}\n");+        }+    }+    fprintf(fp,"};\n");+    secp256k1_ecmult_gen_context_clear(&ctx);+    +    fprintf(fp, "#undef SC\n");+    fprintf(fp, "#endif\n");+    fclose(fp);+    +    return 0;+}
+ src/java/org/bitcoin/NativeSecp256k1.java view
@@ -0,0 +1,60 @@+package org.bitcoin;++import java.nio.ByteBuffer;+import java.nio.ByteOrder;++import com.google.common.base.Preconditions;+++/**+ * This class holds native methods to handle ECDSA verification.+ * You can find an example library that can be used for this at+ * https://github.com/sipa/secp256k1+ */+public class NativeSecp256k1 {+    public static final boolean enabled;+    static {+        boolean isEnabled = true;+        try {+            System.loadLibrary("javasecp256k1");+        } catch (UnsatisfiedLinkError e) {+            isEnabled = false;+        }+        enabled = isEnabled;+    }+    +    private static ThreadLocal<ByteBuffer> nativeECDSABuffer = new ThreadLocal<ByteBuffer>();+    /**+     * Verifies the given secp256k1 signature in native code.+     * Calling when enabled == false is undefined (probably library not loaded)+     * +     * @param data The data which was signed, must be exactly 32 bytes+     * @param signature The signature+     * @param pub The public key which did the signing+     */+    public static boolean verify(byte[] data, byte[] signature, byte[] pub) {+        Preconditions.checkArgument(data.length == 32 && signature.length <= 520 && pub.length <= 520);++        ByteBuffer byteBuff = nativeECDSABuffer.get();+        if (byteBuff == null) {+            byteBuff = ByteBuffer.allocateDirect(32 + 8 + 520 + 520);+            byteBuff.order(ByteOrder.nativeOrder());+            nativeECDSABuffer.set(byteBuff);+        }+        byteBuff.rewind();+        byteBuff.put(data);+        byteBuff.putInt(signature.length);+        byteBuff.putInt(pub.length);+        byteBuff.put(signature);+        byteBuff.put(pub);+        return secp256k1_ecdsa_verify(byteBuff) == 1;+    }++    /**+     * @param byteBuff signature format is byte[32] data,+     *        native-endian int signatureLength, native-endian int pubkeyLength,+     *        byte[signatureLength] signature, byte[pubkeyLength] pub+     * @returns 1 for valid signature, anything else for invalid+     */+    private static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff);+}
+ src/java/org_bitcoin_NativeSecp256k1.c view
@@ -0,0 +1,23 @@+#include "org_bitcoin_NativeSecp256k1.h"+#include "include/secp256k1.h"++JNIEXPORT jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify+  (JNIEnv* env, jclass classObject, jobject byteBufferObject)+{+	unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);+	int sigLen = *((int*)(data + 32));+	int pubLen = *((int*)(data + 32 + 4));++	return secp256k1_ecdsa_verify(data, 32, data+32+8, sigLen, data+32+8+sigLen, pubLen);+}++static void __javasecp256k1_attach(void) __attribute__((constructor));+static void __javasecp256k1_detach(void) __attribute__((destructor));++static void __javasecp256k1_attach(void) {+	secp256k1_start(SECP256K1_START_VERIFY);+}++static void __javasecp256k1_detach(void) {+	secp256k1_stop();+}
+ src/java/org_bitcoin_NativeSecp256k1.h view
@@ -0,0 +1,21 @@+/* DO NOT EDIT THIS FILE - it is machine generated */+#include <jni.h>+/* Header for class org_bitcoin_NativeSecp256k1 */++#ifndef _Included_org_bitcoin_NativeSecp256k1+#define _Included_org_bitcoin_NativeSecp256k1+#ifdef __cplusplus+extern "C" {+#endif+/*+ * Class:     org_bitcoin_NativeSecp256k1+ * Method:    secp256k1_ecdsa_verify+ * Signature: (Ljava/nio/ByteBuffer;)I+ */+JNIEXPORT jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify+  (JNIEnv *, jclass, jobject);++#ifdef __cplusplus+}+#endif+#endif
+ src/libsecp256k1-config.h.in view
@@ -0,0 +1,146 @@+/* src/libsecp256k1-config.h.in.  Generated from configure.ac by autoheader.  */++#ifndef LIBSECP256K1_CONFIG_H++#define LIBSECP256K1_CONFIG_H++/* Define if building universal (internal helper macro) */+#undef AC_APPLE_UNIVERSAL_BUILD++/* Define this symbol to enable the ECDH module */+#undef ENABLE_MODULE_ECDH++/* Define this symbol to enable the ECDSA pubkey recovery module */+#undef ENABLE_MODULE_RECOVERY++/* Define this symbol to enable the Schnorr signature module */+#undef ENABLE_MODULE_SCHNORR++/* Define this symbol if OpenSSL EC functions are available */+#undef ENABLE_OPENSSL_TESTS++/* Define this symbol if __builtin_expect is available */+#undef HAVE_BUILTIN_EXPECT++/* Define to 1 if you have the <dlfcn.h> header file. */+#undef HAVE_DLFCN_H++/* Define to 1 if you have the <inttypes.h> header file. */+#undef HAVE_INTTYPES_H++/* Define this symbol if libcrypto is installed */+#undef HAVE_LIBCRYPTO++/* Define this symbol if libgmp is installed */+#undef HAVE_LIBGMP++/* Define to 1 if you have the <memory.h> header file. */+#undef HAVE_MEMORY_H++/* Define to 1 if you have the <stdint.h> header file. */+#undef HAVE_STDINT_H++/* Define to 1 if you have the <stdlib.h> header file. */+#undef HAVE_STDLIB_H++/* Define to 1 if you have the <strings.h> header file. */+#undef HAVE_STRINGS_H++/* Define to 1 if you have the <string.h> header file. */+#undef HAVE_STRING_H++/* Define to 1 if you have the <sys/stat.h> header file. */+#undef HAVE_SYS_STAT_H++/* Define to 1 if you have the <sys/types.h> header file. */+#undef HAVE_SYS_TYPES_H++/* Define to 1 if you have the <unistd.h> header file. */+#undef HAVE_UNISTD_H++/* Define to 1 if the system has the type `__int128'. */+#undef HAVE___INT128++/* Define to the sub-directory in which libtool stores uninstalled libraries.+   */+#undef LT_OBJDIR++/* Name of package */+#undef PACKAGE++/* Define to the address where bug reports for this package should be sent. */+#undef PACKAGE_BUGREPORT++/* Define to the full name of this package. */+#undef PACKAGE_NAME++/* Define to the full name and version of this package. */+#undef PACKAGE_STRING++/* Define to the one symbol short name of this package. */+#undef PACKAGE_TARNAME++/* Define to the home page for this package. */+#undef PACKAGE_URL++/* Define to the version of this package. */+#undef PACKAGE_VERSION++/* Define to 1 if you have the ANSI C header files. */+#undef STDC_HEADERS++/* Define this symbol to enable x86_64 assembly optimizations */+#undef USE_ASM_X86_64++/* Define this symbol to use a statically generated ecmult table */+#undef USE_ECMULT_STATIC_PRECOMPUTATION++/* Define this symbol to use endomorphism optimization */+#undef USE_ENDOMORPHISM++/* Define this symbol to use the FIELD_10X26 implementation */+#undef USE_FIELD_10X26++/* Define this symbol to use the FIELD_5X52 implementation */+#undef USE_FIELD_5X52++/* Define this symbol to use the native field inverse implementation */+#undef USE_FIELD_INV_BUILTIN++/* Define this symbol to use the num-based field inverse implementation */+#undef USE_FIELD_INV_NUM++/* Define this symbol to use the gmp implementation for num */+#undef USE_NUM_GMP++/* Define this symbol to use no num implementation */+#undef USE_NUM_NONE++/* Define this symbol to use the 4x64 scalar implementation */+#undef USE_SCALAR_4X64++/* Define this symbol to use the 8x32 scalar implementation */+#undef USE_SCALAR_8X32++/* Define this symbol to use the native scalar inverse implementation */+#undef USE_SCALAR_INV_BUILTIN++/* Define this symbol to use the num-based scalar inverse implementation */+#undef USE_SCALAR_INV_NUM++/* Version number of package */+#undef VERSION++/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most+   significant byte first (like Motorola and SPARC, unlike Intel). */+#if defined AC_APPLE_UNIVERSAL_BUILD+# if defined __BIG_ENDIAN__+#  define WORDS_BIGENDIAN 1+# endif+#else+# ifndef WORDS_BIGENDIAN+#  undef WORDS_BIGENDIAN+# endif+#endif++#endif /*LIBSECP256K1_CONFIG_H*/
+ src/modules/ecdh/Makefile.am.include view
@@ -0,0 +1,8 @@+include_HEADERS += include/secp256k1_ecdh.h+noinst_HEADERS += src/modules/ecdh/main_impl.h+noinst_HEADERS += src/modules/ecdh/tests_impl.h+if USE_BENCHMARK+noinst_PROGRAMS += bench_ecdh+bench_ecdh_SOURCES = src/bench_ecdh.c+bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS)+endif
+ src/modules/recovery/Makefile.am.include view
@@ -0,0 +1,8 @@+include_HEADERS += include/secp256k1_recovery.h+noinst_HEADERS += src/modules/recovery/main_impl.h+noinst_HEADERS += src/modules/recovery/tests_impl.h+if USE_BENCHMARK+noinst_PROGRAMS += bench_recover+bench_recover_SOURCES = src/bench_recover.c+bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS)+endif
+ src/modules/schnorr/Makefile.am.include view
@@ -0,0 +1,10 @@+include_HEADERS += include/secp256k1_schnorr.h+noinst_HEADERS += src/modules/schnorr/main_impl.h+noinst_HEADERS += src/modules/schnorr/schnorr.h+noinst_HEADERS += src/modules/schnorr/schnorr_impl.h+noinst_HEADERS += src/modules/schnorr/tests_impl.h+if USE_BENCHMARK+noinst_PROGRAMS += bench_schnorr_verify+bench_schnorr_verify_SOURCES = src/bench_schnorr_verify.c+bench_schnorr_verify_LDADD = libsecp256k1.la $(SECP_LIBS)+endif
+ src/stamp-h1 view
@@ -0,0 +1,1 @@+timestamp for src/libsecp256k1-config.h
+ src/tests.c view
@@ -0,0 +1,3176 @@+/**********************************************************************+ * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell      *+ * Distributed under the MIT software license, see the accompanying   *+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*+ **********************************************************************/++#if defined HAVE_CONFIG_H+#include "libsecp256k1-config.h"+#endif++#include <stdio.h>+#include <stdlib.h>++#include <time.h>++#include "secp256k1.c"+#include "include/secp256k1.h"+#include "testrand_impl.h"++#ifdef ENABLE_OPENSSL_TESTS+#include "openssl/bn.h"+#include "openssl/ec.h"+#include "openssl/ecdsa.h"+#include "openssl/obj_mac.h"+#endif++#include "contrib/lax_der_parsing.h"++#if !defined(VG_CHECK)+# if defined(VALGRIND)+#  include <valgrind/memcheck.h>+#  define VG_UNDEF(x,y) VALGRIND_MAKE_MEM_UNDEFINED((x),(y))+#  define VG_CHECK(x,y) VALGRIND_CHECK_MEM_IS_DEFINED((x),(y))+# else+#  define VG_UNDEF(x,y)+#  define VG_CHECK(x,y)+# endif+#endif++static int count = 64;+static secp256k1_context *ctx = NULL;++void random_field_element_test(secp256k1_fe *fe) {+    do {+        unsigned char b32[32];+        secp256k1_rand256_test(b32);+        if (secp256k1_fe_set_b32(fe, b32)) {+            break;+        }+    } while(1);+}++void random_field_element_magnitude(secp256k1_fe *fe) {+    secp256k1_fe zero;+    int n = secp256k1_rand_int(9);+    secp256k1_fe_normalize(fe);+    if (n == 0) {+        return;+    }+    secp256k1_fe_clear(&zero);+    secp256k1_fe_negate(&zero, &zero, 0);+    secp256k1_fe_mul_int(&zero, n - 1);+    secp256k1_fe_add(fe, &zero);+    VERIFY_CHECK(fe->magnitude == n);+}++void random_group_element_test(secp256k1_ge *ge) {+    secp256k1_fe fe;+    do {+        random_field_element_test(&fe);+        if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_rand_bits(1))) {+            secp256k1_fe_normalize(&ge->y);+            break;+        }+    } while(1);+}++void random_group_element_jacobian_test(secp256k1_gej *gej, const secp256k1_ge *ge) {+    secp256k1_fe z2, z3;+    do {+        random_field_element_test(&gej->z);+        if (!secp256k1_fe_is_zero(&gej->z)) {+            break;+        }+    } while(1);+    secp256k1_fe_sqr(&z2, &gej->z);+    secp256k1_fe_mul(&z3, &z2, &gej->z);+    secp256k1_fe_mul(&gej->x, &ge->x, &z2);+    secp256k1_fe_mul(&gej->y, &ge->y, &z3);+    gej->infinity = ge->infinity;+}++void random_scalar_order_test(secp256k1_scalar *num) {+    do {+        unsigned char b32[32];+        int overflow = 0;+        secp256k1_rand256_test(b32);+        secp256k1_scalar_set_b32(num, b32, &overflow);+        if (overflow || secp256k1_scalar_is_zero(num)) {+            continue;+        }+        break;+    } while(1);+}++void random_scalar_order(secp256k1_scalar *num) {+    do {+        unsigned char b32[32];+        int overflow = 0;+        secp256k1_rand256(b32);+        secp256k1_scalar_set_b32(num, b32, &overflow);+        if (overflow || secp256k1_scalar_is_zero(num)) {+            continue;+        }+        break;+    } while(1);+}++void run_context_tests(void) {+    secp256k1_context *none = secp256k1_context_create(0);+    secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);+    secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);+    secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);++    secp256k1_gej pubj;+    secp256k1_ge pub;+    secp256k1_scalar msg, key, nonce;+    secp256k1_scalar sigr, sigs;++    /*** clone and destroy all of them to make sure cloning was complete ***/+    {+        secp256k1_context *ctx_tmp;++        ctx_tmp = none; none = secp256k1_context_clone(none); secp256k1_context_destroy(ctx_tmp);+        ctx_tmp = sign; sign = secp256k1_context_clone(sign); secp256k1_context_destroy(ctx_tmp);+        ctx_tmp = vrfy; vrfy = secp256k1_context_clone(vrfy); secp256k1_context_destroy(ctx_tmp);+        ctx_tmp = both; both = secp256k1_context_clone(both); secp256k1_context_destroy(ctx_tmp);+    }++    /*** attempt to use them ***/+    random_scalar_order_test(&msg);+    random_scalar_order_test(&key);+    secp256k1_ecmult_gen(&both->ecmult_gen_ctx, &pubj, &key);+    secp256k1_ge_set_gej(&pub, &pubj);++    /* obtain a working nonce */+    do {+        random_scalar_order_test(&nonce);+    } while(!secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL));++    /* try signing */+    CHECK(secp256k1_ecdsa_sig_sign(&sign->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL));+    CHECK(secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL));++    /* try verifying */+    CHECK(secp256k1_ecdsa_sig_verify(&vrfy->ecmult_ctx, &sigr, &sigs, &pub, &msg));+    CHECK(secp256k1_ecdsa_sig_verify(&both->ecmult_ctx, &sigr, &sigs, &pub, &msg));++    /* cleanup */+    secp256k1_context_destroy(none);+    secp256k1_context_destroy(sign);+    secp256k1_context_destroy(vrfy);+    secp256k1_context_destroy(both);+}++/***** HASH TESTS *****/++void run_sha256_tests(void) {+    static const char *inputs[8] = {+        "", "abc", "message digest", "secure hash algorithm", "SHA256 is considered to be safe",+        "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",+        "For this sample, this 63-byte string will be used as input data",+        "This is exactly 64 bytes long, not counting the terminating byte"+    };+    static const unsigned char outputs[8][32] = {+        {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55},+        {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad},+        {0xf7, 0x84, 0x6f, 0x55, 0xcf, 0x23, 0xe1, 0x4e, 0xeb, 0xea, 0xb5, 0xb4, 0xe1, 0x55, 0x0c, 0xad, 0x5b, 0x50, 0x9e, 0x33, 0x48, 0xfb, 0xc4, 0xef, 0xa3, 0xa1, 0x41, 0x3d, 0x39, 0x3c, 0xb6, 0x50},+        {0xf3, 0x0c, 0xeb, 0x2b, 0xb2, 0x82, 0x9e, 0x79, 0xe4, 0xca, 0x97, 0x53, 0xd3, 0x5a, 0x8e, 0xcc, 0x00, 0x26, 0x2d, 0x16, 0x4c, 0xc0, 0x77, 0x08, 0x02, 0x95, 0x38, 0x1c, 0xbd, 0x64, 0x3f, 0x0d},+        {0x68, 0x19, 0xd9, 0x15, 0xc7, 0x3f, 0x4d, 0x1e, 0x77, 0xe4, 0xe1, 0xb5, 0x2d, 0x1f, 0xa0, 0xf9, 0xcf, 0x9b, 0xea, 0xea, 0xd3, 0x93, 0x9f, 0x15, 0x87, 0x4b, 0xd9, 0x88, 0xe2, 0xa2, 0x36, 0x30},+        {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1},+        {0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42},+        {0xab, 0x64, 0xef, 0xf7, 0xe8, 0x8e, 0x2e, 0x46, 0x16, 0x5e, 0x29, 0xf2, 0xbc, 0xe4, 0x18, 0x26, 0xbd, 0x4c, 0x7b, 0x35, 0x52, 0xf6, 0xb3, 0x82, 0xa9, 0xe7, 0xd3, 0xaf, 0x47, 0xc2, 0x45, 0xf8}+    };+    int i;+    for (i = 0; i < 8; i++) {+        unsigned char out[32];+        secp256k1_sha256_t hasher;+        secp256k1_sha256_initialize(&hasher);+        secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i]));+        secp256k1_sha256_finalize(&hasher, out);+        CHECK(memcmp(out, outputs[i], 32) == 0);+        if (strlen(inputs[i]) > 0) {+            int split = secp256k1_rand_int(strlen(inputs[i]));+            secp256k1_sha256_initialize(&hasher);+            secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split);+            secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split);+            secp256k1_sha256_finalize(&hasher, out);+            CHECK(memcmp(out, outputs[i], 32) == 0);+        }+    }+}++void run_hmac_sha256_tests(void) {+    static const char *keys[6] = {+        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",+        "\x4a\x65\x66\x65",+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",+        "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19",+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"+    };+    static const char *inputs[6] = {+        "\x48\x69\x20\x54\x68\x65\x72\x65",+        "\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f",+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",+        "\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74",+        "\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e"+    };+    static const unsigned char outputs[6][32] = {+        {0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7},+        {0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43},+        {0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7, 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22, 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe},+        {0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e, 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a, 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07, 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b},+        {0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54},+        {0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2}+    };+    int i;+    for (i = 0; i < 6; i++) {+        secp256k1_hmac_sha256_t hasher;+        unsigned char out[32];+        secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i]));+        secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i]));+        secp256k1_hmac_sha256_finalize(&hasher, out);+        CHECK(memcmp(out, outputs[i], 32) == 0);+        if (strlen(inputs[i]) > 0) {+            int split = secp256k1_rand_int(strlen(inputs[i]));+            secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i]));+            secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split);+            secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split);+            secp256k1_hmac_sha256_finalize(&hasher, out);+            CHECK(memcmp(out, outputs[i], 32) == 0);+        }+    }+}++void run_rfc6979_hmac_sha256_tests(void) {+    static const unsigned char key1[65] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x4b, 0xf5, 0x12, 0x2f, 0x34, 0x45, 0x54, 0xc5, 0x3b, 0xde, 0x2e, 0xbb, 0x8c, 0xd2, 0xb7, 0xe3, 0xd1, 0x60, 0x0a, 0xd6, 0x31, 0xc3, 0x85, 0xa5, 0xd7, 0xcc, 0xe2, 0x3c, 0x77, 0x85, 0x45, 0x9a, 0};+    static const unsigned char out1[3][32] = {+        {0x4f, 0xe2, 0x95, 0x25, 0xb2, 0x08, 0x68, 0x09, 0x15, 0x9a, 0xcd, 0xf0, 0x50, 0x6e, 0xfb, 0x86, 0xb0, 0xec, 0x93, 0x2c, 0x7b, 0xa4, 0x42, 0x56, 0xab, 0x32, 0x1e, 0x42, 0x1e, 0x67, 0xe9, 0xfb},+        {0x2b, 0xf0, 0xff, 0xf1, 0xd3, 0xc3, 0x78, 0xa2, 0x2d, 0xc5, 0xde, 0x1d, 0x85, 0x65, 0x22, 0x32, 0x5c, 0x65, 0xb5, 0x04, 0x49, 0x1a, 0x0c, 0xbd, 0x01, 0xcb, 0x8f, 0x3a, 0xa6, 0x7f, 0xfd, 0x4a},+        {0xf5, 0x28, 0xb4, 0x10, 0xcb, 0x54, 0x1f, 0x77, 0x00, 0x0d, 0x7a, 0xfb, 0x6c, 0x5b, 0x53, 0xc5, 0xc4, 0x71, 0xea, 0xb4, 0x3e, 0x46, 0x6d, 0x9a, 0xc5, 0x19, 0x0c, 0x39, 0xc8, 0x2f, 0xd8, 0x2e}+    };++    static const unsigned char key2[64] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55};+    static const unsigned char out2[3][32] = {+        {0x9c, 0x23, 0x6c, 0x16, 0x5b, 0x82, 0xae, 0x0c, 0xd5, 0x90, 0x65, 0x9e, 0x10, 0x0b, 0x6b, 0xab, 0x30, 0x36, 0xe7, 0xba, 0x8b, 0x06, 0x74, 0x9b, 0xaf, 0x69, 0x81, 0xe1, 0x6f, 0x1a, 0x2b, 0x95},+        {0xdf, 0x47, 0x10, 0x61, 0x62, 0x5b, 0xc0, 0xea, 0x14, 0xb6, 0x82, 0xfe, 0xee, 0x2c, 0x9c, 0x02, 0xf2, 0x35, 0xda, 0x04, 0x20, 0x4c, 0x1d, 0x62, 0xa1, 0x53, 0x6c, 0x6e, 0x17, 0xae, 0xd7, 0xa9},+        {0x75, 0x97, 0x88, 0x7c, 0xbd, 0x76, 0x32, 0x1f, 0x32, 0xe3, 0x04, 0x40, 0x67, 0x9a, 0x22, 0xcf, 0x7f, 0x8d, 0x9d, 0x2e, 0xac, 0x39, 0x0e, 0x58, 0x1f, 0xea, 0x09, 0x1c, 0xe2, 0x02, 0xba, 0x94}+    };++    secp256k1_rfc6979_hmac_sha256_t rng;+    unsigned char out[32];+    int i;++    secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 64);+    for (i = 0; i < 3; i++) {+        secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32);+        CHECK(memcmp(out, out1[i], 32) == 0);+    }+    secp256k1_rfc6979_hmac_sha256_finalize(&rng);++    secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 65);+    for (i = 0; i < 3; i++) {+        secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32);+        CHECK(memcmp(out, out1[i], 32) != 0);+    }+    secp256k1_rfc6979_hmac_sha256_finalize(&rng);++    secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 64);+    for (i = 0; i < 3; i++) {+        secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32);+        CHECK(memcmp(out, out2[i], 32) == 0);+    }+    secp256k1_rfc6979_hmac_sha256_finalize(&rng);+}++/***** RANDOM TESTS *****/++void test_rand_bits(int rand32, int bits) {+    /* (1-1/2^B)^rounds[B] < 1/10^9, so rounds is the number of iterations to+     * get a false negative chance below once in a billion */+    static const unsigned int rounds[7] = {1, 30, 73, 156, 322, 653, 1316};+    /* We try multiplying the results with various odd numbers, which shouldn't+     * influence the uniform distribution modulo a power of 2. */+    static const uint32_t mults[6] = {1, 3, 21, 289, 0x9999, 0x80402011};+    /* We only select up to 6 bits from the output to analyse */+    unsigned int usebits = bits > 6 ? 6 : bits;+    unsigned int maxshift = bits - usebits;+    /* For each of the maxshift+1 usebits-bit sequences inside a bits-bit+       number, track all observed outcomes, one per bit in a uint64_t. */+    uint64_t x[6][27] = {{0}};+    unsigned int i, shift, m;+    /* Multiply the output of all rand calls with the odd number m, which+       should not change the uniformity of its distribution. */+    for (i = 0; i < rounds[usebits]; i++) {+        uint32_t r = (rand32 ? secp256k1_rand32() : secp256k1_rand_bits(bits));+        CHECK((((uint64_t)r) >> bits) == 0);+        for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) {+            uint32_t rm = r * mults[m];+            for (shift = 0; shift <= maxshift; shift++) {+                x[m][shift] |= (((uint64_t)1) << ((rm >> shift) & ((1 << usebits) - 1)));+            }+        }+    }+    for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) {+        for (shift = 0; shift <= maxshift; shift++) {+            /* Test that the lower usebits bits of x[shift] are 1 */+            CHECK(((~x[m][shift]) << (64 - (1 << usebits))) == 0);+        }+    }+}++/* Subrange must be a whole divisor of range, and at most 64 */+void test_rand_int(uint32_t range, uint32_t subrange) {+    /* (1-1/subrange)^rounds < 1/10^9 */+    int rounds = (subrange * 2073) / 100;+    int i;+    uint64_t x = 0;+    CHECK((range % subrange) == 0);+    for (i = 0; i < rounds; i++) {+        uint32_t r = secp256k1_rand_int(range);+        CHECK(r < range);+        r = r % subrange;+        x |= (((uint64_t)1) << r);+    }+    /* Test that the lower subrange bits of x are 1. */+    CHECK(((~x) << (64 - subrange)) == 0);+}++void run_rand_bits(void) {+    size_t b;+    test_rand_bits(1, 32);+    for (b = 1; b <= 32; b++) {+        test_rand_bits(0, b);+    }+}++void run_rand_int(void) {+    static const uint32_t ms[] = {1, 3, 17, 1000, 13771, 999999, 33554432};+    static const uint32_t ss[] = {1, 3, 6, 9, 13, 31, 64};+    unsigned int m, s;+    for (m = 0; m < sizeof(ms) / sizeof(ms[0]); m++) {+        for (s = 0; s < sizeof(ss) / sizeof(ss[0]); s++) {+            test_rand_int(ms[m] * ss[s], ss[s]);+        }+    }+}++/***** NUM TESTS *****/++#ifndef USE_NUM_NONE+void random_num_negate(secp256k1_num *num) {+    if (secp256k1_rand_bits(1)) {+        secp256k1_num_negate(num);+    }+}++void random_num_order_test(secp256k1_num *num) {+    secp256k1_scalar sc;+    random_scalar_order_test(&sc);+    secp256k1_scalar_get_num(num, &sc);+}++void random_num_order(secp256k1_num *num) {+    secp256k1_scalar sc;+    random_scalar_order(&sc);+    secp256k1_scalar_get_num(num, &sc);+}++void test_num_negate(void) {+    secp256k1_num n1;+    secp256k1_num n2;+    random_num_order_test(&n1); /* n1 = R */+    random_num_negate(&n1);+    secp256k1_num_copy(&n2, &n1); /* n2 = R */+    secp256k1_num_sub(&n1, &n2, &n1); /* n1 = n2-n1 = 0 */+    CHECK(secp256k1_num_is_zero(&n1));+    secp256k1_num_copy(&n1, &n2); /* n1 = R */+    secp256k1_num_negate(&n1); /* n1 = -R */+    CHECK(!secp256k1_num_is_zero(&n1));+    secp256k1_num_add(&n1, &n2, &n1); /* n1 = n2+n1 = 0 */+    CHECK(secp256k1_num_is_zero(&n1));+    secp256k1_num_copy(&n1, &n2); /* n1 = R */+    secp256k1_num_negate(&n1); /* n1 = -R */+    CHECK(secp256k1_num_is_neg(&n1) != secp256k1_num_is_neg(&n2));+    secp256k1_num_negate(&n1); /* n1 = R */+    CHECK(secp256k1_num_eq(&n1, &n2));+}++void test_num_add_sub(void) {+    secp256k1_num n1;+    secp256k1_num n2;+    secp256k1_num n1p2, n2p1, n1m2, n2m1;+    random_num_order_test(&n1); /* n1 = R1 */+    if (secp256k1_rand_bits(1)) {+        random_num_negate(&n1);+    }+    random_num_order_test(&n2); /* n2 = R2 */+    if (secp256k1_rand_bits(1)) {+        random_num_negate(&n2);+    }+    secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = R1 + R2 */+    secp256k1_num_add(&n2p1, &n2, &n1); /* n2p1 = R2 + R1 */+    secp256k1_num_sub(&n1m2, &n1, &n2); /* n1m2 = R1 - R2 */+    secp256k1_num_sub(&n2m1, &n2, &n1); /* n2m1 = R2 - R1 */+    CHECK(secp256k1_num_eq(&n1p2, &n2p1));+    CHECK(!secp256k1_num_eq(&n1p2, &n1m2));+    secp256k1_num_negate(&n2m1); /* n2m1 = -R2 + R1 */+    CHECK(secp256k1_num_eq(&n2m1, &n1m2));+    CHECK(!secp256k1_num_eq(&n2m1, &n1));+    secp256k1_num_add(&n2m1, &n2m1, &n2); /* n2m1 = -R2 + R1 + R2 = R1 */+    CHECK(secp256k1_num_eq(&n2m1, &n1));+    CHECK(!secp256k1_num_eq(&n2p1, &n1));+    secp256k1_num_sub(&n2p1, &n2p1, &n2); /* n2p1 = R2 + R1 - R2 = R1 */+    CHECK(secp256k1_num_eq(&n2p1, &n1));+}++void run_num_smalltests(void) {+    int i;+    for (i = 0; i < 100*count; i++) {+        test_num_negate();+        test_num_add_sub();+    }+}+#endif++/***** SCALAR TESTS *****/++void scalar_test(void) {+    secp256k1_scalar s;+    secp256k1_scalar s1;+    secp256k1_scalar s2;+#ifndef USE_NUM_NONE+    secp256k1_num snum, s1num, s2num;+    secp256k1_num order, half_order;+#endif+    unsigned char c[32];++    /* Set 's' to a random scalar, with value 'snum'. */+    random_scalar_order_test(&s);++    /* Set 's1' to a random scalar, with value 's1num'. */+    random_scalar_order_test(&s1);++    /* Set 's2' to a random scalar, with value 'snum2', and byte array representation 'c'. */+    random_scalar_order_test(&s2);+    secp256k1_scalar_get_b32(c, &s2);++#ifndef USE_NUM_NONE+    secp256k1_scalar_get_num(&snum, &s);+    secp256k1_scalar_get_num(&s1num, &s1);+    secp256k1_scalar_get_num(&s2num, &s2);++    secp256k1_scalar_order_get_num(&order);+    half_order = order;+    secp256k1_num_shift(&half_order, 1);+#endif++    {+        int i;+        /* Test that fetching groups of 4 bits from a scalar and recursing n(i)=16*n(i-1)+p(i) reconstructs it. */+        secp256k1_scalar n;+        secp256k1_scalar_set_int(&n, 0);+        for (i = 0; i < 256; i += 4) {+            secp256k1_scalar t;+            int j;+            secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits(&s, 256 - 4 - i, 4));+            for (j = 0; j < 4; j++) {+                secp256k1_scalar_add(&n, &n, &n);+            }+            secp256k1_scalar_add(&n, &n, &t);+        }+        CHECK(secp256k1_scalar_eq(&n, &s));+    }++    {+        /* Test that fetching groups of randomly-sized bits from a scalar and recursing n(i)=b*n(i-1)+p(i) reconstructs it. */+        secp256k1_scalar n;+        int i = 0;+        secp256k1_scalar_set_int(&n, 0);+        while (i < 256) {+            secp256k1_scalar t;+            int j;+            int now = secp256k1_rand_int(15) + 1;+            if (now + i > 256) {+                now = 256 - i;+            }+            secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits_var(&s, 256 - now - i, now));+            for (j = 0; j < now; j++) {+                secp256k1_scalar_add(&n, &n, &n);+            }+            secp256k1_scalar_add(&n, &n, &t);+            i += now;+        }+        CHECK(secp256k1_scalar_eq(&n, &s));+    }++#ifndef USE_NUM_NONE+    {+        /* Test that adding the scalars together is equal to adding their numbers together modulo the order. */+        secp256k1_num rnum;+        secp256k1_num r2num;+        secp256k1_scalar r;+        secp256k1_num_add(&rnum, &snum, &s2num);+        secp256k1_num_mod(&rnum, &order);+        secp256k1_scalar_add(&r, &s, &s2);+        secp256k1_scalar_get_num(&r2num, &r);+        CHECK(secp256k1_num_eq(&rnum, &r2num));+    }++    {+        /* Test that multipying the scalars is equal to multiplying their numbers modulo the order. */+        secp256k1_scalar r;+        secp256k1_num r2num;+        secp256k1_num rnum;+        secp256k1_num_mul(&rnum, &snum, &s2num);+        secp256k1_num_mod(&rnum, &order);+        secp256k1_scalar_mul(&r, &s, &s2);+        secp256k1_scalar_get_num(&r2num, &r);+        CHECK(secp256k1_num_eq(&rnum, &r2num));+        /* The result can only be zero if at least one of the factors was zero. */+        CHECK(secp256k1_scalar_is_zero(&r) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_zero(&s2)));+        /* The results can only be equal to one of the factors if that factor was zero, or the other factor was one. */+        CHECK(secp256k1_num_eq(&rnum, &snum) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_one(&s2)));+        CHECK(secp256k1_num_eq(&rnum, &s2num) == (secp256k1_scalar_is_zero(&s2) || secp256k1_scalar_is_one(&s)));+    }++    {+        secp256k1_scalar neg;+        secp256k1_num negnum;+        secp256k1_num negnum2;+        /* Check that comparison with zero matches comparison with zero on the number. */+        CHECK(secp256k1_num_is_zero(&snum) == secp256k1_scalar_is_zero(&s));+        /* Check that comparison with the half order is equal to testing for high scalar. */+        CHECK(secp256k1_scalar_is_high(&s) == (secp256k1_num_cmp(&snum, &half_order) > 0));+        secp256k1_scalar_negate(&neg, &s);+        secp256k1_num_sub(&negnum, &order, &snum);+        secp256k1_num_mod(&negnum, &order);+        /* Check that comparison with the half order is equal to testing for high scalar after negation. */+        CHECK(secp256k1_scalar_is_high(&neg) == (secp256k1_num_cmp(&negnum, &half_order) > 0));+        /* Negating should change the high property, unless the value was already zero. */+        CHECK((secp256k1_scalar_is_high(&s) == secp256k1_scalar_is_high(&neg)) == secp256k1_scalar_is_zero(&s));+        secp256k1_scalar_get_num(&negnum2, &neg);+        /* Negating a scalar should be equal to (order - n) mod order on the number. */+        CHECK(secp256k1_num_eq(&negnum, &negnum2));+        secp256k1_scalar_add(&neg, &neg, &s);+        /* Adding a number to its negation should result in zero. */+        CHECK(secp256k1_scalar_is_zero(&neg));+        secp256k1_scalar_negate(&neg, &neg);+        /* Negating zero should still result in zero. */+        CHECK(secp256k1_scalar_is_zero(&neg));+    }++    {+        /* Test secp256k1_scalar_mul_shift_var. */+        secp256k1_scalar r;+        secp256k1_num one;+        secp256k1_num rnum;+        secp256k1_num rnum2;+        unsigned char cone[1] = {0x01};+        unsigned int shift = 256 + secp256k1_rand_int(257);+        secp256k1_scalar_mul_shift_var(&r, &s1, &s2, shift);+        secp256k1_num_mul(&rnum, &s1num, &s2num);+        secp256k1_num_shift(&rnum, shift - 1);+        secp256k1_num_set_bin(&one, cone, 1);+        secp256k1_num_add(&rnum, &rnum, &one);+        secp256k1_num_shift(&rnum, 1);+        secp256k1_scalar_get_num(&rnum2, &r);+        CHECK(secp256k1_num_eq(&rnum, &rnum2));+    }++    {+        /* test secp256k1_scalar_shr_int */+        secp256k1_scalar r;+        int i;+        random_scalar_order_test(&r);+        for (i = 0; i < 100; ++i) {+            int low;+            int shift = 1 + secp256k1_rand_int(15);+            int expected = r.d[0] % (1 << shift);+            low = secp256k1_scalar_shr_int(&r, shift);+            CHECK(expected == low);+        }+    }+#endif++    {+        /* Test that scalar inverses are equal to the inverse of their number modulo the order. */+        if (!secp256k1_scalar_is_zero(&s)) {+            secp256k1_scalar inv;+#ifndef USE_NUM_NONE+            secp256k1_num invnum;+            secp256k1_num invnum2;+#endif+            secp256k1_scalar_inverse(&inv, &s);+#ifndef USE_NUM_NONE+            secp256k1_num_mod_inverse(&invnum, &snum, &order);+            secp256k1_scalar_get_num(&invnum2, &inv);+            CHECK(secp256k1_num_eq(&invnum, &invnum2));+#endif+            secp256k1_scalar_mul(&inv, &inv, &s);+            /* Multiplying a scalar with its inverse must result in one. */+            CHECK(secp256k1_scalar_is_one(&inv));+            secp256k1_scalar_inverse(&inv, &inv);+            /* Inverting one must result in one. */+            CHECK(secp256k1_scalar_is_one(&inv));+        }+    }++    {+        /* Test commutativity of add. */+        secp256k1_scalar r1, r2;+        secp256k1_scalar_add(&r1, &s1, &s2);+        secp256k1_scalar_add(&r2, &s2, &s1);+        CHECK(secp256k1_scalar_eq(&r1, &r2));+    }++    {+        secp256k1_scalar r1, r2;+        secp256k1_scalar b;+        int i;+        /* Test add_bit. */+        int bit = secp256k1_rand_bits(8);+        secp256k1_scalar_set_int(&b, 1);+        CHECK(secp256k1_scalar_is_one(&b));+        for (i = 0; i < bit; i++) {+            secp256k1_scalar_add(&b, &b, &b);+        }+        r1 = s1;+        r2 = s1;+        if (!secp256k1_scalar_add(&r1, &r1, &b)) {+            /* No overflow happened. */+            secp256k1_scalar_cadd_bit(&r2, bit, 1);+            CHECK(secp256k1_scalar_eq(&r1, &r2));+            /* cadd is a noop when flag is zero */+            secp256k1_scalar_cadd_bit(&r2, bit, 0);+            CHECK(secp256k1_scalar_eq(&r1, &r2));+        }+    }++    {+        /* Test commutativity of mul. */+        secp256k1_scalar r1, r2;+        secp256k1_scalar_mul(&r1, &s1, &s2);+        secp256k1_scalar_mul(&r2, &s2, &s1);+        CHECK(secp256k1_scalar_eq(&r1, &r2));+    }++    {+        /* Test associativity of add. */+        secp256k1_scalar r1, r2;+        secp256k1_scalar_add(&r1, &s1, &s2);+        secp256k1_scalar_add(&r1, &r1, &s);+        secp256k1_scalar_add(&r2, &s2, &s);+        secp256k1_scalar_add(&r2, &s1, &r2);+        CHECK(secp256k1_scalar_eq(&r1, &r2));+    }++    {+        /* Test associativity of mul. */+        secp256k1_scalar r1, r2;+        secp256k1_scalar_mul(&r1, &s1, &s2);+        secp256k1_scalar_mul(&r1, &r1, &s);+        secp256k1_scalar_mul(&r2, &s2, &s);+        secp256k1_scalar_mul(&r2, &s1, &r2);+        CHECK(secp256k1_scalar_eq(&r1, &r2));+    }++    {+        /* Test distributitivity of mul over add. */+        secp256k1_scalar r1, r2, t;+        secp256k1_scalar_add(&r1, &s1, &s2);+        secp256k1_scalar_mul(&r1, &r1, &s);+        secp256k1_scalar_mul(&r2, &s1, &s);+        secp256k1_scalar_mul(&t, &s2, &s);+        secp256k1_scalar_add(&r2, &r2, &t);+        CHECK(secp256k1_scalar_eq(&r1, &r2));+    }++    {+        /* Test square. */+        secp256k1_scalar r1, r2;+        secp256k1_scalar_sqr(&r1, &s1);+        secp256k1_scalar_mul(&r2, &s1, &s1);+        CHECK(secp256k1_scalar_eq(&r1, &r2));+    }++    {+        /* Test multiplicative identity. */+        secp256k1_scalar r1, v1;+        secp256k1_scalar_set_int(&v1,1);+        secp256k1_scalar_mul(&r1, &s1, &v1);+        CHECK(secp256k1_scalar_eq(&r1, &s1));+    }++    {+        /* Test additive identity. */+        secp256k1_scalar r1, v0;+        secp256k1_scalar_set_int(&v0,0);+        secp256k1_scalar_add(&r1, &s1, &v0);+        CHECK(secp256k1_scalar_eq(&r1, &s1));+    }++    {+        /* Test zero product property. */+        secp256k1_scalar r1, v0;+        secp256k1_scalar_set_int(&v0,0);+        secp256k1_scalar_mul(&r1, &s1, &v0);+        CHECK(secp256k1_scalar_eq(&r1, &v0));+    }++}++void run_scalar_tests(void) {+    int i;+    for (i = 0; i < 128 * count; i++) {+        scalar_test();+    }++    {+        /* (-1)+1 should be zero. */+        secp256k1_scalar s, o;+        secp256k1_scalar_set_int(&s, 1);+        CHECK(secp256k1_scalar_is_one(&s));+        secp256k1_scalar_negate(&o, &s);+        secp256k1_scalar_add(&o, &o, &s);+        CHECK(secp256k1_scalar_is_zero(&o));+        secp256k1_scalar_negate(&o, &o);+        CHECK(secp256k1_scalar_is_zero(&o));+    }++#ifndef USE_NUM_NONE+    {+        /* A scalar with value of the curve order should be 0. */+        secp256k1_num order;+        secp256k1_scalar zero;+        unsigned char bin[32];+        int overflow = 0;+        secp256k1_scalar_order_get_num(&order);+        secp256k1_num_get_bin(bin, 32, &order);+        secp256k1_scalar_set_b32(&zero, bin, &overflow);+        CHECK(overflow == 1);+        CHECK(secp256k1_scalar_is_zero(&zero));+    }+#endif+}++/***** FIELD TESTS *****/++void random_fe(secp256k1_fe *x) {+    unsigned char bin[32];+    do {+        secp256k1_rand256(bin);+        if (secp256k1_fe_set_b32(x, bin)) {+            return;+        }+    } while(1);+}++void random_fe_non_zero(secp256k1_fe *nz) {+    int tries = 10;+    while (--tries >= 0) {+        random_fe(nz);+        secp256k1_fe_normalize(nz);+        if (!secp256k1_fe_is_zero(nz)) {+            break;+        }+    }+    /* Infinitesimal probability of spurious failure here */+    CHECK(tries >= 0);+}++void random_fe_non_square(secp256k1_fe *ns) {+    secp256k1_fe r;+    random_fe_non_zero(ns);+    if (secp256k1_fe_sqrt_var(&r, ns)) {+        secp256k1_fe_negate(ns, ns, 1);+    }+}++int check_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) {+    secp256k1_fe an = *a;+    secp256k1_fe bn = *b;+    secp256k1_fe_normalize_weak(&an);+    secp256k1_fe_normalize_var(&bn);+    return secp256k1_fe_equal_var(&an, &bn);+}++int check_fe_inverse(const secp256k1_fe *a, const secp256k1_fe *ai) {+    secp256k1_fe x;+    secp256k1_fe one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1);+    secp256k1_fe_mul(&x, a, ai);+    return check_fe_equal(&x, &one);+}++void run_field_convert(void) {+    static const unsigned char b32[32] = {+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,+        0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,+        0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,+        0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40+    };+    static const secp256k1_fe_storage fes = SECP256K1_FE_STORAGE_CONST(+        0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL,+        0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL+    );+    static const secp256k1_fe fe = SECP256K1_FE_CONST(+        0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL,+        0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL+    );+    secp256k1_fe fe2;+    unsigned char b322[32];+    secp256k1_fe_storage fes2;+    /* Check conversions to fe. */+    CHECK(secp256k1_fe_set_b32(&fe2, b32));+    CHECK(secp256k1_fe_equal_var(&fe, &fe2));+    secp256k1_fe_from_storage(&fe2, &fes);+    CHECK(secp256k1_fe_equal_var(&fe, &fe2));+    /* Check conversion from fe. */+    secp256k1_fe_get_b32(b322, &fe);+    CHECK(memcmp(b322, b32, 32) == 0);+    secp256k1_fe_to_storage(&fes2, &fe);+    CHECK(memcmp(&fes2, &fes, sizeof(fes)) == 0);+}++int fe_memcmp(const secp256k1_fe *a, const secp256k1_fe *b) {+    secp256k1_fe t = *b;+#ifdef VERIFY+    t.magnitude = a->magnitude;+    t.normalized = a->normalized;+#endif+    return memcmp(a, &t, sizeof(secp256k1_fe));+}++void run_field_misc(void) {+    secp256k1_fe x;+    secp256k1_fe y;+    secp256k1_fe z;+    secp256k1_fe q;+    secp256k1_fe fe5 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 5);+    int i, j;+    for (i = 0; i < 5*count; i++) {+        secp256k1_fe_storage xs, ys, zs;+        random_fe(&x);+        random_fe_non_zero(&y);+        /* Test the fe equality and comparison operations. */+        CHECK(secp256k1_fe_cmp_var(&x, &x) == 0);+        CHECK(secp256k1_fe_equal_var(&x, &x));+        z = x;+        secp256k1_fe_add(&z,&y);+        /* Test fe conditional move; z is not normalized here. */+        q = x;+        secp256k1_fe_cmov(&x, &z, 0);+        VERIFY_CHECK(!x.normalized && x.magnitude == z.magnitude);+        secp256k1_fe_cmov(&x, &x, 1);+        CHECK(fe_memcmp(&x, &z) != 0);+        CHECK(fe_memcmp(&x, &q) == 0);+        secp256k1_fe_cmov(&q, &z, 1);+        VERIFY_CHECK(!q.normalized && q.magnitude == z.magnitude);+        CHECK(fe_memcmp(&q, &z) == 0);+        secp256k1_fe_normalize_var(&x);+        secp256k1_fe_normalize_var(&z);+        CHECK(!secp256k1_fe_equal_var(&x, &z));+        secp256k1_fe_normalize_var(&q);+        secp256k1_fe_cmov(&q, &z, (i&1));+        VERIFY_CHECK(q.normalized && q.magnitude == 1);+        for (j = 0; j < 6; j++) {+            secp256k1_fe_negate(&z, &z, j+1);+            secp256k1_fe_normalize_var(&q);+            secp256k1_fe_cmov(&q, &z, (j&1));+            VERIFY_CHECK(!q.normalized && q.magnitude == (j+2));+        }+        secp256k1_fe_normalize_var(&z);+        /* Test storage conversion and conditional moves. */+        secp256k1_fe_to_storage(&xs, &x);+        secp256k1_fe_to_storage(&ys, &y);+        secp256k1_fe_to_storage(&zs, &z);+        secp256k1_fe_storage_cmov(&zs, &xs, 0);+        secp256k1_fe_storage_cmov(&zs, &zs, 1);+        CHECK(memcmp(&xs, &zs, sizeof(xs)) != 0);+        secp256k1_fe_storage_cmov(&ys, &xs, 1);+        CHECK(memcmp(&xs, &ys, sizeof(xs)) == 0);+        secp256k1_fe_from_storage(&x, &xs);+        secp256k1_fe_from_storage(&y, &ys);+        secp256k1_fe_from_storage(&z, &zs);+        /* Test that mul_int, mul, and add agree. */+        secp256k1_fe_add(&y, &x);+        secp256k1_fe_add(&y, &x);+        z = x;+        secp256k1_fe_mul_int(&z, 3);+        CHECK(check_fe_equal(&y, &z));+        secp256k1_fe_add(&y, &x);+        secp256k1_fe_add(&z, &x);+        CHECK(check_fe_equal(&z, &y));+        z = x;+        secp256k1_fe_mul_int(&z, 5);+        secp256k1_fe_mul(&q, &x, &fe5);+        CHECK(check_fe_equal(&z, &q));+        secp256k1_fe_negate(&x, &x, 1);+        secp256k1_fe_add(&z, &x);+        secp256k1_fe_add(&q, &x);+        CHECK(check_fe_equal(&y, &z));+        CHECK(check_fe_equal(&q, &y));+    }+}++void run_field_inv(void) {+    secp256k1_fe x, xi, xii;+    int i;+    for (i = 0; i < 10*count; i++) {+        random_fe_non_zero(&x);+        secp256k1_fe_inv(&xi, &x);+        CHECK(check_fe_inverse(&x, &xi));+        secp256k1_fe_inv(&xii, &xi);+        CHECK(check_fe_equal(&x, &xii));+    }+}++void run_field_inv_var(void) {+    secp256k1_fe x, xi, xii;+    int i;+    for (i = 0; i < 10*count; i++) {+        random_fe_non_zero(&x);+        secp256k1_fe_inv_var(&xi, &x);+        CHECK(check_fe_inverse(&x, &xi));+        secp256k1_fe_inv_var(&xii, &xi);+        CHECK(check_fe_equal(&x, &xii));+    }+}++void run_field_inv_all_var(void) {+    secp256k1_fe x[16], xi[16], xii[16];+    int i;+    /* Check it's safe to call for 0 elements */+    secp256k1_fe_inv_all_var(0, xi, x);+    for (i = 0; i < count; i++) {+        size_t j;+        size_t len = secp256k1_rand_int(15) + 1;+        for (j = 0; j < len; j++) {+            random_fe_non_zero(&x[j]);+        }+        secp256k1_fe_inv_all_var(len, xi, x);+        for (j = 0; j < len; j++) {+            CHECK(check_fe_inverse(&x[j], &xi[j]));+        }+        secp256k1_fe_inv_all_var(len, xii, xi);+        for (j = 0; j < len; j++) {+            CHECK(check_fe_equal(&x[j], &xii[j]));+        }+    }+}++void run_sqr(void) {+    secp256k1_fe x, s;++    {+        int i;+        secp256k1_fe_set_int(&x, 1);+        secp256k1_fe_negate(&x, &x, 1);++        for (i = 1; i <= 512; ++i) {+            secp256k1_fe_mul_int(&x, 2);+            secp256k1_fe_normalize(&x);+            secp256k1_fe_sqr(&s, &x);+        }+    }+}++void test_sqrt(const secp256k1_fe *a, const secp256k1_fe *k) {+    secp256k1_fe r1, r2;+    int v = secp256k1_fe_sqrt_var(&r1, a);+    CHECK((v == 0) == (k == NULL));++    if (k != NULL) {+        /* Check that the returned root is +/- the given known answer */+        secp256k1_fe_negate(&r2, &r1, 1);+        secp256k1_fe_add(&r1, k); secp256k1_fe_add(&r2, k);+        secp256k1_fe_normalize(&r1); secp256k1_fe_normalize(&r2);+        CHECK(secp256k1_fe_is_zero(&r1) || secp256k1_fe_is_zero(&r2));+    }+}++void run_sqrt(void) {+    secp256k1_fe ns, x, s, t;+    int i;++    /* Check sqrt(0) is 0 */+    secp256k1_fe_set_int(&x, 0);+    secp256k1_fe_sqr(&s, &x);+    test_sqrt(&s, &x);++    /* Check sqrt of small squares (and their negatives) */+    for (i = 1; i <= 100; i++) {+        secp256k1_fe_set_int(&x, i);+        secp256k1_fe_sqr(&s, &x);+        test_sqrt(&s, &x);+        secp256k1_fe_negate(&t, &s, 1);+        test_sqrt(&t, NULL);+    }++    /* Consistency checks for large random values */+    for (i = 0; i < 10; i++) {+        int j;+        random_fe_non_square(&ns);+        for (j = 0; j < count; j++) {+            random_fe(&x);+            secp256k1_fe_sqr(&s, &x);+            test_sqrt(&s, &x);+            secp256k1_fe_negate(&t, &s, 1);+            test_sqrt(&t, NULL);+            secp256k1_fe_mul(&t, &s, &ns);+            test_sqrt(&t, NULL);+        }+    }+}++/***** GROUP TESTS *****/++void ge_equals_ge(const secp256k1_ge *a, const secp256k1_ge *b) {+    CHECK(a->infinity == b->infinity);+    if (a->infinity) {+        return;+    }+    CHECK(secp256k1_fe_equal_var(&a->x, &b->x));+    CHECK(secp256k1_fe_equal_var(&a->y, &b->y));+}++/* This compares jacobian points including their Z, not just their geometric meaning. */+int gej_xyz_equals_gej(const secp256k1_gej *a, const secp256k1_gej *b) {+    secp256k1_gej a2;+    secp256k1_gej b2;+    int ret = 1;+    ret &= a->infinity == b->infinity;+    if (ret && !a->infinity) {+        a2 = *a;+        b2 = *b;+        secp256k1_fe_normalize(&a2.x);+        secp256k1_fe_normalize(&a2.y);+        secp256k1_fe_normalize(&a2.z);+        secp256k1_fe_normalize(&b2.x);+        secp256k1_fe_normalize(&b2.y);+        secp256k1_fe_normalize(&b2.z);+        ret &= secp256k1_fe_cmp_var(&a2.x, &b2.x) == 0;+        ret &= secp256k1_fe_cmp_var(&a2.y, &b2.y) == 0;+        ret &= secp256k1_fe_cmp_var(&a2.z, &b2.z) == 0;+    }+    return ret;+}++void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) {+    secp256k1_fe z2s;+    secp256k1_fe u1, u2, s1, s2;+    CHECK(a->infinity == b->infinity);+    if (a->infinity) {+        return;+    }+    /* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */+    secp256k1_fe_sqr(&z2s, &b->z);+    secp256k1_fe_mul(&u1, &a->x, &z2s);+    u2 = b->x; secp256k1_fe_normalize_weak(&u2);+    secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z);+    s2 = b->y; secp256k1_fe_normalize_weak(&s2);+    CHECK(secp256k1_fe_equal_var(&u1, &u2));+    CHECK(secp256k1_fe_equal_var(&s1, &s2));+}++void test_ge(void) {+    int i, i1;+#ifdef USE_ENDOMORPHISM+    int runs = 6;+#else+    int runs = 4;+#endif+    /* Points: (infinity, p1, p1, -p1, -p1, p2, p2, -p2, -p2, p3, p3, -p3, -p3, p4, p4, -p4, -p4).+     * The second in each pair of identical points uses a random Z coordinate in the Jacobian form.+     * All magnitudes are randomized.+     * All 17*17 combinations of points are added to eachother, using all applicable methods.+     *+     * When the endomorphism code is compiled in, p5 = lambda*p1 and p6 = lambda^2*p1 are added as well.+     */+    secp256k1_ge *ge = (secp256k1_ge *)malloc(sizeof(secp256k1_ge) * (1 + 4 * runs));+    secp256k1_gej *gej = (secp256k1_gej *)malloc(sizeof(secp256k1_gej) * (1 + 4 * runs));+    secp256k1_fe *zinv = (secp256k1_fe *)malloc(sizeof(secp256k1_fe) * (1 + 4 * runs));+    secp256k1_fe zf;+    secp256k1_fe zfi2, zfi3;++    secp256k1_gej_set_infinity(&gej[0]);+    secp256k1_ge_clear(&ge[0]);+    secp256k1_ge_set_gej_var(&ge[0], &gej[0]);+    for (i = 0; i < runs; i++) {+        int j;+        secp256k1_ge g;+        random_group_element_test(&g);+#ifdef USE_ENDOMORPHISM+        if (i >= runs - 2) {+            secp256k1_ge_mul_lambda(&g, &ge[1]);+        }+        if (i >= runs - 1) {+            secp256k1_ge_mul_lambda(&g, &g);+        }+#endif+        ge[1 + 4 * i] = g;+        ge[2 + 4 * i] = g;+        secp256k1_ge_neg(&ge[3 + 4 * i], &g);+        secp256k1_ge_neg(&ge[4 + 4 * i], &g);+        secp256k1_gej_set_ge(&gej[1 + 4 * i], &ge[1 + 4 * i]);+        random_group_element_jacobian_test(&gej[2 + 4 * i], &ge[2 + 4 * i]);+        secp256k1_gej_set_ge(&gej[3 + 4 * i], &ge[3 + 4 * i]);+        random_group_element_jacobian_test(&gej[4 + 4 * i], &ge[4 + 4 * i]);+        for (j = 0; j < 4; j++) {+            random_field_element_magnitude(&ge[1 + j + 4 * i].x);+            random_field_element_magnitude(&ge[1 + j + 4 * i].y);+            random_field_element_magnitude(&gej[1 + j + 4 * i].x);+            random_field_element_magnitude(&gej[1 + j + 4 * i].y);+            random_field_element_magnitude(&gej[1 + j + 4 * i].z);+        }+    }++    /* Compute z inverses. */+    {+        secp256k1_fe *zs = malloc(sizeof(secp256k1_fe) * (1 + 4 * runs));+        for (i = 0; i < 4 * runs + 1; i++) {+            if (i == 0) {+                /* The point at infinity does not have a meaningful z inverse. Any should do. */+                do {+                    random_field_element_test(&zs[i]);+                } while(secp256k1_fe_is_zero(&zs[i]));+            } else {+                zs[i] = gej[i].z;+            }+        }+        secp256k1_fe_inv_all_var(4 * runs + 1, zinv, zs);+        free(zs);+    }++    /* Generate random zf, and zfi2 = 1/zf^2, zfi3 = 1/zf^3 */+    do {+        random_field_element_test(&zf);+    } while(secp256k1_fe_is_zero(&zf));+    random_field_element_magnitude(&zf);+    secp256k1_fe_inv_var(&zfi3, &zf);+    secp256k1_fe_sqr(&zfi2, &zfi3);+    secp256k1_fe_mul(&zfi3, &zfi3, &zfi2);++    for (i1 = 0; i1 < 1 + 4 * runs; i1++) {+        int i2;+        for (i2 = 0; i2 < 1 + 4 * runs; i2++) {+            /* Compute reference result using gej + gej (var). */+            secp256k1_gej refj, resj;+            secp256k1_ge ref;+            secp256k1_fe zr;+            secp256k1_gej_add_var(&refj, &gej[i1], &gej[i2], secp256k1_gej_is_infinity(&gej[i1]) ? NULL : &zr);+            /* Check Z ratio. */+            if (!secp256k1_gej_is_infinity(&gej[i1]) && !secp256k1_gej_is_infinity(&refj)) {+                secp256k1_fe zrz; secp256k1_fe_mul(&zrz, &zr, &gej[i1].z);+                CHECK(secp256k1_fe_equal_var(&zrz, &refj.z));+            }+            secp256k1_ge_set_gej_var(&ref, &refj);++            /* Test gej + ge with Z ratio result (var). */+            secp256k1_gej_add_ge_var(&resj, &gej[i1], &ge[i2], secp256k1_gej_is_infinity(&gej[i1]) ? NULL : &zr);+            ge_equals_gej(&ref, &resj);+            if (!secp256k1_gej_is_infinity(&gej[i1]) && !secp256k1_gej_is_infinity(&resj)) {+                secp256k1_fe zrz; secp256k1_fe_mul(&zrz, &zr, &gej[i1].z);+                CHECK(secp256k1_fe_equal_var(&zrz, &resj.z));+            }++            /* Test gej + ge (var, with additional Z factor). */+            {+                secp256k1_ge ge2_zfi = ge[i2]; /* the second term with x and y rescaled for z = 1/zf */+                secp256k1_fe_mul(&ge2_zfi.x, &ge2_zfi.x, &zfi2);+                secp256k1_fe_mul(&ge2_zfi.y, &ge2_zfi.y, &zfi3);+                random_field_element_magnitude(&ge2_zfi.x);+                random_field_element_magnitude(&ge2_zfi.y);+                secp256k1_gej_add_zinv_var(&resj, &gej[i1], &ge2_zfi, &zf);+                ge_equals_gej(&ref, &resj);+            }++            /* Test gej + ge (const). */+            if (i2 != 0) {+                /* secp256k1_gej_add_ge does not support its second argument being infinity. */+                secp256k1_gej_add_ge(&resj, &gej[i1], &ge[i2]);+                ge_equals_gej(&ref, &resj);+            }++            /* Test doubling (var). */+            if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 == ((i2 + 3)%4)/2)) {+                secp256k1_fe zr2;+                /* Normal doubling with Z ratio result. */+                secp256k1_gej_double_var(&resj, &gej[i1], &zr2);+                ge_equals_gej(&ref, &resj);+                /* Check Z ratio. */+                secp256k1_fe_mul(&zr2, &zr2, &gej[i1].z);+                CHECK(secp256k1_fe_equal_var(&zr2, &resj.z));+                /* Normal doubling. */+                secp256k1_gej_double_var(&resj, &gej[i2], NULL);+                ge_equals_gej(&ref, &resj);+            }++            /* Test adding opposites. */+            if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 != ((i2 + 3)%4)/2)) {+                CHECK(secp256k1_ge_is_infinity(&ref));+            }++            /* Test adding infinity. */+            if (i1 == 0) {+                CHECK(secp256k1_ge_is_infinity(&ge[i1]));+                CHECK(secp256k1_gej_is_infinity(&gej[i1]));+                ge_equals_gej(&ref, &gej[i2]);+            }+            if (i2 == 0) {+                CHECK(secp256k1_ge_is_infinity(&ge[i2]));+                CHECK(secp256k1_gej_is_infinity(&gej[i2]));+                ge_equals_gej(&ref, &gej[i1]);+            }+        }+    }++    /* Test adding all points together in random order equals infinity. */+    {+        secp256k1_gej sum = SECP256K1_GEJ_CONST_INFINITY;+        secp256k1_gej *gej_shuffled = (secp256k1_gej *)malloc((4 * runs + 1) * sizeof(secp256k1_gej));+        for (i = 0; i < 4 * runs + 1; i++) {+            gej_shuffled[i] = gej[i];+        }+        for (i = 0; i < 4 * runs + 1; i++) {+            int swap = i + secp256k1_rand_int(4 * runs + 1 - i);+            if (swap != i) {+                secp256k1_gej t = gej_shuffled[i];+                gej_shuffled[i] = gej_shuffled[swap];+                gej_shuffled[swap] = t;+            }+        }+        for (i = 0; i < 4 * runs + 1; i++) {+            secp256k1_gej_add_var(&sum, &sum, &gej_shuffled[i], NULL);+        }+        CHECK(secp256k1_gej_is_infinity(&sum));+        free(gej_shuffled);+    }++    /* Test batch gej -> ge conversion with and without known z ratios. */+    {+        secp256k1_fe *zr = (secp256k1_fe *)malloc((4 * runs + 1) * sizeof(secp256k1_fe));+        secp256k1_ge *ge_set_table = (secp256k1_ge *)malloc((4 * runs + 1) * sizeof(secp256k1_ge));+        secp256k1_ge *ge_set_all = (secp256k1_ge *)malloc((4 * runs + 1) * sizeof(secp256k1_ge));+        for (i = 0; i < 4 * runs + 1; i++) {+            /* Compute gej[i + 1].z / gez[i].z (with gej[n].z taken to be 1). */+            if (i < 4 * runs) {+                secp256k1_fe_mul(&zr[i + 1], &zinv[i], &gej[i + 1].z);+            }+        }+        secp256k1_ge_set_table_gej_var(4 * runs + 1, ge_set_table, gej, zr);+        secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej, &ctx->error_callback);+        for (i = 0; i < 4 * runs + 1; i++) {+            secp256k1_fe s;+            random_fe_non_zero(&s);+            secp256k1_gej_rescale(&gej[i], &s);+            ge_equals_gej(&ge_set_table[i], &gej[i]);+            ge_equals_gej(&ge_set_all[i], &gej[i]);+        }+        free(ge_set_table);+        free(ge_set_all);+        free(zr);+    }++    free(ge);+    free(gej);+    free(zinv);+}++void test_add_neg_y_diff_x(void) {+    /* The point of this test is to check that we can add two points+     * whose y-coordinates are negatives of each other but whose x+     * coordinates differ. If the x-coordinates were the same, these+     * points would be negatives of each other and their sum is+     * infinity. This is cool because it "covers up" any degeneracy+     * in the addition algorithm that would cause the xy coordinates+     * of the sum to be wrong (since infinity has no xy coordinates).+     * HOWEVER, if the x-coordinates are different, infinity is the+     * wrong answer, and such degeneracies are exposed. This is the+     * root of https://github.com/bitcoin/secp256k1/issues/257 which+     * this test is a regression test for.+     *+     * These points were generated in sage as+     * # secp256k1 params+     * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)+     * C = EllipticCurve ([F (0), F (7)])+     * G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)+     * N = FiniteField(G.order())+     *+     * # endomorphism values (lambda is 1^{1/3} in N, beta is 1^{1/3} in F)+     * x = polygen(N)+     * lam  = (1 - x^3).roots()[1][0]+     *+     * # random "bad pair"+     * P = C.random_element()+     * Q = -int(lam) * P+     * print "    P: %x %x" % P.xy()+     * print "    Q: %x %x" % Q.xy()+     * print "P + Q: %x %x" % (P + Q).xy()+     */+    secp256k1_gej aj = SECP256K1_GEJ_CONST(+        0x8d24cd95, 0x0a355af1, 0x3c543505, 0x44238d30,+        0x0643d79f, 0x05a59614, 0x2f8ec030, 0xd58977cb,+        0x001e337a, 0x38093dcd, 0x6c0f386d, 0x0b1293a8,+        0x4d72c879, 0xd7681924, 0x44e6d2f3, 0x9190117d+    );+    secp256k1_gej bj = SECP256K1_GEJ_CONST(+        0xc7b74206, 0x1f788cd9, 0xabd0937d, 0x164a0d86,+        0x95f6ff75, 0xf19a4ce9, 0xd013bd7b, 0xbf92d2a7,+        0xffe1cc85, 0xc7f6c232, 0x93f0c792, 0xf4ed6c57,+        0xb28d3786, 0x2897e6db, 0xbb192d0b, 0x6e6feab2+    );+    secp256k1_gej sumj = SECP256K1_GEJ_CONST(+        0x671a63c0, 0x3efdad4c, 0x389a7798, 0x24356027,+        0xb3d69010, 0x278625c3, 0x5c86d390, 0x184a8f7a,+        0x5f6409c2, 0x2ce01f2b, 0x511fd375, 0x25071d08,+        0xda651801, 0x70e95caf, 0x8f0d893c, 0xbed8fbbe+    );+    secp256k1_ge b;+    secp256k1_gej resj;+    secp256k1_ge res;+    secp256k1_ge_set_gej(&b, &bj);++    secp256k1_gej_add_var(&resj, &aj, &bj, NULL);+    secp256k1_ge_set_gej(&res, &resj);+    ge_equals_gej(&res, &sumj);++    secp256k1_gej_add_ge(&resj, &aj, &b);+    secp256k1_ge_set_gej(&res, &resj);+    ge_equals_gej(&res, &sumj);++    secp256k1_gej_add_ge_var(&resj, &aj, &b, NULL);+    secp256k1_ge_set_gej(&res, &resj);+    ge_equals_gej(&res, &sumj);+}++void run_ge(void) {+    int i;+    for (i = 0; i < count * 32; i++) {+        test_ge();+    }+    test_add_neg_y_diff_x();+}++void test_ec_combine(void) {+    secp256k1_scalar sum = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);+    secp256k1_pubkey data[6];+    const secp256k1_pubkey* d[6];+    secp256k1_pubkey sd;+    secp256k1_pubkey sd2;+    secp256k1_gej Qj;+    secp256k1_ge Q;+    int i;+    for (i = 1; i <= 6; i++) {+        secp256k1_scalar s;+        random_scalar_order_test(&s);+        secp256k1_scalar_add(&sum, &sum, &s);+        secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &s);+        secp256k1_ge_set_gej(&Q, &Qj);+        secp256k1_pubkey_save(&data[i - 1], &Q);+        d[i - 1] = &data[i - 1];+        secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &sum);+        secp256k1_ge_set_gej(&Q, &Qj);+        secp256k1_pubkey_save(&sd, &Q);+        CHECK(secp256k1_ec_pubkey_combine(ctx, &sd2, d, i) == 1);+        CHECK(memcmp(&sd, &sd2, sizeof(sd)) == 0);+    }+}++void run_ec_combine(void) {+    int i;+    for (i = 0; i < count * 8; i++) {+         test_ec_combine();+    }+}++/***** ECMULT TESTS *****/++void run_ecmult_chain(void) {+    /* random starting point A (on the curve) */+    secp256k1_gej a = SECP256K1_GEJ_CONST(+        0x8b30bbe9, 0xae2a9906, 0x96b22f67, 0x0709dff3,+        0x727fd8bc, 0x04d3362c, 0x6c7bf458, 0xe2846004,+        0xa357ae91, 0x5c4a6528, 0x1309edf2, 0x0504740f,+        0x0eb33439, 0x90216b4f, 0x81063cb6, 0x5f2f7e0f+    );+    /* two random initial factors xn and gn */+    secp256k1_scalar xn = SECP256K1_SCALAR_CONST(+        0x84cc5452, 0xf7fde1ed, 0xb4d38a8c, 0xe9b1b84c,+        0xcef31f14, 0x6e569be9, 0x705d357a, 0x42985407+    );+    secp256k1_scalar gn = SECP256K1_SCALAR_CONST(+        0xa1e58d22, 0x553dcd42, 0xb2398062, 0x5d4c57a9,+        0x6e9323d4, 0x2b3152e5, 0xca2c3990, 0xedc7c9de+    );+    /* two small multipliers to be applied to xn and gn in every iteration: */+    static const secp256k1_scalar xf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x1337);+    static const secp256k1_scalar gf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x7113);+    /* accumulators with the resulting coefficients to A and G */+    secp256k1_scalar ae = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1);+    secp256k1_scalar ge = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);+    /* actual points */+    secp256k1_gej x;+    secp256k1_gej x2;+    int i;++    /* the point being computed */+    x = a;+    for (i = 0; i < 200*count; i++) {+        /* in each iteration, compute X = xn*X + gn*G; */+        secp256k1_ecmult(&ctx->ecmult_ctx, &x, &x, &xn, &gn);+        /* also compute ae and ge: the actual accumulated factors for A and G */+        /* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */+        secp256k1_scalar_mul(&ae, &ae, &xn);+        secp256k1_scalar_mul(&ge, &ge, &xn);+        secp256k1_scalar_add(&ge, &ge, &gn);+        /* modify xn and gn */+        secp256k1_scalar_mul(&xn, &xn, &xf);+        secp256k1_scalar_mul(&gn, &gn, &gf);++        /* verify */+        if (i == 19999) {+            /* expected result after 19999 iterations */+            secp256k1_gej rp = SECP256K1_GEJ_CONST(+                0xD6E96687, 0xF9B10D09, 0x2A6F3543, 0x9D86CEBE,+                0xA4535D0D, 0x409F5358, 0x6440BD74, 0xB933E830,+                0xB95CBCA2, 0xC77DA786, 0x539BE8FD, 0x53354D2D,+                0x3B4F566A, 0xE6580454, 0x07ED6015, 0xEE1B2A88+            );++            secp256k1_gej_neg(&rp, &rp);+            secp256k1_gej_add_var(&rp, &rp, &x, NULL);+            CHECK(secp256k1_gej_is_infinity(&rp));+        }+    }+    /* redo the computation, but directly with the resulting ae and ge coefficients: */+    secp256k1_ecmult(&ctx->ecmult_ctx, &x2, &a, &ae, &ge);+    secp256k1_gej_neg(&x2, &x2);+    secp256k1_gej_add_var(&x2, &x2, &x, NULL);+    CHECK(secp256k1_gej_is_infinity(&x2));+}++void test_point_times_order(const secp256k1_gej *point) {+    /* X * (point + G) + (order-X) * (pointer + G) = 0 */+    secp256k1_scalar x;+    secp256k1_scalar nx;+    secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);+    secp256k1_scalar one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1);+    secp256k1_gej res1, res2;+    secp256k1_ge res3;+    unsigned char pub[65];+    size_t psize = 65;+    random_scalar_order_test(&x);+    secp256k1_scalar_negate(&nx, &x);+    secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &x, &x); /* calc res1 = x * point + x * G; */+    secp256k1_ecmult(&ctx->ecmult_ctx, &res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */+    secp256k1_gej_add_var(&res1, &res1, &res2, NULL);+    CHECK(secp256k1_gej_is_infinity(&res1));+    CHECK(secp256k1_gej_is_valid_var(&res1) == 0);+    secp256k1_ge_set_gej(&res3, &res1);+    CHECK(secp256k1_ge_is_infinity(&res3));+    CHECK(secp256k1_ge_is_valid_var(&res3) == 0);+    CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 0) == 0);+    psize = 65;+    CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 1) == 0);+    /* check zero/one edge cases */+    secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &zero, &zero);+    secp256k1_ge_set_gej(&res3, &res1);+    CHECK(secp256k1_ge_is_infinity(&res3));+    secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &one, &zero);+    secp256k1_ge_set_gej(&res3, &res1);+    ge_equals_gej(&res3, point);+    secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &zero, &one);+    secp256k1_ge_set_gej(&res3, &res1);+    ge_equals_ge(&res3, &secp256k1_ge_const_g);+}++void run_point_times_order(void) {+    int i;+    secp256k1_fe x = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 2);+    static const secp256k1_fe xr = SECP256K1_FE_CONST(+        0x7603CB59, 0xB0EF6C63, 0xFE608479, 0x2A0C378C,+        0xDB3233A8, 0x0F8A9A09, 0xA877DEAD, 0x31B38C45+    );+    for (i = 0; i < 500; i++) {+        secp256k1_ge p;+        if (secp256k1_ge_set_xo_var(&p, &x, 1)) {+            secp256k1_gej j;+            CHECK(secp256k1_ge_is_valid_var(&p));+            secp256k1_gej_set_ge(&j, &p);+            CHECK(secp256k1_gej_is_valid_var(&j));+            test_point_times_order(&j);+        }+        secp256k1_fe_sqr(&x, &x);+    }+    secp256k1_fe_normalize_var(&x);+    CHECK(secp256k1_fe_equal_var(&x, &xr));+}++void ecmult_const_random_mult(void) {+    /* random starting point A (on the curve) */+    secp256k1_ge a = SECP256K1_GE_CONST(+        0x6d986544, 0x57ff52b8, 0xcf1b8126, 0x5b802a5b,+        0xa97f9263, 0xb1e88044, 0x93351325, 0x91bc450a,+        0x535c59f7, 0x325e5d2b, 0xc391fbe8, 0x3c12787c,+        0x337e4a98, 0xe82a9011, 0x0123ba37, 0xdd769c7d+    );+    /* random initial factor xn */+    secp256k1_scalar xn = SECP256K1_SCALAR_CONST(+        0x649d4f77, 0xc4242df7, 0x7f2079c9, 0x14530327,+        0xa31b876a, 0xd2d8ce2a, 0x2236d5c6, 0xd7b2029b+    );+    /* expected xn * A (from sage) */+    secp256k1_ge expected_b = SECP256K1_GE_CONST(+        0x23773684, 0x4d209dc7, 0x098a786f, 0x20d06fcd,+        0x070a38bf, 0xc11ac651, 0x03004319, 0x1e2a8786,+        0xed8c3b8e, 0xc06dd57b, 0xd06ea66e, 0x45492b0f,+        0xb84e4e1b, 0xfb77e21f, 0x96baae2a, 0x63dec956+    );+    secp256k1_gej b;+    secp256k1_ecmult_const(&b, &a, &xn);++    CHECK(secp256k1_ge_is_valid_var(&a));+    ge_equals_gej(&expected_b, &b);+}++void ecmult_const_commutativity(void) {+    secp256k1_scalar a;+    secp256k1_scalar b;+    secp256k1_gej res1;+    secp256k1_gej res2;+    secp256k1_ge mid1;+    secp256k1_ge mid2;+    random_scalar_order_test(&a);+    random_scalar_order_test(&b);++    secp256k1_ecmult_const(&res1, &secp256k1_ge_const_g, &a);+    secp256k1_ecmult_const(&res2, &secp256k1_ge_const_g, &b);+    secp256k1_ge_set_gej(&mid1, &res1);+    secp256k1_ge_set_gej(&mid2, &res2);+    secp256k1_ecmult_const(&res1, &mid1, &b);+    secp256k1_ecmult_const(&res2, &mid2, &a);+    secp256k1_ge_set_gej(&mid1, &res1);+    secp256k1_ge_set_gej(&mid2, &res2);+    ge_equals_ge(&mid1, &mid2);+}++void ecmult_const_mult_zero_one(void) {+    secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);+    secp256k1_scalar one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1);+    secp256k1_scalar negone;+    secp256k1_gej res1;+    secp256k1_ge res2;+    secp256k1_ge point;+    secp256k1_scalar_negate(&negone, &one);++    random_group_element_test(&point);+    secp256k1_ecmult_const(&res1, &point, &zero);+    secp256k1_ge_set_gej(&res2, &res1);+    CHECK(secp256k1_ge_is_infinity(&res2));+    secp256k1_ecmult_const(&res1, &point, &one);+    secp256k1_ge_set_gej(&res2, &res1);+    ge_equals_ge(&res2, &point);+    secp256k1_ecmult_const(&res1, &point, &negone);+    secp256k1_gej_neg(&res1, &res1);+    secp256k1_ge_set_gej(&res2, &res1);+    ge_equals_ge(&res2, &point);+}++void ecmult_const_chain_multiply(void) {+    /* Check known result (randomly generated test problem from sage) */+    const secp256k1_scalar scalar = SECP256K1_SCALAR_CONST(+        0x4968d524, 0x2abf9b7a, 0x466abbcf, 0x34b11b6d,+        0xcd83d307, 0x827bed62, 0x05fad0ce, 0x18fae63b+    );+    const secp256k1_gej expected_point = SECP256K1_GEJ_CONST(+        0x5494c15d, 0x32099706, 0xc2395f94, 0x348745fd,+        0x757ce30e, 0x4e8c90fb, 0xa2bad184, 0xf883c69f,+        0x5d195d20, 0xe191bf7f, 0x1be3e55f, 0x56a80196,+        0x6071ad01, 0xf1462f66, 0xc997fa94, 0xdb858435+    );+    secp256k1_gej point;+    secp256k1_ge res;+    int i;++    secp256k1_gej_set_ge(&point, &secp256k1_ge_const_g);+    for (i = 0; i < 100; ++i) {+        secp256k1_ge tmp;+        secp256k1_ge_set_gej(&tmp, &point);+        secp256k1_ecmult_const(&point, &tmp, &scalar);+    }+    secp256k1_ge_set_gej(&res, &point);+    ge_equals_gej(&res, &expected_point);+}++void run_ecmult_const_tests(void) {+    ecmult_const_mult_zero_one();+    ecmult_const_random_mult();+    ecmult_const_commutativity();+    ecmult_const_chain_multiply();+}++void test_wnaf(const secp256k1_scalar *number, int w) {+    secp256k1_scalar x, two, t;+    int wnaf[256];+    int zeroes = -1;+    int i;+    int bits;+    secp256k1_scalar_set_int(&x, 0);+    secp256k1_scalar_set_int(&two, 2);+    bits = secp256k1_ecmult_wnaf(wnaf, 256, number, w);+    CHECK(bits <= 256);+    for (i = bits-1; i >= 0; i--) {+        int v = wnaf[i];+        secp256k1_scalar_mul(&x, &x, &two);+        if (v) {+            CHECK(zeroes == -1 || zeroes >= w-1); /* check that distance between non-zero elements is at least w-1 */+            zeroes=0;+            CHECK((v & 1) == 1); /* check non-zero elements are odd */+            CHECK(v <= (1 << (w-1)) - 1); /* check range below */+            CHECK(v >= -(1 << (w-1)) - 1); /* check range above */+        } else {+            CHECK(zeroes != -1); /* check that no unnecessary zero padding exists */+            zeroes++;+        }+        if (v >= 0) {+            secp256k1_scalar_set_int(&t, v);+        } else {+            secp256k1_scalar_set_int(&t, -v);+            secp256k1_scalar_negate(&t, &t);+        }+        secp256k1_scalar_add(&x, &x, &t);+    }+    CHECK(secp256k1_scalar_eq(&x, number)); /* check that wnaf represents number */+}++void test_constant_wnaf_negate(const secp256k1_scalar *number) {+    secp256k1_scalar neg1 = *number;+    secp256k1_scalar neg2 = *number;+    int sign1 = 1;+    int sign2 = 1;++    if (!secp256k1_scalar_get_bits(&neg1, 0, 1)) {+        secp256k1_scalar_negate(&neg1, &neg1);+        sign1 = -1;+    }+    sign2 = secp256k1_scalar_cond_negate(&neg2, secp256k1_scalar_is_even(&neg2));+    CHECK(sign1 == sign2);+    CHECK(secp256k1_scalar_eq(&neg1, &neg2));+}++void test_constant_wnaf(const secp256k1_scalar *number, int w) {+    secp256k1_scalar x, shift;+    int wnaf[256] = {0};+    int i;+#ifdef USE_ENDOMORPHISM+    int skew;+#endif+    secp256k1_scalar num = *number;++    secp256k1_scalar_set_int(&x, 0);+    secp256k1_scalar_set_int(&shift, 1 << w);+    /* With USE_ENDOMORPHISM on we only consider 128-bit numbers */+#ifdef USE_ENDOMORPHISM+    for (i = 0; i < 16; ++i) {+        secp256k1_scalar_shr_int(&num, 8);+    }+    skew = secp256k1_wnaf_const(wnaf, num, w);+#else+    secp256k1_wnaf_const(wnaf, num, w);+#endif++    for (i = WNAF_SIZE(w); i >= 0; --i) {+        secp256k1_scalar t;+        int v = wnaf[i];+        CHECK(v != 0); /* check nonzero */+        CHECK(v & 1);  /* check parity */+        CHECK(v > -(1 << w)); /* check range above */+        CHECK(v < (1 << w));  /* check range below */++        secp256k1_scalar_mul(&x, &x, &shift);+        if (v >= 0) {+            secp256k1_scalar_set_int(&t, v);+        } else {+            secp256k1_scalar_set_int(&t, -v);+            secp256k1_scalar_negate(&t, &t);+        }+        secp256k1_scalar_add(&x, &x, &t);+    }+#ifdef USE_ENDOMORPHISM+    /* Skew num because when encoding 128-bit numbers as odd we use an offset */+    secp256k1_scalar_cadd_bit(&num, skew == 2, 1);+#endif+    CHECK(secp256k1_scalar_eq(&x, &num));+}++void run_wnaf(void) {+    int i;+    secp256k1_scalar n = {{0}};++    /* Sanity check: 1 and 2 are the smallest odd and even numbers and should+     *               have easier-to-diagnose failure modes  */+    n.d[0] = 1;+    test_constant_wnaf(&n, 4);+    n.d[0] = 2;+    test_constant_wnaf(&n, 4);+    /* Random tests */+    for (i = 0; i < count; i++) {+        random_scalar_order(&n);+        test_wnaf(&n, 4+(i%10));+        test_constant_wnaf_negate(&n);+        test_constant_wnaf(&n, 4 + (i % 10));+    }+}++void test_ecmult_constants(void) {+    /* Test ecmult_gen() for [0..36) and [order-36..0). */+    secp256k1_scalar x;+    secp256k1_gej r;+    secp256k1_ge ng;+    int i;+    int j;+    secp256k1_ge_neg(&ng, &secp256k1_ge_const_g);+    for (i = 0; i < 36; i++ ) {+        secp256k1_scalar_set_int(&x, i);+        secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x);+        for (j = 0; j < i; j++) {+            if (j == i - 1) {+                ge_equals_gej(&secp256k1_ge_const_g, &r);+            }+            secp256k1_gej_add_ge(&r, &r, &ng);+        }+        CHECK(secp256k1_gej_is_infinity(&r));+    }+    for (i = 1; i <= 36; i++ ) {+        secp256k1_scalar_set_int(&x, i);+        secp256k1_scalar_negate(&x, &x);+        secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x);+        for (j = 0; j < i; j++) {+            if (j == i - 1) {+                ge_equals_gej(&ng, &r);+            }+            secp256k1_gej_add_ge(&r, &r, &secp256k1_ge_const_g);+        }+        CHECK(secp256k1_gej_is_infinity(&r));+    }+}++void run_ecmult_constants(void) {+    test_ecmult_constants();+}++void test_ecmult_gen_blind(void) {+    /* Test ecmult_gen() blinding and confirm that the blinding changes, the affline points match, and the z's don't match. */+    secp256k1_scalar key;+    secp256k1_scalar b;+    unsigned char seed32[32];+    secp256k1_gej pgej;+    secp256k1_gej pgej2;+    secp256k1_gej i;+    secp256k1_ge pge;+    random_scalar_order_test(&key);+    secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pgej, &key);+    secp256k1_rand256(seed32);+    b = ctx->ecmult_gen_ctx.blind;+    i = ctx->ecmult_gen_ctx.initial;+    secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32);+    CHECK(!secp256k1_scalar_eq(&b, &ctx->ecmult_gen_ctx.blind));+    secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pgej2, &key);+    CHECK(!gej_xyz_equals_gej(&pgej, &pgej2));+    CHECK(!gej_xyz_equals_gej(&i, &ctx->ecmult_gen_ctx.initial));+    secp256k1_ge_set_gej(&pge, &pgej);+    ge_equals_gej(&pge, &pgej2);+}++void test_ecmult_gen_blind_reset(void) {+    /* Test ecmult_gen() blinding reset and confirm that the blinding is consistent. */+    secp256k1_scalar b;+    secp256k1_gej initial;+    secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, 0);+    b = ctx->ecmult_gen_ctx.blind;+    initial = ctx->ecmult_gen_ctx.initial;+    secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, 0);+    CHECK(secp256k1_scalar_eq(&b, &ctx->ecmult_gen_ctx.blind));+    CHECK(gej_xyz_equals_gej(&initial, &ctx->ecmult_gen_ctx.initial));+}++void run_ecmult_gen_blind(void) {+    int i;+    test_ecmult_gen_blind_reset();+    for (i = 0; i < 10; i++) {+        test_ecmult_gen_blind();+    }+}++#ifdef USE_ENDOMORPHISM+/***** ENDOMORPHISH TESTS *****/+void test_scalar_split(void) {+    secp256k1_scalar full;+    secp256k1_scalar s1, slam;+    const unsigned char zero[32] = {0};+    unsigned char tmp[32];++    random_scalar_order_test(&full);+    secp256k1_scalar_split_lambda(&s1, &slam, &full);++    /* check that both are <= 128 bits in size */+    if (secp256k1_scalar_is_high(&s1)) {+        secp256k1_scalar_negate(&s1, &s1);+    }+    if (secp256k1_scalar_is_high(&slam)) {+        secp256k1_scalar_negate(&slam, &slam);+    }++    secp256k1_scalar_get_b32(tmp, &s1);+    CHECK(memcmp(zero, tmp, 16) == 0);+    secp256k1_scalar_get_b32(tmp, &slam);+    CHECK(memcmp(zero, tmp, 16) == 0);+}++void run_endomorphism_tests(void) {+    test_scalar_split();+}+#endif++static void counting_illegal_callback_fn(const char* str, void* data) {+    /* Dummy callback function that just counts. */+    int32_t *p;+    (void)str;+    p = data;+    (*p)++;+}++static void uncounting_illegal_callback_fn(const char* str, void* data) {+    /* Dummy callback function that just counts (backwards). */+    int32_t *p;+    (void)str;+    p = data;+    (*p)--;+}++void ec_pubkey_parse_pointtest(const unsigned char *input, int xvalid, int yvalid) {+    unsigned char pubkeyc[65];+    secp256k1_pubkey pubkey;+    secp256k1_ge ge;+    size_t pubkeyclen;+    int32_t ecount;+    ecount = 0;+    secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount);+    for (pubkeyclen = 3; pubkeyclen <= 65; pubkeyclen++) {+        /* Smaller sizes are tested exhaustively elsewhere. */+        int32_t i;+        memcpy(&pubkeyc[1], input, 64);+        VG_UNDEF(&pubkeyc[pubkeyclen], 65 - pubkeyclen);+        for (i = 0; i < 256; i++) {+            /* Try all type bytes. */+            int xpass;+            int ypass;+            int ysign;+            pubkeyc[0] = i;+            /* What sign does this point have? */+            ysign = (input[63] & 1) + 2;+            /* For the current type (i) do we expect parsing to work? Handled all of compressed/uncompressed/hybrid. */+            xpass = xvalid && (pubkeyclen == 33) && ((i & 254) == 2);+            /* Do we expect a parse and re-serialize as uncompressed to give a matching y? */+            ypass = xvalid && yvalid && ((i & 4) == ((pubkeyclen == 65) << 2)) &&+                ((i == 4) || ((i & 251) == ysign)) && ((pubkeyclen == 33) || (pubkeyclen == 65));+            if (xpass || ypass) {+                /* These cases must parse. */+                unsigned char pubkeyo[65];+                size_t outl;+                memset(&pubkey, 0, sizeof(pubkey));+                VG_UNDEF(&pubkey, sizeof(pubkey));+                ecount = 0;+                CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1);+                VG_CHECK(&pubkey, sizeof(pubkey));+                outl = 65;+                VG_UNDEF(pubkeyo, 65);+                CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyo, &outl, &pubkey, SECP256K1_EC_COMPRESSED) == 1);+                VG_CHECK(pubkeyo, outl);+                CHECK(outl == 33);+                CHECK(memcmp(&pubkeyo[1], &pubkeyc[1], 32) == 0);+                CHECK((pubkeyclen != 33) || (pubkeyo[0] == pubkeyc[0]));+                if (ypass) {+                    /* This test isn't always done because we decode with alternative signs, so the y won't match. */+                    CHECK(pubkeyo[0] == ysign);+                    CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 1);+                    memset(&pubkey, 0, sizeof(pubkey));+                    VG_UNDEF(&pubkey, sizeof(pubkey));+                    secp256k1_pubkey_save(&pubkey, &ge);+                    VG_CHECK(&pubkey, sizeof(pubkey));+                    outl = 65;+                    VG_UNDEF(pubkeyo, 65);+                    CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyo, &outl, &pubkey, 0) == 1);+                    VG_CHECK(pubkeyo, outl);+                    CHECK(outl == 65);+                    CHECK(pubkeyo[0] == 4);+                    CHECK(memcmp(&pubkeyo[1], input, 64) == 0);+                }+                CHECK(ecount == 0);+            } else {+                /* These cases must fail to parse. */+                memset(&pubkey, 0xfe, sizeof(pubkey));+                ecount = 0;+                VG_UNDEF(&pubkey, sizeof(pubkey));+                CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 0);+                VG_CHECK(&pubkey, sizeof(pubkey));+                CHECK(ecount == 0);+                CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0);+                CHECK(ecount == 1);+            }+        }+    }+    secp256k1_context_set_illegal_callback(ctx, NULL, NULL);+}++void run_ec_pubkey_parse_test(void) {+#define SECP256K1_EC_PARSE_TEST_NVALID (12)+    const unsigned char valid[SECP256K1_EC_PARSE_TEST_NVALID][64] = {+        {+            /* Point with leading and trailing zeros in x and y serialization. */+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x52,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x64, 0xef, 0xa1, 0x7b, 0x77, 0x61, 0xe1, 0xe4, 0x27, 0x06, 0x98, 0x9f, 0xb4, 0x83,+            0xb8, 0xd2, 0xd4, 0x9b, 0xf7, 0x8f, 0xae, 0x98, 0x03, 0xf0, 0x99, 0xb8, 0x34, 0xed, 0xeb, 0x00+        },+        {+            /* Point with x equal to a 3rd root of unity.*/+            0x7a, 0xe9, 0x6a, 0x2b, 0x65, 0x7c, 0x07, 0x10, 0x6e, 0x64, 0x47, 0x9e, 0xac, 0x34, 0x34, 0xe9,+            0x9c, 0xf0, 0x49, 0x75, 0x12, 0xf5, 0x89, 0x95, 0xc1, 0x39, 0x6c, 0x28, 0x71, 0x95, 0x01, 0xee,+            0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14,+            0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee,+        },+        {+            /* Point with largest x. (1/2) */+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2c,+            0x0e, 0x99, 0x4b, 0x14, 0xea, 0x72, 0xf8, 0xc3, 0xeb, 0x95, 0xc7, 0x1e, 0xf6, 0x92, 0x57, 0x5e,+            0x77, 0x50, 0x58, 0x33, 0x2d, 0x7e, 0x52, 0xd0, 0x99, 0x5c, 0xf8, 0x03, 0x88, 0x71, 0xb6, 0x7d,+        },+        {+            /* Point with largest x. (2/2) */+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2c,+            0xf1, 0x66, 0xb4, 0xeb, 0x15, 0x8d, 0x07, 0x3c, 0x14, 0x6a, 0x38, 0xe1, 0x09, 0x6d, 0xa8, 0xa1,+            0x88, 0xaf, 0xa7, 0xcc, 0xd2, 0x81, 0xad, 0x2f, 0x66, 0xa3, 0x07, 0xfb, 0x77, 0x8e, 0x45, 0xb2,+        },+        {+            /* Point with smallest x. (1/2) */+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,+            0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14,+            0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee,+        },+        {+            /* Point with smallest x. (2/2) */+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,+            0xbd, 0xe7, 0x0d, 0xf5, 0x19, 0x39, 0xb9, 0x4c, 0x9c, 0x24, 0x97, 0x9f, 0xa7, 0xdd, 0x04, 0xeb,+            0xd9, 0xb3, 0x57, 0x2d, 0xa7, 0x80, 0x22, 0x90, 0x43, 0x8a, 0xf2, 0xa6, 0x81, 0x89, 0x54, 0x41,+        },+        {+            /* Point with largest y. (1/3) */+            0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6,+            0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e,+        },+        {+            /* Point with largest y. (2/3) */+            0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c,+            0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e,+        },+        {+            /* Point with largest y. (3/3) */+            0x14, 0x6d, 0x3b, 0x65, 0xad, 0xd9, 0xf5, 0x4c, 0xcc, 0xa2, 0x85, 0x33, 0xc8, 0x8e, 0x2c, 0xbc,+            0x63, 0xf7, 0x44, 0x3e, 0x16, 0x58, 0x78, 0x3a, 0xb4, 0x1f, 0x8e, 0xf9, 0x7c, 0x2a, 0x10, 0xb5,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e,+        },+        {+            /* Point with smallest y. (1/3) */+            0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6,+            0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,+        },+        {+            /* Point with smallest y. (2/3) */+            0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c,+            0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,+        },+        {+            /* Point with smallest y. (3/3) */+            0x14, 0x6d, 0x3b, 0x65, 0xad, 0xd9, 0xf5, 0x4c, 0xcc, 0xa2, 0x85, 0x33, 0xc8, 0x8e, 0x2c, 0xbc,+            0x63, 0xf7, 0x44, 0x3e, 0x16, 0x58, 0x78, 0x3a, 0xb4, 0x1f, 0x8e, 0xf9, 0x7c, 0x2a, 0x10, 0xb5,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01+        }+    };+#define SECP256K1_EC_PARSE_TEST_NXVALID (4)+    const unsigned char onlyxvalid[SECP256K1_EC_PARSE_TEST_NXVALID][64] = {+        {+            /* Valid if y overflow ignored (y = 1 mod p). (1/3) */+            0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6,+            0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30,+        },+        {+            /* Valid if y overflow ignored (y = 1 mod p). (2/3) */+            0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c,+            0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30,+        },+        {+            /* Valid if y overflow ignored (y = 1 mod p). (3/3)*/+            0x14, 0x6d, 0x3b, 0x65, 0xad, 0xd9, 0xf5, 0x4c, 0xcc, 0xa2, 0x85, 0x33, 0xc8, 0x8e, 0x2c, 0xbc,+            0x63, 0xf7, 0x44, 0x3e, 0x16, 0x58, 0x78, 0x3a, 0xb4, 0x1f, 0x8e, 0xf9, 0x7c, 0x2a, 0x10, 0xb5,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30,+        },+        {+            /* x on curve, y is from y^2 = x^3 + 8. */+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03+        }+    };+#define SECP256K1_EC_PARSE_TEST_NINVALID (7)+    const unsigned char invalid[SECP256K1_EC_PARSE_TEST_NINVALID][64] = {+        {+            /* x is third root of -8, y is -1 * (x^3+7); also on the curve for y^2 = x^3 + 9. */+            0x0a, 0x2d, 0x2b, 0xa9, 0x35, 0x07, 0xf1, 0xdf, 0x23, 0x37, 0x70, 0xc2, 0xa7, 0x97, 0x96, 0x2c,+            0xc6, 0x1f, 0x6d, 0x15, 0xda, 0x14, 0xec, 0xd4, 0x7d, 0x8d, 0x27, 0xae, 0x1c, 0xd5, 0xf8, 0x53,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,+        },+        {+            /* Valid if x overflow ignored (x = 1 mod p). */+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30,+            0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14,+            0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee,+        },+        {+            /* Valid if x overflow ignored (x = 1 mod p). */+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30,+            0xbd, 0xe7, 0x0d, 0xf5, 0x19, 0x39, 0xb9, 0x4c, 0x9c, 0x24, 0x97, 0x9f, 0xa7, 0xdd, 0x04, 0xeb,+            0xd9, 0xb3, 0x57, 0x2d, 0xa7, 0x80, 0x22, 0x90, 0x43, 0x8a, 0xf2, 0xa6, 0x81, 0x89, 0x54, 0x41,+        },+        {+            /* x is -1, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 5. */+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e,+            0xf4, 0x84, 0x14, 0x5c, 0xb0, 0x14, 0x9b, 0x82, 0x5d, 0xff, 0x41, 0x2f, 0xa0, 0x52, 0xa8, 0x3f,+            0xcb, 0x72, 0xdb, 0x61, 0xd5, 0x6f, 0x37, 0x70, 0xce, 0x06, 0x6b, 0x73, 0x49, 0xa2, 0xaa, 0x28,+        },+        {+            /* x is -1, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 5. */+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e,+            0x0b, 0x7b, 0xeb, 0xa3, 0x4f, 0xeb, 0x64, 0x7d, 0xa2, 0x00, 0xbe, 0xd0, 0x5f, 0xad, 0x57, 0xc0,+            0x34, 0x8d, 0x24, 0x9e, 0x2a, 0x90, 0xc8, 0x8f, 0x31, 0xf9, 0x94, 0x8b, 0xb6, 0x5d, 0x52, 0x07,+        },+        {+            /* x is zero, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 7. */+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x8f, 0x53, 0x7e, 0xef, 0xdf, 0xc1, 0x60, 0x6a, 0x07, 0x27, 0xcd, 0x69, 0xb4, 0xa7, 0x33, 0x3d,+            0x38, 0xed, 0x44, 0xe3, 0x93, 0x2a, 0x71, 0x79, 0xee, 0xcb, 0x4b, 0x6f, 0xba, 0x93, 0x60, 0xdc,+        },+        {+            /* x is zero, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 7. */+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x70, 0xac, 0x81, 0x10, 0x20, 0x3e, 0x9f, 0x95, 0xf8, 0xd8, 0x32, 0x96, 0x4b, 0x58, 0xcc, 0xc2,+            0xc7, 0x12, 0xbb, 0x1c, 0x6c, 0xd5, 0x8e, 0x86, 0x11, 0x34, 0xb4, 0x8f, 0x45, 0x6c, 0x9b, 0x53+        }+    };+    const unsigned char pubkeyc[66] = {+        /* Serialization of G. */+        0x04, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B,+        0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17,+        0x98, 0x48, 0x3A, 0xDA, 0x77, 0x26, 0xA3, 0xC4, 0x65, 0x5D, 0xA4, 0xFB, 0xFC, 0x0E, 0x11, 0x08,+        0xA8, 0xFD, 0x17, 0xB4, 0x48, 0xA6, 0x85, 0x54, 0x19, 0x9C, 0x47, 0xD0, 0x8F, 0xFB, 0x10, 0xD4,+        0xB8, 0x00+    };+    unsigned char shortkey[2];+    secp256k1_ge ge;+    secp256k1_pubkey pubkey;+    int32_t i;+    int32_t ecount;+    int32_t ecount2;+    ecount = 0;+    /* Nothing should be reading this far into pubkeyc. */+    VG_UNDEF(&pubkeyc[65], 1);+    secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount);+    /* Zero length claimed, fail, zeroize, no illegal arg error. */+    memset(&pubkey, 0xfe, sizeof(pubkey));+    ecount = 0;+    VG_UNDEF(shortkey, 2);+    VG_UNDEF(&pubkey, sizeof(pubkey));+    CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 0) == 0);+    VG_CHECK(&pubkey, sizeof(pubkey));+    CHECK(ecount == 0);+    CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0);+    CHECK(ecount == 1);+    /* Length one claimed, fail, zeroize, no illegal arg error. */+    for (i = 0; i < 256 ; i++) {+        memset(&pubkey, 0xfe, sizeof(pubkey));+        ecount = 0;+        shortkey[0] = i;+        VG_UNDEF(&shortkey[1], 1);+        VG_UNDEF(&pubkey, sizeof(pubkey));+        CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 1) == 0);+        VG_CHECK(&pubkey, sizeof(pubkey));+        CHECK(ecount == 0);+        CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0);+        CHECK(ecount == 1);+    }+    /* Length two claimed, fail, zeroize, no illegal arg error. */+    for (i = 0; i < 65536 ; i++) {+        memset(&pubkey, 0xfe, sizeof(pubkey));+        ecount = 0;+        shortkey[0] = i & 255;+        shortkey[1] = i >> 8;+        VG_UNDEF(&pubkey, sizeof(pubkey));+        CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 2) == 0);+        VG_CHECK(&pubkey, sizeof(pubkey));+        CHECK(ecount == 0);+        CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0);+        CHECK(ecount == 1);+    }+    memset(&pubkey, 0xfe, sizeof(pubkey));+    ecount = 0;+    VG_UNDEF(&pubkey, sizeof(pubkey));+    /* 33 bytes claimed on otherwise valid input starting with 0x04, fail, zeroize output, no illegal arg error. */+    CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 33) == 0);+    VG_CHECK(&pubkey, sizeof(pubkey));+    CHECK(ecount == 0);+    CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0);+    CHECK(ecount == 1);+    /* NULL pubkey, illegal arg error. Pubkey isn't rewritten before this step, since it's NULL into the parser. */+    CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, pubkeyc, 65) == 0);+    CHECK(ecount == 2);+    /* NULL input string. Illegal arg and zeroize output. */+    memset(&pubkey, 0xfe, sizeof(pubkey));+    ecount = 0;+    VG_UNDEF(&pubkey, sizeof(pubkey));+    CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, NULL, 65) == 0);+    VG_CHECK(&pubkey, sizeof(pubkey));+    CHECK(ecount == 1);+    CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0);+    CHECK(ecount == 2);+    /* 64 bytes claimed on input starting with 0x04, fail, zeroize output, no illegal arg error. */+    memset(&pubkey, 0xfe, sizeof(pubkey));+    ecount = 0;+    VG_UNDEF(&pubkey, sizeof(pubkey));+    CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 64) == 0);+    VG_CHECK(&pubkey, sizeof(pubkey));+    CHECK(ecount == 0);+    CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0);+    CHECK(ecount == 1);+    /* 66 bytes claimed, fail, zeroize output, no illegal arg error. */+    memset(&pubkey, 0xfe, sizeof(pubkey));+    ecount = 0;+    VG_UNDEF(&pubkey, sizeof(pubkey));+    CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 66) == 0);+    VG_CHECK(&pubkey, sizeof(pubkey));+    CHECK(ecount == 0);+    CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0);+    CHECK(ecount == 1);+    /* Valid parse. */+    memset(&pubkey, 0, sizeof(pubkey));+    ecount = 0;+    VG_UNDEF(&pubkey, sizeof(pubkey));+    CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 65) == 1);+    VG_CHECK(&pubkey, sizeof(pubkey));+    CHECK(ecount == 0);+    VG_UNDEF(&ge, sizeof(ge));+    CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 1);+    VG_CHECK(&ge.x, sizeof(ge.x));+    VG_CHECK(&ge.y, sizeof(ge.y));+    VG_CHECK(&ge.infinity, sizeof(ge.infinity));+    ge_equals_ge(&secp256k1_ge_const_g, &ge);+    CHECK(ecount == 0);+    /* Multiple illegal args. Should still set arg error only once. */+    ecount = 0;+    ecount2 = 11;+    CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, NULL, 65) == 0);+    CHECK(ecount == 1);+    /* Does the illegal arg callback actually change the behavior? */+    secp256k1_context_set_illegal_callback(ctx, uncounting_illegal_callback_fn, &ecount2);+    CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, NULL, 65) == 0);+    CHECK(ecount == 1);+    CHECK(ecount2 == 10);+    secp256k1_context_set_illegal_callback(ctx, NULL, NULL);+    /* Try a bunch of prefabbed points with all possible encodings. */+    for (i = 0; i < SECP256K1_EC_PARSE_TEST_NVALID; i++) {+        ec_pubkey_parse_pointtest(valid[i], 1, 1);+    }+    for (i = 0; i < SECP256K1_EC_PARSE_TEST_NXVALID; i++) {+        ec_pubkey_parse_pointtest(onlyxvalid[i], 1, 0);+    }+    for (i = 0; i < SECP256K1_EC_PARSE_TEST_NINVALID; i++) {+        ec_pubkey_parse_pointtest(invalid[i], 0, 0);+    }+}++void random_sign(secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *key, const secp256k1_scalar *msg, int *recid) {+    secp256k1_scalar nonce;+    do {+        random_scalar_order_test(&nonce);+    } while(!secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, sigr, sigs, key, msg, &nonce, recid));+}++void test_ecdsa_sign_verify(void) {+    secp256k1_gej pubj;+    secp256k1_ge pub;+    secp256k1_scalar one;+    secp256k1_scalar msg, key;+    secp256k1_scalar sigr, sigs;+    int recid;+    int getrec;+    random_scalar_order_test(&msg);+    random_scalar_order_test(&key);+    secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubj, &key);+    secp256k1_ge_set_gej(&pub, &pubj);+    getrec = secp256k1_rand_bits(1);+    random_sign(&sigr, &sigs, &key, &msg, getrec?&recid:NULL);+    if (getrec) {+        CHECK(recid >= 0 && recid < 4);+    }+    CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &pub, &msg));+    secp256k1_scalar_set_int(&one, 1);+    secp256k1_scalar_add(&msg, &msg, &one);+    CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &pub, &msg));+}++void run_ecdsa_sign_verify(void) {+    int i;+    for (i = 0; i < 10*count; i++) {+        test_ecdsa_sign_verify();+    }+}++/** Dummy nonce generation function that just uses a precomputed nonce, and fails if it is not accepted. Use only for testing. */+static int precomputed_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) {+    (void)msg32;+    (void)key32;+    (void)algo16;+    memcpy(nonce32, data, 32);+    return (counter == 0);+}++static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) {+   /* Dummy nonce generator that has a fatal error on the first counter value. */+   if (counter == 0) {+       return 0;+   }+   return nonce_function_rfc6979(nonce32, msg32, key32, algo16, data, counter - 1);+}++static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) {+   /* Dummy nonce generator that produces unacceptable nonces for the first several counter values. */+   if (counter < 3) {+       memset(nonce32, counter==0 ? 0 : 255, 32);+       if (counter == 2) {+           nonce32[31]--;+       }+       return 1;+   }+   if (counter < 5) {+       static const unsigned char order[] = {+           0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,+           0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,+           0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,+           0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41+       };+       memcpy(nonce32, order, 32);+       if (counter == 4) {+           nonce32[31]++;+       }+       return 1;+   }+   /* Retry rate of 6979 is negligible esp. as we only call this in determinstic tests. */+   /* If someone does fine a case where it retries for secp256k1, we'd like to know. */+   if (counter > 5) {+       return 0;+   }+   return nonce_function_rfc6979(nonce32, msg32, key32, algo16, data, counter - 5);+}++int is_empty_signature(const secp256k1_ecdsa_signature *sig) {+    static const unsigned char res[sizeof(secp256k1_ecdsa_signature)] = {0};+    return memcmp(sig, res, sizeof(secp256k1_ecdsa_signature)) == 0;+}++void test_ecdsa_end_to_end(void) {+    unsigned char extra[32] = {0x00};+    unsigned char privkey[32];+    unsigned char message[32];+    unsigned char privkey2[32];+    secp256k1_ecdsa_signature signature[6];+    secp256k1_scalar r, s;+    unsigned char sig[74];+    size_t siglen = 74;+    unsigned char pubkeyc[65];+    size_t pubkeyclen = 65;+    secp256k1_pubkey pubkey;+    unsigned char seckey[300];+    size_t seckeylen = 300;++    /* Generate a random key and message. */+    {+        secp256k1_scalar msg, key;+        random_scalar_order_test(&msg);+        random_scalar_order_test(&key);+        secp256k1_scalar_get_b32(privkey, &key);+        secp256k1_scalar_get_b32(message, &msg);+    }++    /* Construct and verify corresponding public key. */+    CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1);+    CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1);++    /* Verify exporting and importing public key. */+    CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyc, &pubkeyclen, &pubkey, secp256k1_rand_bits(1)) == 1);+    memset(&pubkey, 0, sizeof(pubkey));+    CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1);++    /* Verify private key import and export. */+    CHECK(secp256k1_ec_privkey_export(ctx, seckey, &seckeylen, privkey, secp256k1_rand_bits(1) == 1) ? SECP256K1_EC_COMPRESSED : 0);+    CHECK(secp256k1_ec_privkey_import(ctx, privkey2, seckey, seckeylen) == 1);+    CHECK(memcmp(privkey, privkey2, 32) == 0);++    /* Optionally tweak the keys using addition. */+    if (secp256k1_rand_int(3) == 0) {+        int ret1;+        int ret2;+        unsigned char rnd[32];+        secp256k1_pubkey pubkey2;+        secp256k1_rand256_test(rnd);+        ret1 = secp256k1_ec_privkey_tweak_add(ctx, privkey, rnd);+        ret2 = secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, rnd);+        CHECK(ret1 == ret2);+        if (ret1 == 0) {+            return;+        }+        CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, privkey) == 1);+        CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0);+    }++    /* Optionally tweak the keys using multiplication. */+    if (secp256k1_rand_int(3) == 0) {+        int ret1;+        int ret2;+        unsigned char rnd[32];+        secp256k1_pubkey pubkey2;+        secp256k1_rand256_test(rnd);+        ret1 = secp256k1_ec_privkey_tweak_mul(ctx, privkey, rnd);+        ret2 = secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, rnd);+        CHECK(ret1 == ret2);+        if (ret1 == 0) {+            return;+        }+        CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, privkey) == 1);+        CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0);+    }++    /* Sign. */+    CHECK(secp256k1_ecdsa_sign(ctx, &signature[0], message, privkey, NULL, NULL) == 1);+    CHECK(secp256k1_ecdsa_sign(ctx, &signature[4], message, privkey, NULL, NULL) == 1);+    CHECK(secp256k1_ecdsa_sign(ctx, &signature[1], message, privkey, NULL, extra) == 1);+    extra[31] = 1;+    CHECK(secp256k1_ecdsa_sign(ctx, &signature[2], message, privkey, NULL, extra) == 1);+    extra[31] = 0;+    extra[0] = 1;+    CHECK(secp256k1_ecdsa_sign(ctx, &signature[3], message, privkey, NULL, extra) == 1);+    CHECK(memcmp(&signature[0], &signature[4], sizeof(signature[0])) == 0);+    CHECK(memcmp(&signature[0], &signature[1], sizeof(signature[0])) != 0);+    CHECK(memcmp(&signature[0], &signature[2], sizeof(signature[0])) != 0);+    CHECK(memcmp(&signature[0], &signature[3], sizeof(signature[0])) != 0);+    CHECK(memcmp(&signature[1], &signature[2], sizeof(signature[0])) != 0);+    CHECK(memcmp(&signature[1], &signature[3], sizeof(signature[0])) != 0);+    CHECK(memcmp(&signature[2], &signature[3], sizeof(signature[0])) != 0);+    /* Verify. */+    CHECK(secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 1);+    CHECK(secp256k1_ecdsa_verify(ctx, &signature[1], message, &pubkey) == 1);+    CHECK(secp256k1_ecdsa_verify(ctx, &signature[2], message, &pubkey) == 1);+    CHECK(secp256k1_ecdsa_verify(ctx, &signature[3], message, &pubkey) == 1);+    /* Test lower-S form, malleate, verify and fail, test again, malleate again */+    CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[0]));+    secp256k1_ecdsa_signature_load(ctx, &r, &s, &signature[0]);+    secp256k1_scalar_negate(&s, &s);+    secp256k1_ecdsa_signature_save(&signature[5], &r, &s);+    CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 0);+    CHECK(secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5]));+    CHECK(secp256k1_ecdsa_signature_normalize(ctx, &signature[5], &signature[5]));+    CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5]));+    CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 1);+    secp256k1_scalar_negate(&s, &s);+    secp256k1_ecdsa_signature_save(&signature[5], &r, &s);+    CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5]));+    CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 1);+    CHECK(memcmp(&signature[5], &signature[0], 64) == 0);++    /* Serialize/parse DER and verify again */+    CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature[0]) == 1);+    memset(&signature[0], 0, sizeof(signature[0]));+    CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature[0], sig, siglen) == 1);+    CHECK(secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 1);+    /* Serialize/destroy/parse DER and verify again. */+    siglen = 74;+    CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature[0]) == 1);+    sig[secp256k1_rand_int(siglen)] += 1 + secp256k1_rand_int(255);+    CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature[0], sig, siglen) == 0 ||+          secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 0);+}++void test_random_pubkeys(void) {+    secp256k1_ge elem;+    secp256k1_ge elem2;+    unsigned char in[65];+    /* Generate some randomly sized pubkeys. */+    size_t len = secp256k1_rand_bits(2) == 0 ? 65 : 33;+    if (secp256k1_rand_bits(2) == 0) {+        len = secp256k1_rand_bits(6);+    }+    if (len == 65) {+      in[0] = secp256k1_rand_bits(1) ? 4 : (secp256k1_rand_bits(1) ? 6 : 7);+    } else {+      in[0] = secp256k1_rand_bits(1) ? 2 : 3;+    }+    if (secp256k1_rand_bits(3) == 0) {+        in[0] = secp256k1_rand_bits(8);+    }+    if (len > 1) {+        secp256k1_rand256(&in[1]);+    }+    if (len > 33) {+        secp256k1_rand256(&in[33]);+    }+    if (secp256k1_eckey_pubkey_parse(&elem, in, len)) {+        unsigned char out[65];+        unsigned char firstb;+        int res;+        size_t size = len;+        firstb = in[0];+        /* If the pubkey can be parsed, it should round-trip... */+        CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, (len == 33) ? SECP256K1_EC_COMPRESSED : 0));+        CHECK(size == len);+        CHECK(memcmp(&in[1], &out[1], len-1) == 0);+        /* ... except for the type of hybrid inputs. */+        if ((in[0] != 6) && (in[0] != 7)) {+            CHECK(in[0] == out[0]);+        }+        size = 65;+        CHECK(secp256k1_eckey_pubkey_serialize(&elem, in, &size, 0));+        CHECK(size == 65);+        CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size));+        ge_equals_ge(&elem,&elem2);+        /* Check that the X9.62 hybrid type is checked. */+        in[0] = secp256k1_rand_bits(1) ? 6 : 7;+        res = secp256k1_eckey_pubkey_parse(&elem2, in, size);+        if (firstb == 2 || firstb == 3) {+            if (in[0] == firstb + 4) {+              CHECK(res);+            } else {+              CHECK(!res);+            }+        }+        if (res) {+            ge_equals_ge(&elem,&elem2);+            CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, 0));+            CHECK(memcmp(&in[1], &out[1], 64) == 0);+        }+    }+}++void run_random_pubkeys(void) {+    int i;+    for (i = 0; i < 10*count; i++) {+        test_random_pubkeys();+    }+}++void run_ecdsa_end_to_end(void) {+    int i;+    for (i = 0; i < 64*count; i++) {+        test_ecdsa_end_to_end();+    }+}++int test_ecdsa_der_parse(const unsigned char *sig, size_t siglen, int certainly_der, int certainly_not_der) {+    static const unsigned char zeroes[32] = {0};+    static const unsigned char max_scalar[32] = {+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,+        0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,+        0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40+    };++    int ret = 0;++    secp256k1_ecdsa_signature sig_der;+    unsigned char roundtrip_der[2048];+    unsigned char compact_der[64];+    size_t len_der = 2048;+    int parsed_der = 0, valid_der = 0, roundtrips_der = 0;++    secp256k1_ecdsa_signature sig_der_lax;+    unsigned char roundtrip_der_lax[2048];+    unsigned char compact_der_lax[64];+    size_t len_der_lax = 2048;+    int parsed_der_lax = 0, valid_der_lax = 0, roundtrips_der_lax = 0;++#ifdef ENABLE_OPENSSL_TESTS+    ECDSA_SIG *sig_openssl;+    const unsigned char *sigptr;+    unsigned char roundtrip_openssl[2048];+    int len_openssl = 2048;+    int parsed_openssl, valid_openssl = 0, roundtrips_openssl = 0;+#endif++    parsed_der = secp256k1_ecdsa_signature_parse_der(ctx, &sig_der, sig, siglen);+    if (parsed_der) {+        ret |= (!secp256k1_ecdsa_signature_serialize_compact(ctx, compact_der, &sig_der)) << 0;+        valid_der = (memcmp(compact_der, zeroes, 32) != 0) && (memcmp(compact_der + 32, zeroes, 32) != 0);+    }+    if (valid_der) {+        ret |= (!secp256k1_ecdsa_signature_serialize_der(ctx, roundtrip_der, &len_der, &sig_der)) << 1;+        roundtrips_der = (len_der == siglen) && memcmp(roundtrip_der, sig, siglen) == 0;+    }++    parsed_der_lax = secp256k1_ecdsa_signature_parse_der_lax(ctx, &sig_der_lax, sig, siglen);+    if (parsed_der_lax) {+        ret |= (!secp256k1_ecdsa_signature_serialize_compact(ctx, compact_der_lax, &sig_der_lax)) << 10;+        valid_der_lax = (memcmp(compact_der_lax, zeroes, 32) != 0) && (memcmp(compact_der_lax + 32, zeroes, 32) != 0);+    }+    if (valid_der_lax) {+        ret |= (!secp256k1_ecdsa_signature_serialize_der(ctx, roundtrip_der_lax, &len_der_lax, &sig_der_lax)) << 11;+        roundtrips_der_lax = (len_der_lax == siglen) && memcmp(roundtrip_der_lax, sig, siglen) == 0;+    }++    if (certainly_der) {+        ret |= (!parsed_der) << 2;+    }+    if (certainly_not_der) {+        ret |= (parsed_der) << 17;+    }+    if (valid_der) {+        ret |= (!roundtrips_der) << 3;+    }++    if (valid_der) {+        ret |= (!roundtrips_der_lax) << 12;+        ret |= (len_der != len_der_lax) << 13;+        ret |= (memcmp(roundtrip_der_lax, roundtrip_der, len_der) != 0) << 14;+    }+    ret |= (roundtrips_der != roundtrips_der_lax) << 15;+    if (parsed_der) {+        ret |= (!parsed_der_lax) << 16;+    }++#ifdef ENABLE_OPENSSL_TESTS+    sig_openssl = ECDSA_SIG_new();+    sigptr = sig;+    parsed_openssl = (d2i_ECDSA_SIG(&sig_openssl, &sigptr, siglen) != NULL);+    if (parsed_openssl) {+        valid_openssl = !BN_is_negative(sig_openssl->r) && !BN_is_negative(sig_openssl->s) && BN_num_bits(sig_openssl->r) > 0 && BN_num_bits(sig_openssl->r) <= 256 && BN_num_bits(sig_openssl->s) > 0 && BN_num_bits(sig_openssl->s) <= 256;+        if (valid_openssl) {+            unsigned char tmp[32] = {0};+            BN_bn2bin(sig_openssl->r, tmp + 32 - BN_num_bytes(sig_openssl->r));+            valid_openssl = memcmp(tmp, max_scalar, 32) < 0;+        }+        if (valid_openssl) {+            unsigned char tmp[32] = {0};+            BN_bn2bin(sig_openssl->s, tmp + 32 - BN_num_bytes(sig_openssl->s));+            valid_openssl = memcmp(tmp, max_scalar, 32) < 0;+        }+    }+    len_openssl = i2d_ECDSA_SIG(sig_openssl, NULL);+    if (len_openssl <= 2048) {+        unsigned char *ptr = roundtrip_openssl;+        CHECK(i2d_ECDSA_SIG(sig_openssl, &ptr) == len_openssl);+        roundtrips_openssl = valid_openssl && ((size_t)len_openssl == siglen) && (memcmp(roundtrip_openssl, sig, siglen) == 0);+    } else {+        len_openssl = 0;+    }+    ECDSA_SIG_free(sig_openssl);++    ret |= (parsed_der && !parsed_openssl) << 4;+    ret |= (valid_der && !valid_openssl) << 5;+    ret |= (roundtrips_openssl && !parsed_der) << 6;+    ret |= (roundtrips_der != roundtrips_openssl) << 7;+    if (roundtrips_openssl) {+        ret |= (len_der != (size_t)len_openssl) << 8;+        ret |= (memcmp(roundtrip_der, roundtrip_openssl, len_der) != 0) << 9;+    }+#endif+    return ret;+}++static void assign_big_endian(unsigned char *ptr, size_t ptrlen, uint32_t val) {+    size_t i;+    for (i = 0; i < ptrlen; i++) {+        int shift = ptrlen - 1 - i;+        if (shift >= 4) {+            ptr[i] = 0;+        } else {+            ptr[i] = (val >> shift) & 0xFF;+        }+    }+}++static void damage_array(unsigned char *sig, size_t *len) {+    int pos;+    int action = secp256k1_rand_bits(3);+    if (action < 1) {+        /* Delete a byte. */+        pos = secp256k1_rand_int(*len);+        memmove(sig + pos, sig + pos + 1, *len - pos - 1);+        (*len)--;+        return;+    } else if (action < 2) {+        /* Insert a byte. */+        pos = secp256k1_rand_int(1 + *len);+        memmove(sig + pos + 1, sig + pos, *len - pos);+        sig[pos] = secp256k1_rand_bits(8);+        (*len)++;+        return;+    } else if (action < 4) {+        /* Modify a byte. */+        sig[secp256k1_rand_int(*len)] += 1 + secp256k1_rand_int(255);+        return;+    } else { /* action < 8 */+        /* Modify a bit. */+        sig[secp256k1_rand_int(*len)] ^= 1 << secp256k1_rand_bits(3);+        return;+    }+}++static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly_der, int* certainly_not_der) {+    int der;+    int nlow[2], nlen[2], nlenlen[2], nhbit[2], nhbyte[2], nzlen[2];+    size_t tlen, elen, glen;+    int indet;+    int n;++    *len = 0;+    der = secp256k1_rand_bits(2) == 0;+    *certainly_der = der;+    *certainly_not_der = 0;+    indet = der ? 0 : secp256k1_rand_int(10) == 0;++    for (n = 0; n < 2; n++) {+        /* We generate two classes of numbers: nlow==1 "low" ones (up to 32 bytes), nlow==0 "high" ones (32 bytes with 129 top bits set, or larger than 32 bytes) */+        nlow[n] = der ? 1 : (secp256k1_rand_bits(3) != 0);+        /* The length of the number in bytes (the first byte of which will always be nonzero) */+        nlen[n] = nlow[n] ? secp256k1_rand_int(33) : 32 + secp256k1_rand_int(200) * secp256k1_rand_int(8) / 8;+        CHECK(nlen[n] <= 232);+        /* The top bit of the number. */+        nhbit[n] = (nlow[n] == 0 && nlen[n] == 32) ? 1 : (nlen[n] == 0 ? 0 : secp256k1_rand_bits(1));+        /* The top byte of the number (after the potential hardcoded 16 0xFF characters for "high" 32 bytes numbers) */+        nhbyte[n] = nlen[n] == 0 ? 0 : (nhbit[n] ? 128 + secp256k1_rand_bits(7) : 1 + secp256k1_rand_int(127));+        /* The number of zero bytes in front of the number (which is 0 or 1 in case of DER, otherwise we extend up to 300 bytes) */+        nzlen[n] = der ? ((nlen[n] == 0 || nhbit[n]) ? 1 : 0) : (nlow[n] ? secp256k1_rand_int(3) : secp256k1_rand_int(300 - nlen[n]) * secp256k1_rand_int(8) / 8);+        if (nzlen[n] > ((nlen[n] == 0 || nhbit[n]) ? 1 : 0)) {+            *certainly_not_der = 1;+        }+        CHECK(nlen[n] + nzlen[n] <= 300);+        /* The length of the length descriptor for the number. 0 means short encoding, anything else is long encoding. */+        nlenlen[n] = nlen[n] + nzlen[n] < 128 ? 0 : (nlen[n] + nzlen[n] < 256 ? 1 : 2);+        if (!der) {+            /* nlenlen[n] max 127 bytes */+            int add = secp256k1_rand_int(127 - nlenlen[n]) * secp256k1_rand_int(16) * secp256k1_rand_int(16) / 256;+            nlenlen[n] += add;+            if (add != 0) {+                *certainly_not_der = 1;+            }+        }+        CHECK(nlen[n] + nzlen[n] + nlenlen[n] <= 427);+    }++    /* The total length of the data to go, so far */+    tlen = 2 + nlenlen[0] + nlen[0] + nzlen[0] + 2 + nlenlen[1] + nlen[1] + nzlen[1];+    CHECK(tlen <= 856);++    /* The length of the garbage inside the tuple. */+    elen = (der || indet) ? 0 : secp256k1_rand_int(980 - tlen) * secp256k1_rand_int(8) / 8;+    if (elen != 0) {+        *certainly_not_der = 1;+    }+    tlen += elen;+    CHECK(tlen <= 980);++    /* The length of the garbage after the end of the tuple. */+    glen = der ? 0 : secp256k1_rand_int(990 - tlen) * secp256k1_rand_int(8) / 8;+    if (glen != 0) {+        *certainly_not_der = 1;+    }+    CHECK(tlen + glen <= 990);++    /* Write the tuple header. */+    sig[(*len)++] = 0x30;+    if (indet) {+        /* Indeterminate length */+        sig[(*len)++] = 0x80;+        *certainly_not_der = 1;+    } else {+        int tlenlen = tlen < 128 ? 0 : (tlen < 256 ? 1 : 2);+        if (!der) {+            int add = secp256k1_rand_int(127 - tlenlen) * secp256k1_rand_int(16) * secp256k1_rand_int(16) / 256;+            tlenlen += add;+            if (add != 0) {+                *certainly_not_der = 1;+            }+        }+        if (tlenlen == 0) {+            /* Short length notation */+            sig[(*len)++] = tlen;+        } else {+            /* Long length notation */+            sig[(*len)++] = 128 + tlenlen;+            assign_big_endian(sig + *len, tlenlen, tlen);+            *len += tlenlen;+        }+        tlen += tlenlen;+    }+    tlen += 2;+    CHECK(tlen + glen <= 1119);++    for (n = 0; n < 2; n++) {+        /* Write the integer header. */+        sig[(*len)++] = 0x02;+        if (nlenlen[n] == 0) {+            /* Short length notation */+            sig[(*len)++] = nlen[n] + nzlen[n];+        } else {+            /* Long length notation. */+            sig[(*len)++] = 128 + nlenlen[n];+            assign_big_endian(sig + *len, nlenlen[n], nlen[n] + nzlen[n]);+            *len += nlenlen[n];+        }+        /* Write zero padding */+        while (nzlen[n] > 0) {+            sig[(*len)++] = 0x00;+            nzlen[n]--;+        }+        if (nlen[n] == 32 && !nlow[n]) {+            /* Special extra 16 0xFF bytes in "high" 32-byte numbers */+            int i;+            for (i = 0; i < 16; i++) {+                sig[(*len)++] = 0xFF;+            }+            nlen[n] -= 16;+        }+        /* Write first byte of number */+        if (nlen[n] > 0) {+            sig[(*len)++] = nhbyte[n];+            nlen[n]--;+        }+        /* Generate remaining random bytes of number */+        secp256k1_rand_bytes_test(sig + *len, nlen[n]);+        *len += nlen[n];+        nlen[n] = 0;+    }++    /* Generate random garbage inside tuple. */+    secp256k1_rand_bytes_test(sig + *len, elen);+    *len += elen;++    /* Generate end-of-contents bytes. */+    if (indet) {+        sig[(*len)++] = 0;+        sig[(*len)++] = 0;+        tlen += 2;+    }+    CHECK(tlen + glen <= 1121);++    /* Generate random garbage outside tuple. */+    secp256k1_rand_bytes_test(sig + *len, glen);+    *len += glen;+    tlen += glen;+    CHECK(tlen <= 1121);+    CHECK(tlen == *len);+}++void run_ecdsa_der_parse(void) {+    int i,j;+    for (i = 0; i < 200 * count; i++) {+        unsigned char buffer[2048];+        size_t buflen = 0;+        int certainly_der = 0;+        int certainly_not_der = 0;+        random_ber_signature(buffer, &buflen, &certainly_der, &certainly_not_der);+        for (j = 0; j < 16; j++) {+            int ret = 0;+            if (j > 0) {+                damage_array(buffer, &buflen);+                /* We don't know anything anymore about the DERness of the result */+                certainly_der = 0;+                certainly_not_der = 0;+            }+            ret = test_ecdsa_der_parse(buffer, buflen, certainly_der, certainly_not_der);+            if (ret != 0) {+                size_t k;+                fprintf(stderr, "Failure %x on ", ret);+                for (k = 0; k < buflen; k++) {+                    fprintf(stderr, "%02x ", buffer[k]);+                }+                fprintf(stderr, "\n");+            }+            CHECK(ret == 0);+        }+    }+}+++/* Tests several edge cases. */+void test_ecdsa_edge_cases(void) {+    int t;+    secp256k1_ecdsa_signature sig;++    /* Test the case where ECDSA recomputes a point that is infinity. */+    {+        secp256k1_gej keyj;+        secp256k1_ge key;+        secp256k1_scalar msg;+        secp256k1_scalar sr, ss;+        secp256k1_scalar_set_int(&ss, 1);+        secp256k1_scalar_negate(&ss, &ss);+        secp256k1_scalar_inverse(&ss, &ss);+        secp256k1_scalar_set_int(&sr, 1);+        secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &keyj, &sr);+        secp256k1_ge_set_gej(&key, &keyj);+        msg = ss;+        CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0);+    }++    /*Signature where s would be zero.*/+    {+        unsigned char signature[72];+        size_t siglen;+        const unsigned char nonce[32] = {+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,+        };+        static const unsigned char nonce2[32] = {+            0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,+            0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,+            0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,+            0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40+        };+        const unsigned char key[32] = {+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,+        };+        unsigned char msg[32] = {+            0x86, 0x41, 0x99, 0x81, 0x06, 0x23, 0x44, 0x53,+            0xaa, 0x5f, 0x9d, 0x6a, 0x31, 0x78, 0xf4, 0xf7,+            0xb8, 0x12, 0xe0, 0x0b, 0x81, 0x7a, 0x77, 0x62,+            0x65, 0xdf, 0xdd, 0x31, 0xb9, 0x3e, 0x29, 0xa9,+        };+        CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce) == 0);+        CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce2) == 0);+        msg[31] = 0xaa;+        CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce) == 1);+        CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce2) == 1);+        siglen = 72;+        CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, &sig) == 1);+        siglen = 10;+        CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, &sig) == 0);+    }++    /* Nonce function corner cases. */+    for (t = 0; t < 2; t++) {+        static const unsigned char zero[32] = {0x00};+        int i;+        unsigned char key[32];+        unsigned char msg[32];+        secp256k1_ecdsa_signature sig2;+        secp256k1_scalar sr[512], ss;+        const unsigned char *extra;+        extra = t == 0 ? NULL : zero;+        memset(msg, 0, 32);+        msg[31] = 1;+        /* High key results in signature failure. */+        memset(key, 0xFF, 32);+        CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, NULL, extra) == 0);+        CHECK(is_empty_signature(&sig));+        /* Zero key results in signature failure. */+        memset(key, 0, 32);+        CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, NULL, extra) == 0);+        CHECK(is_empty_signature(&sig));+        /* Nonce function failure results in signature failure. */+        key[31] = 1;+        CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, nonce_function_test_fail, extra) == 0);+        CHECK(is_empty_signature(&sig));+        /* The retry loop successfully makes its way to the first good value. */+        CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, nonce_function_test_retry, extra) == 1);+        CHECK(!is_empty_signature(&sig));+        CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, nonce_function_rfc6979, extra) == 1);+        CHECK(!is_empty_signature(&sig2));+        CHECK(memcmp(&sig, &sig2, sizeof(sig)) == 0);+        /* The default nonce function is determinstic. */+        CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1);+        CHECK(!is_empty_signature(&sig2));+        CHECK(memcmp(&sig, &sig2, sizeof(sig)) == 0);+        /* The default nonce function changes output with different messages. */+        for(i = 0; i < 256; i++) {+            int j;+            msg[0] = i;+            CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1);+            CHECK(!is_empty_signature(&sig2));+            secp256k1_ecdsa_signature_load(ctx, &sr[i], &ss, &sig2);+            for (j = 0; j < i; j++) {+                CHECK(!secp256k1_scalar_eq(&sr[i], &sr[j]));+            }+        }+        msg[0] = 0;+        msg[31] = 2;+        /* The default nonce function changes output with different keys. */+        for(i = 256; i < 512; i++) {+            int j;+            key[0] = i - 256;+            CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1);+            CHECK(!is_empty_signature(&sig2));+            secp256k1_ecdsa_signature_load(ctx, &sr[i], &ss, &sig2);+            for (j = 0; j < i; j++) {+                CHECK(!secp256k1_scalar_eq(&sr[i], &sr[j]));+            }+        }+        key[0] = 0;+    }++    /* Privkey export where pubkey is the point at infinity. */+    {+        unsigned char privkey[300];+        unsigned char seckey[32] = {+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,+            0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,+            0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,+        };+        size_t outlen = 300;+        CHECK(!secp256k1_ec_privkey_export(ctx, privkey, &outlen, seckey, 0));+        outlen = 300;+        CHECK(!secp256k1_ec_privkey_export(ctx, privkey, &outlen, seckey, SECP256K1_EC_COMPRESSED));+    }+}++void run_ecdsa_edge_cases(void) {+    test_ecdsa_edge_cases();+}++#ifdef ENABLE_OPENSSL_TESTS+EC_KEY *get_openssl_key(const secp256k1_scalar *key) {+    unsigned char privkey[300];+    size_t privkeylen;+    const unsigned char* pbegin = privkey;+    int compr = secp256k1_rand_bits(1);+    EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1);+    CHECK(secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, &privkeylen, key, compr ? SECP256K1_EC_COMPRESSED : 0));+    CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen));+    CHECK(EC_KEY_check_key(ec_key));+    return ec_key;+}++void test_ecdsa_openssl(void) {+    secp256k1_gej qj;+    secp256k1_ge q;+    secp256k1_scalar sigr, sigs;+    secp256k1_scalar one;+    secp256k1_scalar msg2;+    secp256k1_scalar key, msg;+    EC_KEY *ec_key;+    unsigned int sigsize = 80;+    size_t secp_sigsize = 80;+    unsigned char message[32];+    unsigned char signature[80];+    secp256k1_rand256_test(message);+    secp256k1_scalar_set_b32(&msg, message, NULL);+    random_scalar_order_test(&key);+    secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &qj, &key);+    secp256k1_ge_set_gej(&q, &qj);+    ec_key = get_openssl_key(&key);+    CHECK(ec_key != NULL);+    CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key));+    CHECK(secp256k1_ecdsa_sig_parse(&sigr, &sigs, signature, sigsize));+    CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &q, &msg));+    secp256k1_scalar_set_int(&one, 1);+    secp256k1_scalar_add(&msg2, &msg, &one);+    CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &q, &msg2));++    random_sign(&sigr, &sigs, &key, &msg, NULL);+    CHECK(secp256k1_ecdsa_sig_serialize(signature, &secp_sigsize, &sigr, &sigs));+    CHECK(ECDSA_verify(0, message, sizeof(message), signature, secp_sigsize, ec_key) == 1);++    EC_KEY_free(ec_key);+}++void run_ecdsa_openssl(void) {+    int i;+    for (i = 0; i < 10*count; i++) {+        test_ecdsa_openssl();+    }+}+#endif++#ifdef ENABLE_MODULE_ECDH+# include "modules/ecdh/tests_impl.h"+#endif++#ifdef ENABLE_MODULE_SCHNORR+# include "modules/schnorr/tests_impl.h"+#endif++#ifdef ENABLE_MODULE_RECOVERY+# include "modules/recovery/tests_impl.h"+#endif++int main(int argc, char **argv) {+    unsigned char seed16[16] = {0};+    unsigned char run32[32] = {0};+    /* find iteration count */+    if (argc > 1) {+        count = strtol(argv[1], NULL, 0);+    }++    /* find random seed */+    if (argc > 2) {+        int pos = 0;+        const char* ch = argv[2];+        while (pos < 16 && ch[0] != 0 && ch[1] != 0) {+            unsigned short sh;+            if (sscanf(ch, "%2hx", &sh)) {+                seed16[pos] = sh;+            } else {+                break;+            }+            ch += 2;+            pos++;+        }+    } else {+        FILE *frand = fopen("/dev/urandom", "r");+        if ((frand == NULL) || !fread(&seed16, sizeof(seed16), 1, frand)) {+            uint64_t t = time(NULL) * (uint64_t)1337;+            seed16[0] ^= t;+            seed16[1] ^= t >> 8;+            seed16[2] ^= t >> 16;+            seed16[3] ^= t >> 24;+            seed16[4] ^= t >> 32;+            seed16[5] ^= t >> 40;+            seed16[6] ^= t >> 48;+            seed16[7] ^= t >> 56;+        }+        fclose(frand);+    }+    secp256k1_rand_seed(seed16);++    printf("test count = %i\n", count);+    printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]);++    /* initialize */+    run_context_tests();+    ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);+    if (secp256k1_rand_bits(1)) {+        secp256k1_rand256(run32);+        CHECK(secp256k1_context_randomize(ctx, secp256k1_rand_bits(1) ? run32 : NULL));+    }++    run_rand_bits();+    run_rand_int();++    run_sha256_tests();+    run_hmac_sha256_tests();+    run_rfc6979_hmac_sha256_tests();++#ifndef USE_NUM_NONE+    /* num tests */+    run_num_smalltests();+#endif++    /* scalar tests */+    run_scalar_tests();++    /* field tests */+    run_field_inv();+    run_field_inv_var();+    run_field_inv_all_var();+    run_field_misc();+    run_field_convert();+    run_sqr();+    run_sqrt();++    /* group tests */+    run_ge();++    /* ecmult tests */+    run_wnaf();+    run_point_times_order();+    run_ecmult_chain();+    run_ecmult_constants();+    run_ecmult_gen_blind();+    run_ecmult_const_tests();+    run_ec_combine();++    /* endomorphism tests */+#ifdef USE_ENDOMORPHISM+    run_endomorphism_tests();+#endif++    /* EC point parser test*/+    run_ec_pubkey_parse_test();++#ifdef ENABLE_MODULE_ECDH+    /* ecdh tests */+    run_ecdh_tests();+#endif++    /* ecdsa tests */+    run_random_pubkeys();+    run_ecdsa_der_parse();+    run_ecdsa_sign_verify();+    run_ecdsa_end_to_end();+    run_ecdsa_edge_cases();+#ifdef ENABLE_OPENSSL_TESTS+    run_ecdsa_openssl();+#endif++#ifdef ENABLE_MODULE_SCHNORR+    /* Schnorr tests */+    run_schnorr_tests();+#endif++#ifdef ENABLE_MODULE_RECOVERY+    /* ECDSA pubkey recovery tests */+    run_recovery_tests();+#endif++    secp256k1_rand256(run32);+    printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]);++    /* shutdown */+    secp256k1_context_destroy(ctx);++    printf("no problems found\n");+    return 0;+}
+ stack.yaml view
@@ -0,0 +1,29 @@+# For more information, see: https://github.com/commercialhaskell/stack/blob/master/doc/yaml_configuration.md++# Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2)+resolver: lts-3.4++# Local packages, usually specified by relative directory name+packages:+- '.'++# Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3)+extra-deps: []++# Override default flag values for local packages and extra-deps+flags: {}++# Control whether we use the GHC we find on the path+# system-ghc: true++# Require a specific version of stack, using version ranges+# require-stack-version: -any # Default+# require-stack-version: >= 0.1.4.0++# Override the architecture used by stack, especially useful on Windows+# arch: i386+# arch: x86_64++# Extra directories used by stack for building+# extra-include-dirs: [/path/to/dir]+# extra-lib-dirs: [/path/to/dir]