mirror of
https://github.com/kmackay/micro-ecc.git
synced 2026-08-14 05:57:59 +00:00
Added ECDSA support for secp160r1.
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
#ifndef ECC_PLATFORM
|
||||
#if __AVR__
|
||||
#define ECC_PLATFORM ecc_avr
|
||||
#elif defined(__thumb2__) || defined(_M_ARMT) /* I think MSVC only support Thumb-2 targets */
|
||||
#elif defined(__thumb2__) || defined(_M_ARMT) /* I think MSVC only supports Thumb-2 targets */
|
||||
#define ECC_PLATFORM ecc_arm_thumb2
|
||||
#elif defined(__thumb__)
|
||||
#define ECC_PLATFORM ecc_arm_thumb
|
||||
@@ -256,7 +256,7 @@ static ecc_word_t curve_n[ECC_N_WORDS] = ECC_CONCAT(Curve_N_, ECC_CURVE);
|
||||
static void vli_clear(ecc_word_t *p_vli);
|
||||
static ecc_word_t vli_isZero(const ecc_word_t *p_vli);
|
||||
static ecc_word_t vli_testBit(const ecc_word_t *p_vli, bitcount_t p_bit);
|
||||
static bitcount_t vli_numBits(const ecc_word_t *p_vli);
|
||||
static bitcount_t vli_numBits(const ecc_word_t *p_vli, wordcount_t p_maxWords);
|
||||
static void vli_set(ecc_word_t *p_dest, const ecc_word_t *p_src);
|
||||
static cmpresult_t vli_cmp(ecc_word_t *p_left, ecc_word_t *p_right);
|
||||
static void vli_rshift1(ecc_word_t *p_vli);
|
||||
@@ -399,12 +399,12 @@ static ecc_word_t vli_testBit(const ecc_word_t *p_vli, bitcount_t p_bit)
|
||||
|
||||
/* Counts the number of words in p_vli. */
|
||||
#if !asm_numBits
|
||||
static wordcount_t vli_numDigits(const ecc_word_t *p_vli)
|
||||
static wordcount_t vli_numDigits(const ecc_word_t *p_vli, wordcount_t p_maxWords)
|
||||
{
|
||||
swordcount_t i;
|
||||
/* Search from the end until we find a non-zero digit.
|
||||
We do it in reverse because we expect that most digits will be nonzero. */
|
||||
for(i = ECC_WORDS-1; i >= 0 && p_vli[i] == 0; --i)
|
||||
for(i = p_maxWords-1; i >= 0 && p_vli[i] == 0; --i)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -412,12 +412,12 @@ static wordcount_t vli_numDigits(const ecc_word_t *p_vli)
|
||||
}
|
||||
|
||||
/* Counts the number of bits required to represent p_vli. */
|
||||
static bitcount_t vli_numBits(const ecc_word_t *p_vli)
|
||||
static bitcount_t vli_numBits(const ecc_word_t *p_vli, wordcount_t p_maxWords)
|
||||
{
|
||||
ecc_word_t i;
|
||||
ecc_word_t l_digit;
|
||||
|
||||
wordcount_t l_numDigits = vli_numDigits(p_vli);
|
||||
wordcount_t l_numDigits = vli_numDigits(p_vli, p_maxWords);
|
||||
if(l_numDigits == 0)
|
||||
{
|
||||
return 0;
|
||||
@@ -1548,7 +1548,7 @@ static void mod_sqrt(ecc_word_t *a)
|
||||
/* Since curve_p == 3 (mod 4) for all supported curves, we can
|
||||
compute sqrt(a) = a^((curve_p + 1) / 4) (mod curve_p). */
|
||||
vli_add(p1, curve_p, p1); /* p1 = curve_p + 1 */
|
||||
for(i = vli_numBits(p1) - 1; i > 1; --i)
|
||||
for(i = vli_numBits(p1, ECC_WORDS) - 1; i > 1; --i)
|
||||
{
|
||||
vli_modSquare_fast(l_result, l_result);
|
||||
if(vli_testBit(p1, i))
|
||||
@@ -1639,24 +1639,25 @@ int ecc_make_key(uint8_t p_publicKey[ECC_BYTES*2], uint8_t p_privateKey[ECC_BYTE
|
||||
|
||||
do
|
||||
{
|
||||
repeat:
|
||||
if(!g_rng((uint8_t *)l_private, ECC_WORDS) || (l_tries++ >= MAX_TRIES))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(vli_isZero(l_private))
|
||||
{
|
||||
continue;
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
/* Make sure the private key is in the range [1, n-1]. */
|
||||
#if ECC_CURVE != secp160r1
|
||||
if(vli_cmp(curve_n, l_private) != 1)
|
||||
{
|
||||
continue;
|
||||
goto repeat;
|
||||
}
|
||||
#endif
|
||||
|
||||
EccPoint_mult(&l_public, &curve_G, l_private, 0, vli_numBits(l_private));
|
||||
EccPoint_mult(&l_public, &curve_G, l_private, 0, vli_numBits(l_private, ECC_WORDS));
|
||||
} while(EccPoint_isZero(&l_public));
|
||||
|
||||
vli_nativeToBytes(p_privateKey, l_private);
|
||||
@@ -1678,7 +1679,7 @@ int ecdh_shared_secret(const uint8_t p_publicKey[ECC_BYTES*2], const uint8_t p_p
|
||||
vli_bytesToNative(l_public.y, p_publicKey + ECC_BYTES);
|
||||
|
||||
EccPoint l_product;
|
||||
EccPoint_mult(&l_product, &l_public, l_private, (vli_isZero(l_random) ? 0: l_random), vli_numBits(l_private));
|
||||
EccPoint_mult(&l_product, &l_public, l_private, (vli_isZero(l_random) ? 0: l_random), vli_numBits(l_private, ECC_WORDS));
|
||||
|
||||
vli_nativeToBytes(p_secret, l_product.x);
|
||||
|
||||
@@ -1719,7 +1720,219 @@ void ecc_decompress(uint8_t p_compressed[ECC_BYTES+1], uint8_t p_publicKey[ECC_B
|
||||
|
||||
/* -------- ECDSA code -------- */
|
||||
|
||||
#if (ECC_CURVE != secp160r1)
|
||||
#if (ECC_CURVE == secp160r1)
|
||||
static void vli_clear_n(ecc_word_t *p_vli)
|
||||
{
|
||||
vli_clear(p_vli);
|
||||
p_vli[ECC_N_WORDS - 1] = 0;
|
||||
}
|
||||
|
||||
static ecc_word_t vli_isZero_n(const ecc_word_t *p_vli)
|
||||
{
|
||||
if(p_vli[ECC_N_WORDS - 1])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return vli_isZero(p_vli);
|
||||
}
|
||||
|
||||
static void vli_set_n(ecc_word_t *p_dest, const ecc_word_t *p_src)
|
||||
{
|
||||
vli_set(p_dest, p_src);
|
||||
p_dest[ECC_N_WORDS-1] = p_src[ECC_N_WORDS-1];
|
||||
}
|
||||
|
||||
static cmpresult_t vli_cmp_n(ecc_word_t *p_left, ecc_word_t *p_right)
|
||||
{
|
||||
if(p_left[ECC_N_WORDS-1] > p_right[ECC_N_WORDS-1])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if(p_left[ECC_N_WORDS-1] < p_right[ECC_N_WORDS-1])
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return vli_cmp(p_left, p_right);
|
||||
}
|
||||
|
||||
static void vli_rshift1_n(ecc_word_t *p_vli)
|
||||
{
|
||||
vli_rshift1(p_vli);
|
||||
p_vli[ECC_N_WORDS-2] |= p_vli[ECC_N_WORDS-1] << (ECC_WORD_BITS - 1);
|
||||
p_vli[ECC_N_WORDS-1] = p_vli[ECC_N_WORDS-1] >> 1;
|
||||
}
|
||||
|
||||
static ecc_word_t vli_add_n(ecc_word_t *p_result, ecc_word_t *p_left, ecc_word_t *p_right)
|
||||
{
|
||||
ecc_word_t l_carry = vli_add(p_result, p_left, p_right);
|
||||
ecc_word_t l_sum = p_left[ECC_N_WORDS-1] + p_right[ECC_N_WORDS-1] + l_carry;
|
||||
if(l_sum != p_left[ECC_N_WORDS-1])
|
||||
{
|
||||
l_carry = (l_sum < p_left[ECC_N_WORDS-1]);
|
||||
}
|
||||
p_result[ECC_N_WORDS-1] = l_sum;
|
||||
return l_carry;
|
||||
}
|
||||
|
||||
static ecc_word_t vli_sub_n(ecc_word_t *p_result, ecc_word_t *p_left, ecc_word_t *p_right)
|
||||
{
|
||||
ecc_word_t l_borrow = vli_sub(p_result, p_left, p_right);
|
||||
ecc_word_t l_diff = p_left[ECC_N_WORDS-1] - p_right[ECC_N_WORDS-1] - l_borrow;
|
||||
if(l_diff != p_left[ECC_N_WORDS-1])
|
||||
{
|
||||
l_borrow = (l_diff > p_left[ECC_N_WORDS-1]);
|
||||
}
|
||||
p_result[ECC_N_WORDS-1] = l_diff;
|
||||
return l_borrow;
|
||||
}
|
||||
|
||||
static void vli_mult_n(ecc_word_t *p_result, ecc_word_t *p_left, ecc_word_t *p_right)
|
||||
{
|
||||
ecc_word_t r0 = 0;
|
||||
ecc_word_t r1 = 0;
|
||||
ecc_word_t r2 = 0;
|
||||
|
||||
wordcount_t i, k;
|
||||
for(k = 0; k < ECC_N_WORDS*2 - 1; ++k)
|
||||
{
|
||||
wordcount_t l_min = (k < ECC_N_WORDS ? 0 : (k + 1) - ECC_N_WORDS);
|
||||
wordcount_t l_max = (k < ECC_N_WORDS ? k : ECC_N_WORDS-1);
|
||||
for(i = l_min; i <= l_max; ++i)
|
||||
{
|
||||
muladd(p_left[i], p_right[k-i], &r0, &r1, &r2);
|
||||
}
|
||||
p_result[k] = r0;
|
||||
r0 = r1;
|
||||
r1 = r2;
|
||||
r2 = 0;
|
||||
}
|
||||
|
||||
p_result[ECC_N_WORDS*2 - 1] = r0;
|
||||
}
|
||||
|
||||
static void vli_modAdd_n(ecc_word_t *p_result, ecc_word_t *p_left, ecc_word_t *p_right, ecc_word_t *p_mod)
|
||||
{
|
||||
ecc_word_t l_carry = vli_add_n(p_result, p_left, p_right);
|
||||
if(l_carry || vli_cmp_n(p_result, p_mod) >= 0)
|
||||
{
|
||||
vli_sub_n(p_result, p_result, p_mod);
|
||||
}
|
||||
}
|
||||
|
||||
static void vli_modInv_n(ecc_word_t *p_result, ecc_word_t *p_input, ecc_word_t *p_mod)
|
||||
{
|
||||
ecc_word_t a[ECC_N_WORDS], b[ECC_N_WORDS], u[ECC_N_WORDS], v[ECC_N_WORDS];
|
||||
ecc_word_t l_carry;
|
||||
cmpresult_t l_cmpResult;
|
||||
|
||||
if(vli_isZero_n(p_input))
|
||||
{
|
||||
vli_clear_n(p_result);
|
||||
return;
|
||||
}
|
||||
|
||||
vli_set_n(a, p_input);
|
||||
vli_set_n(b, p_mod);
|
||||
vli_clear_n(u);
|
||||
u[0] = 1;
|
||||
vli_clear_n(v);
|
||||
while((l_cmpResult = vli_cmp_n(a, b)) != 0)
|
||||
{
|
||||
l_carry = 0;
|
||||
if(EVEN(a))
|
||||
{
|
||||
vli_rshift1_n(a);
|
||||
if(!EVEN(u)) l_carry = vli_add_n(u, u, p_mod);
|
||||
vli_rshift1_n(u);
|
||||
if(l_carry) u[ECC_N_WORDS-1] |= HIGH_BIT_SET;
|
||||
}
|
||||
else if(EVEN(b))
|
||||
{
|
||||
vli_rshift1_n(b);
|
||||
if(!EVEN(v)) l_carry = vli_add_n(v, v, p_mod);
|
||||
vli_rshift1_n(v);
|
||||
if(l_carry) v[ECC_N_WORDS-1] |= HIGH_BIT_SET;
|
||||
}
|
||||
else if(l_cmpResult > 0)
|
||||
{
|
||||
vli_sub_n(a, a, b);
|
||||
vli_rshift1_n(a);
|
||||
if(vli_cmp_n(u, v) < 0) vli_add_n(u, u, p_mod);
|
||||
vli_sub_n(u, u, v);
|
||||
if(!EVEN(u)) l_carry = vli_add_n(u, u, p_mod);
|
||||
vli_rshift1_n(u);
|
||||
if(l_carry) u[ECC_N_WORDS-1] |= HIGH_BIT_SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
vli_sub_n(b, b, a);
|
||||
vli_rshift1_n(b);
|
||||
if(vli_cmp_n(v, u) < 0) vli_add_n(v, v, p_mod);
|
||||
vli_sub_n(v, v, u);
|
||||
if(!EVEN(v)) l_carry = vli_add_n(v, v, p_mod);
|
||||
vli_rshift1_n(v);
|
||||
if(l_carry) v[ECC_N_WORDS-1] |= HIGH_BIT_SET;
|
||||
}
|
||||
}
|
||||
|
||||
vli_set_n(p_result, u);
|
||||
}
|
||||
|
||||
static void vli2_rshift1_n(ecc_word_t *p_vli)
|
||||
{
|
||||
vli_rshift1_n(p_vli);
|
||||
p_vli[ECC_N_WORDS-1] |= p_vli[ECC_N_WORDS] << (ECC_WORD_BITS - 1);
|
||||
vli_rshift1_n(p_vli + ECC_N_WORDS);
|
||||
}
|
||||
|
||||
static ecc_word_t vli2_sub_n(ecc_word_t *p_result, ecc_word_t *p_left, ecc_word_t *p_right)
|
||||
{
|
||||
ecc_word_t l_borrow = 0;
|
||||
wordcount_t i;
|
||||
for(i=0; i<ECC_N_WORDS*2; ++i)
|
||||
{
|
||||
ecc_word_t l_diff = p_left[i] - p_right[i] - l_borrow;
|
||||
if(l_diff != p_left[i])
|
||||
{
|
||||
l_borrow = (l_diff > p_left[i]);
|
||||
}
|
||||
p_result[i] = l_diff;
|
||||
}
|
||||
return l_borrow;
|
||||
}
|
||||
|
||||
/* Computes p_result = (p_left * p_right) % curve_n. */
|
||||
static void vli_modMult_n(ecc_word_t *p_result, ecc_word_t *p_left, ecc_word_t *p_right)
|
||||
{
|
||||
ecc_word_t l_product[2 * ECC_N_WORDS];
|
||||
ecc_word_t l_modMultiple[2 * ECC_N_WORDS];
|
||||
ecc_word_t l_tmp[2 * ECC_N_WORDS];
|
||||
ecc_word_t *v[2] = {l_tmp, l_product};
|
||||
|
||||
vli_mult_n(l_product, p_left, p_right);
|
||||
vli_clear_n(l_modMultiple);
|
||||
vli_set(l_modMultiple + ECC_N_WORDS + 1, curve_n);
|
||||
vli_rshift1(l_modMultiple + ECC_N_WORDS + 1);
|
||||
l_modMultiple[2 * ECC_N_WORDS - 1] |= HIGH_BIT_SET;
|
||||
l_modMultiple[ECC_N_WORDS] = HIGH_BIT_SET;
|
||||
|
||||
bitcount_t i;
|
||||
ecc_word_t l_index = 1;
|
||||
for(i=0; i<=((ECC_N_WORDS * ECC_WORD_BITS) + (ECC_WORD_BITS - 1)); ++i)
|
||||
{
|
||||
ecc_word_t l_borrow = vli2_sub_n(v[1-l_index], v[l_index], l_modMultiple);
|
||||
l_index = !(l_index ^ l_borrow); /* Swap the index if there was no borrow */
|
||||
vli2_rshift1_n(l_modMultiple);
|
||||
}
|
||||
|
||||
vli_set_n(p_result, v[l_index]);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define vli_modInv_n vli_modInv
|
||||
#define vli_modAdd_n vli_modAdd
|
||||
|
||||
static void vli2_rshift1(ecc_word_t *p_vli)
|
||||
{
|
||||
vli_rshift1(p_vli);
|
||||
@@ -1766,30 +1979,48 @@ static void vli_modMult_n(ecc_word_t *p_result, ecc_word_t *p_left, ecc_word_t *
|
||||
|
||||
vli_set(p_result, v[l_index]);
|
||||
}
|
||||
#endif /* (ECC_CURVE != secp160r1) */
|
||||
|
||||
int ecdsa_sign(const uint8_t p_privateKey[ECC_BYTES], const uint8_t p_hash[ECC_BYTES], uint8_t p_signature[ECC_BYTES*2])
|
||||
{
|
||||
ecc_word_t k[ECC_WORDS];
|
||||
ecc_word_t l_tmp[ECC_WORDS];
|
||||
ecc_word_t s[ECC_WORDS];
|
||||
ecc_word_t k[ECC_N_WORDS];
|
||||
ecc_word_t l_tmp[ECC_N_WORDS];
|
||||
ecc_word_t s[ECC_N_WORDS];
|
||||
ecc_word_t *k2[2] = {l_tmp, s};
|
||||
EccPoint p;
|
||||
ecc_word_t l_tries = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if(!g_rng((uint8_t *)k, ECC_BYTES) || (l_tries++ >= MAX_TRIES))
|
||||
repeat:
|
||||
if(!g_rng((uint8_t *)k, sizeof(k)) || (l_tries++ >= MAX_TRIES))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(vli_isZero(k))
|
||||
{
|
||||
continue;
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
#if (ECC_CURVE == secp160r1)
|
||||
k[ECC_WORDS] &= 0x01;
|
||||
if(vli_cmp_n(curve_n, k) != 1)
|
||||
{
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
/* make sure that we don't leak timing information about k. See http://eprint.iacr.org/2011/232.pdf */
|
||||
vli_add_n(l_tmp, k, curve_n);
|
||||
ecc_word_t l_carry = (l_tmp[ECC_WORDS] & 0x02);
|
||||
vli_add_n(s, l_tmp, curve_n);
|
||||
|
||||
/* p = k * G */
|
||||
EccPoint_mult(&p, &curve_G, k2[!l_carry], 0, (ECC_BYTES * 8) + 2);
|
||||
#else
|
||||
if(vli_cmp(curve_n, k) != 1)
|
||||
{
|
||||
continue;
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
/* make sure that we don't leak timing information about k. See http://eprint.iacr.org/2011/232.pdf */
|
||||
@@ -1804,12 +2035,13 @@ int ecdsa_sign(const uint8_t p_privateKey[ECC_BYTES], const uint8_t p_hash[ECC_B
|
||||
{
|
||||
vli_sub(p.x, p.x, curve_n);
|
||||
}
|
||||
#endif
|
||||
} while(vli_isZero(p.x));
|
||||
|
||||
l_tries = 0;
|
||||
do
|
||||
{
|
||||
if(!g_rng((uint8_t *)l_tmp, ECC_BYTES) || (l_tries++ >= MAX_TRIES))
|
||||
if(!g_rng((uint8_t *)l_tmp, sizeof(l_tmp)) || (l_tries++ >= MAX_TRIES))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -1818,17 +2050,26 @@ int ecdsa_sign(const uint8_t p_privateKey[ECC_BYTES], const uint8_t p_hash[ECC_B
|
||||
/* Prevent side channel analysis of vli_modInv() to determine
|
||||
bits of k / the private key by premultiplying by a random number */
|
||||
vli_modMult_n(k, k, l_tmp); /* k' = rand * k */
|
||||
vli_modInv(k, k, curve_n); /* k = 1 / k' */
|
||||
vli_modInv_n(k, k, curve_n); /* k = 1 / k' */
|
||||
vli_modMult_n(k, k, l_tmp); /* k = 1 / k */
|
||||
|
||||
vli_nativeToBytes(p_signature, p.x); /* store r */
|
||||
|
||||
l_tmp[ECC_N_WORDS-1] = 0;
|
||||
vli_bytesToNative(l_tmp, p_privateKey); /* tmp = d */
|
||||
vli_modMult_n(s, l_tmp, p.x); /* s = r*d */
|
||||
s[ECC_N_WORDS-1] = 0;
|
||||
vli_set(s, p.x);
|
||||
vli_modMult_n(s, l_tmp, s); /* s = r*d */
|
||||
|
||||
vli_bytesToNative(l_tmp, p_hash);
|
||||
vli_modAdd(s, l_tmp, s, curve_n); /* s = e + r*d */
|
||||
vli_modAdd_n(s, l_tmp, s, curve_n); /* s = e + r*d */
|
||||
vli_modMult_n(s, s, k); /* s = (e + r*d) / k */
|
||||
#if (ECC_CURVE == secp160r1)
|
||||
if(s[ECC_N_WORDS-1])
|
||||
{
|
||||
goto repeat;
|
||||
}
|
||||
#endif
|
||||
vli_nativeToBytes(p_signature + ECC_BYTES, s);
|
||||
|
||||
return 1;
|
||||
@@ -1841,8 +2082,8 @@ static bitcount_t smax(bitcount_t a, bitcount_t b)
|
||||
|
||||
int ecdsa_verify(const uint8_t p_publicKey[ECC_BYTES*2], const uint8_t p_hash[ECC_BYTES], const uint8_t p_signature[ECC_BYTES*2])
|
||||
{
|
||||
ecc_word_t u1[ECC_WORDS], u2[ECC_WORDS];
|
||||
ecc_word_t z[ECC_WORDS];
|
||||
ecc_word_t u1[ECC_N_WORDS], u2[ECC_N_WORDS];
|
||||
ecc_word_t z[ECC_N_WORDS];
|
||||
EccPoint l_public, l_sum;
|
||||
ecc_word_t rx[ECC_WORDS];
|
||||
ecc_word_t ry[ECC_WORDS];
|
||||
@@ -1850,7 +2091,9 @@ int ecdsa_verify(const uint8_t p_publicKey[ECC_BYTES*2], const uint8_t p_hash[EC
|
||||
ecc_word_t ty[ECC_WORDS];
|
||||
ecc_word_t tz[ECC_WORDS];
|
||||
|
||||
ecc_word_t r[ECC_WORDS], s[ECC_WORDS];
|
||||
ecc_word_t r[ECC_N_WORDS], s[ECC_N_WORDS];
|
||||
r[ECC_N_WORDS-1] = 0;
|
||||
s[ECC_N_WORDS-1] = 0;
|
||||
|
||||
vli_bytesToNative(l_public.x, p_publicKey);
|
||||
vli_bytesToNative(l_public.y, p_publicKey + ECC_BYTES);
|
||||
@@ -1862,13 +2105,16 @@ int ecdsa_verify(const uint8_t p_publicKey[ECC_BYTES*2], const uint8_t p_hash[EC
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (ECC_CURVE != secp160r1)
|
||||
if(vli_cmp(curve_n, r) != 1 || vli_cmp(curve_n, s) != 1)
|
||||
{ /* r, s must be < n. */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Calculate u1 and u2. */
|
||||
vli_modInv(z, s, curve_n); /* Z = s^-1 */
|
||||
vli_modInv_n(z, s, curve_n); /* Z = s^-1 */
|
||||
u1[ECC_N_WORDS-1] = 0;
|
||||
vli_bytesToNative(u1, p_hash);
|
||||
vli_modMult_n(u1, u1, z); /* u1 = e/s */
|
||||
vli_modMult_n(u2, r, z); /* u2 = r/s */
|
||||
@@ -1885,7 +2131,7 @@ int ecdsa_verify(const uint8_t p_publicKey[ECC_BYTES*2], const uint8_t p_hash[EC
|
||||
|
||||
/* Use Shamir's trick to calculate u1*G + u2*Q */
|
||||
EccPoint *l_points[4] = {NULL, &curve_G, &l_public, &l_sum};
|
||||
bitcount_t l_numBits = smax(vli_numBits(u1), vli_numBits(u2));
|
||||
bitcount_t l_numBits = smax(vli_numBits(u1, ECC_N_WORDS), vli_numBits(u2, ECC_N_WORDS));
|
||||
|
||||
EccPoint *l_point = l_points[(!!vli_testBit(u1, l_numBits-1)) | ((!!vli_testBit(u2, l_numBits-1)) << 1)];
|
||||
vli_set(rx, l_point->x);
|
||||
@@ -1915,12 +2161,13 @@ int ecdsa_verify(const uint8_t p_publicKey[ECC_BYTES*2], const uint8_t p_hash[EC
|
||||
apply_z(rx, ry, z);
|
||||
|
||||
/* v = x1 (mod n) */
|
||||
#if (ECC_CURVE != secp160r1)
|
||||
if(vli_cmp(curve_n, rx) != 1)
|
||||
{
|
||||
vli_sub(rx, rx, curve_n);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Accept only if v == r. */
|
||||
return (vli_cmp(rx, r) == 0);
|
||||
}
|
||||
#endif /* (ECC_CURVE != secp160r1) */
|
||||
|
||||
Reference in New Issue
Block a user