mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-12 18:49:07 +00:00
optimize computations
This commit is contained in:
parent
7ed18947ba
commit
f4f246f3d7
42
bignum.c
42
bignum.c
@ -94,13 +94,12 @@ int bn_is_less(const bignum256 *a, const bignum256 *b)
|
||||
}
|
||||
|
||||
int bn_bitlen(const bignum256 *a) {
|
||||
int i, r = 0;
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (a->val[i / 30] & (1 << (i % 30))) {
|
||||
r = i;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
int i = 8, j;
|
||||
while (i >= 0 && a->val[i] == 0) i--;
|
||||
if (i == -1) return 0;
|
||||
j = 29;
|
||||
while ((a->val[i] & (1 << j)) == 0) j--;
|
||||
return i * 30 + j + 1;
|
||||
}
|
||||
|
||||
void bn_lshift(bignum256 *a)
|
||||
@ -444,15 +443,11 @@ void bn_inverse(bignum256 *x, const bignum256 *prime)
|
||||
|
||||
void bn_normalize(bignum256 *a) {
|
||||
int i;
|
||||
uint32_t carry = 0;
|
||||
uint32_t tmp = 0;
|
||||
for (i = 0; i < 9; i++) {
|
||||
a->val[i] += carry;
|
||||
if (a->val[i] > 0x3FFFFFFF) {
|
||||
carry = a->val[i] >> 30;
|
||||
a->val[i] &= 0x3FFFFFFF;
|
||||
} else {
|
||||
carry = 0;
|
||||
}
|
||||
tmp += a->val[i];
|
||||
a->val[i] = tmp & 0x3FFFFFFF;
|
||||
tmp >>= 30;
|
||||
}
|
||||
}
|
||||
|
||||
@ -463,12 +458,14 @@ void bn_addmod(bignum256 *a, const bignum256 *b, const bignum256 *prime)
|
||||
a->val[i] += b->val[i];
|
||||
}
|
||||
bn_normalize(a);
|
||||
bn_fast_mod(a, prime);
|
||||
bn_mod(a, prime);
|
||||
}
|
||||
|
||||
void bn_addmodi(bignum256 *a, uint32_t b, const bignum256 *prime) {
|
||||
a->val[0] += b;
|
||||
bn_normalize(a);
|
||||
bn_fast_mod(a, prime);
|
||||
bn_mod(a, prime);
|
||||
}
|
||||
|
||||
@ -489,17 +486,12 @@ void bn_substract(const bignum256 *a, const bignum256 *b, bignum256 *res)
|
||||
void bn_substract_noprime(const bignum256 *a, const bignum256 *b, bignum256 *res)
|
||||
{
|
||||
int i;
|
||||
char carry = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (a->val[i] >= b->val[i] + carry) {
|
||||
res->val[i] = a->val[i] - b->val[i] - carry;
|
||||
carry = 0;
|
||||
} else {
|
||||
res->val[i] = a->val[i] + 0x40000000 - b->val[i];
|
||||
carry = 1;
|
||||
}
|
||||
uint32_t tmp = 1;
|
||||
for (i = 0; i < 9; i++) {
|
||||
tmp += 0x3FFFFFFF + a->val[i] - b->val[i];
|
||||
res->val[i] = tmp & 0x3FFFFFFF;
|
||||
tmp >>= 30;
|
||||
}
|
||||
res->val[8] = a->val[8] - b->val[8] - carry;
|
||||
}
|
||||
|
||||
// a / 58 = a (+r)
|
||||
|
12
ecdsa.c
12
ecdsa.c
@ -195,7 +195,7 @@ void generate_k_rfc6979(bignum256 *secret, const uint8_t *priv_key, const uint8_
|
||||
// msg is a data to be signed
|
||||
// msg_len is the message length
|
||||
// sig is 64 bytes long array for the signature
|
||||
void ecdsa_sign(const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, uint8_t *sig)
|
||||
int ecdsa_sign(const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, uint8_t *sig)
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t hash[32];
|
||||
@ -224,7 +224,9 @@ void ecdsa_sign(const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, u
|
||||
for (i = 0; i < 9; i++) {
|
||||
if (R.x.val[i] != 0) break;
|
||||
}
|
||||
if (i == 9) continue;
|
||||
if (i == 9) {
|
||||
return 1;
|
||||
}
|
||||
bn_inverse(&k, &order256k1);
|
||||
bn_read_be(priv_key, da);
|
||||
bn_multiply(&R.x, da, &order256k1);
|
||||
@ -239,13 +241,17 @@ void ecdsa_sign(const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, u
|
||||
for (i = 0; i < 9; i++) {
|
||||
if (k.val[i] != 0) break;
|
||||
}
|
||||
if (i == 9) continue;
|
||||
if (i == 9) {
|
||||
return 2;
|
||||
}
|
||||
// we are done, R.x and k is the result signature
|
||||
break;
|
||||
}
|
||||
|
||||
bn_write_be(&R.x, sig);
|
||||
bn_write_be(&k, sig + 32);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ecdsa_get_public_key33(const uint8_t *priv_key, uint8_t *pub_key)
|
||||
|
2
ecdsa.h
2
ecdsa.h
@ -29,7 +29,7 @@
|
||||
#include "secp256k1.h"
|
||||
|
||||
// all functions use secp256k1 curve
|
||||
void ecdsa_sign(const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, uint8_t *sig);
|
||||
int ecdsa_sign(const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, uint8_t *sig);
|
||||
void ecdsa_get_public_key33(const uint8_t *priv_key, uint8_t *pub_key);
|
||||
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);
|
||||
|
@ -75,7 +75,10 @@ int main()
|
||||
}
|
||||
|
||||
// use our ECDSA signer to sign the message with the key
|
||||
ecdsa_sign(priv_key, msg, msg_len, sig);
|
||||
if (ecdsa_sign(priv_key, msg, msg_len, sig) != 0) {
|
||||
printf("MicroECDSA signing failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// generate public key from private key
|
||||
ecdsa_get_public_key33(priv_key, pub_key33);
|
||||
|
8
tests.c
8
tests.c
@ -188,7 +188,7 @@ END_TEST
|
||||
START_TEST(test_sign_speed)
|
||||
{
|
||||
uint8_t sig[64], priv_key[32], msg[256];
|
||||
int i;
|
||||
int i, res;
|
||||
|
||||
for (i = 0; i < sizeof(msg); i++) {
|
||||
msg[i] = i * 1103515245;
|
||||
@ -198,12 +198,14 @@ START_TEST(test_sign_speed)
|
||||
|
||||
memcpy(priv_key, fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), 32);
|
||||
for (i = 0 ; i < 250; i++) {
|
||||
ecdsa_sign(priv_key, msg, sizeof(msg), sig);
|
||||
res = ecdsa_sign(priv_key, msg, sizeof(msg), sig);
|
||||
ck_assert_int_eq(res, 0);
|
||||
}
|
||||
|
||||
memcpy(priv_key, fromhex("509a0382ff5da48e402967a671bdcde70046d07f0df52cff12e8e3883b426a0a"), 32);
|
||||
for (i = 0 ; i < 250; i++) {
|
||||
ecdsa_sign(priv_key, msg, sizeof(msg), sig);
|
||||
res = ecdsa_sign(priv_key, msg, sizeof(msg), sig);
|
||||
ck_assert_int_eq(res, 0);
|
||||
}
|
||||
|
||||
printf("Signing speed: %0.2f sig/s\n", 500.0f / ((float)(clock() - t) / CLOCKS_PER_SEC));
|
||||
|
Loading…
Reference in New Issue
Block a user