Add some additional tests.

This commit is contained in:
Gregory Maxwell 2014-12-08 00:48:53 -08:00
parent 3545627acb
commit 8d11164bc0
1 changed files with 172 additions and 2 deletions

View File

@ -400,6 +400,30 @@ void scalar_test(void) {
CHECK(secp256k1_scalar_eq(&r1, &r2)); CHECK(secp256k1_scalar_eq(&r1, &r2));
} }
{
/* Test multiplicative identity. */
secp256k1_scalar_t 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_t 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_t 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) { void run_scalar_tests(void) {
@ -411,9 +435,12 @@ void run_scalar_tests(void) {
/* (-1)+1 should be zero. */ /* (-1)+1 should be zero. */
secp256k1_scalar_t s, o; secp256k1_scalar_t s, o;
secp256k1_scalar_set_int(&s, 1); secp256k1_scalar_set_int(&s, 1);
CHECK(secp256k1_scalar_is_one(&s));
secp256k1_scalar_negate(&o, &s); secp256k1_scalar_negate(&o, &s);
secp256k1_scalar_add(&o, &o, &s); secp256k1_scalar_add(&o, &o, &s);
CHECK(secp256k1_scalar_is_zero(&o)); CHECK(secp256k1_scalar_is_zero(&o));
secp256k1_scalar_negate(&o, &o);
CHECK(secp256k1_scalar_is_zero(&o));
} }
#ifndef USE_NUM_NONE #ifndef USE_NUM_NONE
@ -466,7 +493,7 @@ void random_fe_non_square(secp256k1_fe_t *ns) {
int check_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { int check_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
secp256k1_fe_t an = *a; secp256k1_fe_normalize(&an); secp256k1_fe_t an = *a; secp256k1_fe_normalize(&an);
secp256k1_fe_t bn = *b; secp256k1_fe_normalize(&bn); secp256k1_fe_t bn = *b; secp256k1_fe_normalize_var(&bn);
return secp256k1_fe_equal(&an, &bn); return secp256k1_fe_equal(&an, &bn);
} }
@ -476,6 +503,55 @@ int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) {
return check_fe_equal(&x, &one); return check_fe_equal(&x, &one);
} }
void run_field_misc(void) {
const unsigned char f32_5[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, 0x05,
};
secp256k1_fe_t x;
secp256k1_fe_t y;
secp256k1_fe_t z;
secp256k1_fe_t q;
secp256k1_fe_t fe5;
CHECK(secp256k1_fe_set_b32(&fe5, f32_5));
for (int i=0; i<5*count; i++) {
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(&x, &x));
z = x;
secp256k1_fe_add(&z,&y);
secp256k1_fe_normalize(&z);
/* Test the conditional move. */
secp256k1_fe_cmov(&z, &x, 0);
CHECK(secp256k1_fe_equal(&x, &z) == 0);
CHECK(secp256k1_fe_cmp_var(&x, &z) != 0);
secp256k1_fe_cmov(&y, &x, 1);
CHECK(secp256k1_fe_equal(&x, &y));
/* 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) { void run_field_inv(void) {
secp256k1_fe_t x, xi, xii; secp256k1_fe_t x, xi, xii;
for (int i=0; i<10*count; i++) { for (int i=0; i<10*count; i++) {
@ -752,6 +828,7 @@ void run_ecmult_chain(void) {
} }
void test_point_times_order(const secp256k1_gej_t *point) { void test_point_times_order(const secp256k1_gej_t *point) {
unsigned char pub[65];
/* X * (point + G) + (order-X) * (pointer + G) = 0 */ /* X * (point + G) + (order-X) * (pointer + G) = 0 */
secp256k1_scalar_t x; secp256k1_scalar_t x;
random_scalar_order_test(&x); random_scalar_order_test(&x);
@ -767,6 +844,10 @@ void test_point_times_order(const secp256k1_gej_t *point) {
secp256k1_ge_set_gej(&res3, &res1); secp256k1_ge_set_gej(&res3, &res1);
CHECK(secp256k1_ge_is_infinity(&res3)); CHECK(secp256k1_ge_is_infinity(&res3));
CHECK(secp256k1_ge_is_valid_var(&res3) == 0); CHECK(secp256k1_ge_is_valid_var(&res3) == 0);
int psize = 65;
CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 0) == 0);
psize = 65;
CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 1) == 0);
} }
void run_point_times_order(void) { void run_point_times_order(void) {
@ -877,7 +958,10 @@ void test_ecdsa_end_to_end(void) {
/* Construct and verify corresponding public key. */ /* Construct and verify corresponding public key. */
CHECK(secp256k1_ec_seckey_verify(privkey) == 1); CHECK(secp256k1_ec_seckey_verify(privkey) == 1);
unsigned char pubkey[65]; int pubkeylen = 65; unsigned char pubkey[65]; int pubkeylen = 65;
CHECK(secp256k1_ec_pubkey_create(pubkey, &pubkeylen, privkey, secp256k1_rand32() % 2) == 1); CHECK(secp256k1_ec_pubkey_create(pubkey, &pubkeylen, privkey, (secp256k1_rand32() & 3) != 0) == 1);
if (secp256k1_rand32() & 1) {
CHECK(secp256k1_ec_pubkey_decompress(pubkey, &pubkeylen));
}
CHECK(secp256k1_ec_pubkey_verify(pubkey, pubkeylen)); CHECK(secp256k1_ec_pubkey_verify(pubkey, pubkeylen));
/* Verify private key import and export. */ /* Verify private key import and export. */
@ -999,6 +1083,36 @@ void test_ecdsa_edge_cases(void) {
for (int recid = 0; recid < 4; recid++) { for (int recid = 0; recid < 4; recid++) {
/* (4,4) encoded in DER. */ /* (4,4) encoded in DER. */
unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04}; unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04};
unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01};
unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00};
unsigned char sigbderalt1[39] = {
0x30, 0x25, 0x02, 0x20, 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, 0x04, 0x02, 0x01, 0x04,
};
unsigned char sigbderalt2[39] = {
0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 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, 0x04,
};
unsigned char sigbderalt3[40] = {
0x30, 0x26, 0x02, 0x21, 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, 0x04, 0x02, 0x01, 0x04,
};
unsigned char sigbderalt4[40] = {
0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 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, 0x04,
};
/* (order + r,4) encoded in DER. */ /* (order + r,4) encoded in DER. */
unsigned char sigbderlong[40] = { unsigned char sigbderlong[40] = {
0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF, 0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF,
@ -1016,9 +1130,36 @@ void test_ecdsa_edge_cases(void) {
/* Verifying with (order + r,4) should always fail. */ /* Verifying with (order + r,4) should always fail. */
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbderlong, sizeof(sigbderlong), pubkey2b, pubkey2blen) != 1); CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbderlong, sizeof(sigbderlong), pubkey2b, pubkey2blen) != 1);
} }
/* DER parsing tests. */
/* Zero length r/s. */
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigcder_zr, sizeof(sigcder_zr), pubkeyb, pubkeyblen) == -2);
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigcder_zs, sizeof(sigcder_zs), pubkeyb, pubkeyblen) == -2);
/* Leading zeros. */
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbderalt1, sizeof(sigbderalt1), pubkeyb, pubkeyblen) == 1);
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbderalt2, sizeof(sigbderalt2), pubkeyb, pubkeyblen) == 1);
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == 1);
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == 1);
sigbderalt3[4] = 1;
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == -2);
sigbderalt4[7] = 1;
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == -2);
/* Damage signature. */ /* Damage signature. */
sigbder[7]++; sigbder[7]++;
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0); CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0);
sigbder[7]--;
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbder, 6, pubkeyb, pubkeyblen) == -2);
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbder, sizeof(sigbder)-1, pubkeyb, pubkeyblen) == -2);
for(int i = 0; i<8; i++) {
unsigned char orig = sigbder[i];
/*Try every single-byte change.*/
for (int c=0; c<256; c++) {
if (c == orig ) continue;
sigbder[i] = c;
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) ==
(i==4 || i==7) ? 0 : -2 );
}
sigbder[i] = orig;
}
} }
/* Test the case where ECDSA recomputes a point that is infinity. */ /* Test the case where ECDSA recomputes a point that is infinity. */
@ -1065,6 +1206,34 @@ void test_ecdsa_edge_cases(void) {
CHECK(secp256k1_ecdsa_recover_compact(msg32, 32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0); CHECK(secp256k1_ecdsa_recover_compact(msg32, 32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0);
CHECK(secp256k1_ecdsa_verify(msg32, 32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0); CHECK(secp256k1_ecdsa_verify(msg32, 32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0);
} }
/*Signature where s would be zero.*/
{
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,
};
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,
};
unsigned char sig[72];
int siglen = 72;
CHECK(secp256k1_ecdsa_sign(msg, 32, sig, &siglen, key, nonce) == 0);
msg[31] = 0xaa;
siglen = 72;
CHECK(secp256k1_ecdsa_sign(msg, 32, sig, &siglen, key, nonce) == 1);
}
} }
void run_ecdsa_edge_cases(void) { void run_ecdsa_edge_cases(void) {
@ -1169,6 +1338,7 @@ int main(int argc, char **argv) {
run_field_inv(); run_field_inv();
run_field_inv_var(); run_field_inv_var();
run_field_inv_all_var(); run_field_inv_all_var();
run_field_misc();
run_sqr(); run_sqr();
run_sqrt(); run_sqrt();