Commit 889a582f authored by Niels Möller's avatar Niels Möller

Merge branch 'curve448' into master

parents 85fd4910 5fffda51
2019-11-21 Niels Möller <nisse@lysator.liu.se>
* Merge curve448 preparations, from September 2017.
2017-09-23 Niels Möller <nisse@lysator.liu.se>
* eccdata.c: Reorganize curve25519 precomputation to work directly
with the twisted Edwards curve, with new point addition based on a
patch from Daiki Ueno.
* ecc-25519.c (_nettle_curve25519): Update for removed Montgomery
curve constant.
* ecc-internal.h (struct ecc_curve): Delete unused pointer
edwards_root. Update all instances.
* eccdata.c (output_curve): Don't output it.
* testsuite/ecc-add-test.c (test_main): Reduce test duplication.
Use ecc->add_hhh_itch.
* testsuite/ecc-dup-test.c (test_main): Reduce test duplication.
Use ecc->dup_itch.
2017-09-23 Daiki Ueno <dueno@redhat.com>
* ecc-eh-to-a.c (ecc_eh_to_a): Use ecc->q.bit_size, instead of
hard-coded value for curve25519.
* eddsa-sign.c (_eddsa_sign): Likewise.
* ecc-internal.h (ecc_dup_func): New typedef.
(struct ecc_curve): New constants add_hh_itch and dup_itch, new
function pointers add_hh and dup.
* ecc-192.c, ecc-224.c, ecc-256.c, ecc-384.c, ecc-521.c,
ecc-25519.c: Update accordingly.
* ecc-mul-g-eh.c (ecc_mul_g_eh): Use new function pointers.
* ecc-mul-a-eh.c (ecc_mul_a_eh, table_init, ecc_mul_a_eh):
Likewise.
* testsuite/ecc-dup-test.c (test_main): Likewise.
* testsuite/ecc-add-test.c (test_main): Likewise.
2019-10-01 Niels Möller <nisse@lysator.liu.se> 2019-10-01 Niels Möller <nisse@lysator.liu.se>
* testsuite/testutils.c (test_cipher_cfb8): Reset destination area * testsuite/testutils.c (test_cipher_cfb8): Reset destination area
......
...@@ -155,19 +155,22 @@ const struct ecc_curve _nettle_secp_192r1 = ...@@ -155,19 +155,22 @@ const struct ecc_curve _nettle_secp_192r1 =
ECC_PIPPENGER_K, ECC_PIPPENGER_K,
ECC_PIPPENGER_C, ECC_PIPPENGER_C,
ECC_ADD_JJA_ITCH (ECC_LIMB_SIZE),
ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE), ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE),
ECC_DUP_JJ_ITCH (ECC_LIMB_SIZE),
ECC_MUL_A_ITCH (ECC_LIMB_SIZE), ECC_MUL_A_ITCH (ECC_LIMB_SIZE),
ECC_MUL_G_ITCH (ECC_LIMB_SIZE), ECC_MUL_G_ITCH (ECC_LIMB_SIZE),
ECC_J_TO_A_ITCH (ECC_LIMB_SIZE), ECC_J_TO_A_ITCH (ECC_LIMB_SIZE),
ecc_add_jja,
ecc_add_jjj, ecc_add_jjj,
ecc_dup_jj,
ecc_mul_a, ecc_mul_a,
ecc_mul_g, ecc_mul_g,
ecc_j_to_a, ecc_j_to_a,
ecc_b, ecc_b,
ecc_g, ecc_g,
NULL,
ecc_unit, ecc_unit,
ecc_table ecc_table
}; };
......
...@@ -107,19 +107,22 @@ const struct ecc_curve _nettle_secp_224r1 = ...@@ -107,19 +107,22 @@ const struct ecc_curve _nettle_secp_224r1 =
ECC_PIPPENGER_K, ECC_PIPPENGER_K,
ECC_PIPPENGER_C, ECC_PIPPENGER_C,
ECC_ADD_JJA_ITCH (ECC_LIMB_SIZE),
ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE), ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE),
ECC_DUP_JJ_ITCH (ECC_LIMB_SIZE),
ECC_MUL_A_ITCH (ECC_LIMB_SIZE), ECC_MUL_A_ITCH (ECC_LIMB_SIZE),
ECC_MUL_G_ITCH (ECC_LIMB_SIZE), ECC_MUL_G_ITCH (ECC_LIMB_SIZE),
ECC_J_TO_A_ITCH (ECC_LIMB_SIZE), ECC_J_TO_A_ITCH (ECC_LIMB_SIZE),
ecc_add_jja,
ecc_add_jjj, ecc_add_jjj,
ecc_dup_jj,
ecc_mul_a, ecc_mul_a,
ecc_mul_g, ecc_mul_g,
ecc_j_to_a, ecc_j_to_a,
ecc_b, ecc_b,
ecc_g, ecc_g,
NULL,
ecc_unit, ecc_unit,
ecc_table ecc_table
}; };
......
...@@ -335,19 +335,22 @@ const struct ecc_curve _nettle_curve25519 = ...@@ -335,19 +335,22 @@ const struct ecc_curve _nettle_curve25519 =
ECC_PIPPENGER_K, ECC_PIPPENGER_K,
ECC_PIPPENGER_C, ECC_PIPPENGER_C,
ECC_ADD_EH_ITCH (ECC_LIMB_SIZE),
ECC_ADD_EHH_ITCH (ECC_LIMB_SIZE), ECC_ADD_EHH_ITCH (ECC_LIMB_SIZE),
ECC_DUP_EH_ITCH (ECC_LIMB_SIZE),
ECC_MUL_A_EH_ITCH (ECC_LIMB_SIZE), ECC_MUL_A_EH_ITCH (ECC_LIMB_SIZE),
ECC_MUL_G_EH_ITCH (ECC_LIMB_SIZE), ECC_MUL_G_EH_ITCH (ECC_LIMB_SIZE),
ECC_EH_TO_A_ITCH (ECC_LIMB_SIZE, ECC_25519_INV_ITCH), ECC_EH_TO_A_ITCH (ECC_LIMB_SIZE, ECC_25519_INV_ITCH),
ecc_add_eh,
ecc_add_ehh, ecc_add_ehh,
ecc_dup_eh,
ecc_mul_a_eh, ecc_mul_a_eh,
ecc_mul_g_eh, ecc_mul_g_eh,
ecc_eh_to_a, ecc_eh_to_a,
ecc_d, /* Use the Edwards curve constant. */ ecc_b, /* Edwards curve constant. */
ecc_g, ecc_g,
ecc_edwards,
ecc_unit, ecc_unit,
ecc_table ecc_table
}; };
...@@ -284,19 +284,22 @@ const struct ecc_curve _nettle_secp_256r1 = ...@@ -284,19 +284,22 @@ const struct ecc_curve _nettle_secp_256r1 =
ECC_PIPPENGER_K, ECC_PIPPENGER_K,
ECC_PIPPENGER_C, ECC_PIPPENGER_C,
ECC_ADD_JJA_ITCH (ECC_LIMB_SIZE),
ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE), ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE),
ECC_DUP_JJ_ITCH (ECC_LIMB_SIZE),
ECC_MUL_A_ITCH (ECC_LIMB_SIZE), ECC_MUL_A_ITCH (ECC_LIMB_SIZE),
ECC_MUL_G_ITCH (ECC_LIMB_SIZE), ECC_MUL_G_ITCH (ECC_LIMB_SIZE),
ECC_J_TO_A_ITCH (ECC_LIMB_SIZE), ECC_J_TO_A_ITCH (ECC_LIMB_SIZE),
ecc_add_jja,
ecc_add_jjj, ecc_add_jjj,
ecc_dup_jj,
ecc_mul_a, ecc_mul_a,
ecc_mul_g, ecc_mul_g,
ecc_j_to_a, ecc_j_to_a,
ecc_b, ecc_b,
ecc_g, ecc_g,
NULL,
ecc_unit, ecc_unit,
ecc_table ecc_table
}; };
......
...@@ -192,19 +192,22 @@ const struct ecc_curve _nettle_secp_384r1 = ...@@ -192,19 +192,22 @@ const struct ecc_curve _nettle_secp_384r1 =
ECC_PIPPENGER_K, ECC_PIPPENGER_K,
ECC_PIPPENGER_C, ECC_PIPPENGER_C,
ECC_ADD_JJA_ITCH (ECC_LIMB_SIZE),
ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE), ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE),
ECC_DUP_JJ_ITCH (ECC_LIMB_SIZE),
ECC_MUL_A_ITCH (ECC_LIMB_SIZE), ECC_MUL_A_ITCH (ECC_LIMB_SIZE),
ECC_MUL_G_ITCH (ECC_LIMB_SIZE), ECC_MUL_G_ITCH (ECC_LIMB_SIZE),
ECC_J_TO_A_ITCH (ECC_LIMB_SIZE), ECC_J_TO_A_ITCH (ECC_LIMB_SIZE),
ecc_add_jja,
ecc_add_jjj, ecc_add_jjj,
ecc_dup_jj,
ecc_mul_a, ecc_mul_a,
ecc_mul_g, ecc_mul_g,
ecc_j_to_a, ecc_j_to_a,
ecc_b, ecc_b,
ecc_g, ecc_g,
NULL,
ecc_unit, ecc_unit,
ecc_table ecc_table
}; };
......
...@@ -120,19 +120,22 @@ const struct ecc_curve _nettle_secp_521r1 = ...@@ -120,19 +120,22 @@ const struct ecc_curve _nettle_secp_521r1 =
ECC_PIPPENGER_K, ECC_PIPPENGER_K,
ECC_PIPPENGER_C, ECC_PIPPENGER_C,
ECC_ADD_JJA_ITCH (ECC_LIMB_SIZE),
ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE), ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE),
ECC_DUP_JJ_ITCH (ECC_LIMB_SIZE),
ECC_MUL_A_ITCH (ECC_LIMB_SIZE), ECC_MUL_A_ITCH (ECC_LIMB_SIZE),
ECC_MUL_G_ITCH (ECC_LIMB_SIZE), ECC_MUL_G_ITCH (ECC_LIMB_SIZE),
ECC_J_TO_A_ITCH (ECC_LIMB_SIZE), ECC_J_TO_A_ITCH (ECC_LIMB_SIZE),
ecc_add_jja,
ecc_add_jjj, ecc_add_jjj,
ecc_dup_jj,
ecc_mul_a, ecc_mul_a,
ecc_mul_g, ecc_mul_g,
ecc_j_to_a, ecc_j_to_a,
ecc_b, ecc_b,
ecc_g, ecc_g,
NULL,
ecc_unit, ecc_unit,
ecc_table ecc_table
}; };
......
...@@ -68,12 +68,13 @@ ecc_eh_to_a (const struct ecc_curve *ecc, ...@@ -68,12 +68,13 @@ ecc_eh_to_a (const struct ecc_curve *ecc,
/* Skip y coordinate */ /* Skip y coordinate */
if (op > 1) if (op > 1)
{ {
/* Reduce modulo q. FIXME: Hardcoded for curve25519, /* Reduce modulo q. Hardcoded for curve25519, duplicates end
duplicates end of ecc_25519_modq. FIXME: Is this needed of ecc_25519_modq. FIXME: Is this needed at all? op > 0
at all? Full reduction mod p is maybe sufficient. */ is only used by ecdsa code, and ecdsa on Edwards curves
makes little sense and is is only used by tests. */
unsigned shift; unsigned shift;
assert (ecc->p.bit_size == 255); assert (ecc->p.bit_size == 255);
shift = 252 - GMP_NUMB_BITS * (ecc->p.size - 1); shift = ecc->q.bit_size - 1 - GMP_NUMB_BITS * (ecc->p.size - 1);
cy = mpn_submul_1 (r, ecc->q.m, ecc->p.size, cy = mpn_submul_1 (r, ecc->q.m, ecc->p.size,
r[ecc->p.size-1] >> shift); r[ecc->p.size-1] >> shift);
assert (cy < 2); assert (cy < 2);
......
...@@ -118,6 +118,10 @@ typedef void ecc_add_func (const struct ecc_curve *ecc, ...@@ -118,6 +118,10 @@ typedef void ecc_add_func (const struct ecc_curve *ecc,
const mp_limb_t *p, const mp_limb_t *q, const mp_limb_t *p, const mp_limb_t *q,
mp_limb_t *scratch); mp_limb_t *scratch);
typedef void ecc_dup_func (const struct ecc_curve *ecc,
mp_limb_t *r, const mp_limb_t *p,
mp_limb_t *scratch);
typedef void ecc_mul_g_func (const struct ecc_curve *ecc, mp_limb_t *r, typedef void ecc_mul_g_func (const struct ecc_curve *ecc, mp_limb_t *r,
const mp_limb_t *np, mp_limb_t *scratch); const mp_limb_t *np, mp_limb_t *scratch);
...@@ -174,12 +178,16 @@ struct ecc_curve ...@@ -174,12 +178,16 @@ struct ecc_curve
unsigned short pippenger_k; unsigned short pippenger_k;
unsigned short pippenger_c; unsigned short pippenger_c;
unsigned short add_hh_itch;
unsigned short add_hhh_itch; unsigned short add_hhh_itch;
unsigned short dup_itch;
unsigned short mul_itch; unsigned short mul_itch;
unsigned short mul_g_itch; unsigned short mul_g_itch;
unsigned short h_to_a_itch; unsigned short h_to_a_itch;
ecc_add_func *add_hh;
ecc_add_func *add_hhh; ecc_add_func *add_hhh;
ecc_dup_func *dup;
ecc_mul_func *mul; ecc_mul_func *mul;
ecc_mul_g_func *mul_g; ecc_mul_g_func *mul_g;
ecc_h_to_a_func *h_to_a; ecc_h_to_a_func *h_to_a;
...@@ -189,9 +197,6 @@ struct ecc_curve ...@@ -189,9 +197,6 @@ struct ecc_curve
/* Generator, x coordinate followed by y (affine coordinates). /* Generator, x coordinate followed by y (affine coordinates).
Currently used only by the test suite. */ Currently used only by the test suite. */
const mp_limb_t *g; const mp_limb_t *g;
/* If non-NULL, the constant needed for transformation to the
equivalent Edwards curve. */
const mp_limb_t *edwards_root;
/* For redc, same as B mod p, otherwise 1. */ /* For redc, same as B mod p, otherwise 1. */
const mp_limb_t *unit; const mp_limb_t *unit;
...@@ -281,18 +286,16 @@ ecc_a_to_j (const struct ecc_curve *ecc, ...@@ -281,18 +286,16 @@ ecc_a_to_j (const struct ecc_curve *ecc,
/* Converts a point P in jacobian coordinates into a point R in affine /* Converts a point P in jacobian coordinates into a point R in affine
coordinates. If op == 1, produce x coordinate only. If op == 2, coordinates. If op == 1, produce x coordinate only. If op == 2,
produce the x coordinate only, and also reduce it modulo q. FIXME: produce the x coordinate only, and also reduce it modulo q. */
For the public interface, have separate functions for the three
cases, and use this flag argument only for the internal ecc->h_to_a
function. */
void void
ecc_j_to_a (const struct ecc_curve *ecc, ecc_j_to_a (const struct ecc_curve *ecc,
int op, int op,
mp_limb_t *r, const mp_limb_t *p, mp_limb_t *r, const mp_limb_t *p,
mp_limb_t *scratch); mp_limb_t *scratch);
/* Converts a point P on an Edwards curve to affine coordinates on /* Converts a point P in homogeneous coordinates on an Edwards curve
the corresponding Montgomery curve. */ to affine coordinates. Meaning of op is the same as for
ecc_j_to_a. */
void void
ecc_eh_to_a (const struct ecc_curve *ecc, ecc_eh_to_a (const struct ecc_curve *ecc,
int op, int op,
......
...@@ -75,8 +75,8 @@ ecc_mul_a_eh (const struct ecc_curve *ecc, ...@@ -75,8 +75,8 @@ ecc_mul_a_eh (const struct ecc_curve *ecc,
{ {
int digit; int digit;
ecc_dup_eh (ecc, r, r, scratch_out); ecc->dup (ecc, r, r, scratch_out);
ecc_add_ehh (ecc, tp, r, pe, scratch_out); ecc->add_hhh (ecc, tp, r, pe, scratch_out);
digit = (w & bit) > 0; digit = (w & bit) > 0;
/* If we had a one-bit, use the sum. */ /* If we had a one-bit, use the sum. */
...@@ -107,8 +107,8 @@ table_init (const struct ecc_curve *ecc, ...@@ -107,8 +107,8 @@ table_init (const struct ecc_curve *ecc,
for (j = 2; j < size; j += 2) for (j = 2; j < size; j += 2)
{ {
ecc_dup_eh (ecc, TABLE(j), TABLE(j/2), scratch); ecc->dup (ecc, TABLE(j), TABLE(j/2), scratch);
ecc_add_ehh (ecc, TABLE(j+1), TABLE(j), TABLE(1), scratch); ecc->add_hhh (ecc, TABLE(j+1), TABLE(j), TABLE(1), scratch);
} }
} }
...@@ -163,11 +163,11 @@ ecc_mul_a_eh (const struct ecc_curve *ecc, ...@@ -163,11 +163,11 @@ ecc_mul_a_eh (const struct ecc_curve *ecc,
bits |= w >> shift; bits |= w >> shift;
} }
for (j = 0; j < ECC_MUL_A_EH_WBITS; j++) for (j = 0; j < ECC_MUL_A_EH_WBITS; j++)
ecc_dup_eh (ecc, r, r, scratch_out); ecc->dup (ecc, r, r, scratch_out);
bits &= TABLE_MASK; bits &= TABLE_MASK;
sec_tabselect (tp, 3*ecc->p.size, table, TABLE_SIZE, bits); sec_tabselect (tp, 3*ecc->p.size, table, TABLE_SIZE, bits);
ecc_add_ehh (ecc, r, tp, r, scratch_out); ecc->add_hhh (ecc, r, tp, r, scratch_out);
} }
#undef table #undef table
#undef tp #undef tp
......
...@@ -64,7 +64,7 @@ ecc_mul_g_eh (const struct ecc_curve *ecc, mp_limb_t *r, ...@@ -64,7 +64,7 @@ ecc_mul_g_eh (const struct ecc_curve *ecc, mp_limb_t *r,
for (i = k; i-- > 0; ) for (i = k; i-- > 0; )
{ {
ecc_dup_eh (ecc, r, r, scratch); ecc->dup (ecc, r, r, scratch);
for (j = 0; j * c < bit_rows; j++) for (j = 0; j * c < bit_rows; j++)
{ {
unsigned bits; unsigned bits;
...@@ -93,7 +93,7 @@ ecc_mul_g_eh (const struct ecc_curve *ecc, mp_limb_t *r, ...@@ -93,7 +93,7 @@ ecc_mul_g_eh (const struct ecc_curve *ecc, mp_limb_t *r,
+ (2*ecc->p.size * (mp_size_t) j << c)), + (2*ecc->p.size * (mp_size_t) j << c)),
1<<c, bits); 1<<c, bits);
ecc_add_eh (ecc, r, r, tp, scratch_out); ecc->add_hh (ecc, r, r, tp, scratch_out);
} }
} }
#undef tp #undef tp
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
Generate compile time constant (but machine dependent) tables. Generate compile time constant (but machine dependent) tables.
Copyright (C) 2013, 2014 Niels Möller Copyright (C) 2013, 2014, 2017 Niels Möller
Copyright (C) 2017 Daiki Ueno
Copyright (C) 2017 Red Hat, Inc.
This file is part of GNU Nettle. This file is part of GNU Nettle.
...@@ -53,8 +55,12 @@ enum ecc_type ...@@ -53,8 +55,12 @@ enum ecc_type
{ {
/* y^2 = x^3 - 3x + b (mod p) */ /* y^2 = x^3 - 3x + b (mod p) */
ECC_TYPE_WEIERSTRASS, ECC_TYPE_WEIERSTRASS,
/* y^2 = x^3 + b x^2 + x */ #if 0
ECC_TYPE_MONTGOMERY /* x^2 + y^2 = 1 - d x^2 y^2 */
ECC_TYPE_EDWARDS,
#endif
/* -x^2 + y^2 = 1 - d x^2 y^2 */
ECC_TYPE_TWISTED_EDWARDS,
}; };
struct ecc_curve struct ecc_curve
...@@ -73,16 +79,6 @@ struct ecc_curve ...@@ -73,16 +79,6 @@ struct ecc_curve
mpz_t q; mpz_t q;
struct ecc_point g; struct ecc_point g;
/* Non-zero if we want elements represented as point s(u, v) on an
equivalent Edwards curve, using
u = t x / y
v = (x-1) / (x+1)
*/
int use_edwards;
mpz_t d;
mpz_t t;
/* Table for pippenger's algorithm. /* Table for pippenger's algorithm.
Element Element
...@@ -127,9 +123,11 @@ ecc_equal_p (const struct ecc_point *p, const struct ecc_point *q) ...@@ -127,9 +123,11 @@ ecc_equal_p (const struct ecc_point *p, const struct ecc_point *q)
} }
static void static void
ecc_set_zero (struct ecc_point *r) ecc_set_zero (const struct ecc_curve *ecc, struct ecc_point *r)
{ {
r->is_zero = 1; r->is_zero = 1;
mpz_set_ui (r->x, 0);
mpz_set_ui (r->y, ecc->type != ECC_TYPE_WEIERSTRASS);
} }
static void static void
...@@ -140,13 +138,22 @@ ecc_set (struct ecc_point *r, const struct ecc_point *p) ...@@ -140,13 +138,22 @@ ecc_set (struct ecc_point *r, const struct ecc_point *p)
mpz_set (r->y, p->y); mpz_set (r->y, p->y);
} }
static void
ecc_add (const struct ecc_curve *ecc, struct ecc_point *r,
const struct ecc_point *p, const struct ecc_point *q);
/* Needs to support in-place operation. */ /* Needs to support in-place operation. */
static void static void
ecc_dup (const struct ecc_curve *ecc, ecc_dup (const struct ecc_curve *ecc,
struct ecc_point *r, const struct ecc_point *p) struct ecc_point *r, const struct ecc_point *p)
{ {
if (ecc->type != ECC_TYPE_WEIERSTRASS)
{
ecc_add (ecc, r, p, p);
return;
}
if (ecc_zero_p (p)) if (ecc_zero_p (p))
ecc_set_zero (r); ecc_set_zero (ecc, r);
else else
{ {
...@@ -161,32 +168,18 @@ ecc_dup (const struct ecc_curve *ecc, ...@@ -161,32 +168,18 @@ ecc_dup (const struct ecc_curve *ecc,
mpz_mul_ui (m, p->y, 2); mpz_mul_ui (m, p->y, 2);
mpz_invert (m, m, ecc->p); mpz_invert (m, m, ecc->p);
switch (ecc->type) /* t = 3 (x^2 - 1) * m */
{ mpz_mul (t, p->x, p->x);
case ECC_TYPE_WEIERSTRASS: mpz_mod (t, t, ecc->p);
/* t = 3 (x^2 - 1) * m */ mpz_sub_ui (t, t, 1);
mpz_mul (t, p->x, p->x); mpz_mul_ui (t, t, 3);
mpz_mod (t, t, ecc->p);
mpz_sub_ui (t, t, 1);
mpz_mul_ui (t, t, 3);
break;
case ECC_TYPE_MONTGOMERY:
/* t = (3 x^2 + 2 b x + 1) m = [x(3x+2b)+1] m */
mpz_mul_ui (t, ecc->b, 2);
mpz_addmul_ui (t, p->x, 3);
mpz_mul (t, t, p->x);
mpz_mod (t, t, ecc->p);
mpz_add_ui (t, t, 1);
break;
}
mpz_mul (t, t, m); mpz_mul (t, t, m);
mpz_mod (t, t, ecc->p); mpz_mod (t, t, ecc->p);
/* x' = t^2 - 2 x */ /* x' = t^2 - 2 x */
mpz_mul (x, t, t); mpz_mul (x, t, t);
mpz_submul_ui (x, p->x, 2); mpz_submul_ui (x, p->x, 2);
if (ecc->type == ECC_TYPE_MONTGOMERY)
mpz_sub (x, x, ecc->b);
mpz_mod (x, x, ecc->p); mpz_mod (x, x, ecc->p);
...@@ -208,55 +201,114 @@ ecc_dup (const struct ecc_curve *ecc, ...@@ -208,55 +201,114 @@ ecc_dup (const struct ecc_curve *ecc,
} }
static void static void
ecc_add (const struct ecc_curve *ecc, ecc_add (const struct ecc_curve *ecc, struct ecc_point *r,
struct ecc_point *r, const struct ecc_point *p, const struct ecc_point *q) const struct ecc_point *p, const struct ecc_point *q)
{ {
if (ecc_zero_p (p)) if (ecc->type == ECC_TYPE_WEIERSTRASS)
ecc_set (r, q); {
if (ecc_zero_p (p))
ecc_set (r, q);
else if (ecc_zero_p (q)) else if (ecc_zero_p (q))
ecc_set (r, p); ecc_set (r, p);
else if (mpz_cmp (p->x, q->x) == 0) else if (mpz_cmp (p->x, q->x) == 0)
{ {
if (mpz_cmp (p->y, q->y) == 0) if (mpz_cmp (p->y, q->y) == 0)
ecc_dup (ecc, r, p); ecc_dup (ecc, r, p);
else
ecc_set_zero (ecc, r);
}
else else
ecc_set_zero (r); {
mpz_t s, t, x, y;
mpz_init (s);
mpz_init (t);
mpz_init (x);