|
|
|
@ -6,8 +6,8 @@
@@ -6,8 +6,8 @@
|
|
|
|
|
#include "libsecp256k1-config.h" |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#include <assert.h> |
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
|
|
|
|
|
#include "num_impl.h" |
|
|
|
|
#include "field_impl.h" |
|
|
|
@ -23,6 +23,13 @@
@@ -23,6 +23,13 @@
|
|
|
|
|
#include "openssl/obj_mac.h" |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#define TEST_FAILURE(msg) do { \ |
|
|
|
|
fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \ |
|
|
|
|
abort(); \ |
|
|
|
|
} while(0) |
|
|
|
|
|
|
|
|
|
#define CHECK(cond) do { if (!(cond)) { TEST_FAILURE("test condition failed: " #cond); } } while(0) |
|
|
|
|
|
|
|
|
|
static int count = 100; |
|
|
|
|
|
|
|
|
|
/***** NUM TESTS *****/ |
|
|
|
@ -64,11 +71,11 @@ void test_num_copy_inc_cmp() {
@@ -64,11 +71,11 @@ void test_num_copy_inc_cmp() {
|
|
|
|
|
secp256k1_num_init(&n2); |
|
|
|
|
random_num_order(&n1); |
|
|
|
|
secp256k1_num_copy(&n2, &n1); |
|
|
|
|
assert(secp256k1_num_cmp(&n1, &n2) == 0); |
|
|
|
|
assert(secp256k1_num_cmp(&n2, &n1) == 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n1, &n2) == 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n2, &n1) == 0); |
|
|
|
|
secp256k1_num_inc(&n2); |
|
|
|
|
assert(secp256k1_num_cmp(&n1, &n2) != 0); |
|
|
|
|
assert(secp256k1_num_cmp(&n2, &n1) != 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n1, &n2) != 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n2, &n1) != 0); |
|
|
|
|
secp256k1_num_free(&n1); |
|
|
|
|
secp256k1_num_free(&n2); |
|
|
|
|
} |
|
|
|
@ -82,18 +89,18 @@ void test_num_get_set_hex() {
@@ -82,18 +89,18 @@ void test_num_get_set_hex() {
|
|
|
|
|
char c[64]; |
|
|
|
|
secp256k1_num_get_hex(c, 64, &n1); |
|
|
|
|
secp256k1_num_set_hex(&n2, c, 64); |
|
|
|
|
assert(secp256k1_num_cmp(&n1, &n2) == 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n1, &n2) == 0); |
|
|
|
|
for (int i=0; i<64; i++) { |
|
|
|
|
// check whether the lower 4 bits correspond to the last hex character
|
|
|
|
|
int low1 = secp256k1_num_shift(&n1, 4); |
|
|
|
|
int lowh = c[63]; |
|
|
|
|
int low2 = (lowh>>6)*9+(lowh-'0')&15; |
|
|
|
|
assert(low1 == low2); |
|
|
|
|
CHECK(low1 == low2); |
|
|
|
|
// shift bits off the hex representation, and compare
|
|
|
|
|
memmove(c+1, c, 63); |
|
|
|
|
c[0] = '0'; |
|
|
|
|
secp256k1_num_set_hex(&n2, c, 64); |
|
|
|
|
assert(secp256k1_num_cmp(&n1, &n2) == 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n1, &n2) == 0); |
|
|
|
|
} |
|
|
|
|
secp256k1_num_free(&n2); |
|
|
|
|
secp256k1_num_free(&n1); |
|
|
|
@ -107,17 +114,17 @@ void test_num_get_set_bin() {
@@ -107,17 +114,17 @@ void test_num_get_set_bin() {
|
|
|
|
|
unsigned char c[32]; |
|
|
|
|
secp256k1_num_get_bin(c, 32, &n1); |
|
|
|
|
secp256k1_num_set_bin(&n2, c, 32); |
|
|
|
|
assert(secp256k1_num_cmp(&n1, &n2) == 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n1, &n2) == 0); |
|
|
|
|
for (int i=0; i<32; i++) { |
|
|
|
|
// check whether the lower 8 bits correspond to the last byte
|
|
|
|
|
int low1 = secp256k1_num_shift(&n1, 8); |
|
|
|
|
int low2 = c[31]; |
|
|
|
|
assert(low1 == low2); |
|
|
|
|
CHECK(low1 == low2); |
|
|
|
|
// shift bits off the byte representation, and compare
|
|
|
|
|
memmove(c+1, c, 31); |
|
|
|
|
c[0] = 0; |
|
|
|
|
secp256k1_num_set_bin(&n2, c, 32); |
|
|
|
|
assert(secp256k1_num_cmp(&n1, &n2) == 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n1, &n2) == 0); |
|
|
|
|
} |
|
|
|
|
secp256k1_num_free(&n2); |
|
|
|
|
secp256k1_num_free(&n1); |
|
|
|
@ -132,7 +139,7 @@ void run_num_int() {
@@ -132,7 +139,7 @@ void run_num_int() {
|
|
|
|
|
unsigned char c2[3] = {0x11,0x22,0x33}; |
|
|
|
|
secp256k1_num_set_int(&n1, i); |
|
|
|
|
secp256k1_num_get_bin(c2, 3, &n1); |
|
|
|
|
assert(memcmp(c1, c2, 3) == 0); |
|
|
|
|
CHECK(memcmp(c1, c2, 3) == 0); |
|
|
|
|
} |
|
|
|
|
secp256k1_num_free(&n1); |
|
|
|
|
} |
|
|
|
@ -146,18 +153,18 @@ void test_num_negate() {
@@ -146,18 +153,18 @@ void test_num_negate() {
|
|
|
|
|
random_num_negate(&n1); |
|
|
|
|
secp256k1_num_copy(&n2, &n1); // n2 = R
|
|
|
|
|
secp256k1_num_sub(&n1, &n2, &n1); // n1 = n2-n1 = 0
|
|
|
|
|
assert(secp256k1_num_is_zero(&n1)); |
|
|
|
|
CHECK(secp256k1_num_is_zero(&n1)); |
|
|
|
|
secp256k1_num_copy(&n1, &n2); // n1 = R
|
|
|
|
|
secp256k1_num_negate(&n1); // n1 = -R
|
|
|
|
|
assert(!secp256k1_num_is_zero(&n1)); |
|
|
|
|
CHECK(!secp256k1_num_is_zero(&n1)); |
|
|
|
|
secp256k1_num_add(&n1, &n2, &n1); // n1 = n2+n1 = 0
|
|
|
|
|
assert(secp256k1_num_is_zero(&n1)); |
|
|
|
|
CHECK(secp256k1_num_is_zero(&n1)); |
|
|
|
|
secp256k1_num_copy(&n1, &n2); // n1 = R
|
|
|
|
|
secp256k1_num_negate(&n1); // n1 = -R
|
|
|
|
|
assert(secp256k1_num_is_neg(&n1) != secp256k1_num_is_neg(&n2)); |
|
|
|
|
CHECK(secp256k1_num_is_neg(&n1) != secp256k1_num_is_neg(&n2)); |
|
|
|
|
secp256k1_num_negate(&n1); // n1 = R
|
|
|
|
|
assert(secp256k1_num_cmp(&n1, &n2) == 0); |
|
|
|
|
assert(secp256k1_num_is_neg(&n1) == secp256k1_num_is_neg(&n2)); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n1, &n2) == 0); |
|
|
|
|
CHECK(secp256k1_num_is_neg(&n1) == secp256k1_num_is_neg(&n2)); |
|
|
|
|
secp256k1_num_free(&n2); |
|
|
|
|
secp256k1_num_free(&n1); |
|
|
|
|
} |
|
|
|
@ -180,16 +187,16 @@ void test_num_add_sub() {
@@ -180,16 +187,16 @@ void test_num_add_sub() {
|
|
|
|
|
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
|
|
|
|
|
assert(secp256k1_num_cmp(&n1p2, &n2p1) == 0); |
|
|
|
|
assert(secp256k1_num_cmp(&n1p2, &n1m2) != 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n1p2, &n2p1) == 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n1p2, &n1m2) != 0); |
|
|
|
|
secp256k1_num_negate(&n2m1); // n2m1 = -R2 + R1
|
|
|
|
|
assert(secp256k1_num_cmp(&n2m1, &n1m2) == 0); |
|
|
|
|
assert(secp256k1_num_cmp(&n2m1, &n1) != 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n2m1, &n1m2) == 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n2m1, &n1) != 0); |
|
|
|
|
secp256k1_num_add(&n2m1, &n2m1, &n2); // n2m1 = -R2 + R1 + R2 = R1
|
|
|
|
|
assert(secp256k1_num_cmp(&n2m1, &n1) == 0); |
|
|
|
|
assert(secp256k1_num_cmp(&n2p1, &n1) != 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n2m1, &n1) == 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n2p1, &n1) != 0); |
|
|
|
|
secp256k1_num_sub(&n2p1, &n2p1, &n2); // n2p1 = R2 + R1 - R2 = R1
|
|
|
|
|
assert(secp256k1_num_cmp(&n2p1, &n1) == 0); |
|
|
|
|
CHECK(secp256k1_num_cmp(&n2p1, &n1) == 0); |
|
|
|
|
secp256k1_num_free(&n2m1); |
|
|
|
|
secp256k1_num_free(&n1m2); |
|
|
|
|
secp256k1_num_free(&n2p1); |
|
|
|
@ -226,7 +233,7 @@ void random_fe_non_zero(secp256k1_fe_t *nz) {
@@ -226,7 +233,7 @@ void random_fe_non_zero(secp256k1_fe_t *nz) {
|
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
// Infinitesimal probability of spurious failure here
|
|
|
|
|
assert(tries >= 0); |
|
|
|
|
CHECK(tries >= 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void random_fe_non_square(secp256k1_fe_t *ns) { |
|
|
|
@ -240,14 +247,14 @@ void random_fe_non_square(secp256k1_fe_t *ns) {
@@ -240,14 +247,14 @@ void random_fe_non_square(secp256k1_fe_t *ns) {
|
|
|
|
|
void test_sqrt(const secp256k1_fe_t *a, const secp256k1_fe_t *k) { |
|
|
|
|
secp256k1_fe_t r1, r2; |
|
|
|
|
int v = secp256k1_fe_sqrt(&r1, a); |
|
|
|
|
assert((v == 0) == (k == NULL)); |
|
|
|
|
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); |
|
|
|
|
assert(secp256k1_fe_is_zero(&r1) || secp256k1_fe_is_zero(&r2)); |
|
|
|
|
CHECK(secp256k1_fe_is_zero(&r1) || secp256k1_fe_is_zero(&r2)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -331,7 +338,7 @@ void run_ecmult_chain() {
@@ -331,7 +338,7 @@ void run_ecmult_chain() {
|
|
|
|
|
if (i == 19999) { |
|
|
|
|
char res[132]; int resl = 132; |
|
|
|
|
secp256k1_gej_get_hex(res, &resl, &x); |
|
|
|
|
assert(strcmp(res, "(D6E96687F9B10D092A6F35439D86CEBEA4535D0D409F53586440BD74B933E830,B95CBCA2C77DA786539BE8FD53354D2D3B4F566AE658045407ED6015EE1B2A88)") == 0); |
|
|
|
|
CHECK(strcmp(res, "(D6E96687F9B10D092A6F35439D86CEBEA4535D0D409F53586440BD74B933E830,B95CBCA2C77DA786539BE8FD53354D2D3B4F566AE658045407ED6015EE1B2A88)") == 0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// redo the computation, but directly with the resulting ae and ge coefficients:
|
|
|
|
@ -340,8 +347,8 @@ void run_ecmult_chain() {
@@ -340,8 +347,8 @@ void run_ecmult_chain() {
|
|
|
|
|
char res2[132]; int resl2 = 132; |
|
|
|
|
secp256k1_gej_get_hex(res, &resl, &x); |
|
|
|
|
secp256k1_gej_get_hex(res2, &resl2, &x2); |
|
|
|
|
assert(strcmp(res, res2) == 0); |
|
|
|
|
assert(strlen(res) == 131); |
|
|
|
|
CHECK(strcmp(res, res2) == 0); |
|
|
|
|
CHECK(strlen(res) == 131); |
|
|
|
|
secp256k1_num_free(&xn); |
|
|
|
|
secp256k1_num_free(&gn); |
|
|
|
|
secp256k1_num_free(&xf); |
|
|
|
@ -358,7 +365,7 @@ void test_point_times_order(const secp256k1_gej_t *point) {
@@ -358,7 +365,7 @@ void test_point_times_order(const secp256k1_gej_t *point) {
|
|
|
|
|
secp256k1_num_set_int(&zero, 0); |
|
|
|
|
secp256k1_gej_t res; |
|
|
|
|
secp256k1_ecmult(&res, point, order, order); // calc res = order * point + order * G;
|
|
|
|
|
assert(secp256k1_gej_is_infinity(&res)); |
|
|
|
|
CHECK(secp256k1_gej_is_infinity(&res)); |
|
|
|
|
secp256k1_num_free(&zero); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -367,17 +374,17 @@ void run_point_times_order() {
@@ -367,17 +374,17 @@ void run_point_times_order() {
|
|
|
|
|
for (int i=0; i<500; i++) { |
|
|
|
|
secp256k1_ge_t p; |
|
|
|
|
if (secp256k1_ge_set_xo(&p, &x, 1)) { |
|
|
|
|
assert(secp256k1_ge_is_valid(&p)); |
|
|
|
|
CHECK(secp256k1_ge_is_valid(&p)); |
|
|
|
|
secp256k1_gej_t j; |
|
|
|
|
secp256k1_gej_set_ge(&j, &p); |
|
|
|
|
assert(secp256k1_gej_is_valid(&j)); |
|
|
|
|
CHECK(secp256k1_gej_is_valid(&j)); |
|
|
|
|
test_point_times_order(&j); |
|
|
|
|
} |
|
|
|
|
secp256k1_fe_sqr(&x, &x); |
|
|
|
|
} |
|
|
|
|
char c[65]; int cl=65; |
|
|
|
|
secp256k1_fe_get_hex(c, &cl, &x); |
|
|
|
|
assert(strcmp(c, "7603CB59B0EF6C63FE6084792A0C378CDB3233A80F8A9A09A877DEAD31B38C45") == 0); |
|
|
|
|
CHECK(strcmp(c, "7603CB59B0EF6C63FE6084792A0C378CDB3233A80F8A9A09A877DEAD31B38C45") == 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void test_wnaf(const secp256k1_num_t *number, int w) { |
|
|
|
@ -394,19 +401,19 @@ void test_wnaf(const secp256k1_num_t *number, int w) {
@@ -394,19 +401,19 @@ void test_wnaf(const secp256k1_num_t *number, int w) {
|
|
|
|
|
secp256k1_num_mul(&x, &x, &two); |
|
|
|
|
int v = wnaf[i]; |
|
|
|
|
if (v) { |
|
|
|
|
assert(zeroes == -1 || zeroes >= w-1); // check that distance between non-zero elements is at least w-1
|
|
|
|
|
CHECK(zeroes == -1 || zeroes >= w-1); // check that distance between non-zero elements is at least w-1
|
|
|
|
|
zeroes=0; |
|
|
|
|
assert((v & 1) == 1); // check non-zero elements are odd
|
|
|
|
|
assert(v <= (1 << (w-1)) - 1); // check range below
|
|
|
|
|
assert(v >= -(1 << (w-1)) - 1); // check range above
|
|
|
|
|
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 { |
|
|
|
|
assert(zeroes != -1); // check that no unnecessary zero padding exists
|
|
|
|
|
CHECK(zeroes != -1); // check that no unnecessary zero padding exists
|
|
|
|
|
zeroes++; |
|
|
|
|
} |
|
|
|
|
secp256k1_num_set_int(&t, v); |
|
|
|
|
secp256k1_num_add(&x, &x, &t); |
|
|
|
|
} |
|
|
|
|
assert(secp256k1_num_cmp(&x, number) == 0); // check that wnaf represents number
|
|
|
|
|
CHECK(secp256k1_num_cmp(&x, number) == 0); // check that wnaf represents number
|
|
|
|
|
secp256k1_num_free(&x); |
|
|
|
|
secp256k1_num_free(&two); |
|
|
|
|
secp256k1_num_free(&t); |
|
|
|
@ -445,9 +452,9 @@ void test_ecdsa_sign_verify() {
@@ -445,9 +452,9 @@ void test_ecdsa_sign_verify() {
|
|
|
|
|
secp256k1_ecdsa_sig_t sig; |
|
|
|
|
secp256k1_ecdsa_sig_init(&sig); |
|
|
|
|
random_sign(&sig, &key, &msg, NULL); |
|
|
|
|
assert(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg)); |
|
|
|
|
CHECK(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg)); |
|
|
|
|
secp256k1_num_inc(&msg); |
|
|
|
|
assert(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg)); |
|
|
|
|
CHECK(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg)); |
|
|
|
|
secp256k1_ecdsa_sig_free(&sig); |
|
|
|
|
secp256k1_num_free(&msg); |
|
|
|
|
secp256k1_num_free(&key); |
|
|
|
@ -466,9 +473,9 @@ EC_KEY *get_openssl_key(const secp256k1_num_t *key) {
@@ -466,9 +473,9 @@ EC_KEY *get_openssl_key(const secp256k1_num_t *key) {
|
|
|
|
|
int compr = secp256k1_rand32() & 1; |
|
|
|
|
const unsigned char* pbegin = privkey; |
|
|
|
|
EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1); |
|
|
|
|
assert(secp256k1_ecdsa_privkey_serialize(privkey, &privkeylen, key, compr)); |
|
|
|
|
assert(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen)); |
|
|
|
|
assert(EC_KEY_check_key(ec_key)); |
|
|
|
|
CHECK(secp256k1_ecdsa_privkey_serialize(privkey, &privkeylen, key, compr)); |
|
|
|
|
CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen)); |
|
|
|
|
CHECK(EC_KEY_check_key(ec_key)); |
|
|
|
|
return ec_key; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -486,21 +493,21 @@ void test_ecdsa_openssl() {
@@ -486,21 +493,21 @@ void test_ecdsa_openssl() {
|
|
|
|
|
secp256k1_ge_t q; |
|
|
|
|
secp256k1_ge_set_gej(&q, &qj); |
|
|
|
|
EC_KEY *ec_key = get_openssl_key(&key); |
|
|
|
|
assert(ec_key); |
|
|
|
|
CHECK(ec_key); |
|
|
|
|
unsigned char signature[80]; |
|
|
|
|
int sigsize = 80; |
|
|
|
|
assert(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key)); |
|
|
|
|
CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key)); |
|
|
|
|
secp256k1_ecdsa_sig_t sig; |
|
|
|
|
secp256k1_ecdsa_sig_init(&sig); |
|
|
|
|
assert(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize)); |
|
|
|
|
assert(secp256k1_ecdsa_sig_verify(&sig, &q, &msg)); |
|
|
|
|
CHECK(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize)); |
|
|
|
|
CHECK(secp256k1_ecdsa_sig_verify(&sig, &q, &msg)); |
|
|
|
|
secp256k1_num_inc(&sig.r); |
|
|
|
|
assert(!secp256k1_ecdsa_sig_verify(&sig, &q, &msg)); |
|
|
|
|
CHECK(!secp256k1_ecdsa_sig_verify(&sig, &q, &msg)); |
|
|
|
|
|
|
|
|
|
random_sign(&sig, &key, &msg, NULL); |
|
|
|
|
sigsize = 80; |
|
|
|
|
assert(secp256k1_ecdsa_sig_serialize(signature, &sigsize, &sig)); |
|
|
|
|
assert(ECDSA_verify(0, message, sizeof(message), signature, sigsize, ec_key) == 1); |
|
|
|
|
CHECK(secp256k1_ecdsa_sig_serialize(signature, &sigsize, &sig)); |
|
|
|
|
CHECK(ECDSA_verify(0, message, sizeof(message), signature, sigsize, ec_key) == 1); |
|
|
|
|
|
|
|
|
|
secp256k1_ecdsa_sig_free(&sig); |
|
|
|
|
EC_KEY_free(ec_key); |
|
|
|
|