void test_num_add_sub(void) { int r = secp256k1_rand32(); secp256k1_num_t n1; secp256k1_num_t n2; random_num_order_test(&n1); /* n1 = R1 */ if (r & 1) { random_num_negate(&n1); } random_num_order_test(&n2); /* n2 = R2 */ if (r & 2) { random_num_negate(&n2); } secp256k1_num_t n1p2, n2p1, n1m2, n2m1; secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = R1 + R2 */ 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 */ CHECK(secp256k1_num_eq(&n1p2, &n2p1)); CHECK(!secp256k1_num_eq(&n1p2, &n1m2)); secp256k1_num_negate(&n2m1); /* n2m1 = -R2 + R1 */ CHECK(secp256k1_num_eq(&n2m1, &n1m2)); CHECK(!secp256k1_num_eq(&n2m1, &n1)); secp256k1_num_add(&n2m1, &n2m1, &n2); /* n2m1 = -R2 + R1 + R2 = R1 */ CHECK(secp256k1_num_eq(&n2m1, &n1)); CHECK(!secp256k1_num_eq(&n2p1, &n1)); secp256k1_num_sub(&n2p1, &n2p1, &n2); /* n2p1 = R2 + R1 - R2 = R1 */ CHECK(secp256k1_num_eq(&n2p1, &n1)); }
void test_num_add_sub() { secp256k1_num_t n1; secp256k1_num_t n2; secp256k1_num_init(&n1); secp256k1_num_init(&n2); random_num_order_test(&n1); // n1 = R1 random_num_negate(&n1); random_num_order_test(&n2); // n2 = R2 random_num_negate(&n2); secp256k1_num_t n1p2, n2p1, n1m2, n2m1; secp256k1_num_init(&n1p2); secp256k1_num_init(&n2p1); secp256k1_num_init(&n1m2); secp256k1_num_init(&n2m1); secp256k1_num_add(&n1p2, &n1, &n2); // n1p2 = R1 + R2 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); secp256k1_num_negate(&n2m1); // n2m1 = -R2 + R1 assert(secp256k1_num_cmp(&n2m1, &n1m2) == 0); assert(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); secp256k1_num_sub(&n2p1, &n2p1, &n2); // n2p1 = R2 + R1 - R2 = R1 assert(secp256k1_num_cmp(&n2p1, &n1) == 0); secp256k1_num_free(&n2m1); secp256k1_num_free(&n1m2); secp256k1_num_free(&n2p1); secp256k1_num_free(&n1p2); secp256k1_num_free(&n2); secp256k1_num_free(&n1); }
void test_ecdsa_openssl() { const secp256k1_ge_consts_t *c = secp256k1_ge_consts; secp256k1_num_t key, msg; secp256k1_num_init(&msg); unsigned char message[32]; secp256k1_rand256_test(message); secp256k1_num_set_bin(&msg, message, 32); secp256k1_num_init(&key); random_num_order_test(&key); secp256k1_gej_t qj; secp256k1_ecmult_gen(&qj, &key); secp256k1_ge_t q; secp256k1_ge_set_gej(&q, &qj); EC_KEY *ec_key = get_openssl_key(&key); assert(ec_key); unsigned char signature[80]; int sigsize = 80; assert(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)); secp256k1_num_inc(&sig.r); assert(!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); secp256k1_ecdsa_sig_free(&sig); EC_KEY_free(ec_key); secp256k1_num_free(&key); secp256k1_num_free(&msg); }
void random_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *key, const secp256k1_num_t *msg, int *recid) { secp256k1_num_t nonce; secp256k1_num_init(&nonce); do { random_num_order_test(&nonce); } while(!secp256k1_ecdsa_sig_sign(sig, key, msg, &nonce, recid)); secp256k1_num_free(&nonce); }
void test_ecdsa_sign_verify() { const secp256k1_ge_consts_t *c = secp256k1_ge_consts; secp256k1_num_t msg, key; secp256k1_num_init(&msg); random_num_order_test(&msg); secp256k1_num_init(&key); random_num_order_test(&key); secp256k1_gej_t pubj; secp256k1_ecmult_gen(&pubj, &key); secp256k1_ge_t pub; secp256k1_ge_set_gej(&pub, &pubj); secp256k1_ecdsa_sig_t sig; secp256k1_ecdsa_sig_init(&sig); random_sign(&sig, &key, &msg, NULL); assert(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg)); secp256k1_num_inc(&msg); assert(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg)); secp256k1_ecdsa_sig_free(&sig); secp256k1_num_free(&msg); secp256k1_num_free(&key); }
void test_num_negate(void) { secp256k1_num_t n1; secp256k1_num_t n2; random_num_order_test(&n1); /* n1 = R */ random_num_negate(&n1); secp256k1_num_copy(&n2, &n1); /* n2 = R */ secp256k1_num_sub(&n1, &n2, &n1); /* n1 = n2-n1 = 0 */ CHECK(secp256k1_num_is_zero(&n1)); secp256k1_num_copy(&n1, &n2); /* n1 = R */ secp256k1_num_negate(&n1); /* n1 = -R */ CHECK(!secp256k1_num_is_zero(&n1)); secp256k1_num_add(&n1, &n2, &n1); /* n1 = n2+n1 = 0 */ CHECK(secp256k1_num_is_zero(&n1)); secp256k1_num_copy(&n1, &n2); /* n1 = R */ secp256k1_num_negate(&n1); /* n1 = -R */ CHECK(secp256k1_num_is_neg(&n1) != secp256k1_num_is_neg(&n2)); secp256k1_num_negate(&n1); /* n1 = R */ CHECK(secp256k1_num_eq(&n1, &n2)); }
void test_num_get_set_bin(void) { secp256k1_num_t n1,n2; random_num_order_test(&n1); unsigned char c[32]; secp256k1_num_get_bin(c, 32, &n1); secp256k1_num_set_bin(&n2, c, 32); CHECK(secp256k1_num_eq(&n1, &n2)); 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]; 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); CHECK(secp256k1_num_eq(&n1, &n2)); } }
void test_num_get_set_hex(void) { secp256k1_num_t n1,n2; random_num_order_test(&n1); char c[64]; secp256k1_num_get_hex(c, 64, &n1); secp256k1_num_set_hex(&n2, c, 64); CHECK(secp256k1_num_eq(&n1, &n2)); 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; 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); CHECK(secp256k1_num_eq(&n1, &n2)); } }
void test_num_get_set_bin() { secp256k1_num_t n1,n2; secp256k1_num_init(&n1); secp256k1_num_init(&n2); random_num_order_test(&n1); 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); 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); // 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); } secp256k1_num_free(&n2); secp256k1_num_free(&n1); }
void test_num_get_set_hex() { secp256k1_num_t n1,n2; secp256k1_num_init(&n1); secp256k1_num_init(&n2); random_num_order_test(&n1); char c[64]; secp256k1_num_get_hex(c, 64, &n1); secp256k1_num_set_hex(&n2, c, 64); assert(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); // 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); } secp256k1_num_free(&n2); secp256k1_num_free(&n1); }
void test_num_negate() { secp256k1_num_t n1; secp256k1_num_t n2; secp256k1_num_init(&n1); secp256k1_num_init(&n2); random_num_order_test(&n1); // n1 = R 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)); secp256k1_num_copy(&n1, &n2); // n1 = R secp256k1_num_negate(&n1); // n1 = -R assert(!secp256k1_num_is_zero(&n1)); secp256k1_num_add(&n1, &n2, &n1); // n1 = n2+n1 = 0 assert(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)); secp256k1_num_negate(&n1); // n1 = R assert(secp256k1_num_cmp(&n1, &n2) == 0); assert(secp256k1_num_is_neg(&n1) == secp256k1_num_is_neg(&n2)); secp256k1_num_free(&n2); secp256k1_num_free(&n1); }
void test_ecdsa_end_to_end(void) { unsigned char privkey[32]; unsigned char message[32]; /* Generate a random key and message. */ { secp256k1_num_t msg, key; random_num_order_test(&msg); random_num_order_test(&key); secp256k1_num_get_bin(privkey, 32, &key); secp256k1_num_get_bin(message, 32, &msg); } /* Construct and verify corresponding public key. */ CHECK(secp256k1_ec_seckey_verify(privkey) == 1); unsigned char pubkey[65]; int pubkeylen = 65; CHECK(secp256k1_ec_pubkey_create(pubkey, &pubkeylen, privkey, secp256k1_rand32() % 2) == 1); CHECK(secp256k1_ec_pubkey_verify(pubkey, pubkeylen)); /* Verify private key import and export. */ unsigned char seckey[300]; int seckeylen = 300; CHECK(secp256k1_ec_privkey_export(privkey, seckey, &seckeylen, secp256k1_rand32() % 2) == 1); unsigned char privkey2[32]; CHECK(secp256k1_ec_privkey_import(privkey2, seckey, seckeylen) == 1); CHECK(memcmp(privkey, privkey2, 32) == 0); /* Optionally tweak the keys using addition. */ if (secp256k1_rand32() % 3 == 0) { unsigned char rnd[32]; secp256k1_rand256_test(rnd); int ret1 = secp256k1_ec_privkey_tweak_add(privkey, rnd); int ret2 = secp256k1_ec_pubkey_tweak_add(pubkey, pubkeylen, rnd); CHECK(ret1 == ret2); if (ret1 == 0) return; unsigned char pubkey2[65]; int pubkeylen2 = 65; CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); } /* Optionally tweak the keys using multiplication. */ if (secp256k1_rand32() % 3 == 0) { unsigned char rnd[32]; secp256k1_rand256_test(rnd); int ret1 = secp256k1_ec_privkey_tweak_mul(privkey, rnd); int ret2 = secp256k1_ec_pubkey_tweak_mul(pubkey, pubkeylen, rnd); CHECK(ret1 == ret2); if (ret1 == 0) return; unsigned char pubkey2[65]; int pubkeylen2 = 65; CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); } /* Sign. */ unsigned char signature[72]; int signaturelen = 72; while(1) { unsigned char rnd[32]; secp256k1_rand256_test(rnd); if (secp256k1_ecdsa_sign(message, 32, signature, &signaturelen, privkey, rnd) == 1) { break; } } /* Verify. */ CHECK(secp256k1_ecdsa_verify(message, 32, signature, signaturelen, pubkey, pubkeylen) == 1); /* Destroy signature and verify again. */ signature[signaturelen - 1 - secp256k1_rand32() % 20] += 1 + (secp256k1_rand32() % 255); CHECK(secp256k1_ecdsa_verify(message, 32, signature, signaturelen, pubkey, pubkeylen) != 1); /* Compact sign. */ unsigned char csignature[64]; int recid = 0; while(1) { unsigned char rnd[32]; secp256k1_rand256_test(rnd); if (secp256k1_ecdsa_sign_compact(message, 32, csignature, privkey, rnd, &recid) == 1) { break; } } /* Recover. */ unsigned char recpubkey[65]; int recpubkeylen = 0; CHECK(secp256k1_ecdsa_recover_compact(message, 32, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1); CHECK(recpubkeylen == pubkeylen); CHECK(memcmp(pubkey, recpubkey, pubkeylen) == 0); /* Destroy signature and verify again. */ csignature[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255); CHECK(secp256k1_ecdsa_recover_compact(message, 32, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) != 1 || memcmp(pubkey, recpubkey, pubkeylen) != 0); CHECK(recpubkeylen == pubkeylen); }