Merge remote-tracking branch 'upstream/master' into temp-merge-835

This commit is contained in:
Jonas Nick
2020-11-05 20:21:38 +00:00
47 changed files with 1738 additions and 1067 deletions

View File

@@ -80,7 +80,7 @@ void test_ecdh_generator_basepoint(void) {
/* compute "explicitly" */
CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], SECP256K1_EC_UNCOMPRESSED) == 1);
/* compare */
CHECK(memcmp(output_ecdh, point_ser, 65) == 0);
CHECK(secp256k1_memcmp_var(output_ecdh, point_ser, 65) == 0);
/* compute using ECDH function with default hash function */
CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32, NULL, NULL) == 1);
@@ -90,7 +90,7 @@ void test_ecdh_generator_basepoint(void) {
secp256k1_sha256_write(&sha, point_ser, point_ser_len);
secp256k1_sha256_finalize(&sha, output_ser);
/* compare */
CHECK(memcmp(output_ecdh, output_ser, 32) == 0);
CHECK(secp256k1_memcmp_var(output_ecdh, output_ser, 32) == 0);
}
}

View File

@@ -1,3 +1,4 @@
include_HEADERS += include/secp256k1_extrakeys.h
noinst_HEADERS += src/modules/extrakeys/tests_impl.h
noinst_HEADERS += src/modules/extrakeys/tests_exhaustive_impl.h
noinst_HEADERS += src/modules/extrakeys/main_impl.h

View File

@@ -33,6 +33,9 @@ int secp256k1_xonly_pubkey_parse(const secp256k1_context* ctx, secp256k1_xonly_p
if (!secp256k1_ge_set_xo_var(&pk, &x, 0)) {
return 0;
}
if (!secp256k1_ge_is_in_correct_subgroup(&pk)) {
return 0;
}
secp256k1_xonly_pubkey_save(pubkey, &pk);
return 1;
}
@@ -121,7 +124,7 @@ int secp256k1_xonly_pubkey_tweak_add_check(const secp256k1_context* ctx, const u
secp256k1_fe_normalize_var(&pk.y);
secp256k1_fe_get_b32(pk_expected32, &pk.x);
return memcmp(&pk_expected32, tweaked_pubkey32, 32) == 0
return secp256k1_memcmp_var(&pk_expected32, tweaked_pubkey32, 32) == 0
&& secp256k1_fe_is_odd(&pk.y) == tweaked_pk_parity;
}
@@ -177,7 +180,7 @@ int secp256k1_keypair_create(const secp256k1_context* ctx, secp256k1_keypair *ke
ret = secp256k1_ec_pubkey_create_helper(&ctx->ecmult_gen_ctx, &sk, &pk, seckey32);
secp256k1_keypair_save(keypair, &sk, &pk);
memczero(keypair, sizeof(*keypair), !ret);
secp256k1_memczero(keypair, sizeof(*keypair), !ret);
secp256k1_scalar_clear(&sk);
return ret;

View File

@@ -0,0 +1,68 @@
/**********************************************************************
* Copyright (c) 2020 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#ifndef _SECP256K1_MODULE_EXTRAKEYS_TESTS_EXHAUSTIVE_
#define _SECP256K1_MODULE_EXTRAKEYS_TESTS_EXHAUSTIVE_
#include "src/modules/extrakeys/main_impl.h"
#include "include/secp256k1_extrakeys.h"
static void test_exhaustive_extrakeys(const secp256k1_context *ctx, const secp256k1_ge* group) {
secp256k1_keypair keypair[EXHAUSTIVE_TEST_ORDER - 1];
secp256k1_pubkey pubkey[EXHAUSTIVE_TEST_ORDER - 1];
secp256k1_xonly_pubkey xonly_pubkey[EXHAUSTIVE_TEST_ORDER - 1];
int parities[EXHAUSTIVE_TEST_ORDER - 1];
unsigned char xonly_pubkey_bytes[EXHAUSTIVE_TEST_ORDER - 1][32];
int i;
for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) {
secp256k1_fe fe;
secp256k1_scalar scalar_i;
unsigned char buf[33];
int parity;
secp256k1_scalar_set_int(&scalar_i, i);
secp256k1_scalar_get_b32(buf, &scalar_i);
/* Construct pubkey and keypair. */
CHECK(secp256k1_keypair_create(ctx, &keypair[i - 1], buf));
CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey[i - 1], buf));
/* Construct serialized xonly_pubkey from keypair. */
CHECK(secp256k1_keypair_xonly_pub(ctx, &xonly_pubkey[i - 1], &parities[i - 1], &keypair[i - 1]));
CHECK(secp256k1_xonly_pubkey_serialize(ctx, xonly_pubkey_bytes[i - 1], &xonly_pubkey[i - 1]));
/* Parse the xonly_pubkey back and verify it matches the previously serialized value. */
CHECK(secp256k1_xonly_pubkey_parse(ctx, &xonly_pubkey[i - 1], xonly_pubkey_bytes[i - 1]));
CHECK(secp256k1_xonly_pubkey_serialize(ctx, buf, &xonly_pubkey[i - 1]));
CHECK(secp256k1_memcmp_var(xonly_pubkey_bytes[i - 1], buf, 32) == 0);
/* Construct the xonly_pubkey from the pubkey, and verify it matches the same. */
CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pubkey[i - 1], &parity, &pubkey[i - 1]));
CHECK(parity == parities[i - 1]);
CHECK(secp256k1_xonly_pubkey_serialize(ctx, buf, &xonly_pubkey[i - 1]));
CHECK(secp256k1_memcmp_var(xonly_pubkey_bytes[i - 1], buf, 32) == 0);
/* Compare the xonly_pubkey bytes against the precomputed group. */
secp256k1_fe_set_b32(&fe, xonly_pubkey_bytes[i - 1]);
CHECK(secp256k1_fe_equal_var(&fe, &group[i].x));
/* Check the parity against the precomputed group. */
fe = group[i].y;
secp256k1_fe_normalize_var(&fe);
CHECK(secp256k1_fe_is_odd(&fe) == parities[i - 1]);
/* Verify that the higher half is identical to the lower half mirrored. */
if (i > EXHAUSTIVE_TEST_ORDER / 2) {
CHECK(secp256k1_memcmp_var(xonly_pubkey_bytes[i - 1], xonly_pubkey_bytes[EXHAUSTIVE_TEST_ORDER - i - 1], 32) == 0);
CHECK(parities[i - 1] == 1 - parities[EXHAUSTIVE_TEST_ORDER - i - 1]);
}
}
/* TODO: keypair/xonly_pubkey tweak tests */
}
#endif

View File

@@ -35,9 +35,9 @@ void test_xonly_pubkey(void) {
secp256k1_context *sign = api_test_context(SECP256K1_CONTEXT_SIGN, &ecount);
secp256k1_context *verify = api_test_context(SECP256K1_CONTEXT_VERIFY, &ecount);
secp256k1_rand256(sk);
secp256k1_testrand256(sk);
memset(ones32, 0xFF, 32);
secp256k1_rand256(xy_sk);
secp256k1_testrand256(xy_sk);
CHECK(secp256k1_ec_pubkey_create(sign, &pk, sk) == 1);
CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 1);
@@ -60,7 +60,7 @@ void test_xonly_pubkey(void) {
sk[0] = 1;
CHECK(secp256k1_ec_pubkey_create(ctx, &pk, sk) == 1);
CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, &pk_parity, &pk) == 1);
CHECK(memcmp(&pk, &xonly_pk, sizeof(pk)) == 0);
CHECK(secp256k1_memcmp_var(&pk, &xonly_pk, sizeof(pk)) == 0);
CHECK(pk_parity == 0);
/* Choose a secret key such that pubkey and xonly_pubkey are each others
@@ -68,7 +68,7 @@ void test_xonly_pubkey(void) {
sk[0] = 2;
CHECK(secp256k1_ec_pubkey_create(ctx, &pk, sk) == 1);
CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, &pk_parity, &pk) == 1);
CHECK(memcmp(&xonly_pk, &pk, sizeof(xonly_pk)) != 0);
CHECK(secp256k1_memcmp_var(&xonly_pk, &pk, sizeof(xonly_pk)) != 0);
CHECK(pk_parity == 1);
secp256k1_pubkey_load(ctx, &pk1, &pk);
secp256k1_pubkey_load(ctx, &pk2, (secp256k1_pubkey *) &xonly_pk);
@@ -81,7 +81,7 @@ void test_xonly_pubkey(void) {
CHECK(secp256k1_xonly_pubkey_serialize(none, NULL, &xonly_pk) == 0);
CHECK(ecount == 1);
CHECK(secp256k1_xonly_pubkey_serialize(none, buf32, NULL) == 0);
CHECK(memcmp(buf32, zeros64, 32) == 0);
CHECK(secp256k1_memcmp_var(buf32, zeros64, 32) == 0);
CHECK(ecount == 2);
{
/* A pubkey filled with 0s will fail to serialize due to pubkey_load
@@ -104,28 +104,28 @@ void test_xonly_pubkey(void) {
CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, NULL, &pk) == 1);
CHECK(secp256k1_xonly_pubkey_serialize(ctx, buf32, &xonly_pk) == 1);
CHECK(secp256k1_xonly_pubkey_parse(ctx, &xonly_pk_tmp, buf32) == 1);
CHECK(memcmp(&xonly_pk, &xonly_pk_tmp, sizeof(xonly_pk)) == 0);
CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(xonly_pk)) == 0);
/* Test parsing invalid field elements */
memset(&xonly_pk, 1, sizeof(xonly_pk));
/* Overflowing field element */
CHECK(secp256k1_xonly_pubkey_parse(none, &xonly_pk, ones32) == 0);
CHECK(memcmp(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
memset(&xonly_pk, 1, sizeof(xonly_pk));
/* There's no point with x-coordinate 0 on secp256k1 */
CHECK(secp256k1_xonly_pubkey_parse(none, &xonly_pk, zeros64) == 0);
CHECK(memcmp(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
/* If a random 32-byte string can not be parsed with ec_pubkey_parse
* (because interpreted as X coordinate it does not correspond to a point on
* the curve) then xonly_pubkey_parse should fail as well. */
for (i = 0; i < count; i++) {
unsigned char rand33[33];
secp256k1_rand256(&rand33[1]);
secp256k1_testrand256(&rand33[1]);
rand33[0] = SECP256K1_TAG_PUBKEY_EVEN;
if (!secp256k1_ec_pubkey_parse(ctx, &pk, rand33, 33)) {
memset(&xonly_pk, 1, sizeof(xonly_pk));
CHECK(secp256k1_xonly_pubkey_parse(ctx, &xonly_pk, &rand33[1]) == 0);
CHECK(memcmp(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
} else {
CHECK(secp256k1_xonly_pubkey_parse(ctx, &xonly_pk, &rand33[1]) == 1);
}
@@ -154,8 +154,8 @@ void test_xonly_pubkey_tweak(void) {
secp256k1_context *verify = api_test_context(SECP256K1_CONTEXT_VERIFY, &ecount);
memset(overflows, 0xff, sizeof(overflows));
secp256k1_rand256(tweak);
secp256k1_rand256(sk);
secp256k1_testrand256(tweak);
secp256k1_testrand256(sk);
CHECK(secp256k1_ec_pubkey_create(ctx, &internal_pk, sk) == 1);
CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
@@ -170,15 +170,15 @@ void test_xonly_pubkey_tweak(void) {
CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, NULL, tweak) == 0);
CHECK(ecount == 4);
/* NULL internal_xonly_pk zeroes the output_pk */
CHECK(memcmp(&output_pk, zeros64, sizeof(output_pk)) == 0);
CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, NULL) == 0);
CHECK(ecount == 5);
/* NULL tweak zeroes the output_pk */
CHECK(memcmp(&output_pk, zeros64, sizeof(output_pk)) == 0);
CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
/* Invalid tweak zeroes the output_pk */
CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, overflows) == 0);
CHECK(memcmp(&output_pk, zeros64, sizeof(output_pk)) == 0);
CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
/* A zero tweak is fine */
CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, zeros64) == 1);
@@ -193,16 +193,16 @@ void test_xonly_pubkey_tweak(void) {
secp256k1_scalar_get_b32(tweak, &scalar_tweak);
CHECK((secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, sk) == 0)
|| (secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 0));
CHECK(memcmp(&output_pk, zeros64, sizeof(output_pk)) == 0);
CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
}
/* Invalid pk with a valid tweak */
memset(&internal_xonly_pk, 0, sizeof(internal_xonly_pk));
secp256k1_rand256(tweak);
secp256k1_testrand256(tweak);
ecount = 0;
CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 0);
CHECK(ecount == 1);
CHECK(memcmp(&output_pk, zeros64, sizeof(output_pk)) == 0);
CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
secp256k1_context_destroy(none);
secp256k1_context_destroy(sign);
@@ -228,8 +228,8 @@ void test_xonly_pubkey_tweak_check(void) {
secp256k1_context *verify = api_test_context(SECP256K1_CONTEXT_VERIFY, &ecount);
memset(overflows, 0xff, sizeof(overflows));
secp256k1_rand256(tweak);
secp256k1_rand256(sk);
secp256k1_testrand256(tweak);
secp256k1_testrand256(sk);
CHECK(secp256k1_ec_pubkey_create(ctx, &internal_pk, sk) == 1);
CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
@@ -268,7 +268,7 @@ void test_xonly_pubkey_tweak_check(void) {
/* Overflowing tweak not allowed */
CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, output_pk32, pk_parity, &internal_xonly_pk, overflows) == 0);
CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &output_pk, &internal_xonly_pk, overflows) == 0);
CHECK(memcmp(&output_pk, zeros64, sizeof(output_pk)) == 0);
CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
CHECK(ecount == 5);
secp256k1_context_destroy(none);
@@ -287,7 +287,7 @@ void test_xonly_pubkey_tweak_recursive(void) {
unsigned char tweak[N_PUBKEYS - 1][32];
int i;
secp256k1_rand256(sk);
secp256k1_testrand256(sk);
CHECK(secp256k1_ec_pubkey_create(ctx, &pk[0], sk) == 1);
/* Add tweaks */
for (i = 0; i < N_PUBKEYS - 1; i++) {
@@ -327,51 +327,51 @@ void test_keypair(void) {
/* Test keypair_create */
ecount = 0;
secp256k1_rand256(sk);
secp256k1_testrand256(sk);
CHECK(secp256k1_keypair_create(none, &keypair, sk) == 0);
CHECK(memcmp(zeros96, &keypair, sizeof(keypair)) == 0);
CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
CHECK(ecount == 1);
CHECK(secp256k1_keypair_create(verify, &keypair, sk) == 0);
CHECK(memcmp(zeros96, &keypair, sizeof(keypair)) == 0);
CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
CHECK(ecount == 2);
CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
CHECK(secp256k1_keypair_create(sign, NULL, sk) == 0);
CHECK(ecount == 3);
CHECK(secp256k1_keypair_create(sign, &keypair, NULL) == 0);
CHECK(memcmp(zeros96, &keypair, sizeof(keypair)) == 0);
CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
CHECK(ecount == 4);
/* Invalid secret key */
CHECK(secp256k1_keypair_create(sign, &keypair, zeros96) == 0);
CHECK(memcmp(zeros96, &keypair, sizeof(keypair)) == 0);
CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
CHECK(secp256k1_keypair_create(sign, &keypair, overflows) == 0);
CHECK(memcmp(zeros96, &keypair, sizeof(keypair)) == 0);
CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
/* Test keypair_pub */
ecount = 0;
secp256k1_rand256(sk);
secp256k1_testrand256(sk);
CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
CHECK(secp256k1_keypair_pub(none, &pk, &keypair) == 1);
CHECK(secp256k1_keypair_pub(none, NULL, &keypair) == 0);
CHECK(ecount == 1);
CHECK(secp256k1_keypair_pub(none, &pk, NULL) == 0);
CHECK(ecount == 2);
CHECK(memcmp(zeros96, &pk, sizeof(pk)) == 0);
CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
/* Using an invalid keypair is fine for keypair_pub */
memset(&keypair, 0, sizeof(keypair));
CHECK(secp256k1_keypair_pub(none, &pk, &keypair) == 1);
CHECK(memcmp(zeros96, &pk, sizeof(pk)) == 0);
CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
/* keypair holds the same pubkey as pubkey_create */
CHECK(secp256k1_ec_pubkey_create(sign, &pk, sk) == 1);
CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
CHECK(secp256k1_keypair_pub(none, &pk_tmp, &keypair) == 1);
CHECK(memcmp(&pk, &pk_tmp, sizeof(pk)) == 0);
CHECK(secp256k1_memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0);
/** Test keypair_xonly_pub **/
ecount = 0;
secp256k1_rand256(sk);
secp256k1_testrand256(sk);
CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 1);
CHECK(secp256k1_keypair_xonly_pub(none, NULL, &pk_parity, &keypair) == 0);
@@ -379,13 +379,13 @@ void test_keypair(void) {
CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, NULL, &keypair) == 1);
CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, NULL) == 0);
CHECK(ecount == 2);
CHECK(memcmp(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
/* Using an invalid keypair will set the xonly_pk to 0 (first reset
* xonly_pk). */
CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 1);
memset(&keypair, 0, sizeof(keypair));
CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 0);
CHECK(memcmp(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
CHECK(ecount == 3);
/** keypair holds the same xonly pubkey as pubkey_create **/
@@ -393,7 +393,7 @@ void test_keypair(void) {
CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 1);
CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk_tmp, &pk_parity_tmp, &keypair) == 1);
CHECK(memcmp(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0);
CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0);
CHECK(pk_parity == pk_parity_tmp);
secp256k1_context_destroy(none);
@@ -414,8 +414,8 @@ void test_keypair_add(void) {
secp256k1_context *verify = api_test_context(SECP256K1_CONTEXT_VERIFY, &ecount);
CHECK(sizeof(zeros96) == sizeof(keypair));
secp256k1_rand256(sk);
secp256k1_rand256(tweak);
secp256k1_testrand256(sk);
secp256k1_testrand256(tweak);
memset(overflows, 0xFF, 32);
CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
@@ -429,12 +429,12 @@ void test_keypair_add(void) {
CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, NULL) == 0);
CHECK(ecount == 4);
/* This does not set the keypair to zeroes */
CHECK(memcmp(&keypair, zeros96, sizeof(keypair)) != 0);
CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) != 0);
/* Invalid tweak zeroes the keypair */
CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, overflows) == 0);
CHECK(memcmp(&keypair, zeros96, sizeof(keypair)) == 0);
CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
/* A zero tweak is fine */
CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
@@ -444,7 +444,7 @@ void test_keypair_add(void) {
for (i = 0; i < count; i++) {
secp256k1_scalar scalar_tweak;
secp256k1_keypair keypair_tmp;
secp256k1_rand256(sk);
secp256k1_testrand256(sk);
CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
memcpy(&keypair_tmp, &keypair, sizeof(keypair));
/* Because sk may be negated before adding, we need to try with tweak =
@@ -454,17 +454,17 @@ void test_keypair_add(void) {
secp256k1_scalar_get_b32(tweak, &scalar_tweak);
CHECK((secp256k1_keypair_xonly_tweak_add(ctx, &keypair, sk) == 0)
|| (secp256k1_keypair_xonly_tweak_add(ctx, &keypair_tmp, tweak) == 0));
CHECK(memcmp(&keypair, zeros96, sizeof(keypair)) == 0
|| memcmp(&keypair_tmp, zeros96, sizeof(keypair_tmp)) == 0);
CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0
|| secp256k1_memcmp_var(&keypair_tmp, zeros96, sizeof(keypair_tmp)) == 0);
}
/* Invalid keypair with a valid tweak */
memset(&keypair, 0, sizeof(keypair));
secp256k1_rand256(tweak);
secp256k1_testrand256(tweak);
ecount = 0;
CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
CHECK(ecount == 1);
CHECK(memcmp(&keypair, zeros96, sizeof(keypair)) == 0);
CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
/* Only seckey part of keypair invalid */
CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
memset(&keypair, 0, 32);
@@ -486,7 +486,7 @@ void test_keypair_add(void) {
unsigned char pk32[32];
int pk_parity;
secp256k1_rand256(tweak);
secp256k1_testrand256(tweak);
CHECK(secp256k1_keypair_xonly_pub(ctx, &internal_pk, NULL, &keypair) == 1);
CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, tweak) == 1);
CHECK(secp256k1_keypair_xonly_pub(ctx, &output_pk, &pk_parity, &keypair) == 1);
@@ -498,11 +498,11 @@ void test_keypair_add(void) {
/* Check that the resulting pubkey matches xonly_pubkey_tweak_add */
CHECK(secp256k1_keypair_pub(ctx, &output_pk_xy, &keypair) == 1);
CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &output_pk_expected, &internal_pk, tweak) == 1);
CHECK(memcmp(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
/* Check that the secret key in the keypair is tweaked correctly */
CHECK(secp256k1_ec_pubkey_create(ctx, &output_pk_expected, &keypair.data[0]) == 1);
CHECK(memcmp(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
}
secp256k1_context_destroy(none);
secp256k1_context_destroy(sign);

View File

@@ -33,8 +33,8 @@ void test_generator_api(void) {
secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount);
secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount);
secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount);
secp256k1_rand256(key);
secp256k1_rand256(blind);
secp256k1_testrand256(key);
secp256k1_testrand256(blind);
CHECK(secp256k1_generator_generate(none, &gen, key) == 1);
CHECK(ecount == 0);

View File

@@ -35,11 +35,11 @@ void musig_simple_test(secp256k1_scratch_space *scratch) {
secp256k1_musig_partial_signature partial_sig[2];
unsigned char final_sig[64];
secp256k1_rand256(session_id[0]);
secp256k1_rand256(session_id[1]);
secp256k1_rand256(sk[0]);
secp256k1_rand256(sk[1]);
secp256k1_rand256(msg);
secp256k1_testrand256(session_id[0]);
secp256k1_testrand256(session_id[1]);
secp256k1_testrand256(sk[0]);
secp256k1_testrand256(sk[1]);
secp256k1_testrand256(msg);
CHECK(secp256k1_xonly_pubkey_create(&pk[0], sk[0]) == 1);
CHECK(secp256k1_xonly_pubkey_create(&pk[1], sk[1]) == 1);
@@ -123,13 +123,13 @@ void musig_api_tests(secp256k1_scratch_space *scratch) {
* behavior */
memset(&pre_session_uninitialized, 0, sizeof(pre_session_uninitialized));
secp256k1_rand256(session_id[0]);
secp256k1_rand256(session_id[1]);
secp256k1_rand256(sk[0]);
secp256k1_rand256(sk[1]);
secp256k1_rand256(msg);
secp256k1_rand256(sec_adaptor);
secp256k1_rand256(tweak);
secp256k1_testrand256(session_id[0]);
secp256k1_testrand256(session_id[1]);
secp256k1_testrand256(sk[0]);
secp256k1_testrand256(sk[1]);
secp256k1_testrand256(msg);
secp256k1_testrand256(sec_adaptor);
secp256k1_testrand256(tweak);
CHECK(secp256k1_xonly_pubkey_create(&pk[0], sk[0]) == 1);
CHECK(secp256k1_xonly_pubkey_create(&pk[1], sk[1]) == 1);
@@ -459,7 +459,7 @@ int musig_state_machine_diff_signer_msghash_test(unsigned char *msghash, secp256
secp256k1_pubkey nonce;
/* Set up signers with different public keys */
secp256k1_rand256(sk_dummy);
secp256k1_testrand256(sk_dummy);
pks_tmp[0] = pks[0];
CHECK(secp256k1_xonly_pubkey_create(&pks_tmp[1], sk_dummy) == 1);
CHECK(secp256k1_musig_pubkey_combine(ctx, NULL, &combined_pk_tmp, &pre_session_tmp, pks_tmp, 2) == 1);
@@ -493,7 +493,7 @@ int musig_state_machine_diff_signers_combine_nonce_test(secp256k1_xonly_pubkey *
const unsigned char *ncs[2];
/* Initialize new signers */
secp256k1_rand256(session_id);
secp256k1_testrand256(session_id);
CHECK(secp256k1_musig_session_initialize(ctx, &session, signers, nonce_commitment, session_id, msg, combined_pk, pre_session, 2, 1, sk) == 1);
ncs[0] = nonce_commitment_other;
ncs[1] = nonce_commitment;
@@ -608,11 +608,11 @@ void musig_state_machine_tests(secp256k1_scratch_space *scratch) {
* reinitialize session and session_signer_data. */
for (i = 0; i < 2; i++) {
/* Setup */
secp256k1_rand256(session_id[0]);
secp256k1_rand256(session_id[1]);
secp256k1_rand256(sk[0]);
secp256k1_rand256(sk[1]);
secp256k1_rand256(msg);
secp256k1_testrand256(session_id[0]);
secp256k1_testrand256(session_id[1]);
secp256k1_testrand256(sk[0]);
secp256k1_testrand256(sk[1]);
secp256k1_testrand256(msg);
CHECK(secp256k1_xonly_pubkey_create(&pk[0], sk[0]) == 1);
CHECK(secp256k1_xonly_pubkey_create(&pk[1], sk[1]) == 1);
CHECK(secp256k1_musig_pubkey_combine(ctx, scratch, &combined_pk, &pre_session, pk, 2) == 1);
@@ -719,11 +719,11 @@ void scriptless_atomic_swap(secp256k1_scratch_space *scratch) {
const unsigned char msg32_b[32] = "this is the message blockchain b";
/* Step 1: key setup */
secp256k1_rand256(seckey_a[0]);
secp256k1_rand256(seckey_a[1]);
secp256k1_rand256(seckey_b[0]);
secp256k1_rand256(seckey_b[1]);
secp256k1_rand256(sec_adaptor);
secp256k1_testrand256(seckey_a[0]);
secp256k1_testrand256(seckey_a[1]);
secp256k1_testrand256(seckey_b[0]);
secp256k1_testrand256(seckey_b[1]);
secp256k1_testrand256(sec_adaptor);
CHECK(secp256k1_xonly_pubkey_create(&pk_a[0], seckey_a[0]));
CHECK(secp256k1_xonly_pubkey_create(&pk_a[1], seckey_a[1]));

View File

@@ -23,9 +23,9 @@ static void test_pedersen_api(const secp256k1_context *none, const secp256k1_con
unsigned char blind_out[32];
const unsigned char *blind_ptr = blind;
unsigned char *blind_out_ptr = blind_out;
uint64_t val = secp256k1_rand32();
uint64_t val = secp256k1_testrand32();
secp256k1_rand256(blind);
secp256k1_testrand256(blind);
CHECK(secp256k1_pedersen_commit(none, &commit, blind, val, secp256k1_generator_h) == 0);
CHECK(*ecount == 1);
CHECK(secp256k1_pedersen_commit(vrfy, &commit, blind, val, secp256k1_generator_h) == 0);
@@ -80,8 +80,8 @@ static void test_rangeproof_api(const secp256k1_context *none, const secp256k1_c
unsigned char proof[5134];
unsigned char blind[32];
secp256k1_pedersen_commitment commit;
uint64_t vmin = secp256k1_rand32();
uint64_t val = vmin + secp256k1_rand32();
uint64_t vmin = secp256k1_testrand32();
uint64_t val = vmin + secp256k1_testrand32();
size_t len = sizeof(proof);
/* we'll switch to dylan thomas for this one */
const unsigned char message[68] = "My tears are like the quiet drift / Of petals from some magic rose;";
@@ -89,7 +89,7 @@ static void test_rangeproof_api(const secp256k1_context *none, const secp256k1_c
const unsigned char ext_commit[72] = "And all my grief flows from the rift / Of unremembered skies and snows.";
size_t ext_commit_len = sizeof(ext_commit);
secp256k1_rand256(blind);
secp256k1_testrand256(blind);
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, val, secp256k1_generator_h));
CHECK(secp256k1_rangeproof_sign(none, proof, &len, vmin, &commit, blind, commit.data, 0, 0, val, message, mlen, ext_commit, ext_commit_len, secp256k1_generator_h) == 0);
@@ -271,8 +271,8 @@ static void test_pedersen(void) {
int inputs;
int outputs;
int total;
inputs = (secp256k1_rand32() & 7) + 1;
outputs = (secp256k1_rand32() & 7) + 2;
inputs = (secp256k1_testrand32() & 7) + 1;
outputs = (secp256k1_testrand32() & 7) + 2;
total = inputs + outputs;
for (i = 0; i < 19; i++) {
cptr[i] = &commits[i];
@@ -331,27 +331,27 @@ static void test_borromean(void) {
size_t i;
size_t j;
int c;
secp256k1_rand256_test(m);
nrings = 1 + (secp256k1_rand32()&7);
secp256k1_testrand256_test(m);
nrings = 1 + (secp256k1_testrand32()&7);
c = 0;
secp256k1_scalar_set_int(&one, 1);
if (secp256k1_rand32()&1) {
if (secp256k1_testrand32()&1) {
secp256k1_scalar_negate(&one, &one);
}
for (i = 0; i < nrings; i++) {
rsizes[i] = 1 + (secp256k1_rand32()&7);
secidx[i] = secp256k1_rand32() % rsizes[i];
rsizes[i] = 1 + (secp256k1_testrand32()&7);
secidx[i] = secp256k1_testrand32() % rsizes[i];
random_scalar_order(&sec[i]);
random_scalar_order(&k[i]);
if(secp256k1_rand32()&7) {
if(secp256k1_testrand32()&7) {
sec[i] = one;
}
if(secp256k1_rand32()&7) {
if(secp256k1_testrand32()&7) {
k[i] = one;
}
for (j = 0; j < rsizes[i]; j++) {
random_scalar_order(&s[c + j]);
if(secp256k1_rand32()&7) {
if(secp256k1_testrand32()&7) {
s[i] = one;
}
if (j == secidx[i]) {
@@ -365,14 +365,14 @@ static void test_borromean(void) {
}
CHECK(secp256k1_borromean_sign(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx, e0, s, pubs, k, sec, rsizes, secidx, nrings, m, 32));
CHECK(secp256k1_borromean_verify(&ctx->ecmult_ctx, NULL, e0, s, pubs, rsizes, nrings, m, 32));
i = secp256k1_rand32() % c;
i = secp256k1_testrand32() % c;
secp256k1_scalar_negate(&s[i],&s[i]);
CHECK(!secp256k1_borromean_verify(&ctx->ecmult_ctx, NULL, e0, s, pubs, rsizes, nrings, m, 32));
secp256k1_scalar_negate(&s[i],&s[i]);
secp256k1_scalar_set_int(&one, 1);
for(j = 0; j < 4; j++) {
i = secp256k1_rand32() % c;
if (secp256k1_rand32() & 1) {
i = secp256k1_testrand32() % c;
if (secp256k1_testrand32() & 1) {
secp256k1_gej_double_var(&pubs[i],&pubs[i], NULL);
} else {
secp256k1_scalar_add(&s[i],&s[i],&one);
@@ -408,7 +408,7 @@ static void test_rangeproof(void) {
memcpy(&message_long[i], message_short, sizeof(message_short));
}
secp256k1_rand256(blind);
secp256k1_testrand256(blind);
for (i = 0; i < 11; i++) {
v = testvs[i];
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v, secp256k1_generator_h));
@@ -464,7 +464,7 @@ static void test_rangeproof(void) {
CHECK(maxv == v);
}
}
secp256k1_rand256(blind);
secp256k1_testrand256(blind);
v = INT64_MAX - 1;
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v, secp256k1_generator_h));
for (i = 0; i < 19; i++) {
@@ -477,7 +477,7 @@ static void test_rangeproof(void) {
/* Make sure it fails when validating with a committed message */
CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len, message_short, sizeof(message_short), secp256k1_generator_h));
}
secp256k1_rand256(blind);
secp256k1_testrand256(blind);
{
/*Malleability test.*/
v = secp256k1_rands64(0, 255);
@@ -501,12 +501,12 @@ static void test_rangeproof(void) {
for (i = 0; i < (size_t) 2*count; i++) {
int exp;
int min_bits;
v = secp256k1_rands64(0, UINT64_MAX >> (secp256k1_rand32()&63));
v = secp256k1_rands64(0, UINT64_MAX >> (secp256k1_testrand32()&63));
vmin = 0;
if ((v < INT64_MAX) && (secp256k1_rand32()&1)) {
if ((v < INT64_MAX) && (secp256k1_testrand32()&1)) {
vmin = secp256k1_rands64(0, v);
}
secp256k1_rand256(blind);
secp256k1_testrand256(blind);
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v, secp256k1_generator_h));
len = 5134;
exp = (int)secp256k1_rands64(0,18)-(int)secp256k1_rands64(0,18);
@@ -534,7 +534,7 @@ static void test_rangeproof(void) {
}
for (j = 0; j < 5; j++) {
for (i = 0; i < 96; i++) {
secp256k1_rand256(&proof[i * 32]);
secp256k1_testrand256(&proof[i * 32]);
}
for (k = 0; k < 128; k++) {
len = k;
@@ -547,8 +547,8 @@ static void test_rangeproof(void) {
#define MAX_N_GENS 30
void test_multiple_generators(void) {
const size_t n_inputs = (secp256k1_rand32() % (MAX_N_GENS / 2)) + 1;
const size_t n_outputs = (secp256k1_rand32() % (MAX_N_GENS / 2)) + 1;
const size_t n_inputs = (secp256k1_testrand32() % (MAX_N_GENS / 2)) + 1;
const size_t n_outputs = (secp256k1_testrand32() % (MAX_N_GENS / 2)) + 1;
const size_t n_generators = n_inputs + n_outputs;
unsigned char *generator_blind[MAX_N_GENS];
unsigned char *pedersen_blind[MAX_N_GENS];

View File

@@ -1,6 +1,7 @@
include_HEADERS += include/secp256k1_recovery.h
noinst_HEADERS += src/modules/recovery/main_impl.h
noinst_HEADERS += src/modules/recovery/tests_impl.h
noinst_HEADERS += src/modules/recovery/tests_exhaustive_impl.h
if USE_BENCHMARK
noinst_PROGRAMS += bench_recover
bench_recover_SOURCES = src/bench_recover.c

View File

@@ -0,0 +1,149 @@
/**********************************************************************
* Copyright (c) 2016 Andrew Poelstra *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#ifndef SECP256K1_MODULE_RECOVERY_EXHAUSTIVE_TESTS_H
#define SECP256K1_MODULE_RECOVERY_EXHAUSTIVE_TESTS_H
#include "src/modules/recovery/main_impl.h"
#include "include/secp256k1_recovery.h"
void test_exhaustive_recovery_sign(const secp256k1_context *ctx, const secp256k1_ge *group) {
int i, j, k;
uint64_t iter = 0;
/* Loop */
for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { /* message */
for (j = 1; j < EXHAUSTIVE_TEST_ORDER; j++) { /* key */
if (skip_section(&iter)) continue;
for (k = 1; k < EXHAUSTIVE_TEST_ORDER; k++) { /* nonce */
const int starting_k = k;
secp256k1_fe r_dot_y_normalized;
secp256k1_ecdsa_recoverable_signature rsig;
secp256k1_ecdsa_signature sig;
secp256k1_scalar sk, msg, r, s, expected_r;
unsigned char sk32[32], msg32[32];
int expected_recid;
int recid;
int overflow;
secp256k1_scalar_set_int(&msg, i);
secp256k1_scalar_set_int(&sk, j);
secp256k1_scalar_get_b32(sk32, &sk);
secp256k1_scalar_get_b32(msg32, &msg);
secp256k1_ecdsa_sign_recoverable(ctx, &rsig, msg32, sk32, secp256k1_nonce_function_smallint, &k);
/* Check directly */
secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, &rsig);
r_from_k(&expected_r, group, k, &overflow);
CHECK(r == expected_r);
CHECK((k * s) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER ||
(k * (EXHAUSTIVE_TEST_ORDER - s)) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER);
/* The recid's second bit is for conveying overflow (R.x value >= group order).
* In the actual secp256k1 this is an astronomically unlikely event, but in the
* small group used here, it will be the case for all points except the ones where
* R.x=1 (which the group is specifically selected to have).
* Note that this isn't actually useful; full recovery would need to convey
* floor(R.x / group_order), but only one bit is used as that is sufficient
* in the real group. */
expected_recid = overflow ? 2 : 0;
r_dot_y_normalized = group[k].y;
secp256k1_fe_normalize(&r_dot_y_normalized);
/* Also the recovery id is flipped depending if we hit the low-s branch */
if ((k * s) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER) {
expected_recid |= secp256k1_fe_is_odd(&r_dot_y_normalized);
} else {
expected_recid |= !secp256k1_fe_is_odd(&r_dot_y_normalized);
}
CHECK(recid == expected_recid);
/* Convert to a standard sig then check */
secp256k1_ecdsa_recoverable_signature_convert(ctx, &sig, &rsig);
secp256k1_ecdsa_signature_load(ctx, &r, &s, &sig);
/* Note that we compute expected_r *after* signing -- this is important
* because our nonce-computing function function might change k during
* signing. */
r_from_k(&expected_r, group, k, NULL);
CHECK(r == expected_r);
CHECK((k * s) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER ||
(k * (EXHAUSTIVE_TEST_ORDER - s)) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER);
/* Overflow means we've tried every possible nonce */
if (k < starting_k) {
break;
}
}
}
}
}
void test_exhaustive_recovery_verify(const secp256k1_context *ctx, const secp256k1_ge *group) {
/* This is essentially a copy of test_exhaustive_verify, with recovery added */
int s, r, msg, key;
uint64_t iter = 0;
for (s = 1; s < EXHAUSTIVE_TEST_ORDER; s++) {
for (r = 1; r < EXHAUSTIVE_TEST_ORDER; r++) {
for (msg = 1; msg < EXHAUSTIVE_TEST_ORDER; msg++) {
for (key = 1; key < EXHAUSTIVE_TEST_ORDER; key++) {
secp256k1_ge nonconst_ge;
secp256k1_ecdsa_recoverable_signature rsig;
secp256k1_ecdsa_signature sig;
secp256k1_pubkey pk;
secp256k1_scalar sk_s, msg_s, r_s, s_s;
secp256k1_scalar s_times_k_s, msg_plus_r_times_sk_s;
int recid = 0;
int k, should_verify;
unsigned char msg32[32];
if (skip_section(&iter)) continue;
secp256k1_scalar_set_int(&s_s, s);
secp256k1_scalar_set_int(&r_s, r);
secp256k1_scalar_set_int(&msg_s, msg);
secp256k1_scalar_set_int(&sk_s, key);
secp256k1_scalar_get_b32(msg32, &msg_s);
/* Verify by hand */
/* Run through every k value that gives us this r and check that *one* works.
* Note there could be none, there could be multiple, ECDSA is weird. */
should_verify = 0;
for (k = 0; k < EXHAUSTIVE_TEST_ORDER; k++) {
secp256k1_scalar check_x_s;
r_from_k(&check_x_s, group, k, NULL);
if (r_s == check_x_s) {
secp256k1_scalar_set_int(&s_times_k_s, k);
secp256k1_scalar_mul(&s_times_k_s, &s_times_k_s, &s_s);
secp256k1_scalar_mul(&msg_plus_r_times_sk_s, &r_s, &sk_s);
secp256k1_scalar_add(&msg_plus_r_times_sk_s, &msg_plus_r_times_sk_s, &msg_s);
should_verify |= secp256k1_scalar_eq(&s_times_k_s, &msg_plus_r_times_sk_s);
}
}
/* nb we have a "high s" rule */
should_verify &= !secp256k1_scalar_is_high(&s_s);
/* We would like to try recovering the pubkey and checking that it matches,
* but pubkey recovery is impossible in the exhaustive tests (the reason
* being that there are 12 nonzero r values, 12 nonzero points, and no
* overlap between the sets, so there are no valid signatures). */
/* Verify by converting to a standard signature and calling verify */
secp256k1_ecdsa_recoverable_signature_save(&rsig, &r_s, &s_s, recid);
secp256k1_ecdsa_recoverable_signature_convert(ctx, &sig, &rsig);
memcpy(&nonconst_ge, &group[sk_s], sizeof(nonconst_ge));
secp256k1_pubkey_save(&pk, &nonconst_ge);
CHECK(should_verify ==
secp256k1_ecdsa_verify(ctx, &sig, msg32, &pk));
}
}
}
}
}
static void test_exhaustive_recovery(const secp256k1_context *ctx, const secp256k1_ge *group) {
test_exhaustive_recovery_sign(ctx, group);
test_exhaustive_recovery_verify(ctx, group);
}
#endif /* SECP256K1_MODULE_RECOVERY_EXHAUSTIVE_TESTS_H */

View File

@@ -25,7 +25,7 @@ static int recovery_test_nonce_function(unsigned char *nonce32, const unsigned c
}
/* On the next run, return a valid nonce, but flip a coin as to whether or not to fail signing. */
memset(nonce32, 1, 32);
return secp256k1_rand_bits(1);
return secp256k1_testrand_bits(1);
}
void test_ecdsa_recovery_api(void) {
@@ -184,7 +184,7 @@ void test_ecdsa_recovery_end_to_end(void) {
CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[3], message, privkey, NULL, extra) == 1);
CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1);
CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1);
CHECK(memcmp(&signature[4], &signature[0], 64) == 0);
CHECK(secp256k1_memcmp_var(&signature[4], &signature[0], 64) == 0);
CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1);
memset(&rsignature[4], 0, sizeof(rsignature[4]));
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1);
@@ -193,16 +193,16 @@ void test_ecdsa_recovery_end_to_end(void) {
/* Parse compact (with recovery id) and recover. */
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1);
CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 1);
CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0);
CHECK(secp256k1_memcmp_var(&pubkey, &recpubkey, sizeof(pubkey)) == 0);
/* Serialize/destroy/parse signature and verify again. */
CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1);
sig[secp256k1_rand_bits(6)] += 1 + secp256k1_rand_int(255);
sig[secp256k1_testrand_bits(6)] += 1 + secp256k1_testrand_int(255);
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1);
CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 0);
/* Recover again */
CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 0 ||
memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0);
secp256k1_memcmp_var(&pubkey, &recpubkey, sizeof(pubkey)) != 0);
}
/* Tests several edge cases. */

View File

@@ -1,6 +1,7 @@
include_HEADERS += include/secp256k1_schnorrsig.h
noinst_HEADERS += src/modules/schnorrsig/main_impl.h
noinst_HEADERS += src/modules/schnorrsig/tests_impl.h
noinst_HEADERS += src/modules/schnorrsig/tests_exhaustive_impl.h
if USE_BENCHMARK
noinst_PROGRAMS += bench_schnorrsig
bench_schnorrsig_SOURCES = src/bench_schnorrsig.c

View File

@@ -68,7 +68,7 @@ static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *ms
/* Tag the hash with algo16 which is important to avoid nonce reuse across
* algorithms. If this nonce function is used in BIP-340 signing as defined
* in the spec, an optimized tagging implementation is used. */
if (memcmp(algo16, bip340_algo16, 16) == 0) {
if (secp256k1_memcmp_var(algo16, bip340_algo16, 16) == 0) {
secp256k1_nonce_function_bip340_sha256_tagged(&sha);
} else {
int algo16_len = 16;
@@ -108,6 +108,22 @@ static void secp256k1_schnorrsig_sha256_tagged(secp256k1_sha256 *sha) {
sha->bytes = 64;
}
static void secp256k1_schnorrsig_challenge(secp256k1_scalar* e, const unsigned char *r32, const unsigned char *msg32, const unsigned char *pubkey32)
{
unsigned char buf[32];
secp256k1_sha256 sha;
/* tagged hash(r.x, pk.x, msg32) */
secp256k1_schnorrsig_sha256_tagged(&sha);
secp256k1_sha256_write(&sha, r32, 32);
secp256k1_sha256_write(&sha, pubkey32, 32);
secp256k1_sha256_write(&sha, msg32, 32);
secp256k1_sha256_finalize(&sha, buf);
/* Set scalar e to the challenge hash modulo the curve order as per
* BIP340. */
secp256k1_scalar_set_b32(e, buf, NULL);
}
int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, secp256k1_nonce_function_hardened noncefp, void *ndata) {
secp256k1_scalar sk;
secp256k1_scalar e;
@@ -115,7 +131,6 @@ int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, unsigned char *sig64
secp256k1_gej rj;
secp256k1_ge pk;
secp256k1_ge r;
secp256k1_sha256 sha;
unsigned char buf[32] = { 0 };
unsigned char pk_buf[32];
unsigned char seckey[32];
@@ -159,21 +174,12 @@ int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, unsigned char *sig64
secp256k1_fe_normalize_var(&r.x);
secp256k1_fe_get_b32(&sig64[0], &r.x);
/* tagged hash(r.x, pk.x, msg32) */
secp256k1_schnorrsig_sha256_tagged(&sha);
secp256k1_sha256_write(&sha, &sig64[0], 32);
secp256k1_sha256_write(&sha, pk_buf, sizeof(pk_buf));
secp256k1_sha256_write(&sha, msg32, 32);
secp256k1_sha256_finalize(&sha, buf);
/* Set scalar e to the challenge hash modulo the curve order as per
* BIP340. */
secp256k1_scalar_set_b32(&e, buf, NULL);
secp256k1_schnorrsig_challenge(&e, &sig64[0], msg32, pk_buf);
secp256k1_scalar_mul(&e, &e, &sk);
secp256k1_scalar_add(&e, &e, &k);
secp256k1_scalar_get_b32(&sig64[32], &e);
memczero(sig64, 64, !ret);
secp256k1_memczero(sig64, 64, !ret);
secp256k1_scalar_clear(&k);
secp256k1_scalar_clear(&sk);
memset(seckey, 0, sizeof(seckey));
@@ -189,7 +195,6 @@ int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned cha
secp256k1_gej pkj;
secp256k1_fe rx;
secp256k1_ge r;
secp256k1_sha256 sha;
unsigned char buf[32];
int overflow;
@@ -212,13 +217,9 @@ int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned cha
return 0;
}
secp256k1_schnorrsig_sha256_tagged(&sha);
secp256k1_sha256_write(&sha, &sig64[0], 32);
/* Compute e. */
secp256k1_fe_get_b32(buf, &pk.x);
secp256k1_sha256_write(&sha, buf, sizeof(buf));
secp256k1_sha256_write(&sha, msg32, 32);
secp256k1_sha256_finalize(&sha, buf);
secp256k1_scalar_set_b32(&e, buf, NULL);
secp256k1_schnorrsig_challenge(&e, &sig64[0], msg32, buf);
/* Compute rj = s*G + (-e)*pkj */
secp256k1_scalar_negate(&e, &e);

View File

@@ -0,0 +1,206 @@
/**********************************************************************
* Copyright (c) 2020 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#ifndef _SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_
#define _SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_
#include "include/secp256k1_schnorrsig.h"
#include "src/modules/schnorrsig/main_impl.h"
static const unsigned char invalid_pubkey_bytes[][32] = {
/* 0 */
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
},
/* 2 */
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2
},
/* order */
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
((EXHAUSTIVE_TEST_ORDER + 0UL) >> 24) & 0xFF,
((EXHAUSTIVE_TEST_ORDER + 0UL) >> 16) & 0xFF,
((EXHAUSTIVE_TEST_ORDER + 0UL) >> 8) & 0xFF,
(EXHAUSTIVE_TEST_ORDER + 0UL) & 0xFF
},
/* order + 1 */
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
((EXHAUSTIVE_TEST_ORDER + 1UL) >> 24) & 0xFF,
((EXHAUSTIVE_TEST_ORDER + 1UL) >> 16) & 0xFF,
((EXHAUSTIVE_TEST_ORDER + 1UL) >> 8) & 0xFF,
(EXHAUSTIVE_TEST_ORDER + 1UL) & 0xFF
},
/* field size */
{
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, 0x2F
},
/* field size + 1 (note that 1 is legal) */
{
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
},
/* 2^256 - 1 */
{
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
}
};
#define NUM_INVALID_KEYS (sizeof(invalid_pubkey_bytes) / sizeof(invalid_pubkey_bytes[0]))
static int secp256k1_hardened_nonce_function_smallint(unsigned char *nonce32, const unsigned char *msg32,
const unsigned char *key32, const unsigned char *xonly_pk32,
const unsigned char *algo16, void* data) {
secp256k1_scalar s;
int *idata = data;
(void)msg32;
(void)key32;
(void)xonly_pk32;
(void)algo16;
secp256k1_scalar_set_int(&s, *idata);
secp256k1_scalar_get_b32(nonce32, &s);
return 1;
}
static void test_exhaustive_schnorrsig_verify(const secp256k1_context *ctx, const secp256k1_xonly_pubkey* pubkeys, unsigned char (*xonly_pubkey_bytes)[32], const int* parities) {
int d;
uint64_t iter = 0;
/* Iterate over the possible public keys to verify against (through their corresponding DL d). */
for (d = 1; d <= EXHAUSTIVE_TEST_ORDER / 2; ++d) {
int actual_d;
unsigned k;
unsigned char pk32[32];
memcpy(pk32, xonly_pubkey_bytes[d - 1], 32);
actual_d = parities[d - 1] ? EXHAUSTIVE_TEST_ORDER - d : d;
/* Iterate over the possible valid first 32 bytes in the signature, through their corresponding DL k.
Values above EXHAUSTIVE_TEST_ORDER/2 refer to the entries in invalid_pubkey_bytes. */
for (k = 1; k <= EXHAUSTIVE_TEST_ORDER / 2 + NUM_INVALID_KEYS; ++k) {
unsigned char sig64[64];
int actual_k = -1;
int e_done[EXHAUSTIVE_TEST_ORDER] = {0};
int e_count_done = 0;
if (skip_section(&iter)) continue;
if (k <= EXHAUSTIVE_TEST_ORDER / 2) {
memcpy(sig64, xonly_pubkey_bytes[k - 1], 32);
actual_k = parities[k - 1] ? EXHAUSTIVE_TEST_ORDER - k : k;
} else {
memcpy(sig64, invalid_pubkey_bytes[k - 1 - EXHAUSTIVE_TEST_ORDER / 2], 32);
}
/* Randomly generate messages until all challenges have been hit. */
while (e_count_done < EXHAUSTIVE_TEST_ORDER) {
secp256k1_scalar e;
unsigned char msg32[32];
secp256k1_testrand256(msg32);
secp256k1_schnorrsig_challenge(&e, sig64, msg32, pk32);
/* Only do work if we hit a challenge we haven't tried before. */
if (!e_done[e]) {
/* Iterate over the possible valid last 32 bytes in the signature.
0..order=that s value; order+1=random bytes */
int count_valid = 0, s;
for (s = 0; s <= EXHAUSTIVE_TEST_ORDER + 1; ++s) {
int expect_valid, valid;
if (s <= EXHAUSTIVE_TEST_ORDER) {
secp256k1_scalar s_s;
secp256k1_scalar_set_int(&s_s, s);
secp256k1_scalar_get_b32(sig64 + 32, &s_s);
expect_valid = actual_k != -1 && s != EXHAUSTIVE_TEST_ORDER &&
(s_s == (actual_k + actual_d * e) % EXHAUSTIVE_TEST_ORDER);
} else {
secp256k1_testrand256(sig64 + 32);
expect_valid = 0;
}
valid = secp256k1_schnorrsig_verify(ctx, sig64, msg32, &pubkeys[d - 1]);
CHECK(valid == expect_valid);
count_valid += valid;
}
/* Exactly one s value must verify, unless R is illegal. */
CHECK(count_valid == (actual_k != -1));
/* Don't retry other messages that result in the same challenge. */
e_done[e] = 1;
++e_count_done;
}
}
}
}
}
static void test_exhaustive_schnorrsig_sign(const secp256k1_context *ctx, unsigned char (*xonly_pubkey_bytes)[32], const secp256k1_keypair* keypairs, const int* parities) {
int d, k;
uint64_t iter = 0;
/* Loop over keys. */
for (d = 1; d < EXHAUSTIVE_TEST_ORDER; ++d) {
int actual_d = d;
if (parities[d - 1]) actual_d = EXHAUSTIVE_TEST_ORDER - d;
/* Loop over nonces. */
for (k = 1; k < EXHAUSTIVE_TEST_ORDER; ++k) {
int e_done[EXHAUSTIVE_TEST_ORDER] = {0};
int e_count_done = 0;
unsigned char msg32[32];
unsigned char sig64[64];
int actual_k = k;
if (skip_section(&iter)) continue;
if (parities[k - 1]) actual_k = EXHAUSTIVE_TEST_ORDER - k;
/* Generate random messages until all challenges have been tried. */
while (e_count_done < EXHAUSTIVE_TEST_ORDER) {
secp256k1_scalar e;
secp256k1_testrand256(msg32);
secp256k1_schnorrsig_challenge(&e, xonly_pubkey_bytes[k - 1], msg32, xonly_pubkey_bytes[d - 1]);
/* Only do work if we hit a challenge we haven't tried before. */
if (!e_done[e]) {
secp256k1_scalar expected_s = (actual_k + e * actual_d) % EXHAUSTIVE_TEST_ORDER;
unsigned char expected_s_bytes[32];
secp256k1_scalar_get_b32(expected_s_bytes, &expected_s);
/* Invoke the real function to construct a signature. */
CHECK(secp256k1_schnorrsig_sign(ctx, sig64, msg32, &keypairs[d - 1], secp256k1_hardened_nonce_function_smallint, &k));
/* The first 32 bytes must match the xonly pubkey for the specified k. */
CHECK(secp256k1_memcmp_var(sig64, xonly_pubkey_bytes[k - 1], 32) == 0);
/* The last 32 bytes must match the expected s value. */
CHECK(secp256k1_memcmp_var(sig64 + 32, expected_s_bytes, 32) == 0);
/* Don't retry other messages that result in the same challenge. */
e_done[e] = 1;
++e_count_done;
}
}
}
}
}
static void test_exhaustive_schnorrsig(const secp256k1_context *ctx) {
secp256k1_keypair keypair[EXHAUSTIVE_TEST_ORDER - 1];
secp256k1_xonly_pubkey xonly_pubkey[EXHAUSTIVE_TEST_ORDER - 1];
int parity[EXHAUSTIVE_TEST_ORDER - 1];
unsigned char xonly_pubkey_bytes[EXHAUSTIVE_TEST_ORDER - 1][32];
unsigned i;
/* Verify that all invalid_pubkey_bytes are actually invalid. */
for (i = 0; i < NUM_INVALID_KEYS; ++i) {
secp256k1_xonly_pubkey pk;
CHECK(!secp256k1_xonly_pubkey_parse(ctx, &pk, invalid_pubkey_bytes[i]));
}
/* Construct keypairs and xonly-pubkeys for the entire group. */
for (i = 1; i < EXHAUSTIVE_TEST_ORDER; ++i) {
secp256k1_scalar scalar_i;
unsigned char buf[32];
secp256k1_scalar_set_int(&scalar_i, i);
secp256k1_scalar_get_b32(buf, &scalar_i);
CHECK(secp256k1_keypair_create(ctx, &keypair[i - 1], buf));
CHECK(secp256k1_keypair_xonly_pub(ctx, &xonly_pubkey[i - 1], &parity[i - 1], &keypair[i - 1]));
CHECK(secp256k1_xonly_pubkey_serialize(ctx, xonly_pubkey_bytes[i - 1], &xonly_pubkey[i - 1]));
}
test_exhaustive_schnorrsig_sign(ctx, xonly_pubkey_bytes, keypair, parity);
test_exhaustive_schnorrsig_verify(ctx, xonly_pubkey, xonly_pubkey_bytes, parity);
}
#endif

View File

@@ -15,9 +15,9 @@
void nonce_function_bip340_bitflip(unsigned char **args, size_t n_flip, size_t n_bytes) {
unsigned char nonces[2][32];
CHECK(nonce_function_bip340(nonces[0], args[0], args[1], args[2], args[3], args[4]) == 1);
secp256k1_rand_flip(args[n_flip], n_bytes);
secp256k1_testrand_flip(args[n_flip], n_bytes);
CHECK(nonce_function_bip340(nonces[1], args[0], args[1], args[2], args[3], args[4]) == 1);
CHECK(memcmp(nonces[0], nonces[1], 32) != 0);
CHECK(secp256k1_memcmp_var(nonces[0], nonces[1], 32) != 0);
}
/* Tests for the equality of two sha256 structs. This function only produces a
@@ -28,7 +28,7 @@ void test_sha256_eq(const secp256k1_sha256 *sha1, const secp256k1_sha256 *sha2)
CHECK((sha1->bytes & 0x3F) == 0);
CHECK(sha1->bytes == sha2->bytes);
CHECK(memcmp(sha1->s, sha2->s, sizeof(sha1->s)) == 0);
CHECK(secp256k1_memcmp_var(sha1->s, sha2->s, sizeof(sha1->s)) == 0);
}
void run_nonce_function_bip340_tests(void) {
@@ -59,10 +59,10 @@ void run_nonce_function_bip340_tests(void) {
secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha_optimized);
test_sha256_eq(&sha, &sha_optimized);
secp256k1_rand256(msg);
secp256k1_rand256(key);
secp256k1_rand256(pk);
secp256k1_rand256(aux_rand);
secp256k1_testrand256(msg);
secp256k1_testrand256(key);
secp256k1_testrand256(pk);
secp256k1_testrand256(aux_rand);
/* Check that a bitflip in an argument results in different nonces. */
args[0] = msg;
@@ -124,10 +124,10 @@ void test_schnorrsig_api(void) {
secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount);
secp256k1_context_set_illegal_callback(both, counting_illegal_callback_fn, &ecount);
secp256k1_rand256(sk1);
secp256k1_rand256(sk2);
secp256k1_rand256(sk3);
secp256k1_rand256(msg);
secp256k1_testrand256(sk1);
secp256k1_testrand256(sk2);
secp256k1_testrand256(sk3);
secp256k1_testrand256(msg);
CHECK(secp256k1_keypair_create(ctx, &keypairs[0], sk1) == 1);
CHECK(secp256k1_keypair_create(ctx, &keypairs[1], sk2) == 1);
CHECK(secp256k1_keypair_create(ctx, &keypairs[2], sk3) == 1);
@@ -197,11 +197,11 @@ void test_schnorrsig_bip_vectors_check_signing(const unsigned char *sk, const un
CHECK(secp256k1_keypair_create(ctx, &keypair, sk));
CHECK(secp256k1_schnorrsig_sign(ctx, sig, msg, &keypair, NULL, aux_rand));
CHECK(memcmp(sig, expected_sig, 64) == 0);
CHECK(secp256k1_memcmp_var(sig, expected_sig, 64) == 0);
CHECK(secp256k1_xonly_pubkey_parse(ctx, &pk_expected, pk_serialized));
CHECK(secp256k1_keypair_xonly_pub(ctx, &pk, NULL, &keypair));
CHECK(memcmp(&pk, &pk_expected, sizeof(pk)) == 0);
CHECK(secp256k1_memcmp_var(&pk, &pk_expected, sizeof(pk)) == 0);
CHECK(secp256k1_schnorrsig_verify(ctx, sig, msg, &pk));
}
@@ -675,19 +675,19 @@ void test_schnorrsig_sign(void) {
unsigned char sig[64];
unsigned char zeros64[64] = { 0 };
secp256k1_rand256(sk);
secp256k1_testrand256(sk);
CHECK(secp256k1_keypair_create(ctx, &keypair, sk));
CHECK(secp256k1_schnorrsig_sign(ctx, sig, msg, &keypair, NULL, NULL) == 1);
/* Test different nonce functions */
memset(sig, 1, sizeof(sig));
CHECK(secp256k1_schnorrsig_sign(ctx, sig, msg, &keypair, nonce_function_failing, NULL) == 0);
CHECK(memcmp(sig, zeros64, sizeof(sig)) == 0);
CHECK(secp256k1_memcmp_var(sig, zeros64, sizeof(sig)) == 0);
memset(&sig, 1, sizeof(sig));
CHECK(secp256k1_schnorrsig_sign(ctx, sig, msg, &keypair, nonce_function_0, NULL) == 0);
CHECK(memcmp(sig, zeros64, sizeof(sig)) == 0);
CHECK(secp256k1_memcmp_var(sig, zeros64, sizeof(sig)) == 0);
CHECK(secp256k1_schnorrsig_sign(ctx, sig, msg, &keypair, nonce_function_overflowing, NULL) == 1);
CHECK(memcmp(sig, zeros64, sizeof(sig)) != 0);
CHECK(secp256k1_memcmp_var(sig, zeros64, sizeof(sig)) != 0);
}
#define N_SIGS 3
@@ -703,12 +703,12 @@ void test_schnorrsig_sign_verify(void) {
secp256k1_xonly_pubkey pk;
secp256k1_scalar s;
secp256k1_rand256(sk);
secp256k1_testrand256(sk);
CHECK(secp256k1_keypair_create(ctx, &keypair, sk));
CHECK(secp256k1_keypair_xonly_pub(ctx, &pk, NULL, &keypair));
for (i = 0; i < N_SIGS; i++) {
secp256k1_rand256(msg[i]);
secp256k1_testrand256(msg[i]);
CHECK(secp256k1_schnorrsig_sign(ctx, sig[i], msg[i], &keypair, NULL, NULL));
CHECK(secp256k1_schnorrsig_verify(ctx, sig[i], msg[i], &pk));
}
@@ -716,19 +716,19 @@ void test_schnorrsig_sign_verify(void) {
{
/* Flip a few bits in the signature and in the message and check that
* verify and verify_batch (TODO) fail */
size_t sig_idx = secp256k1_rand_int(N_SIGS);
size_t byte_idx = secp256k1_rand_int(32);
unsigned char xorbyte = secp256k1_rand_int(254)+1;
size_t sig_idx = secp256k1_testrand_int(N_SIGS);
size_t byte_idx = secp256k1_testrand_int(32);
unsigned char xorbyte = secp256k1_testrand_int(254)+1;
sig[sig_idx][byte_idx] ^= xorbyte;
CHECK(!secp256k1_schnorrsig_verify(ctx, sig[sig_idx], msg[sig_idx], &pk));
sig[sig_idx][byte_idx] ^= xorbyte;
byte_idx = secp256k1_rand_int(32);
byte_idx = secp256k1_testrand_int(32);
sig[sig_idx][32+byte_idx] ^= xorbyte;
CHECK(!secp256k1_schnorrsig_verify(ctx, sig[sig_idx], msg[sig_idx], &pk));
sig[sig_idx][32+byte_idx] ^= xorbyte;
byte_idx = secp256k1_rand_int(32);
byte_idx = secp256k1_testrand_int(32);
msg[sig_idx][byte_idx] ^= xorbyte;
CHECK(!secp256k1_schnorrsig_verify(ctx, sig[sig_idx], msg[sig_idx], &pk));
msg[sig_idx][byte_idx] ^= xorbyte;
@@ -766,7 +766,7 @@ void test_schnorrsig_taproot(void) {
unsigned char sig[64];
/* Create output key */
secp256k1_rand256(sk);
secp256k1_testrand256(sk);
CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
CHECK(secp256k1_keypair_xonly_pub(ctx, &internal_pk, NULL, &keypair) == 1);
/* In actual taproot the tweak would be hash of internal_pk */
@@ -776,7 +776,7 @@ void test_schnorrsig_taproot(void) {
CHECK(secp256k1_xonly_pubkey_serialize(ctx, output_pk_bytes, &output_pk) == 1);
/* Key spend */
secp256k1_rand256(msg);
secp256k1_testrand256(msg);
CHECK(secp256k1_schnorrsig_sign(ctx, sig, msg, &keypair, NULL, NULL) == 1);
/* Verify key spend */
CHECK(secp256k1_xonly_pubkey_parse(ctx, &output_pk, output_pk_bytes) == 1);

View File

@@ -34,7 +34,7 @@ static void test_surjectionproof_api(void) {
int32_t ecount = 0;
size_t i;
secp256k1_rand256(seed);
secp256k1_testrand256(seed);
secp256k1_context_set_error_callback(none, counting_illegal_callback_fn, &ecount);
secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount);
secp256k1_context_set_error_callback(vrfy, counting_illegal_callback_fn, &ecount);
@@ -45,11 +45,11 @@ static void test_surjectionproof_api(void) {
secp256k1_context_set_illegal_callback(both, counting_illegal_callback_fn, &ecount);
for (i = 0; i < n_inputs; i++) {
secp256k1_rand256(input_blinding_key[i]);
secp256k1_rand256(fixed_input_tags[i].data);
secp256k1_testrand256(input_blinding_key[i]);
secp256k1_testrand256(fixed_input_tags[i].data);
CHECK(secp256k1_generator_generate_blinded(ctx, &ephemeral_input_tags[i], fixed_input_tags[i].data, input_blinding_key[i]));
}
secp256k1_rand256(output_blinding_key);
secp256k1_testrand256(output_blinding_key);
memcpy(&fixed_output_tag, &fixed_input_tags[0], sizeof(fixed_input_tags[0]));
CHECK(secp256k1_generator_generate_blinded(ctx, &ephemeral_output_tag, fixed_output_tag.data, output_blinding_key));
@@ -213,10 +213,10 @@ static void test_input_selection(size_t n_inputs) {
const size_t max_n_inputs = sizeof(fixed_input_tags) / sizeof(fixed_input_tags[0]) - 1;
CHECK(n_inputs < max_n_inputs);
secp256k1_rand256(seed);
secp256k1_testrand256(seed);
for (i = 0; i < n_inputs + 1; i++) {
secp256k1_rand256(fixed_input_tags[i].data);
secp256k1_testrand256(fixed_input_tags[i].data);
}
/* cannot match output when told to use zero keys */
@@ -281,7 +281,7 @@ static void test_input_selection_distribution_helper(const secp256k1_fixed_asset
used_inputs[i] = 0;
}
for(j = 0; j < 10000; j++) {
secp256k1_rand256(seed);
secp256k1_testrand256(seed);
result = secp256k1_surjectionproof_initialize(ctx, &proof, &input_index, fixed_input_tags, n_input_tags, n_input_tags_to_use, &fixed_input_tags[0], 64, seed);
CHECK(result > 0);
@@ -304,7 +304,7 @@ static void test_input_selection_distribution(void) {
size_t used_inputs[4];
for (i = 0; i < n_inputs; i++) {
secp256k1_rand256(fixed_input_tags[i].data);
secp256k1_testrand256(fixed_input_tags[i].data);
}
/* If there is one input tag to use, initialize must choose the one equal to fixed_output_tag. */
@@ -387,16 +387,16 @@ static void test_gen_verify(size_t n_inputs, size_t n_used) {
/* setup */
CHECK(n_used <= n_inputs);
CHECK(n_inputs < max_n_inputs);
secp256k1_rand256(seed);
secp256k1_testrand256(seed);
key_index = (((size_t) seed[0] << 8) + seed[1]) % n_inputs;
for (i = 0; i < n_inputs + 1; i++) {
input_blinding_key[i] = malloc(32);
secp256k1_rand256(input_blinding_key[i]);
secp256k1_testrand256(input_blinding_key[i]);
/* choose random fixed tag, except that for the output one copy from the key_index */
if (i < n_inputs) {
secp256k1_rand256(fixed_input_tags[i].data);
secp256k1_testrand256(fixed_input_tags[i].data);
} else {
memcpy(&fixed_input_tags[i], &fixed_input_tags[key_index], sizeof(fixed_input_tags[i]));
}
@@ -476,11 +476,11 @@ static void test_no_used_inputs_verify(void) {
memset(proof.used_inputs, 0, SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS / 8);
/* create different fixed input and output tags */
secp256k1_rand256(fixed_input_tag.data);
secp256k1_rand256(fixed_output_tag.data);
secp256k1_testrand256(fixed_input_tag.data);
secp256k1_testrand256(fixed_output_tag.data);
/* blind fixed output tags with random blinding key */
secp256k1_rand256(blinding_key);
secp256k1_testrand256(blinding_key);
CHECK(secp256k1_generator_generate_blinded(ctx, &ephemeral_input_tags[0], fixed_input_tag.data, blinding_key));
CHECK(secp256k1_generator_generate_blinded(ctx, &ephemeral_output_tag, fixed_output_tag.data, blinding_key));