]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
New function ecc_mod_zero_p.
authorNiels Möller <nisse@lysator.liu.se>
Tue, 26 Oct 2021 16:00:07 +0000 (18:00 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Tue, 26 Oct 2021 16:00:07 +0000 (18:00 +0200)
* ecc-mod-arith.c (ecc_mod_zero_p): New function.
* ecc-curve25519.c (ecc_curve25519_zero_p): Use it.
* ecc-curve448.c (ecc_curve448_zero_p): Deleted, usage replaced
with ecc_mod_zero_p.
* testsuite/ecc-modinv-test.c (mod_eq_p): Rewritten to use
ecc_mod_zero_p, and require that one input is canonically reduced.
(zero_p): Deleted, usage replaced with ecc_mod_zero_p.

ChangeLog
ecc-curve25519.c
ecc-curve448.c
ecc-internal.h
ecc-mod-arith.c
testsuite/ecc-modinv-test.c

index 07ec71bcad733bb2a3851d6d9ef0a0f9cd14f77c..e1bc071ae79feb9d02e607e6d6663e70e5d21f74 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2021-10-26  Niels Möller  <nisse@lysator.liu.se>
+
+       * ecc-mod-arith.c (ecc_mod_zero_p): New function.
+       * ecc-curve25519.c (ecc_curve25519_zero_p): Use it.
+       * ecc-curve448.c (ecc_curve448_zero_p): Deleted, usage replaced
+       with ecc_mod_zero_p.
+       * testsuite/ecc-modinv-test.c (mod_eq_p): Rewritten to use
+       ecc_mod_zero_p, and require that one input is canonically reduced.
+       (zero_p): Deleted, usage replaced with ecc_mod_zero_p.
+
 2021-10-23  Niels Möller  <nisse@lysator.liu.se>
 
        * gmp-glue.c (sec_zero_p): New function.
index 3a85f07e4eb55fe25756e1c116137dae4ffcbaca..a1d68afd32f3f6eb785c17ad542173262437e2d0 100644 (file)
@@ -170,20 +170,17 @@ ecc_curve25519_inv (const struct ecc_modulo *p,
   ecc_mod_mul (p, rp, ap, rp, scratch);
 }
 
-/* First, do a canonical reduction, then check if zero */
 static int
 ecc_curve25519_zero_p (const struct ecc_modulo *p, mp_limb_t *xp)
 {
-  mp_limb_t cy;
+/* First, reduce to < 2p. */
 #if PHIGH_BITS > 0
   mp_limb_t hi = xp[ECC_LIMB_SIZE-1];
   xp[ECC_LIMB_SIZE-1] = (hi & (GMP_NUMB_MASK >> PHIGH_BITS))
     + sec_add_1 (xp, xp, ECC_LIMB_SIZE - 1, 19 * (hi >> (GMP_NUMB_BITS - PHIGH_BITS)));
 #endif
-  cy = mpn_sub_n (xp, xp, p->m, ECC_LIMB_SIZE);
-  mpn_cnd_add_n (cy, xp, xp, p->m, ECC_LIMB_SIZE);
 
-  return sec_zero_p (xp, ECC_LIMB_SIZE);
+  return ecc_mod_zero_p (p, xp);
 }
 
 /* Compute x such that x^2 = u/v (mod p). Returns one on success, zero
index 2c3d54ba76458597fc364c1e41a71e0c45a72812..a83be1213e1f43e2b0905400daf66fecaac1a80a 100644 (file)
@@ -154,15 +154,10 @@ static void ecc_curve448_inv (const struct ecc_modulo *p,
   ecc_mod_mul (p, rp, ap, rp, tp);     /* a^{2^448-2^224-3} */
 }
 
-/* First, do a canonical reduction, then check if zero */
-static int
-ecc_curve448_zero_p (const struct ecc_modulo *p, mp_limb_t *xp)
-{
-  mp_limb_t cy = mpn_sub_n (xp, xp, p->m, ECC_LIMB_SIZE);
-  mpn_cnd_add_n (cy, xp, xp, p->m, ECC_LIMB_SIZE);
-
-  return sec_zero_p (xp, ECC_LIMB_SIZE);
-}
+/* To guarantee that inputs to ecc_mod_zero_p are in the required range. */
+#if ECC_LIMB_SIZE * GMP_NUMB_BITS != 448
+#error Unsupported limb size
+#endif
 
 /* Compute x such that x^2 = u/v (mod p). Returns one on success, zero
    on failure.
@@ -203,7 +198,7 @@ ecc_curve448_sqrt(const struct ecc_modulo *p, mp_limb_t *rp,
   ecc_mod_mul (p, t0, t0, vp, scratch_out);    /* v x^2 */
   ecc_mod_sub (p, t0, t0, up);
 
-  return ecc_curve448_zero_p (p, t0);
+  return ecc_mod_zero_p (p, t0);
 #undef uv
 #undef u3v
 #undef u5v3
index 245a6517c5823369e248270aef0928d2534a5207..76f505e8c75349ee46389e63866ba87d38e6bdb4 100644 (file)
@@ -42,6 +42,7 @@
 /* Name mangling */
 #define ecc_pp1_redc _nettle_ecc_pp1_redc
 #define ecc_pm1_redc _nettle_ecc_pm1_redc
+#define ecc_mod_zero_p _nettle_ecc_mod_zero_p
 #define ecc_mod_add _nettle_ecc_mod_add
 #define ecc_mod_sub _nettle_ecc_mod_sub
 #define ecc_mod_mul_1 _nettle_ecc_mod_mul_1
@@ -236,6 +237,9 @@ ecc_mod_func ecc_pm1_redc;
 
 ecc_mod_inv_func ecc_mod_inv;
 
+/* Side channel silent. Requires that x < 2m, so checks if x == 0 or x == p */
+int ecc_mod_zero_p (const struct ecc_modulo *m, const mp_limb_t *xp);
+
 void
 ecc_mod_add (const struct ecc_modulo *m, mp_limb_t *rp,
             const mp_limb_t *ap, const mp_limb_t *bp);
index b3021d940e815bf7ffc0e99b7fe90c00f0f02054..0b0631af7bc37d0a13e9c2ff061cb36473f60e4f 100644 (file)
 /* Routines for modp arithmetic. All values are ecc->size limbs, but
    not necessarily < p. */
 
+int
+ecc_mod_zero_p (const struct ecc_modulo *m, const mp_limb_t *xp_in)
+{
+  volatile mp_limb_t is_non_zero, is_not_p;
+  const volatile mp_limb_t *xp;
+  mp_size_t i;
+
+  for (xp = xp_in, i = 0, is_non_zero = is_not_p = 0; i < m->size; i++)
+    {
+      is_non_zero |= xp[i];
+      is_not_p |= (xp[i] ^ m->m[i]);
+    }
+
+  return (is_non_zero == 0) | (is_not_p == 0);
+}
+
 void
 ecc_mod_add (const struct ecc_modulo *m, mp_limb_t *rp,
             const mp_limb_t *ap, const mp_limb_t *bp)
index 9ba284faffbb45263e5b76d84acf8167784dae48..b9993e02b57d5a8ef4829d289d254eed23189b31 100644 (file)
@@ -1,4 +1,5 @@
 #include "testutils.h"
+#include <assert.h>
 
 static int
 ref_modinv (mp_limb_t *rp, const mp_limb_t *ap,
@@ -37,18 +38,16 @@ ref_modinv (mp_limb_t *rp, const mp_limb_t *ap,
   return res;
 }
 
+/* Requires that a < 2m, and ref < m. */
 static int
-zero_p (const struct ecc_modulo *m, const mp_limb_t *xp)
-{
-  return mpn_zero_p (xp, m->size)
-    || mpn_cmp (xp, m->m, m->size) == 0;
-}
-
-static int
-mod_eq_p (const struct ecc_modulo *m, const mp_limb_t *a, const mp_limb_t *b,
+mod_eq_p (const struct ecc_modulo *m, const mp_limb_t *a, const mp_limb_t *ref,
          mp_limb_t *scratch) {
-  ecc_mod_sub (m, scratch, a, b);
-  return zero_p (m, scratch);
+  mp_limb_t cy;
+  assert (mpn_cmp (ref, m->m, m->size) < 0);
+  cy = mpn_sub_n (scratch, a, ref, m->size);
+  /* If cy > 0, i.e., a < ref, then they can't be equal mod m. */
+  return (cy == 0) & ecc_mod_zero_p (m, scratch);
+
 }
 
 #define MAX_ECC_SIZE (1 + 521 / GMP_NUMB_BITS)
@@ -76,7 +75,7 @@ test_modulo (gmp_randstate_t rands, const char *name,
   mpn_zero (a, m->size);
   memset (ai, 17, m->size * sizeof(*ai));
   m->invert (m, ai, a, scratch);
-  if (!zero_p (m, ai))
+  if (!ecc_mod_zero_p (m, ai))
     {
       fprintf (stderr, "%s->invert failed for zero input (bit size %u):\n",
               name, m->bit_size);
@@ -91,7 +90,7 @@ test_modulo (gmp_randstate_t rands, const char *name,
   /* Check behaviour for a = m */
   memset (ai, 17, m->size * sizeof(*ai));
   m->invert (m, ai, m->m, scratch);
-  if (!zero_p (m, ai))
+  if (!ecc_mod_zero_p (m, ai))
     {
       fprintf (stderr, "%s->invert failed for a = p input (bit size %u):\n",
               name, m->bit_size);