optimize computations

pull/25/head
Pavol Rusnak 11 years ago
parent 7ed18947ba
commit f4f246f3d7

@ -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)

@ -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)

@ -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);

@ -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…
Cancel
Save