END_TEST /* Random unit test for ec_mul and ec_add */ START_TEST (test_random_addmul) { FF_NUM a, b, c; EC_POINT P, Q, R, T1, T2; for (int passes = 0; passes < 10; ++passes) { ff_rand (&a, &ec_n); ff_rand (&b, &ec_n); ff_add (&c, &a, &b, &ec_n); ec_mul (&P, &a, &ec_G); ec_mul (&Q, &b, &ec_G); ec_mul (&R, &c, &ec_G); ec_add (&T1, &P, &Q); ec_add (&T2, &Q, &P); if (ff_compare (&(T1.x), &(R.x)) != 0 || ff_compare (&(T1.y), &(R.y)) != 0 || ff_compare (&(T2.x), &(R.x)) != 0 || ff_compare (&(T2.y), &(R.y)) != 0) { printf ("a: "); print_ff (&a); printf ("\nb: "); print_ff (&b); printf ("\nc: "); print_ff (&c); printf ("\nP: 04"); print_ff (&(P.x)); print_ff (&(P.y)); printf ("\nQ: 04"); print_ff (&(Q.x)); print_ff (&(Q.y)); printf ("\nR: 04"); print_ff (&(R.x)); print_ff (&(R.y)); printf ("\nT1: 04"); print_ff (&(T1.x)); print_ff (&(T1.y)); printf ("\nT2: 04"); print_ff (&(T2.x)); print_ff (&(T2.y)); printf ("\n"); return "If c = a + b is true then the following should be true: aG + bG == cG and bG + aG == cG."; } } }
int cp_ecdh_key(uint8_t *key, int key_len, bn_t d, ec_t q) { ec_t p; bn_t x, h; int l, result = STS_OK; uint8_t _x[FC_BYTES]; ec_null(p); bn_null(x); bn_null(h); TRY { ec_new(p); bn_new(x); bn_new(h); ec_curve_get_cof(h); if (bn_bits(h) < BN_DIGIT) { ec_mul_dig(p, q, h->dp[0]); } else { ec_mul(p, q, h); } ec_mul(p, p, d); if (ec_is_infty(p)) { result = STS_ERR; } ec_get_x(x, p); l = bn_size_bin(x); bn_write_bin(_x, l, x); md_kdf2(key, key_len, _x, l); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ec_free(p); bn_free(x); bn_free(h); } return result; }
END_TEST /* Test corner cases */ START_TEST (test_sign_corner) { EC_POINT pubkey; FF_NUM privkey = {0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000}; const FF_NUM hash = {0}; FF_NUM r, s; const FF_NUM hash2 = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; ec_mul (&pubkey, &privkey, &ec_G); ec_sign (&r, &s, &hash, &privkey); mu_assert (ec_verify (&hash, &pubkey, &r, &s), "ec_sign should create a signature that can be verified with ec_verify when the private key is 1."); ec_create_key (&privkey, &pubkey); ec_sign (&r, &s, &hash, &privkey); mu_assert (ec_verify (&hash, &pubkey, &r, &s), "ec_sign should create a signature that can be verified with ec_verify when the hash is 0."); ec_sign (&r, &s, &hash2, &privkey); mu_assert (ec_verify (&hash2, &pubkey, &r, &s), "ec_sign should create a signature that can be verified with ec_verify when the hash is 2^256-1."); }