]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Document and test that ecc_modp_inv produces 0 for input a == 0 (mod p).
authorNiels Möller <nisse@lysator.liu.se>
Sat, 23 Aug 2014 19:39:10 +0000 (21:39 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Sat, 23 Aug 2014 19:39:10 +0000 (21:39 +0200)
ChangeLog
sec-modinv.c
testsuite/ecc-modinv-test.c

index 956b0ca8afe6b74a032da2d59ca18795f05e3849..a4e89d42cdc933b081d20829b3ec5295d8a19970 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2014-08-23  Niels Möller  <nisse@lysator.liu.se>
+
+       * sec-modinv.c (sec_modinv): Document that for a == 0 (mod m), we
+       should produce the "inverse" 0.
+
+       * testsuite/ecc-modinv-test.c (test_main): Check that ecc_modp_inv
+       produces 0 if a == 0 or a == p.
+
 2014-08-22  Niels Möller  <nisse@lysator.liu.se>
 
        * x86_64/ecc-25519-modp.asm: New file. Assembly implementation,
index 6c7253df4ab6107af2d998c72b8387db0f771211..ea94abd3ac85810de14f264179221ecde99d5e30 100644 (file)
@@ -71,6 +71,7 @@ cnd_swap (int cnd, mp_limb_t *ap, mp_limb_t *bp, mp_size_t n)
 }
 
 /* Compute a^{-1} mod m, with running time depending only on the size.
+   Returns zero if a == 0 (mod m), to be consistent with a^{phi(m)-1}.
    Also needs (m+1)/2, and m must be odd. */
 void
 sec_modinv (mp_limb_t *vp, mp_limb_t *ap, mp_size_t n,
index 31b5c27e934ecf72b0cd24e809bea55a1eaa6a76..ee4267dc811a6bbdb1bb47843f1292a7a79cb10d 100644 (file)
@@ -37,6 +37,17 @@ ref_modinv (mp_limb_t *rp, const mp_limb_t *ap, const mp_limb_t *mp, mp_size_t m
 #define MAX_ECC_SIZE (1 + 521 / GMP_NUMB_BITS)
 #define COUNT 500
 
+static int
+mpn_zero_p (mp_srcptr ap, mp_size_t n)
+{
+  while (--n >= 0)
+    {
+      if (ap[n] != 0)
+       return 0;
+    }
+  return 1;
+}
+
 void
 test_main (void)
 {
@@ -55,6 +66,36 @@ test_main (void)
     {
       const struct ecc_curve *ecc = ecc_curves[i];
       unsigned j;
+      /* Check behaviour for zero input */
+      mpn_zero (a, ecc->size);
+      memset (ai, 17, ecc->size * sizeof(*ai));
+      ecc_modp_inv (ecc, ai, a, scratch);
+      if (!mpn_zero_p (ai, ecc->size))
+       {
+         fprintf (stderr, "ecc_modp_inv failed for zero input (bit size %u):\n",
+                      ecc->bit_size);
+         gmp_fprintf (stderr, "p = %Nx\n"
+                      "t = %Nx (bad)\n",
+                      ecc->p, ecc->size,
+                      ai, ecc->size);
+         abort ();
+       }
+         
+      /* Check behaviour for a = p */
+      mpn_copyi (a, ecc->p, ecc->size);
+      memset (ai, 17, ecc->size * sizeof(*ai));
+      ecc_modp_inv (ecc, ai, a, scratch);
+      if (!mpn_zero_p (ai, ecc->size))
+       {
+         fprintf (stderr, "ecc_modp_inv failed for a = p input (bit size %u):\n",
+                      ecc->bit_size);
+         gmp_fprintf (stderr, "p = %Nx\n"
+                      "t = %Nx (bad)\n",
+                      ecc->p, ecc->size,
+                      ai, ecc->size);
+         abort ();
+       }
+       
       for (j = 0; j < COUNT; j++)
        {
          if (j & 1)