]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Optimize modular inversion for secp521r1.
authorNiels Möller <nisse@lysator.liu.se>
Mon, 19 Oct 2020 18:12:56 +0000 (20:12 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Wed, 11 Nov 2020 19:56:27 +0000 (20:56 +0100)
* ecc-secp521r1.c (ecc_secp521r1_inv): New function, modular
inverse using powering.
(_nettle_secp_521r1): Analogous updates. Increases signing
performance roughly 15% on x86_64.

ChangeLog
ecc-secp521r1.c

index 02d4361b38d30d97bcfb8308713d8feb61b24f87..0f71d045361bc35c31499b585d6e4656b9f26452 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2020-10-19  Niels Möller  <nisse@lysator.liu.se>
+
+       * ecc-secp521r1.c (ecc_secp521r1_inv): New function, modular
+       inverse using powering.
+       (_nettle_secp_521r1): Analogous updates. Increases signing
+       performance roughly 15% on x86_64.
+
 2020-10-15  Niels Möller  <nisse@lysator.liu.se>
 
        * ecc-secp192r1.c (ecc_secp192r1_inv): New function, modular
index ec875dbf813b094418b887e851387588f8fc2e1a..0d9f88fc3d784c43342735463402a263dac490e4 100644 (file)
@@ -75,6 +75,53 @@ ecc_secp521r1_modp (const struct ecc_modulo *m UNUSED, mp_limb_t *rp, mp_limb_t
 }
 #endif
 
+#define ECC_SECP521R1_INV_ITCH (3*ECC_LIMB_SIZE)
+
+static void
+ecc_secp521r1_inv (const struct ecc_modulo *p,
+                  mp_limb_t *rp, const mp_limb_t *ap,
+                  mp_limb_t *scratch)
+{
+#define t0 scratch
+#define tp (scratch + ECC_LIMB_SIZE)
+
+  /* Addition chain for p - 2:
+
+     2^{521} - 3
+     = 1 + 2^2(2^519 - 1)
+     = 1 + 2^2(1 + 2 (2^518 - 1)
+     = 1 + 2^2(1 + 2 (2^259 + 1) (1 + 2(2^258 - 1)))
+     = 1 + 2^2(1 + 2 (2^259 + 1) (1 + 2(2^129 + 1) (2^129 - 1)))
+     = 1 + 2^2(1 + 2 (2^259 + 1) (1 + 2(2^129 + 1) (1 + 2 (2^128 - 1))))
+
+     where
+
+     2^{128} - 1 = (2^64 + 1) (2^32+1) (2^16 + 1) (2^8 + 1) (2^4 + 1) (2^2 + 1) (2 + 1)
+
+     This addition chain needs 520 squarings and 13 multiplies.
+  */
+
+  ecc_mod_sqr (p, rp, ap, tp);         /* a^2 */
+  ecc_mod_mul (p, rp, ap, rp, tp);     /* a^3 = a^{2^2 - 1} */
+  ecc_mod_pow_2kp1 (p, t0, rp, 2, tp); /* a^15 = a^{2^4 - 1} */
+  ecc_mod_pow_2kp1 (p, rp, t0, 4, tp); /* a^{2^8 - 1} */
+  ecc_mod_pow_2kp1 (p, t0, rp, 8, tp); /* a^{2^16 - 1} */
+  ecc_mod_pow_2kp1 (p, rp, t0, 16, tp);        /* a^{2^32 - 1} */
+  ecc_mod_pow_2kp1 (p, t0, rp, 32, tp);        /* a^{2^64 - 1} */
+  ecc_mod_pow_2kp1 (p, rp, t0, 64, tp);        /* a^{2^128 - 1} */
+  ecc_mod_sqr (p, rp, rp, tp);         /* a^{2^129 - 2} */
+  ecc_mod_mul (p, rp, rp, ap, tp);     /* a^{2^129 - 1} */
+  ecc_mod_pow_2kp1 (p, t0, rp, 129, tp);/* a^{2^258 - 1} */
+  ecc_mod_sqr (p, rp, t0, tp);         /* a^{2^259 - 2} */
+  ecc_mod_mul (p, rp, rp, ap, tp);     /* a^{2^259 - 1} */
+  ecc_mod_pow_2kp1 (p, t0, rp, 259, tp);/* a^{2^518 - 1} */
+  ecc_mod_sqr (p, rp, t0, tp);         /* a^{2^519 - 2} */
+  ecc_mod_mul (p, rp, rp, ap, tp);     /* a^{2^519 - 1} */
+  ecc_mod_sqr (p, rp, rp, tp);         /* a^{2^520 - 2} */
+  ecc_mod_sqr (p, rp, rp, tp);         /* a^{2^521 - 4} */
+  ecc_mod_mul (p, rp, rp, ap, tp);     /* a^{2^519 - 3} */
+}
+
 const struct ecc_curve _nettle_secp_521r1 =
 {
   {
@@ -82,7 +129,7 @@ const struct ecc_curve _nettle_secp_521r1 =
     ECC_LIMB_SIZE,    
     ECC_BMODP_SIZE,
     ECC_REDC_SIZE,
-    ECC_MOD_INV_ITCH (ECC_LIMB_SIZE),
+    ECC_SECP521R1_INV_ITCH,
     0,
 
     ecc_p,
@@ -93,7 +140,7 @@ const struct ecc_curve _nettle_secp_521r1 =
 
     ecc_secp521r1_modp,
     ecc_secp521r1_modp,
-    ecc_mod_inv,
+    ecc_secp521r1_inv,
     NULL,
   },
   {
@@ -125,7 +172,7 @@ const struct ecc_curve _nettle_secp_521r1 =
   ECC_DUP_JJ_ITCH (ECC_LIMB_SIZE),
   ECC_MUL_A_ITCH (ECC_LIMB_SIZE),
   ECC_MUL_G_ITCH (ECC_LIMB_SIZE),
-  ECC_J_TO_A_ITCH (ECC_LIMB_SIZE),
+  2*ECC_LIMB_SIZE + ECC_SECP521R1_INV_ITCH,
 
   ecc_add_jja,
   ecc_add_jjj,