Updated so that private keys are always the correct length.

Specifically, the private key for secp160r1 is now required to be
21 bytes. Added some comments about buffer sizes.
This commit is contained in:
Ken MacKay
2015-10-12 21:29:57 -07:00
parent 1341d3dce5
commit 4ae15e365b
4 changed files with 130 additions and 128 deletions
+25 -25
View File
@@ -17,8 +17,6 @@
#define num_words_secp256r1 32
#define num_words_secp256k1 32
#define num_n_words_secp160r1 21
#define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) \
0x##a, 0x##b, 0x##c, 0x##d, 0x##e, 0x##f, 0x##g, 0x##h
#define BYTES_TO_WORDS_4(a, b, c, d) 0x##a, 0x##b, 0x##c, 0x##d
@@ -31,8 +29,6 @@
#define num_words_secp256r1 8
#define num_words_secp256k1 8
#define num_n_words_secp160r1 6
#define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##d##c##b##a, 0x##h##g##f##e
#define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a
@@ -44,13 +40,13 @@
#define num_words_secp256r1 4
#define num_words_secp256k1 4
#define num_n_words_secp160r1 3
#define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##h##g##f##e##d##c##b##a##ull
#define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a##ull
#endif /* uECC_WORD_SIZE */
#if uECC_SUPPORTS_secp160r1 || uECC_SUPPORTS_secp192r1 || \
uECC_SUPPORTS_secp224r1 || uECC_SUPPORTS_secp256r1
static void double_jacobian_default(uECC_word_t * X1,
uECC_word_t * Y1,
uECC_word_t * Z1,
@@ -98,7 +94,21 @@ static void double_jacobian_default(uECC_word_t * X1,
uECC_vli_set(Y1, t4, num_words);
}
/* Computes result = x^3 + ax + b. result must not overlap x. */
static void x_side_default(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) {
uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */
wordcount_t num_words = curve->num_words;
uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */
uECC_vli_modSub(result, result, _3, curve->p, num_words); /* r = x^2 - 3 */
uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 - 3x */
uECC_vli_modAdd(result, result, curve->b, curve->p, num_words); /* r = x^3 - 3x + b */
}
#endif /* uECC_SUPPORTS_secp... */
#if uECC_SUPPORT_COMPRESSED_POINT
#if uECC_SUPPORTS_secp160r1 || uECC_SUPPORTS_secp192r1 || \
uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1
/* Compute a = sqrt(a) (mod curve_p). */
static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) {
bitcount_t i;
@@ -117,18 +127,8 @@ static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) {
}
uECC_vli_set(a, l_result, num_words);
}
#endif
/* Computes result = x^3 + ax + b. result must not overlap x. */
static void x_side_default(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) {
uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */
wordcount_t num_words = curve->num_words;
uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */
uECC_vli_modSub(result, result, _3, curve->p, num_words); /* r = x^2 - 3 */
uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 - 3x */
uECC_vli_modAdd(result, result, curve->b, curve->p, num_words); /* r = x^3 - 3x + b */
}
#endif /* uECC_SUPPORTS_secp... */
#endif /* uECC_SUPPORT_COMPRESSED_POINT */
#if uECC_SUPPORTS_secp160r1
@@ -138,8 +138,8 @@ static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product);
static const struct uECC_Curve_t curve_secp160r1 = {
num_words_secp160r1,
num_n_words_secp160r1,
num_bytes_secp160r1,
161, /* num_n_bits */
{ BYTES_TO_WORDS_8(FF, FF, FF, 7F, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_4(FF, FF, FF, FF) },
@@ -282,9 +282,9 @@ static void vli_mmod_fast_secp192r1(uECC_word_t *result, uECC_word_t *product);
#endif
static const struct uECC_Curve_t curve_secp192r1 = {
num_words_secp192r1,
num_words_secp192r1,
num_bytes_secp192r1,
192, /* num_n_bits */
{ BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) },
@@ -382,7 +382,7 @@ static void vli_mmod_fast_secp192r1(uint64_t *result, uint64_t *product) {
uECC_vli_set(result, product, num_words_secp192r1);
uECC_vli_set(tmp, &product[3], num_words_secp192r1);
carry = uECC_vli_add(result, result, tmp, num_words_secp192r1);
carry = (int)uECC_vli_add(result, result, tmp, num_words_secp192r1);
tmp[0] = 0;
tmp[1] = product[3];
@@ -412,9 +412,9 @@ static void vli_mmod_fast_secp224r1(uECC_word_t *result, uECC_word_t *product);
#endif
static const struct uECC_Curve_t curve_secp224r1 = {
num_words_secp224r1,
num_words_secp224r1,
num_bytes_secp224r1,
224, /* num_n_bits */
{ BYTES_TO_WORDS_8(01, 00, 00, 00, 00, 00, 00, 00),
BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
@@ -734,9 +734,9 @@ static void vli_mmod_fast_secp256r1(uECC_word_t *result, uECC_word_t *product);
#endif
static const struct uECC_Curve_t curve_secp256r1 = {
num_words_secp256r1,
num_words_secp256r1,
num_bytes_secp256r1,
256, /* num_n_bits */
{ BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00),
BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00),
@@ -990,7 +990,7 @@ static void vli_mmod_fast_secp256r1(uint64_t *result, uint64_t *product) {
tmp[1] = product[5] & 0xffffffff00000000ull;
tmp[2] = product[6];
tmp[3] = product[7];
carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1);
carry = (int)uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1);
carry += uECC_vli_add(result, result, tmp, num_words_secp256r1);
/* s2 */
@@ -1069,9 +1069,9 @@ static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product);
#endif
static const struct uECC_Curve_t curve_secp256k1 = {
num_words_secp256k1,
num_words_secp256k1,
num_bytes_secp256k1,
256, /* num_n_bits */
{ BYTES_TO_WORDS_8(2F, FC, FF, FF, FE, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
+82 -96
View File
@@ -39,10 +39,13 @@
#define uECC_MAX_WORDS ((uECC_MAX_BYTES + 7) / 8)
#endif /* uECC_WORD_SIZE */
#define BITS_TO_WORDS(num_bits) ((num_bits + ((uECC_WORD_SIZE * 8) - 1)) / (uECC_WORD_SIZE * 8))
#define BITS_TO_BYTES(num_bits) ((num_bits + 7) / 8)
struct uECC_Curve_t {
wordcount_t num_words;
wordcount_t num_n_words;
wordcount_t num_bytes;
bitcount_t num_n_bits;
uECC_word_t p[uECC_MAX_WORDS];
uECC_word_t n[uECC_MAX_WORDS];
uECC_word_t G[uECC_MAX_WORDS * 2];
@@ -769,11 +772,11 @@ static uECC_word_t regularize_k(const uECC_word_t * const k,
uECC_word_t *k0,
uECC_word_t *k1,
uECC_Curve curve) {
wordcount_t num_n_words = curve->num_n_words;
bitcount_t num_bits = uECC_vli_numBits(curve->n, num_n_words);
wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
bitcount_t num_n_bits = curve->num_n_bits;
uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) ||
(num_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) &&
uECC_vli_testBit(k0, num_bits));
(num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) &&
uECC_vli_testBit(k0, num_n_bits));
uECC_vli_add(k1, k0, curve->n, num_n_words);
return carry;
}
@@ -791,7 +794,7 @@ static uECC_word_t EccPoint_compute_public_key(uECC_word_t *result,
return 0;
}
if (uECC_vli_cmp(curve->n, private, curve->num_n_words) != 1) {
if (uECC_vli_cmp(curve->n, private, BITS_TO_WORDS(curve->num_n_bits)) != 1) {
return 0;
}
@@ -799,9 +802,7 @@ static uECC_word_t EccPoint_compute_public_key(uECC_word_t *result,
attack to learn the number of leading zeros. */
carry = regularize_k(private, tmp1, tmp2, curve);
EccPoint_mult(result, curve->G, p2[!carry], 0,
uECC_vli_numBits(curve->n, curve->num_n_words) + 1,
curve);
EccPoint_mult(result, curve->G, p2[!carry], 0, curve->num_n_bits + 1, curve);
if (EccPoint_isZero(result, curve)) {
return 0;
@@ -811,60 +812,46 @@ static uECC_word_t EccPoint_compute_public_key(uECC_word_t *result,
#if uECC_WORD_SIZE == 1
uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, const uint8_t *native, uECC_Curve curve) {
uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes,
int num_bytes,
const uint8_t *native,
uECC_Curve curve) {
wordcount_t i;
wordcount_t num_words = curve->num_words;
for (i = 0; i < num_words; ++i) {
dest[i] = src[(num_words - 1) - i];
for (i = 0; i < num_bytes; ++i) {
bytes[i] = native[(num_bytes - 1) - i];
}
}
uECC_VLI_API void uECC_vli_bytesToNative(uint8_t *native, const uint8_t *bytes, uECC_Curve curve) {
uECC_vli_nativeToBytes(dest, src, curve);
}
#elif uECC_WORD_SIZE == 4
uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, const uint32_t *native, uECC_Curve curve) {
wordcount_t i;
wordcount_t num_words = curve->num_words;
for (i = 0; i < num_words; ++i) {
uint8_t *digit = bytes + 4 * (num_words - 1 - i);
digit[0] = native[i] >> 24;
digit[1] = native[i] >> 16;
digit[2] = native[i] >> 8;
digit[3] = native[i];
}
}
uECC_VLI_API void uECC_vli_bytesToNative(uint32_t *native, const uint8_t *bytes, uECC_Curve curve) {
wordcount_t i;
wordcount_t num_words = curve->num_words;
for (i = 0; i < num_words; ++i) {
const uint8_t *digit = bytes + 4 * (num_words - 1 - i);
native[i] = ((uint32_t)digit[0] << 24) | ((uint32_t)digit[1] << 16) |
((uint32_t)digit[2] << 8) | (uint32_t)digit[3];
}
uECC_VLI_API void uECC_vli_bytesToNative(uint8_t *native,
const uint8_t *bytes,
int num_bytes,
uECC_Curve curve) {
uECC_vli_nativeToBytes(native, num_bytes, bytes, curve);
}
#else
uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, const uint64_t *native, uECC_Curve curve) {
uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes,
int num_bytes,
const uECC_word_t *native,
uECC_Curve curve) {
wordcount_t i;
wordcount_t num_bytes = curve->num_bytes;
for (i = 0; i < num_bytes; ++i) {
unsigned b = num_bytes - 1 - i;
bytes[i] = native[b / 8] >> (8 * (b % 8));
bytes[i] = native[b / uECC_WORD_SIZE] >> (8 * (b % uECC_WORD_SIZE));
}
}
uECC_VLI_API void uECC_vli_bytesToNative(uint64_t *native, const uint8_t *bytes, uECC_Curve curve) {
uECC_VLI_API void uECC_vli_bytesToNative(uECC_word_t *native,
const uint8_t *bytes,
int num_bytes,
uECC_Curve curve) {
wordcount_t i;
wordcount_t num_bytes = curve->num_bytes;
uECC_vli_clear(native, curve->num_words);
uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE);
for (i = 0; i < num_bytes; ++i) {
unsigned b = num_bytes - 1 - i;
native[b / 8] |= (uint64_t)bytes[i] << (8 * (b % 8));
native[b / uECC_WORD_SIZE] |=
(uECC_word_t)bytes[i] << (8 * (b % uECC_WORD_SIZE));
}
}
@@ -892,18 +879,16 @@ int uECC_make_key(uint8_t *public_key,
uECC_word_t public[uECC_MAX_WORDS * 2];
uECC_word_t tries;
/* Zero out correctly (to compare to curve->n) for secp160r1. */
private[curve->num_n_words - 1] = 0;
for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
if (!generate_random_int(private, curve->num_words, curve->num_bytes * 8)) {
if (!generate_random_int(private, BITS_TO_WORDS(curve->num_n_bits), curve->num_n_bits)) {
return 0;
}
if (EccPoint_compute_public_key(public, private, curve)) {
uECC_vli_nativeToBytes(private_key, private, curve);
uECC_vli_nativeToBytes(public_key, public, curve);
uECC_vli_nativeToBytes(public_key + curve->num_bytes, public + curve->num_words, curve);
uECC_vli_nativeToBytes(private_key, BITS_TO_BYTES(curve->num_n_bits), private, curve);
uECC_vli_nativeToBytes(public_key, curve->num_bytes, public, curve);
uECC_vli_nativeToBytes(
public_key + curve->num_bytes, curve->num_bytes, public + curve->num_words, curve);
return 1;
}
}
@@ -923,12 +908,10 @@ int uECC_shared_secret(const uint8_t *public_key,
uECC_word_t carry;
wordcount_t num_words = curve->num_words;
/* Zero out correctly (for addition with curve->n) for secp160r1. */
private[curve->num_n_words - 1] = 0;
uECC_vli_bytesToNative(private, private_key, curve);
uECC_vli_bytesToNative(public, public_key, curve);
uECC_vli_bytesToNative(public + num_words, public_key + curve->num_bytes, curve);
uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits), curve);
uECC_vli_bytesToNative(public, public_key, curve->num_bytes, curve);
uECC_vli_bytesToNative(
public + num_words, public_key + curve->num_bytes, curve->num_bytes, curve);
/* Regularize the bitcount for the private key so that attackers cannot use a side channel
attack to learn the number of leading zeros. */
@@ -950,10 +933,8 @@ int uECC_shared_secret(const uint8_t *public_key,
}
}
EccPoint_mult(public, public, p2[!carry], initial_Z,
uECC_vli_numBits(curve->n, curve->num_n_words) + 1,
curve);
uECC_vli_nativeToBytes(secret, public, curve);
EccPoint_mult(public, public, p2[!carry], initial_Z, curve->num_n_bits + 1, curve);
uECC_vli_nativeToBytes(secret, curve->num_bytes, public, curve);
return !EccPoint_isZero(public, curve);
}
@@ -969,7 +950,7 @@ void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve cu
void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve) {
uECC_word_t point[uECC_MAX_WORDS * 2];
uECC_word_t *y = point + curve->num_words;
uECC_vli_bytesToNative(point, compressed + 1, curve);
uECC_vli_bytesToNative(point, compressed + 1, curve->num_bytes, curve);
curve->x_side(y, point, curve);
curve->mod_sqrt(y, curve);
@@ -977,8 +958,8 @@ void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve
uECC_vli_sub(y, curve->p, y, curve->num_words);
}
uECC_vli_nativeToBytes(public_key, point, curve);
uECC_vli_nativeToBytes(public_key + curve->num_bytes, y, curve);
uECC_vli_nativeToBytes(public_key, curve->num_bytes, point, curve);
uECC_vli_nativeToBytes(public_key + curve->num_bytes, curve->num_bytes, y, curve);
}
#endif /* uECC_SUPPORT_COMPRESSED_POINT */
@@ -1002,14 +983,15 @@ int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) {
curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */
/* Make sure that y^2 == x^3 + ax + b */
return (uECC_vli_equal(tmp1, tmp2, num_words));
return (int)(uECC_vli_equal(tmp1, tmp2, num_words));
}
int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve) {
uECC_word_t public[uECC_MAX_WORDS * 2];
uECC_vli_bytesToNative(public, public_key, curve);
uECC_vli_bytesToNative(public + curve->num_words, public_key + curve->num_bytes, curve);
uECC_vli_bytesToNative(public, public_key, curve->num_bytes, curve);
uECC_vli_bytesToNative(
public + curve->num_words, public_key + curve->num_bytes, curve->num_bytes, curve);
return uECC_valid_point(public, curve);
}
@@ -1017,14 +999,15 @@ int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uEC
uECC_word_t private[uECC_MAX_WORDS];
uECC_word_t public[uECC_MAX_WORDS * 2];
uECC_vli_bytesToNative(private, private_key, curve);
uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits), curve);
if (!EccPoint_compute_public_key(public, private, curve)) {
return 0;
}
uECC_vli_nativeToBytes(public_key, public, curve);
uECC_vli_nativeToBytes(public_key + curve->num_bytes, public + curve->num_words, curve);
uECC_vli_nativeToBytes(public_key, curve->num_bytes, public, curve);
uECC_vli_nativeToBytes(
public_key + curve->num_bytes, curve->num_bytes, public + curve->num_words, curve);
return 1;
}
@@ -1042,8 +1025,8 @@ static int uECC_sign_with_k(const uint8_t *private_key,
uECC_word_t p[uECC_MAX_WORDS * 2];
uECC_word_t carry;
wordcount_t num_words = curve->num_words;
wordcount_t num_n_words = curve->num_n_words;
bitcount_t num_n_bits = uECC_vli_numBits(curve->n, num_n_words);
wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
bitcount_t num_n_bits = curve->num_n_bits;
/* Make sure 0 < k < curve_n */
if (uECC_vli_isZero(k, num_words) || uECC_vli_cmp(curve->n, k, num_n_words) != 1) {
@@ -1081,21 +1064,20 @@ got_random:
uECC_vli_modInv(k, k, curve->n, num_n_words); /* k = 1 / k' */
uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k = 1 / k */
uECC_vli_nativeToBytes(signature, p, curve); /* store r */
uECC_vli_nativeToBytes(signature, curve->num_bytes, p, curve); /* store r */
tmp[num_n_words - 1] = 0;
uECC_vli_bytesToNative(tmp, private_key, curve); /* tmp = d */
uECC_vli_bytesToNative(tmp, private_key, BITS_TO_BYTES(curve->num_n_bits), curve); /* tmp = d */
s[num_n_words - 1] = 0;
uECC_vli_set(s, p, num_words);
uECC_vli_modMult(s, tmp, s, curve->n, num_n_words); /* s = r*d */
uECC_vli_bytesToNative(tmp, message_hash, curve);
uECC_vli_bytesToNative(tmp, message_hash, curve->num_bytes, curve);
uECC_vli_modAdd(s, tmp, s, curve->n, num_n_words); /* s = e + r*d */
uECC_vli_modMult(s, s, k, curve->n, num_n_words); /* s = (e + r*d) / k */
if (uECC_vli_numBits(s, num_n_words) > (bitcount_t)curve->num_bytes * 8) {
return 0;
}
uECC_vli_nativeToBytes(signature + curve->num_bytes, s, curve);
uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s, curve);
return 1;
}
@@ -1105,10 +1087,11 @@ int uECC_sign(const uint8_t *private_key,
uECC_Curve curve) {
uECC_word_t k[uECC_MAX_WORDS];
uECC_word_t tries;
bitcount_t num_n_bits = uECC_vli_numBits(curve->n, curve->num_n_words);
wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
bitcount_t num_n_bits = curve->num_n_bits;
for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
if (!generate_random_int(k, curve->num_n_words, num_n_bits)) {
if (!generate_random_int(k, num_n_words, num_n_bits)) {
return 0;
}
@@ -1176,8 +1159,8 @@ int uECC_sign_deterministic(const uint8_t *private_key,
uint8_t *K = hash_context->tmp;
uint8_t *V = K + hash_context->result_size;
wordcount_t num_bytes = curve->num_bytes;
wordcount_t num_n_words = curve->num_n_words;
bitcount_t num_n_bits = uECC_vli_numBits(curve->n, num_n_words);
wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
bitcount_t num_n_bits = curve->num_n_bits;
uECC_word_t tries;
unsigned i;
for (i = 0; i < hash_context->result_size; ++i) {
@@ -1263,16 +1246,17 @@ int uECC_verify(const uint8_t *public_key,
bitcount_t i;
uECC_word_t r[uECC_MAX_WORDS], s[uECC_MAX_WORDS];
wordcount_t num_words = curve->num_words;
wordcount_t num_n_words = curve->num_n_words;
wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
rx[num_n_words - 1] = 0;
r[num_n_words - 1] = 0;
s[num_n_words - 1] = 0;
uECC_vli_bytesToNative(public, public_key, curve);
uECC_vli_bytesToNative(public + num_words, public_key + curve->num_bytes, curve);
uECC_vli_bytesToNative(r, signature, curve);
uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve);
uECC_vli_bytesToNative(public, public_key, curve->num_bytes, curve);
uECC_vli_bytesToNative(
public + num_words, public_key + curve->num_bytes, curve->num_bytes, curve);
uECC_vli_bytesToNative(r, signature, curve->num_bytes, curve);
uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve->num_bytes, curve);
/* r, s must not be 0. */
if (uECC_vli_isZero(r, num_words) || uECC_vli_isZero(s, num_words)) {
@@ -1288,7 +1272,7 @@ int uECC_verify(const uint8_t *public_key,
/* Calculate u1 and u2. */
uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */
u1[num_n_words - 1] = 0;
uECC_vli_bytesToNative(u1, hash, curve);
uECC_vli_bytesToNative(u1, hash, curve->num_bytes, curve);
uECC_vli_modMult(u1, u1, z, curve->n, num_n_words); /* u1 = e/s */
uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */
@@ -1342,7 +1326,7 @@ int uECC_verify(const uint8_t *public_key,
}
/* Accept only if v == r. */
return (uECC_vli_equal(rx, r, num_words));
return (int)(uECC_vli_equal(rx, r, num_words));
}
#if uECC_ENABLE_VLI_API
@@ -1356,7 +1340,11 @@ unsigned uECC_curve_num_bits(uECC_Curve curve) {
}
unsigned uECC_curve_num_n_words(uECC_Curve curve) {
return curve->num_n_words;
return BITS_TO_WORDS(curve->num_n_bits);
}
unsigned uECC_curve_num_n_bits(uECC_Curve curve) {
return curve->num_n_bits;
}
const uECC_word_t *uECC_curve_p(uECC_Curve curve) {
@@ -1398,14 +1386,12 @@ void uECC_point_mult(uECC_word_t *result,
uECC_word_t *p2[2] = {tmp1, tmp2};
uECC_word_t carry = regularize_k(scalar, tmp1, tmp2, curve);
EccPoint_mult(result, point, p2[!carry], 0,
uECC_vli_numBits(curve->n, curve->num_n_words) + 1,
curve);
EccPoint_mult(result, point, p2[!carry], 0, curve->num_n_bits + 1, curve);
}
int uECC_generate_random_int(uECC_word_t *random, uECC_Curve curve) {
wordcount_t num_n_words = curve->num_n_words;
bitcount_t num_n_bits = uECC_vli_numBits(curve->n, num_n_words);
wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
bitcount_t num_n_bits = curve->num_n_bits;
uECC_word_t tries;
for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
+16 -5
View File
@@ -113,8 +113,15 @@ void uECC_set_rng(uECC_RNG_Function rng_function);
Create a public/private key pair.
Outputs:
public_key - Will be filled in with the public key.
private_key - Will be filled in with the private key.
public_key - Will be filled in with the public key. Must be at least 2 * the curve size
(in bytes) long. For example, if the curve is secp256r1, public_key must be 64
bytes long.
private_key - Will be filled in with the private key. Must be as long as the curve order; this
is typically the same as the curve size, except for secp160r1. For example, if the
curve is secp256r1, private_key must be 32 bytes long.
For secp160r1, private_key must be 21 bytes long! Note that the first byte will
almost always be 0 (there is about a 1 in 2^80 chance of it being non-zero).
Returns 1 if the key pair was generated successfully, 0 if an error occurred.
*/
@@ -130,7 +137,8 @@ Inputs:
private_key - Your private key.
Outputs:
secret - Will be filled in with the shared secret value.
secret - Will be filled in with the shared secret value. Must be the same size as the
curve size; for example, if the curve is secp256r1, secret must be 32 bytes long.
Returns 1 if the shared secret was generated successfully, 0 if an error occurred.
*/
@@ -147,7 +155,9 @@ Inputs:
public_key - The public key to compress.
Outputs:
compressed - Will be filled in with the compressed public key.
compressed - Will be filled in with the compressed public key. Must be at least
(curve size + 1) bytes long; for example, if the curve is secp256r1,
compressed must be 33 bytes long.
*/
void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve);
@@ -201,7 +211,8 @@ Inputs:
message_hash - The hash of the message to sign.
Outputs:
signature - Will be filled in with the signature value.
signature - Will be filled in with the signature value. Must be at least 2 * curve size long.
For example, if the curve is secp256r1, signature must be 64 bytes long.
Returns 1 if the signature generated successfully, 0 if an error occurred.
*/
+7 -2
View File
@@ -59,11 +59,13 @@ uECC_word_t uECC_vli_sub(uECC_word_t *result,
const uECC_word_t *right,
wordcount_t num_words);
/* Computes result = left * right. Result must be 2 * num_words long. */
void uECC_vli_mult(uECC_word_t *result,
const uECC_word_t *left,
const uECC_word_t *right,
wordcount_t num_words);
/* Computes result = left^2. Result must be 2 * num_words long. */
void uECC_vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t num_words);
/* Computes result = (left + right) % mod.
@@ -128,12 +130,15 @@ void uECC_vli_modInv(uECC_word_t *result,
void uECC_vli_mod_sqrt(uECC_word_t *a, uECC_Curve curve);
#endif
void uECC_vli_nativeToBytes(uint8_t *bytes, const uECC_word_t *native, uECC_Curve curve);
void uECC_vli_bytesToNative(uECC_word_t *native, const uint8_t *bytes, uECC_Curve curve);
/* Converts an integer in uECC native format to big-endian bytes. */
void uECC_vli_nativeToBytes(uint8_t *bytes, int num_bytes, const uECC_word_t *native, uECC_Curve curve);
/* Converts big-endian bytes to an integer in uECC native format. */
void uECC_vli_bytesToNative(uECC_word_t *native, const uint8_t *bytes, int num_bytes, uECC_Curve curve);
unsigned uECC_curve_num_words(uECC_Curve curve);
unsigned uECC_curve_num_bits(uECC_Curve curve);
unsigned uECC_curve_num_n_words(uECC_Curve curve);
unsigned uECC_curve_num_n_bits(uECC_Curve curve);
const uECC_word_t *uECC_curve_p(uECC_Curve curve);
const uECC_word_t *uECC_curve_n(uECC_Curve curve);