diff --git a/ChangeLog b/ChangeLog index efab61a6c233c0d45387ba6dd30b1ebeeb484b65..cb8ac84d3607cb1522b3322313077f3de083a0ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2019-12-03 Niels Möller <nisse@lysator.liu.se> + + * ecc-448.c (ecc_448_modp) [GMP_NUMB_BITS == 64]: New function. + 2019-12-01 Niels Möller <nisse@lysator.liu.se> Curve 448 support contributed by Daiki Ueno. diff --git a/ecc-448.c b/ecc-448.c index 24d970e4e05ae2dee0780c13e7c315b9fdb339c8..7d68e1c8e743bd190546cd001b46c2cead708b12 100644 --- a/ecc-448.c +++ b/ecc-448.c @@ -36,6 +36,8 @@ # include "config.h" #endif +#include <assert.h> + #include "ecc.h" #include "ecc-internal.h" @@ -43,6 +45,55 @@ #include "ecc-448.h" +#if GMP_NUMB_BITS == 64 +static void +ecc_448_modp(const struct ecc_modulo *m, mp_limb_t *rp) +{ + /* Let B = 2^64, b = 2^32 = sqrt(B). + p = B^7 - b B^3 - 1 ==> B^7 = b B^3 + 1 + + We use this to reduce + + {r_{13}, ..., r_0} = + {r_6,...,r_0} + + {r_{10},...,r_7} + + 2 {r_{13},r_{12}, r_{11}} B^4 + + b {r_{10},...,r_7,r_{13},r_{12},r_{11} (mod p) + + or + + +----+----+----+----+----+----+----+ + |r_6 |r_5 |r_4 |r_3 |r_2 |r_1 |r_0 | + +----+----+----+----+----+----+----+ + |r_10|r_9 |r_8 |r_7 | + +----+----+----+----+----+----+----+ + 2 * |r_13|r_12|r_11| + +----+----+----+----+----+----+----+ + + b * |r_10|r_9 |r_8 |r_7 |r_13|r_12|r_11| + -------+----+----+----+----+----+----+----+ + c_7 |r_6 |r_5 |r_4 |r_3 |r_2 |r_1 |r_0 | + +----+----+----+----+----+----+----+ + */ + mp_limb_t c3, c4, c7; + mp_limb_t *tp = rp + 7; + + c4 = mpn_add_n (rp, rp, rp + 7, 4); + c7 = mpn_addmul_1 (rp + 4, rp + 11, 3, 2); + c3 = mpn_addmul_1 (rp, rp + 11, 3, (mp_limb_t) 1 << 32); + c7 += mpn_addmul_1 (rp + 3, rp + 7, 4, (mp_limb_t) 1 << 32); + tp[0] = c7; + tp[1] = tp[2] = 0; + tp[3] = c3 + (c7 << 32); + tp[4] = c4 + (c7 >> 32) + (tp[3] < c3); + tp[5] = tp[6] = 0; + c7 = mpn_add_n (rp, rp, tp, 7); + c7 = cnd_add_n (c7, rp, m->B, 7); + assert (c7 == 0); +} +#else +#define ecc_448_modp ecc_mod +#endif + /* Needs 2*ecc->size limbs at rp, and 2*ecc->size additional limbs of scratch space. No overlap allowed. */ static void @@ -219,8 +270,8 @@ const struct ecc_curve _nettle_curve448 = NULL, ecc_pp1h, - ecc_mod, /* FIXME: Implement optimized mod function */ - ecc_mod, /* FIXME: Implement optimized reduce function */ + ecc_448_modp, + ecc_448_modp, ecc_448_inv, ecc_448_sqrt, },