From cb8f059724ea58cdf90e3a9637625aa2e60259c7 Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Mon, 11 Feb 2019 19:06:11 +0000 Subject: [PATCH] Add fixups from upstream schnorrsig PR f make helper functions static f hash noncedata into nonce in nonce_function_bipschnorr f expose nonce_function_bipschnorr f fix undefined behavior when shifting an int 31 places f add cplusplus ifdef to schnorrsig include file f hash complete pubkey into batch seed f chacha20 for bigendians f add schnorrsig to travis f show in configure if schnorrsig is enabled --- .travis.yml | 12 +++++----- configure.ac | 1 + include/secp256k1.h | 6 +++++ include/secp256k1_schnorrsig.h | 11 +++++++++ src/modules/schnorrsig/main_impl.h | 8 +++---- src/modules/schnorrsig/tests_impl.h | 2 +- src/scalar_4x64_impl.h | 19 +++++++--------- src/scalar_8x32_impl.h | 35 +++++++++++++---------------- src/secp256k1.c | 7 ++++-- 9 files changed, 58 insertions(+), 43 deletions(-) diff --git a/.travis.yml b/.travis.yml index a3307b44..dae95e40 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,22 +11,22 @@ cache: - src/java/guava/ env: global: - - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no RECOVERY=no EXPERIMENTAL=no JNI=no GENERATOR=no RANGEPROOF=no WHITELIST=no + - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no RECOVERY=no EXPERIMENTAL=no JNI=no GENERATOR=no RANGEPROOF=no WHITELIST=no SCHNORRSIG=no - GUAVA_URL=https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar GUAVA_JAR=src/java/guava/guava-18.0.jar matrix: - - SCALAR=32bit FIELD=32bit EXPERIMENTAL=yes RANGEPROOF=yes WHITELIST=yes GENERATOR=yes - - FIELD=64bit EXPERIMENTAL=yes RANGEPROOF=yes WHITELIST=yes GENERATOR=yes + - SCALAR=32bit FIELD=32bit EXPERIMENTAL=yes RANGEPROOF=yes WHITELIST=yes GENERATOR=yes SCHNORRSIG=yes + - FIELD=64bit EXPERIMENTAL=yes RANGEPROOF=yes WHITELIST=yes GENERATOR=yes SCHNORRSIG=yes - SCALAR=32bit RECOVERY=yes - SCALAR=32bit FIELD=32bit ECDH=yes EXPERIMENTAL=yes - SCALAR=64bit - FIELD=64bit RECOVERY=yes - FIELD=64bit ENDOMORPHISM=yes - - FIELD=64bit ENDOMORPHISM=yes ECDH=yes EXPERIMENTAL=yes + - FIELD=64bit ENDOMORPHISM=yes ECDH=yes EXPERIMENTAL=yes SCHNORRSIG=yes - FIELD=64bit ASM=x86_64 - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64 - FIELD=32bit ENDOMORPHISM=yes - BIGNUM=no - - BIGNUM=no ENDOMORPHISM=yes RECOVERY=yes EXPERIMENTAL=yes + - BIGNUM=no ENDOMORPHISM=yes RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes - BIGNUM=no STATICPRECOMPUTATION=no - BUILD=distcheck - EXTRAFLAGS=CPPFLAGS=-DDETERMINISTIC @@ -67,4 +67,4 @@ before_script: ./autogen.sh script: - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi - if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi - - ./configure --enable-experimental=$EXPERIMENTAL --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-recovery=$RECOVERY --enable-module-rangeproof=$RANGEPROOF --enable-module-whitelist=$WHITELIST --enable-module-generator=$GENERATOR --enable-jni=$JNI $EXTRAFLAGS $USE_HOST && make -j2 $BUILD + - ./configure --enable-experimental=$EXPERIMENTAL --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-recovery=$RECOVERY --enable-module-rangeproof=$RANGEPROOF --enable-module-whitelist=$WHITELIST --enable-module-generator=$GENERATOR --enable-module-schnorrsig=$SCHNORRSIG --enable-jni=$JNI $EXTRAFLAGS $USE_HOST && make -j2 $BUILD diff --git a/configure.ac b/configure.ac index 2ba2d749..73a34e4d 100644 --- a/configure.ac +++ b/configure.ac @@ -670,6 +670,7 @@ echo " with benchmarks = $use_benchmark" echo " with coverage = $enable_coverage" echo " module ecdh = $enable_module_ecdh" echo " module recovery = $enable_module_recovery" +echo " module schnorrsig = $enable_module_schnorrsig" echo echo " asm = $set_asm" echo " bignum = $set_bignum" diff --git a/include/secp256k1.h b/include/secp256k1.h index 3e90b1bc..5988b141 100644 --- a/include/secp256k1.h +++ b/include/secp256k1.h @@ -523,6 +523,12 @@ SECP256K1_API int secp256k1_ecdsa_signature_normalize( */ SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; +/** An implementation of the nonce generation function as defined in BIP-schnorr. + * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of + * extra entropy. + */ +SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_bipschnorr; + /** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */ SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_default; diff --git a/include/secp256k1_schnorrsig.h b/include/secp256k1_schnorrsig.h index e507c63f..4c0f263d 100644 --- a/include/secp256k1_schnorrsig.h +++ b/include/secp256k1_schnorrsig.h @@ -1,6 +1,12 @@ #ifndef SECP256K1_SCHNORRSIG_H #define SECP256K1_SCHNORRSIG_H +#include "secp256k1.h" + +#ifdef __cplusplus +extern "C" { +#endif + /** This module implements a variant of Schnorr signatures compliant with * BIP-schnorr * (https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr.mediawiki). @@ -115,4 +121,9 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify_batch const secp256k1_pubkey *const *pk, size_t n_sigs ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); + +#ifdef __cplusplus +} #endif + +#endif /* SECP256K1_SCHNORRSIG_H */ diff --git a/src/modules/schnorrsig/main_impl.h b/src/modules/schnorrsig/main_impl.h index bebb49fe..b20969cd 100644 --- a/src/modules/schnorrsig/main_impl.h +++ b/src/modules/schnorrsig/main_impl.h @@ -240,7 +240,7 @@ static int secp256k1_schnorrsig_verify_batch_ecmult_callback(secp256k1_scalar *s * pk: array of public keys, or NULL if there are no signatures * n_sigs: number of signatures in above arrays (must be 0 if they are NULL) */ -int secp256k1_schnorrsig_verify_batch_init_randomizer(const secp256k1_context *ctx, secp256k1_schnorrsig_verify_ecmult_context *ecmult_context, secp256k1_sha256 *sha, const secp256k1_schnorrsig *const *sig, const unsigned char *const *msg32, const secp256k1_pubkey *const *pk, size_t n_sigs) { +static int secp256k1_schnorrsig_verify_batch_init_randomizer(const secp256k1_context *ctx, secp256k1_schnorrsig_verify_ecmult_context *ecmult_context, secp256k1_sha256 *sha, const secp256k1_schnorrsig *const *sig, const unsigned char *const *msg32, const secp256k1_pubkey *const *pk, size_t n_sigs) { size_t i; if (n_sigs > 0) { @@ -255,7 +255,7 @@ int secp256k1_schnorrsig_verify_batch_init_randomizer(const secp256k1_context *c secp256k1_sha256_write(sha, sig[i]->data, 64); secp256k1_sha256_write(sha, msg32[i], 32); secp256k1_ec_pubkey_serialize(ctx, buf, &buflen, pk[i], SECP256K1_EC_COMPRESSED); - secp256k1_sha256_write(sha, buf, 32); + secp256k1_sha256_write(sha, buf, buflen); } ecmult_context->ctx = ctx; ecmult_context->sig = sig; @@ -276,7 +276,7 @@ int secp256k1_schnorrsig_verify_batch_init_randomizer(const secp256k1_context *c * sig: array of signatures, or NULL if there are no signatures * n_sigs: number of signatures in above array (must be 0 if they are NULL) */ -int secp256k1_schnorrsig_verify_batch_sum_s(secp256k1_scalar *s, unsigned char *chacha_seed, const secp256k1_schnorrsig *const *sig, size_t n_sigs) { +static int secp256k1_schnorrsig_verify_batch_sum_s(secp256k1_scalar *s, unsigned char *chacha_seed, const secp256k1_schnorrsig *const *sig, size_t n_sigs) { secp256k1_scalar randomizer_cache[2]; size_t i; @@ -316,7 +316,7 @@ int secp256k1_schnorrsig_verify_batch(const secp256k1_context *ctx, secp256k1_sc ARG_CHECK(n_sigs <= SIZE_MAX / 2); /* Check that n_sigs is less than 2^31 to ensure the same behavior of this function on 32-bit * and 64-bit platforms. */ - ARG_CHECK(n_sigs < (size_t)(1 << 31)); + ARG_CHECK(n_sigs < ((uint32_t)1 << 31)); secp256k1_sha256_initialize(&sha); if (!secp256k1_schnorrsig_verify_batch_init_randomizer(ctx, &ecmult_context, &sha, sig, msg32, pk, n_sigs)) { diff --git a/src/modules/schnorrsig/tests_impl.h b/src/modules/schnorrsig/tests_impl.h index e067058a..eaaa9e2a 100644 --- a/src/modules/schnorrsig/tests_impl.h +++ b/src/modules/schnorrsig/tests_impl.h @@ -119,7 +119,7 @@ void test_schnorrsig_api(secp256k1_scratch_space *scratch) { CHECK(ecount == 5); CHECK(secp256k1_schnorrsig_verify_batch(vrfy, scratch, &sigptr, &msgptr, &pkptr, (size_t)1 << (sizeof(size_t)*8-1)) == 0); CHECK(ecount == 6); - CHECK(secp256k1_schnorrsig_verify_batch(vrfy, scratch, &sigptr, &msgptr, &pkptr, 1 << 31) == 0); + CHECK(secp256k1_schnorrsig_verify_batch(vrfy, scratch, &sigptr, &msgptr, &pkptr, (uint32_t)1 << 31) == 0); CHECK(ecount == 7); secp256k1_context_destroy(none); diff --git a/src/scalar_4x64_impl.h b/src/scalar_4x64_impl.h index 0c4e7b93..4fe001a3 100644 --- a/src/scalar_4x64_impl.h +++ b/src/scalar_4x64_impl.h @@ -965,9 +965,7 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, #ifdef WORDS_BIGENDIAN #define LE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24)) -#define BE32(p) (p) #else -#define BE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24)) #define LE32(p) (p) #endif @@ -1026,14 +1024,14 @@ static void secp256k1_scalar_chacha20(secp256k1_scalar *r1, secp256k1_scalar *r2 x14 += 0; x15 += over_count; - r1->d[3] = LE32((uint64_t) x0) << 32 | LE32(x1); - r1->d[2] = LE32((uint64_t) x2) << 32 | LE32(x3); - r1->d[1] = LE32((uint64_t) x4) << 32 | LE32(x5); - r1->d[0] = LE32((uint64_t) x6) << 32 | LE32(x7); - r2->d[3] = LE32((uint64_t) x8) << 32 | LE32(x9); - r2->d[2] = LE32((uint64_t) x10) << 32 | LE32(x11); - r2->d[1] = LE32((uint64_t) x12) << 32 | LE32(x13); - r2->d[0] = LE32((uint64_t) x14) << 32 | LE32(x15); + r1->d[3] = (((uint64_t) x0) << 32) | x1; + r1->d[2] = (((uint64_t) x2) << 32) | x3; + r1->d[1] = (((uint64_t) x4) << 32) | x5; + r1->d[0] = (((uint64_t) x6) << 32) | x7; + r2->d[3] = (((uint64_t) x8) << 32) | x9; + r2->d[2] = (((uint64_t) x10) << 32) | x11; + r2->d[1] = (((uint64_t) x12) << 32) | x13; + r2->d[0] = (((uint64_t) x14) << 32) | x15; over1 = secp256k1_scalar_check_overflow(r1); over2 = secp256k1_scalar_check_overflow(r2); @@ -1043,7 +1041,6 @@ static void secp256k1_scalar_chacha20(secp256k1_scalar *r1, secp256k1_scalar *r2 #undef ROTL32 #undef QUARTERROUND -#undef BE32 #undef LE32 #endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/src/scalar_8x32_impl.h b/src/scalar_8x32_impl.h index 11fac6c2..c2d22230 100644 --- a/src/scalar_8x32_impl.h +++ b/src/scalar_8x32_impl.h @@ -740,9 +740,7 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, #ifdef WORDS_BIGENDIAN #define LE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24)) -#define BE32(p) (p) #else -#define BE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24)) #define LE32(p) (p) #endif @@ -801,22 +799,22 @@ static void secp256k1_scalar_chacha20(secp256k1_scalar *r1, secp256k1_scalar *r2 x14 += 0; x15 += over_count; - r1->d[7] = LE32(x0); - r1->d[6] = LE32(x1); - r1->d[5] = LE32(x2); - r1->d[4] = LE32(x3); - r1->d[3] = LE32(x4); - r1->d[2] = LE32(x5); - r1->d[1] = LE32(x6); - r1->d[0] = LE32(x7); - r2->d[7] = LE32(x8); - r2->d[6] = LE32(x9); - r2->d[5] = LE32(x10); - r2->d[4] = LE32(x11); - r2->d[3] = LE32(x12); - r2->d[2] = LE32(x13); - r2->d[1] = LE32(x14); - r2->d[0] = LE32(x15); + r1->d[7] = x0; + r1->d[6] = x1; + r1->d[5] = x2; + r1->d[4] = x3; + r1->d[3] = x4; + r1->d[2] = x5; + r1->d[1] = x6; + r1->d[0] = x7; + r2->d[7] = x8; + r2->d[6] = x9; + r2->d[5] = x10; + r2->d[4] = x11; + r2->d[3] = x12; + r2->d[2] = x13; + r2->d[1] = x14; + r2->d[0] = x15; over1 = secp256k1_scalar_check_overflow(r1); over2 = secp256k1_scalar_check_overflow(r2); @@ -826,7 +824,6 @@ static void secp256k1_scalar_chacha20(secp256k1_scalar *r1, secp256k1_scalar *r2 #undef ROTL32 #undef QUARTERROUND -#undef BE32 #undef LE32 #endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/src/secp256k1.c b/src/secp256k1.c index b4fb7716..471c4032 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -425,9 +425,8 @@ static SECP256K1_INLINE void buffer_append(unsigned char *buf, unsigned int *off /* This nonce function is described in BIP-schnorr * (https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr.mediawiki) */ -static int secp256k1_nonce_function_bipschnorr(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { +static int nonce_function_bipschnorr(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { secp256k1_sha256 sha; - (void) data; (void) counter; VERIFY_CHECK(counter == 0); @@ -440,6 +439,9 @@ static int secp256k1_nonce_function_bipschnorr(unsigned char *nonce32, const uns if (algo16 != NULL) { secp256k1_sha256_write(&sha, algo16, 16); } + if (data != NULL) { + secp256k1_sha256_write(&sha, data, 32); + } secp256k1_sha256_finalize(&sha, nonce32); return 1; } @@ -474,6 +476,7 @@ static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *m return 1; } +const secp256k1_nonce_function secp256k1_nonce_function_bipschnorr = nonce_function_bipschnorr; const secp256k1_nonce_function secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979; const secp256k1_nonce_function secp256k1_nonce_function_default = nonce_function_rfc6979;