Move p from curve structure to its own constant

This removes an indirection, which both makes the code smaller and decreases
the number of glitching opportunities for an attacker.
This commit is contained in:
Manuel Pégourié-Gonnard 2019-11-21 10:02:58 +01:00
parent 30833f2a07
commit 4d8777cbb6
3 changed files with 58 additions and 48 deletions

View File

@ -124,7 +124,6 @@ typedef uint64_t uECC_dword_t;
struct uECC_Curve_t;
typedef const struct uECC_Curve_t * uECC_Curve;
struct uECC_Curve_t {
uECC_word_t p[NUM_ECC_WORDS];
uECC_word_t n[NUM_ECC_WORDS];
uECC_word_t G[NUM_ECC_WORDS * 2];
uECC_word_t b[NUM_ECC_WORDS];
@ -155,14 +154,11 @@ void vli_mmod_fast_secp256r1(unsigned int *result, unsigned int *product);
((num_bits + ((uECC_WORD_SIZE * 8) - 1)) / (uECC_WORD_SIZE * 8))
#define BITS_TO_BYTES(num_bits) ((num_bits + 7) / 8)
extern const uECC_word_t curve_p[NUM_ECC_WORDS];
/* definition of curve NIST p-256: */
static const struct uECC_Curve_t curve_secp256r1 = {
{
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),
BYTES_TO_WORDS_8(01, 00, 00, 00, FF, FF, FF, FF)
}, {
BYTES_TO_WORDS_8(51, 25, 63, FC, C2, CA, B9, F3),
BYTES_TO_WORDS_8(84, 9E, 17, A7, AD, FA, E6, BC),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),

View File

@ -68,6 +68,14 @@
#include "mbedtls/platform_util.h"
#include <string.h>
/* Parameters for curve NIST P-256 aka secp256r1 */
const uECC_word_t curve_p[NUM_ECC_WORDS] = {
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),
BYTES_TO_WORDS_8(01, 00, 00, 00, FF, FF, FF, FF)
};
/* IMPORTANT: Make sure a cryptographically-secure PRNG is set and the platform
* has access to enough entropy in order to feed the PRNG regularly. */
#if default_RNG_defined
@ -585,6 +593,8 @@ void double_jacobian_default(uECC_word_t * X1, uECC_word_t * Y1,
uECC_word_t t5[NUM_ECC_WORDS];
wordcount_t num_words = NUM_ECC_WORDS;
(void) curve;
if (uECC_vli_isZero(Z1)) {
return;
}
@ -595,15 +605,15 @@ void double_jacobian_default(uECC_word_t * X1, uECC_word_t * Y1,
uECC_vli_modMult_fast(Y1, Y1, Z1); /* t2 = y1*z1 = z3 */
uECC_vli_modMult_fast(Z1, Z1, Z1); /* t3 = z1^2 */
uECC_vli_modAdd(X1, X1, Z1, curve->p); /* t1 = x1 + z1^2 */
uECC_vli_modAdd(Z1, Z1, Z1, curve->p); /* t3 = 2*z1^2 */
uECC_vli_modSub(Z1, X1, Z1, curve->p); /* t3 = x1 - z1^2 */
uECC_vli_modAdd(X1, X1, Z1, curve_p); /* t1 = x1 + z1^2 */
uECC_vli_modAdd(Z1, Z1, Z1, curve_p); /* t3 = 2*z1^2 */
uECC_vli_modSub(Z1, X1, Z1, curve_p); /* t3 = x1 - z1^2 */
uECC_vli_modMult_fast(X1, X1, Z1); /* t1 = x1^2 - z1^4 */
uECC_vli_modAdd(Z1, X1, X1, curve->p); /* t3 = 2*(x1^2 - z1^4) */
uECC_vli_modAdd(X1, X1, Z1, curve->p); /* t1 = 3*(x1^2 - z1^4) */
uECC_vli_modAdd(Z1, X1, X1, curve_p); /* t3 = 2*(x1^2 - z1^4) */
uECC_vli_modAdd(X1, X1, Z1, curve_p); /* t1 = 3*(x1^2 - z1^4) */
if (uECC_vli_testBit(X1, 0)) {
uECC_word_t l_carry = uECC_vli_add(X1, X1, curve->p);
uECC_word_t l_carry = uECC_vli_add(X1, X1, curve_p);
uECC_vli_rshift1(X1);
X1[num_words - 1] |= l_carry << (uECC_WORD_BITS - 1);
} else {
@ -612,12 +622,12 @@ void double_jacobian_default(uECC_word_t * X1, uECC_word_t * Y1,
/* t1 = 3/2*(x1^2 - z1^4) = B */
uECC_vli_modMult_fast(Z1, X1, X1); /* t3 = B^2 */
uECC_vli_modSub(Z1, Z1, t5, curve->p); /* t3 = B^2 - A */
uECC_vli_modSub(Z1, Z1, t5, curve->p); /* t3 = B^2 - 2A = x3 */
uECC_vli_modSub(t5, t5, Z1, curve->p); /* t5 = A - x3 */
uECC_vli_modSub(Z1, Z1, t5, curve_p); /* t3 = B^2 - A */
uECC_vli_modSub(Z1, Z1, t5, curve_p); /* t3 = B^2 - 2A = x3 */
uECC_vli_modSub(t5, t5, Z1, curve_p); /* t5 = A - x3 */
uECC_vli_modMult_fast(X1, X1, t5); /* t1 = B * (A - x3) */
/* t4 = B * (A - x3) - y1^4 = y3: */
uECC_vli_modSub(t4, X1, t4, curve->p);
uECC_vli_modSub(t4, X1, t4, curve_p);
uECC_vli_set(X1, Z1);
uECC_vli_set(Z1, Y1);
@ -637,10 +647,10 @@ static void x_side_default(uECC_word_t *result,
uECC_word_t _3[NUM_ECC_WORDS] = {3}; /* -a = 3 */
uECC_vli_modMult_fast(result, x, x); /* r = x^2 */
uECC_vli_modSub(result, result, _3, curve->p); /* r = x^2 - 3 */
uECC_vli_modSub(result, result, _3, curve_p); /* r = x^2 - 3 */
uECC_vli_modMult_fast(result, result, x); /* r = x^3 - 3x */
/* r = x^3 - 3x + b: */
uECC_vli_modAdd(result, result, curve->b, curve->p);
uECC_vli_modAdd(result, result, curve->b, curve_p);
}
uECC_Curve uECC_secp256r1(void)
@ -738,13 +748,13 @@ void vli_mmod_fast_secp256r1(unsigned int *result, unsigned int*product)
if (carry < 0) {
do {
carry += uECC_vli_add(result, result, curve_secp256r1.p);
carry += uECC_vli_add(result, result, curve_p);
}
while (carry < 0);
} else {
while (carry ||
uECC_vli_cmp_unsafe(curve_secp256r1.p, result) != 1) {
carry -= uECC_vli_sub(result, result, curve_secp256r1.p);
uECC_vli_cmp_unsafe(curve_p, result) != 1) {
carry -= uECC_vli_sub(result, result, curve_p);
}
}
}
@ -795,20 +805,22 @@ static void XYcZ_add_rnd(uECC_word_t * X1, uECC_word_t * Y1,
uECC_word_t t5[NUM_ECC_WORDS];
const uECC_Curve curve = &curve_secp256r1;
uECC_vli_modSub(t5, X2, X1, curve->p); /* t5 = x2 - x1 */
(void) curve;
uECC_vli_modSub(t5, X2, X1, curve_p); /* t5 = x2 - x1 */
uECC_vli_modMult_rnd(t5, t5, t5, s); /* t5 = (x2 - x1)^2 = A */
uECC_vli_modMult_rnd(X1, X1, t5, s); /* t1 = x1*A = B */
uECC_vli_modMult_rnd(X2, X2, t5, s); /* t3 = x2*A = C */
uECC_vli_modSub(Y2, Y2, Y1, curve->p); /* t4 = y2 - y1 */
uECC_vli_modSub(Y2, Y2, Y1, curve_p); /* t4 = y2 - y1 */
uECC_vli_modMult_rnd(t5, Y2, Y2, s); /* t5 = (y2 - y1)^2 = D */
uECC_vli_modSub(t5, t5, X1, curve->p); /* t5 = D - B */
uECC_vli_modSub(t5, t5, X2, curve->p); /* t5 = D - B - C = x3 */
uECC_vli_modSub(X2, X2, X1, curve->p); /* t3 = C - B */
uECC_vli_modSub(t5, t5, X1, curve_p); /* t5 = D - B */
uECC_vli_modSub(t5, t5, X2, curve_p); /* t5 = D - B - C = x3 */
uECC_vli_modSub(X2, X2, X1, curve_p); /* t3 = C - B */
uECC_vli_modMult_rnd(Y1, Y1, X2, s); /* t2 = y1*(C - B) */
uECC_vli_modSub(X2, X1, t5, curve->p); /* t3 = B - x3 */
uECC_vli_modSub(X2, X1, t5, curve_p); /* t3 = B - x3 */
uECC_vli_modMult_rnd(Y2, Y2, X2, s); /* t4 = (y2 - y1)*(B - x3) */
uECC_vli_modSub(Y2, Y2, Y1, curve->p); /* t4 = y3 */
uECC_vli_modSub(Y2, Y2, Y1, curve_p); /* t4 = y3 */
uECC_vli_set(X2, t5);
}
@ -835,30 +847,32 @@ static void XYcZ_addC_rnd(uECC_word_t * X1, uECC_word_t * Y1,
uECC_word_t t7[NUM_ECC_WORDS];
const uECC_Curve curve = &curve_secp256r1;
uECC_vli_modSub(t5, X2, X1, curve->p); /* t5 = x2 - x1 */
(void) curve;
uECC_vli_modSub(t5, X2, X1, curve_p); /* t5 = x2 - x1 */
uECC_vli_modMult_rnd(t5, t5, t5, s); /* t5 = (x2 - x1)^2 = A */
uECC_vli_modMult_rnd(X1, X1, t5, s); /* t1 = x1*A = B */
uECC_vli_modMult_rnd(X2, X2, t5, s); /* t3 = x2*A = C */
uECC_vli_modAdd(t5, Y2, Y1, curve->p); /* t5 = y2 + y1 */
uECC_vli_modSub(Y2, Y2, Y1, curve->p); /* t4 = y2 - y1 */
uECC_vli_modAdd(t5, Y2, Y1, curve_p); /* t5 = y2 + y1 */
uECC_vli_modSub(Y2, Y2, Y1, curve_p); /* t4 = y2 - y1 */
uECC_vli_modSub(t6, X2, X1, curve->p); /* t6 = C - B */
uECC_vli_modSub(t6, X2, X1, curve_p); /* t6 = C - B */
uECC_vli_modMult_rnd(Y1, Y1, t6, s); /* t2 = y1 * (C - B) = E */
uECC_vli_modAdd(t6, X1, X2, curve->p); /* t6 = B + C */
uECC_vli_modAdd(t6, X1, X2, curve_p); /* t6 = B + C */
uECC_vli_modMult_rnd(X2, Y2, Y2, s); /* t3 = (y2 - y1)^2 = D */
uECC_vli_modSub(X2, X2, t6, curve->p); /* t3 = D - (B + C) = x3 */
uECC_vli_modSub(X2, X2, t6, curve_p); /* t3 = D - (B + C) = x3 */
uECC_vli_modSub(t7, X1, X2, curve->p); /* t7 = B - x3 */
uECC_vli_modSub(t7, X1, X2, curve_p); /* t7 = B - x3 */
uECC_vli_modMult_rnd(Y2, Y2, t7, s); /* t4 = (y2 - y1)*(B - x3) */
/* t4 = (y2 - y1)*(B - x3) - E = y3: */
uECC_vli_modSub(Y2, Y2, Y1, curve->p);
uECC_vli_modSub(Y2, Y2, Y1, curve_p);
uECC_vli_modMult_rnd(t7, t5, t5, s); /* t7 = (y2 + y1)^2 = F */
uECC_vli_modSub(t7, t7, t6, curve->p); /* t7 = F - (B + C) = x3' */
uECC_vli_modSub(t6, t7, X1, curve->p); /* t6 = x3' - B */
uECC_vli_modSub(t7, t7, t6, curve_p); /* t7 = F - (B + C) = x3' */
uECC_vli_modSub(t6, t7, X1, curve_p); /* t6 = x3' - B */
uECC_vli_modMult_rnd(t6, t6, t5, s); /* t6 = (y2+y1)*(x3' - B) */
/* t2 = (y2+y1)*(x3' - B) - E = y3': */
uECC_vli_modSub(Y1, t6, Y1, curve->p);
uECC_vli_modSub(Y1, t6, Y1, curve_p);
uECC_vli_set(X1, t7);
}
@ -896,10 +910,10 @@ static void EccPoint_mult(uECC_word_t * result, const uECC_word_t * point,
XYcZ_addC_rnd(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], ws);
/* Find final 1/Z value. */
uECC_vli_modSub(z, Rx[1], Rx[0], curve->p); /* X1 - X0 */
uECC_vli_modSub(z, Rx[1], Rx[0], curve_p); /* X1 - X0 */
uECC_vli_modMult_fast(z, z, Ry[1 - nb]); /* Yb * (X1 - X0) */
uECC_vli_modMult_fast(z, z, point); /* xP * Yb * (X1 - X0) */
uECC_vli_modInv(z, z, curve->p); /* 1 / (xP * Yb * (X1 - X0))*/
uECC_vli_modInv(z, z, curve_p); /* 1 / (xP * Yb * (X1 - X0))*/
/* yP / (xP * Yb * (X1 - X0)) */
uECC_vli_modMult_fast(z, z, point + num_words);
/* Xb * yP / (xP * Yb * (X1 - X0)) */
@ -956,7 +970,7 @@ int EccPoint_mult_safer(uECC_word_t * result, const uECC_word_t * point,
/* If an RNG function was specified, get a random initial Z value to
* protect against side-channel attacks such as Template SPA */
if (g_rng_function) {
if (!uECC_generate_random_int(k2[carry], curve->p, num_words)) {
if (!uECC_generate_random_int(k2[carry], curve_p, num_words)) {
r = 0;
goto clear_and_out;
}
@ -1052,8 +1066,8 @@ int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve)
}
/* x and y must be smaller than p. */
if (uECC_vli_cmp_unsafe(curve->p, point) != 1 ||
uECC_vli_cmp_unsafe(curve->p, point + num_words) != 1) {
if (uECC_vli_cmp_unsafe(curve_p, point) != 1 ||
uECC_vli_cmp_unsafe(curve_p, point + num_words) != 1) {
return -2;
}

View File

@ -258,9 +258,9 @@ int uECC_verify(const uint8_t *public_key, const uint8_t *message_hash,
uECC_vli_set(sum + num_words, _public + num_words);
uECC_vli_set(tx, curve->G);
uECC_vli_set(ty, curve->G + num_words);
uECC_vli_modSub(z, sum, tx, curve->p); /* z = x2 - x1 */
uECC_vli_modSub(z, sum, tx, curve_p); /* z = x2 - x1 */
XYcZ_add(tx, ty, sum, sum + num_words, curve);
uECC_vli_modInv(z, z, curve->p); /* z = 1/z */
uECC_vli_modInv(z, z, curve_p); /* z = 1/z */
apply_z(sum, sum + num_words, z);
/* Use Shamir's trick to calculate u1*G + u2*Q */
@ -288,13 +288,13 @@ int uECC_verify(const uint8_t *public_key, const uint8_t *message_hash,
uECC_vli_set(tx, point);
uECC_vli_set(ty, point + num_words);
apply_z(tx, ty, z);
uECC_vli_modSub(tz, rx, tx, curve->p); /* Z = x2 - x1 */
uECC_vli_modSub(tz, rx, tx, curve_p); /* Z = x2 - x1 */
XYcZ_add(tx, ty, rx, ry, curve);
uECC_vli_modMult_fast(z, z, tz);
}
}
uECC_vli_modInv(z, z, curve->p); /* Z = 1/Z */
uECC_vli_modInv(z, z, curve_p); /* Z = 1/Z */
apply_z(rx, ry, z);
/* v = x1 (mod n) */