New Unit Tests

- Added unit tests for the NIST curve.
- Fix some missing bn_mod in unit tests.
- New tests for tricky 2 (2j+1) 2^{4i} exponents.
pull/25/head
Jochen Hoenicke 9 years ago
parent f2081d88d8
commit e1347fcdf8

@ -38,12 +38,7 @@
#include "sha2.h"
#include "options.h"
#include "secp256k1.h"
#define CURVE (&secp256k1)
#define prime256k1 (CURVE->prime)
#define G256k1 (CURVE->G)
#define order256k1 (CURVE->order)
#define secp256k1_cp (CURVE->cp)
#include "nist256p1.h"
uint8_t *fromhex(const char *str)
{
@ -509,7 +504,7 @@ END_TEST
#define test_deterministic(KEY, MSG, K) do { \
sha256_Raw((uint8_t *)MSG, strlen(MSG), buf); \
res = generate_k_rfc6979(CURVE, &k, fromhex(KEY), buf); \
res = generate_k_rfc6979(curve, &k, fromhex(KEY), buf); \
ck_assert_int_eq(res, 0); \
bn_write_be(&k, buf); \
ck_assert_mem_eq(buf, fromhex(K), 32); \
@ -520,6 +515,7 @@ START_TEST(test_rfc6979)
int res;
bignum256 k;
uint8_t buf[32];
const ecdsa_curve *curve = &secp256k1;
test_deterministic("cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50", "sample", "2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3");
test_deterministic("0000000000000000000000000000000000000000000000000000000000000001", "Satoshi Nakamoto", "8f8a276c19f4149656b280621e358cce24f5f52542772691ee69063b74f15d15");
@ -535,6 +531,7 @@ START_TEST(test_sign_speed)
uint8_t sig[64], priv_key[32], msg[256];
size_t i;
int res;
const ecdsa_curve *curve = &secp256k1;
for (i = 0; i < sizeof(msg); i++) {
msg[i] = i * 1103515245;
@ -544,13 +541,13 @@ START_TEST(test_sign_speed)
memcpy(priv_key, fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), 32);
for (i = 0 ; i < 250; i++) {
res = ecdsa_sign(CURVE, priv_key, msg, sizeof(msg), sig, 0);
res = ecdsa_sign(curve, priv_key, msg, sizeof(msg), sig, 0);
ck_assert_int_eq(res, 0);
}
memcpy(priv_key, fromhex("509a0382ff5da48e402967a671bdcde70046d07f0df52cff12e8e3883b426a0a"), 32);
for (i = 0 ; i < 250; i++) {
res = ecdsa_sign(CURVE, priv_key, msg, sizeof(msg), sig, 0);
res = ecdsa_sign(curve, priv_key, msg, sizeof(msg), sig, 0);
ck_assert_int_eq(res, 0);
}
@ -563,6 +560,7 @@ START_TEST(test_verify_speed)
uint8_t sig[64], pub_key33[33], pub_key65[65], msg[256];
size_t i;
int res;
const ecdsa_curve *curve = &secp256k1;
for (i = 0; i < sizeof(msg); i++) {
msg[i] = i * 1103515245;
@ -575,9 +573,9 @@ START_TEST(test_verify_speed)
memcpy(pub_key65, fromhex("044054fd18aeb277aeedea01d3f3986ff4e5be18092a04339dcf4e524e2c0a09746c7083ed2097011b1223a17a644e81f59aa3de22dac119fd980b36a8ff29a244"), 65);
for (i = 0 ; i < 25; i++) {
res = ecdsa_verify(CURVE, pub_key65, sig, msg, sizeof(msg));
res = ecdsa_verify(curve, pub_key65, sig, msg, sizeof(msg));
ck_assert_int_eq(res, 0);
res = ecdsa_verify(CURVE, pub_key33, sig, msg, sizeof(msg));
res = ecdsa_verify(curve, pub_key33, sig, msg, sizeof(msg));
ck_assert_int_eq(res, 0);
}
@ -586,9 +584,9 @@ START_TEST(test_verify_speed)
memcpy(pub_key65, fromhex("04ff45a5561a76be930358457d113f25fac790794ec70317eff3b97d7080d457196235193a15778062ddaa44aef7e6901b781763e52147f2504e268b2d572bf197"), 65);
for (i = 0 ; i < 25; i++) {
res = ecdsa_verify(CURVE, pub_key65, sig, msg, sizeof(msg));
res = ecdsa_verify(curve, pub_key65, sig, msg, sizeof(msg));
ck_assert_int_eq(res, 0);
res = ecdsa_verify(CURVE, pub_key33, sig, msg, sizeof(msg));
res = ecdsa_verify(curve, pub_key33, sig, msg, sizeof(msg));
ck_assert_int_eq(res, 0);
}
@ -1039,45 +1037,46 @@ START_TEST(test_pubkey_validity)
uint8_t pub_key[65];
curve_point pub;
int res;
const ecdsa_curve *curve = &secp256k1;
memcpy(pub_key, fromhex("0226659c1cf7321c178c07437150639ff0c5b7679c7ea195253ed9abda2e081a37"), 33);
res = ecdsa_read_pubkey(CURVE, pub_key, &pub);
res = ecdsa_read_pubkey(curve, pub_key, &pub);
ck_assert_int_eq(res, 1);
memcpy(pub_key, fromhex("025b1654a0e78d28810094f6c5a96b8efb8a65668b578f170ac2b1f83bc63ba856"), 33);
res = ecdsa_read_pubkey(CURVE, pub_key, &pub);
res = ecdsa_read_pubkey(curve, pub_key, &pub);
ck_assert_int_eq(res, 1);
memcpy(pub_key, fromhex("03433f246a12e6486a51ff08802228c61cf895175a9b49ed4766ea9a9294a3c7fe"), 33);
res = ecdsa_read_pubkey(CURVE, pub_key, &pub);
res = ecdsa_read_pubkey(curve, pub_key, &pub);
ck_assert_int_eq(res, 1);
memcpy(pub_key, fromhex("03aeb03abeee0f0f8b4f7a5d65ce31f9570cef9f72c2dd8a19b4085a30ab033d48"), 33);
res = ecdsa_read_pubkey(CURVE, pub_key, &pub);
res = ecdsa_read_pubkey(curve, pub_key, &pub);
ck_assert_int_eq(res, 1);
memcpy(pub_key, fromhex("0496e8f2093f018aff6c2e2da5201ee528e2c8accbf9cac51563d33a7bb74a016054201c025e2a5d96b1629b95194e806c63eb96facaedc733b1a4b70ab3b33e3a"), 65);
res = ecdsa_read_pubkey(CURVE, pub_key, &pub);
res = ecdsa_read_pubkey(curve, pub_key, &pub);
ck_assert_int_eq(res, 1);
memcpy(pub_key, fromhex("0498010f8a687439ff497d3074beb4519754e72c4b6220fb669224749591dde416f3961f8ece18f8689bb32235e436874d2174048b86118a00afbd5a4f33a24f0f"), 65);
res = ecdsa_read_pubkey(CURVE, pub_key, &pub);
res = ecdsa_read_pubkey(curve, pub_key, &pub);
ck_assert_int_eq(res, 1);
memcpy(pub_key, fromhex("04f80490839af36d13701ec3f9eebdac901b51c362119d74553a3c537faff31b17e2a59ebddbdac9e87b816307a7ed5b826b8f40b92719086238e1bebf19b77a4d"), 65);
res = ecdsa_read_pubkey(CURVE, pub_key, &pub);
res = ecdsa_read_pubkey(curve, pub_key, &pub);
ck_assert_int_eq(res, 1);
memcpy(pub_key, fromhex("04f80490839af36d13701ec3f9eebdac901b51c362119d74553a3c537faff31b17e2a59ebddbdac9e87b816307a7ed5b826b8f40b92719086238e1bebf00000000"), 65);
res = ecdsa_read_pubkey(CURVE, pub_key, &pub);
res = ecdsa_read_pubkey(curve, pub_key, &pub);
ck_assert_int_eq(res, 0);
memcpy(pub_key, fromhex("04f80490839af36d13701ec3f9eebdac901b51c362119d74553a3c537faff31b17e2a59ebddbdac9e87b816307a7ed5b8211111111111111111111111111111111"), 65);
res = ecdsa_read_pubkey(CURVE, pub_key, &pub);
res = ecdsa_read_pubkey(curve, pub_key, &pub);
ck_assert_int_eq(res, 0);
memcpy(pub_key, fromhex("00"), 1);
res = ecdsa_read_pubkey(CURVE, pub_key, &pub);
res = ecdsa_read_pubkey(curve, pub_key, &pub);
ck_assert_int_eq(res, 0);
}
END_TEST
@ -1210,7 +1209,7 @@ START_TEST(test_ecdsa_der)
}
END_TEST
START_TEST(test_secp256k1_cp) {
static void test_codepoints_curve(const ecdsa_curve *curve) {
int i, j;
bignum256 a;
curve_point p, p1;
@ -1221,108 +1220,130 @@ START_TEST(test_secp256k1_cp) {
bn_normalize(&a);
// note that this is not a trivial test. We add 64 curve
// points in the table to get that particular curve point.
scalar_multiply(CURVE, &a, &p);
ck_assert_mem_eq(&p, &secp256k1_cp[i][j], sizeof(curve_point));
bn_zero(&p.y); // test that point_multiply CURVE, is not a noop
point_multiply(CURVE, &a, &G256k1, &p);
ck_assert_mem_eq(&p, &secp256k1_cp[i][j], sizeof(curve_point));
// even/odd has different behaviour;
// increment by one and test again
p1 = p;
point_add(CURVE, &G256k1, &p1);
bn_addi(&a, 1);
scalar_multiply(CURVE, &a, &p);
scalar_multiply(curve, &a, &p);
ck_assert_mem_eq(&p, &curve->cp[i][j], sizeof(curve_point));
bn_zero(&p.y); // test that point_multiply curve, is not a noop
point_multiply(curve, &a, &curve->G, &p);
ck_assert_mem_eq(&p, &curve->cp[i][j], sizeof(curve_point));
// mul 2 test. this should catch bugs
bn_lshift(&a);
bn_mod(&a, &curve->order);
p1 = curve->cp[i][j];
point_double(curve, &p1);
// note that this is not a trivial test. We add 64 curve
// points in the table to get that particular curve point.
scalar_multiply(curve, &a, &p);
ck_assert_mem_eq(&p, &p1, sizeof(curve_point));
bn_zero(&p.y); // test that point_multiply CURVE, is not a noop
point_multiply(CURVE, &a, &G256k1, &p);
bn_zero(&p.y); // test that point_multiply curve, is not a noop
point_multiply(curve, &a, &curve->G, &p);
ck_assert_mem_eq(&p, &p1, sizeof(curve_point));
}
}
}
START_TEST(test_codepoints) {
test_codepoints_curve(&secp256k1);
test_codepoints_curve(&nist256p1);
}
END_TEST
START_TEST(test_mult_border_cases) {
static void test_mult_border_cases_curve(const ecdsa_curve *curve) {
bignum256 a;
curve_point p;
curve_point expected;
bn_zero(&a); // a == 0
scalar_multiply(CURVE, &a, &p);
scalar_multiply(curve, &a, &p);
ck_assert(point_is_infinity(&p));
point_multiply(CURVE, &a, &p, &p);
point_multiply(curve, &a, &p, &p);
ck_assert(point_is_infinity(&p));
point_multiply(CURVE, &a, &G256k1, &p);
point_multiply(curve, &a, &curve->G, &p);
ck_assert(point_is_infinity(&p));
bn_addi(&a, 1); // a == 1
scalar_multiply(CURVE, &a, &p);
ck_assert_mem_eq(&p, &G256k1, sizeof(curve_point));
point_multiply(CURVE, &a, &G256k1, &p);
ck_assert_mem_eq(&p, &G256k1, sizeof(curve_point));
bn_subtract(&order256k1, &a, &a); // a == -1
expected = G256k1;
bn_subtract(&prime256k1, &expected.y, &expected.y);
scalar_multiply(CURVE, &a, &p);
scalar_multiply(curve, &a, &p);
ck_assert_mem_eq(&p, &curve->G, sizeof(curve_point));
point_multiply(curve, &a, &curve->G, &p);
ck_assert_mem_eq(&p, &curve->G, sizeof(curve_point));
bn_subtract(&curve->order, &a, &a); // a == -1
expected = curve->G;
bn_subtract(&curve->prime, &expected.y, &expected.y);
scalar_multiply(curve, &a, &p);
ck_assert_mem_eq(&p, &expected, sizeof(curve_point));
point_multiply(CURVE, &a, &G256k1, &p);
point_multiply(curve, &a, &curve->G, &p);
ck_assert_mem_eq(&p, &expected, sizeof(curve_point));
bn_subtract(&order256k1, &a, &a);
bn_subtract(&curve->order, &a, &a);
bn_addi(&a, 1); // a == 2
expected = G256k1;
point_add(CURVE, &expected, &expected);
scalar_multiply(CURVE, &a, &p);
expected = curve->G;
point_add(curve, &expected, &expected);
scalar_multiply(curve, &a, &p);
ck_assert_mem_eq(&p, &expected, sizeof(curve_point));
point_multiply(CURVE, &a, &G256k1, &p);
point_multiply(curve, &a, &curve->G, &p);
ck_assert_mem_eq(&p, &expected, sizeof(curve_point));
bn_subtract(&order256k1, &a, &a); // a == -2
expected = G256k1;
point_add(CURVE, &expected, &expected);
bn_subtract(&prime256k1, &expected.y, &expected.y);
scalar_multiply(CURVE, &a, &p);
bn_subtract(&curve->order, &a, &a); // a == -2
expected = curve->G;
point_add(curve, &expected, &expected);
bn_subtract(&curve->prime, &expected.y, &expected.y);
scalar_multiply(curve, &a, &p);
ck_assert_mem_eq(&p, &expected, sizeof(curve_point));
point_multiply(CURVE, &a, &G256k1, &p);
point_multiply(curve, &a, &curve->G, &p);
ck_assert_mem_eq(&p, &expected, sizeof(curve_point));
}
START_TEST(test_mult_border_cases) {
test_mult_border_cases_curve(&secp256k1);
test_mult_border_cases_curve(&nist256p1);
}
END_TEST
START_TEST(test_scalar_mult) {
static void test_scalar_mult_curve(const ecdsa_curve *curve) {
int i;
// get two "random" numbers
bignum256 a = G256k1.x;
bignum256 b = G256k1.y;
bignum256 a = curve->G.x;
bignum256 b = curve->G.y;
curve_point p1, p2, p3;
for (i = 0; i < 1000; i++) {
/* test distributivity: (a + b)G = aG + bG */
scalar_multiply(CURVE, &a, &p1);
scalar_multiply(CURVE, &b, &p2);
bn_addmod(&a, &b, &order256k1);
scalar_multiply(CURVE, &a, &p3);
point_add(CURVE, &p1, &p2);
bn_mod(&a, &curve->order);
bn_mod(&b, &curve->order);
scalar_multiply(curve, &a, &p1);
scalar_multiply(curve, &b, &p2);
bn_addmod(&a, &b, &curve->order);
bn_mod(&a, &curve->order);
scalar_multiply(curve, &a, &p3);
point_add(curve, &p1, &p2);
ck_assert_mem_eq(&p2, &p3, sizeof(curve_point));
// new "random" numbers
a = p3.x;
b = p3.y;
}
}
START_TEST(test_scalar_mult) {
test_scalar_mult_curve(&secp256k1);
test_scalar_mult_curve(&nist256p1);
}
END_TEST
START_TEST(test_point_mult) {
static void test_point_mult_curve(const ecdsa_curve *curve) {
int i;
// get two "random" numbers and a "random" point
bignum256 a = G256k1.x;
bignum256 b = G256k1.y;
curve_point p = G256k1;
bignum256 a = curve->G.x;
bignum256 b = curve->G.y;
curve_point p = curve->G;
curve_point p1, p2, p3;
for (i = 0; i < 200; i++) {
/* test distributivity: (a + b)P = aP + bP */
point_multiply(CURVE, &a, &p, &p1);
point_multiply(CURVE, &b, &p, &p2);
bn_addmod(&a, &b, &order256k1);
point_multiply(CURVE, &a, &p, &p3);
point_add(CURVE, &p1, &p2);
bn_mod(&a, &curve->order);
bn_mod(&b, &curve->order);
point_multiply(curve, &a, &p, &p1);
point_multiply(curve, &b, &p, &p2);
bn_addmod(&a, &b, &curve->order);
bn_mod(&a, &curve->order);
point_multiply(curve, &a, &p, &p3);
point_add(curve, &p1, &p2);
ck_assert_mem_eq(&p2, &p3, sizeof(curve_point));
// new "random" numbers and a "random" point
a = p1.x;
@ -1330,28 +1351,36 @@ START_TEST(test_point_mult) {
p = p3;
}
}
START_TEST(test_point_mult) {
test_point_mult_curve(&secp256k1);
test_point_mult_curve(&nist256p1);
}
END_TEST
START_TEST(test_scalar_point_mult) {
static void test_scalar_point_mult_curve(const ecdsa_curve *curve) {
int i;
// get two "random" numbers
bignum256 a = G256k1.x;
bignum256 b = G256k1.y;
bignum256 a = curve->G.x;
bignum256 b = curve->G.y;
curve_point p1, p2;
for (i = 0; i < 200; i++) {
/* test commutativity and associativity:
* a(bG) = (ab)G = b(aG)
*/
scalar_multiply(CURVE, &a, &p1);
point_multiply(CURVE, &b, &p1, &p1);
bn_mod(&a, &curve->order);
bn_mod(&b, &curve->order);
scalar_multiply(curve, &a, &p1);
point_multiply(curve, &b, &p1, &p1);
scalar_multiply(CURVE, &b, &p2);
point_multiply(CURVE, &a, &p2, &p2);
scalar_multiply(curve, &b, &p2);
point_multiply(curve, &a, &p2, &p2);
ck_assert_mem_eq(&p1, &p2, sizeof(curve_point));
bn_multiply(&a, &b, &order256k1);
scalar_multiply(CURVE, &b, &p2);
bn_multiply(&a, &b, &curve->order);
bn_mod(&b, &curve->order);
scalar_multiply(curve, &b, &p2);
ck_assert_mem_eq(&p1, &p2, sizeof(curve_point));
@ -1360,6 +1389,11 @@ START_TEST(test_scalar_point_mult) {
b = p1.y;
}
}
START_TEST(test_scalar_point_mult) {
test_scalar_point_mult_curve(&secp256k1);
test_scalar_point_mult_curve(&nist256p1);
}
END_TEST
// define test suite and cases
@ -1423,8 +1457,8 @@ Suite *test_suite(void)
tcase_add_test(tc, test_pubkey_validity);
suite_add_tcase(s, tc);
tc = tcase_create("secp256k1_cp");
tcase_add_test(tc, test_secp256k1_cp);
tc = tcase_create("codepoints");
tcase_add_test(tc, test_codepoints);
suite_add_tcase(s, tc);
tc = tcase_create("mult_border_cases");

Loading…
Cancel
Save