From: Niels Möller Date: Mon, 8 Nov 2021 16:51:07 +0000 (+0100) Subject: Implement secp521r1 square root, based on patch by Wim Lewis. X-Git-Tag: nettle_3.8_release_20220602~78 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4e987de3c0a15f059e4d7bb296f0ceb83f6c7354;p=thirdparty%2Fnettle.git Implement secp521r1 square root, based on patch by Wim Lewis. --- diff --git a/ChangeLog b/ChangeLog index de091241..b6f8f388 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,7 @@ (ecc_secp192r1_sqrt): New function. * ecc-secp256r1.c (ecc_secp256r1_sqrt): New function. * ecc-secp384r1.c (ecc_secp384r1_sqrt): New function. + * ecc-secp521r1.c (ecc_secp521r1_sqrt): New function. * testsuite/ecc-sqrt-test.c (test_sqrt): New function. (test_sqrt_ratio): Renamed function (was test_modulo). diff --git a/ecc-secp521r1.c b/ecc-secp521r1.c index 1b09e7b1..26314e59 100644 --- a/ecc-secp521r1.c +++ b/ecc-secp521r1.c @@ -43,6 +43,8 @@ #include "ecc-secp521r1.h" +#define B_SHIFT (521 % GMP_NUMB_BITS) + #if HAVE_NATIVE_ecc_secp521r1_modp #define ecc_secp521r1_modp _nettle_ecc_secp521r1_modp void @@ -50,7 +52,6 @@ ecc_secp521r1_modp (const struct ecc_modulo *m, mp_limb_t *rp, mp_limb_t *xp); #else -#define B_SHIFT (521 % GMP_NUMB_BITS) #define BMODP_SHIFT (GMP_NUMB_BITS - B_SHIFT) #define BMODP ((mp_limb_t) 1 << BMODP_SHIFT) @@ -121,6 +122,39 @@ ecc_secp521r1_inv (const struct ecc_modulo *p, ecc_mod_mul (p, rp, rp, ap, tp); /* a^{2^519 - 3} */ } +#define ECC_SECP521R1_SQRT_ITCH (2*ECC_LIMB_SIZE) + +static int +ecc_secp521r1_sqrt (const struct ecc_modulo *m, + mp_limb_t *rp, + const mp_limb_t *cp, + mp_limb_t *scratch) +{ + mp_limb_t hi; + + /* This computes the square root modulo p256 using the identity: + + sqrt(c) = c^(2^519) (mod P-521) + + which can be seen as a special case of Tonelli-Shanks with e=1. + */ + + ecc_mod_pow_2k (m, rp, cp, 519, scratch); + + /* Check result. */ + ecc_mod_sqr (m, scratch, rp, scratch); + ecc_mod_sub (m, scratch, scratch, cp); + + /* Reduce top bits, since ecc_mod_zero_p requires input < 2p */ + hi = scratch[ECC_LIMB_SIZE-1] >> B_SHIFT; + scratch[ECC_LIMB_SIZE-1] = (scratch[ECC_LIMB_SIZE-1] + & (((mp_limb_t) 1 << B_SHIFT)-1)) + + sec_add_1 (scratch, scratch, ECC_LIMB_SIZE - 1, hi); + + return ecc_mod_zero_p (m, scratch); +} + + const struct ecc_curve _nettle_secp_521r1 = { { @@ -129,7 +163,7 @@ const struct ecc_curve _nettle_secp_521r1 = ECC_BMODP_SIZE, ECC_REDC_SIZE, ECC_SECP521R1_INV_ITCH, - 0, + ECC_SECP521R1_SQRT_ITCH, 0, ecc_p, @@ -141,7 +175,7 @@ const struct ecc_curve _nettle_secp_521r1 = ecc_secp521r1_modp, ecc_secp521r1_modp, ecc_secp521r1_inv, - NULL, + ecc_secp521r1_sqrt, NULL, }, {