1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-12 18:49:07 +00:00

replace infinite loops with loops with counters

This commit is contained in:
Pavol Rusnak 2013-09-27 15:55:55 +02:00
parent f4f246f3d7
commit 71ff1c5124
3 changed files with 55 additions and 46 deletions

93
ecdsa.c
View File

@ -136,9 +136,9 @@ void scalar_multiply(bignum256 *k, curve_point *res)
}
// generate random K for signing
void generate_k_random(bignum256 *k) {
int i;
for (;;) {
int generate_k_random(bignum256 *k) {
int i, j;
for (j = 0; j < 10000; j++) {
for (i = 0; i < 8; i++) {
k->val[i] = random32() & 0x3FFFFFFF;
}
@ -146,14 +146,17 @@ void generate_k_random(bignum256 *k) {
// if k is too big or too small, we don't like it
if (k->val[5] == 0x3FFFFFFF && k->val[6] == 0x3FFFFFFF && k->val[7] == 0x3FFFFFFF && k->val[8] == 0xFFFF) continue;
if (k->val[5] == 0x0 && k->val[6] == 0x0 && k->val[7] == 0x0 && k->val[8] == 0x0) continue;
return;
return 0; // good number - no error
}
// we generated 10000 numbers, none of them is good -> fail
return 1;
}
// generate K in a deterministic way, according to RFC6979
// http://tools.ietf.org/html/rfc6979
void generate_k_rfc6979(bignum256 *secret, const uint8_t *priv_key, const uint8_t *hash)
int generate_k_rfc6979(bignum256 *secret, const uint8_t *priv_key, const uint8_t *hash)
{
int i;
uint8_t v[32], k[32], bx[2*32], buf[32 + 1 + sizeof(bx)], t[32];
bignum256 z1;
@ -177,17 +180,19 @@ void generate_k_rfc6979(bignum256 *secret, const uint8_t *priv_key, const uint8_
hmac_sha256(k, sizeof(k), buf, sizeof(buf), k);
hmac_sha256(k, sizeof(k), v, sizeof(k), v);
for (;;) {
for (i = 0; i < 10000; i++) {
hmac_sha256(k, sizeof(k), v, sizeof(v), t);
bn_read_be(t, secret);
if ( !bn_is_zero(secret) && bn_is_less(secret, &order256k1) ) {
return;
return 0; // good number -> no error
}
memcpy(buf, v, sizeof(v));
buf[sizeof(v)] = 0x00;
hmac_sha256(k, sizeof(k), buf, sizeof(v) + 1, k);
hmac_sha256(k, sizeof(k), v, sizeof(v), v);
}
// we generated 10000 numbers, none of them is good -> fail
return 1;
}
// uses secp256k1 curve
@ -208,46 +213,48 @@ int ecdsa_sign(const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, ui
// SHA256_Raw(hash, 32, hash);
bn_read_be(hash, &z);
for (;;) {
// generate random number k
//generate_k_random(&k);
// generate random number k
//if (generate_k_random(&k) != 0) {
// return 1;
//}
// generate K deterministically
generate_k_rfc6979(&k, priv_key, hash);
// compute k*G
scalar_multiply(&k, &R);
// r = (rx mod n)
bn_mod(&R.x, &order256k1);
// if r is zero, we try different k
for (i = 0; i < 9; i++) {
if (R.x.val[i] != 0) break;
}
if (i == 9) {
return 1;
}
bn_inverse(&k, &order256k1);
bn_read_be(priv_key, da);
bn_multiply(&R.x, da, &order256k1);
for (i = 0; i < 8; i++) {
da->val[i] += z.val[i];
da->val[i + 1] += (da->val[i] >> 30);
da->val[i] &= 0x3FFFFFFF;
}
da->val[8] += z.val[8];
bn_multiply(da, &k, &order256k1);
bn_mod(&k, &order256k1);
for (i = 0; i < 9; i++) {
if (k.val[i] != 0) break;
}
if (i == 9) {
return 2;
}
// we are done, R.x and k is the result signature
break;
// generate K deterministically
if (generate_k_rfc6979(&k, priv_key, hash) != 0) {
return 1;
}
// compute k*G
scalar_multiply(&k, &R);
// r = (rx mod n)
bn_mod(&R.x, &order256k1);
// if r is zero, we fail
for (i = 0; i < 9; i++) {
if (R.x.val[i] != 0) break;
}
if (i == 9) {
return 2;
}
bn_inverse(&k, &order256k1);
bn_read_be(priv_key, da);
bn_multiply(&R.x, da, &order256k1);
for (i = 0; i < 8; i++) {
da->val[i] += z.val[i];
da->val[i + 1] += (da->val[i] >> 30);
da->val[i] &= 0x3FFFFFFF;
}
da->val[8] += z.val[8];
bn_multiply(da, &k, &order256k1);
bn_mod(&k, &order256k1);
for (i = 0; i < 9; i++) {
if (k.val[i] != 0) break;
}
// if k is zero, we fail
if (i == 9) {
return 3;
}
// we are done, R.x and k is the result signature
bn_write_be(&R.x, sig);
bn_write_be(&k, sig + 32);

View File

@ -35,6 +35,6 @@ void ecdsa_get_public_key65(const uint8_t *priv_key, uint8_t *pub_key);
void ecdsa_get_address(const uint8_t *pub_key, char version, char *addr);
int ecdsa_verify(const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, uint32_t msg_len);
void generate_k_rfc6979(bignum256 *secret, const uint8_t *priv_key, const uint8_t *hash);
int generate_k_rfc6979(bignum256 *secret, const uint8_t *priv_key, const uint8_t *hash);
#endif

View File

@ -174,13 +174,15 @@ END_TEST
START_TEST(test_rfc6979)
{
int res;
bignum256 k;
uint8_t buf[32];
SHA256_Raw((uint8_t *)"sample", 6, buf);
generate_k_rfc6979(&k, fromhex("cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50"), buf);
bn_write_be(&k, buf);
res = generate_k_rfc6979(&k, fromhex("cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50"), buf);
ck_assert_int_eq(res, 0);
bn_write_be(&k, buf);
ck_assert_mem_eq(buf, fromhex("2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3"), 32);
}
END_TEST