summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2015-12-18 11:48:39 +0100
committerNiels Möller <nisse@lysator.liu.se>2015-12-18 11:48:39 +0100
commit230e83121f9ec6dd04efb5c9ed4cb9971e9da966 (patch)
treec1c71fb25c7dbde1d2fe0a468f85188f9315b239
parentfa269b6ad06dd13c901dbd84a12e52b918a09cd7 (diff)
downloadnettle-230e83121f9ec6dd04efb5c9ed4cb9971e9da966.tar.gz
Improved ecc-mod-test with random seeding.
-rw-r--r--ChangeLog5
-rw-r--r--testsuite/ecc-mod-test.c204
2 files changed, 169 insertions, 40 deletions
diff --git a/ChangeLog b/ChangeLog
index a13dcca6..6b7a7b39 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2015-12-18 Niels Möller <nisse@lysator.liu.se>
+
+ * testsuite/ecc-mod-test.c (test_main): Handle random seeding if
+ NETTLE_TEST_SEED is set in the environment.
+
2015-12-15 Niels Möller <nisse@lysator.liu.se>
* x86_64/ecc-384-modp.asm: Fixed carry propagation bug. Problem
diff --git a/testsuite/ecc-mod-test.c b/testsuite/ecc-mod-test.c
index 3001d8e2..17e35a92 100644
--- a/testsuite/ecc-mod-test.c
+++ b/testsuite/ecc-mod-test.c
@@ -1,5 +1,9 @@
#include "testutils.h"
+#include <errno.h>
+#include <limits.h>
+#include <sys/time.h>
+
static void
ref_mod (mp_limb_t *rp, const mp_limb_t *ap, const mp_limb_t *mp, mp_size_t mn)
{
@@ -16,38 +20,49 @@ ref_mod (mp_limb_t *rp, const mp_limb_t *ap, const mp_limb_t *mp, mp_size_t mn)
#define COUNT 50000
static void
-test_modulo (gmp_randstate_t rands, const char *name,
- const struct ecc_modulo *m)
+test_one(const char *name,
+ const struct ecc_modulo *m,
+ const mpz_t r)
{
mp_limb_t a[MAX_SIZE];
mp_limb_t t[MAX_SIZE];
mp_limb_t ref[MAX_SIZE];
- mpz_t r;
- unsigned j;
- mpz_init (r);
-
- for (j = 0; j < COUNT; j++)
- {
- if (j & 1)
- mpz_rrandomb (r, rands, 2*m->size * GMP_NUMB_BITS);
- else
- mpz_urandomb (r, rands, 2*m->size * GMP_NUMB_BITS);
+ mpz_limbs_copy (a, r, 2*m->size);
- mpz_limbs_copy (a, r, 2*m->size);
+ ref_mod (ref, a, m->m, m->size);
- ref_mod (ref, a, m->m, m->size);
+ mpn_copyi (t, a, 2*m->size);
+ m->mod (m, t);
+ if (mpn_cmp (t, m->m, m->size) >= 0)
+ mpn_sub_n (t, t, m->m, m->size);
+ if (mpn_cmp (t, ref, m->size))
+ {
+ fprintf (stderr, "m->mod %s failed: bit_size = %u\n",
+ name, m->bit_size);
+
+ fprintf (stderr, "a = ");
+ mpn_out_str (stderr, 16, a, 2*m->size);
+ fprintf (stderr, "\nt = ");
+ mpn_out_str (stderr, 16, t, m->size);
+ fprintf (stderr, " (bad)\nref = ");
+ mpn_out_str (stderr, 16, ref, m->size);
+ fprintf (stderr, "\n");
+ abort ();
+ }
+
+ if (m->B_size < m->size)
+ {
mpn_copyi (t, a, 2*m->size);
- m->mod (m, t);
+ ecc_mod (m, t);
if (mpn_cmp (t, m->m, m->size) >= 0)
mpn_sub_n (t, t, m->m, m->size);
if (mpn_cmp (t, ref, m->size))
{
- fprintf (stderr, "m->mod %s failed: bit_size = %u\n",
+ fprintf (stderr, "ecc_mod %s failed: bit_size = %u\n",
name, m->bit_size);
-
fprintf (stderr, "a = ");
mpn_out_str (stderr, 16, a, 2*m->size);
fprintf (stderr, "\nt = ");
@@ -57,44 +72,153 @@ test_modulo (gmp_randstate_t rands, const char *name,
fprintf (stderr, "\n");
abort ();
}
+ }
+}
- if (m->B_size < m->size)
+static void
+test_modulo (gmp_randstate_t rands, const char *name,
+ const struct ecc_modulo *m, unsigned count)
+{
+ mpz_t r;
+ unsigned j;
+
+ mpz_init (r);
+
+ for (j = 0; j < count; j++)
+ {
+ if (j & 1)
+ mpz_rrandomb (r, rands, 2*m->size * GMP_NUMB_BITS);
+ else
+ mpz_urandomb (r, rands, 2*m->size * GMP_NUMB_BITS);
+
+ test_one (name, m, r);
+ }
+ mpz_clear (r);
+}
+
+static void
+test_fixed (void)
+{
+ mpz_t r;
+ mpz_init (r);
+
+ /* Triggered a bug reported by Hanno Böck. */
+ mpz_set_str (r, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFF001C2C00", 16);
+ mpz_mul_2exp (r, r, 256);
+ test_one ("p", &nettle_secp_256r1.p, r);
+ test_one ("q", &nettle_secp_256r1.q, r);
+
+ mpz_set_str (r, "ffffffff00000001fffffffeffffffffffffffffffffffffffffffc0000000000007ffffffffffffffffffffffffffff00000000000000000fffffffffffffff", 16);
+ test_one ("p", &nettle_secp_256r1.p, r);
+ test_one ("q", &nettle_secp_256r1.q, r);
+
+ /* Triggered a bug reported by Hanno Böck. */
+ mpz_set_str (r, "4c9000000000000000000000000000000000000000000000004a604db486e000000000000000000000000000000000000000121025be29575adb2c8ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16);
+ test_one ("p", &nettle_secp_384r1.p, r);
+ test_one ("q", &nettle_secp_384r1.q, r);
+
+ /* Triggered a carry bug in development version. */
+ mpz_set_str (r, "e64a84643150260640e4677c19ffc4faef06042132b86af6e9ee33fe1850222e57a514d5f1d6d444008bb896a96a43d5629945e57548f5e12f66be132b24110cbb2df6d7d3dd3aaadc98b0bbf29573843ad72e57f59fc5d4f56cc599da18bb99", 16);
+
+ test_one ("p", &nettle_secp_384r1.p, r);
+ test_one ("q", &nettle_secp_384r1.q, r);
+
+ mpz_clear (r);
+}
+
+static void
+test_patterns (const char *name,
+ const struct ecc_modulo *m)
+{
+ mpz_t r;
+ unsigned j;
+
+ mpz_init (r);
+
+ for (j = m->bit_size; j < 2*m->bit_size; j++)
+ {
+ mpz_set_ui (r, 1);
+ mpz_mul_2exp (r, r, j);
+
+ test_one (name, m, r);
+ }
+ mpz_clear (r);
+}
+
+#if !NETTLE_USE_MINI_GMP
+static void
+get_random_seed(mpz_t seed)
+{
+ struct timeval tv;
+ FILE *f;
+ f = fopen ("/dev/urandom", "rb");
+ if (f)
+ {
+ uint8_t buf[8];
+ size_t res;
+
+ setbuf (f, NULL);
+ res = fread (&buf, sizeof(buf), 1, f);
+ fclose(f);
+ if (res == 1)
{
- mpn_copyi (t, a, 2*m->size);
- ecc_mod (m, t);
- if (mpn_cmp (t, m->m, m->size) >= 0)
- mpn_sub_n (t, t, m->m, m->size);
-
- if (mpn_cmp (t, ref, m->size))
- {
- fprintf (stderr, "ecc_mod %s failed: bit_size = %u\n",
- name, m->bit_size);
- fprintf (stderr, "a = ");
- mpn_out_str (stderr, 16, a, 2*m->size);
- fprintf (stderr, "\nt = ");
- mpn_out_str (stderr, 16, t, m->size);
- fprintf (stderr, " (bad)\nref = ");
- mpn_out_str (stderr, 16, ref, m->size);
- fprintf (stderr, "\n");
- abort ();
- }
+ nettle_mpz_set_str_256_u (seed, sizeof(buf), buf);
+ return;
}
+ fprintf (stderr, "Read of /dev/urandom failed: %s\n",
+ strerror (errno));
}
- mpz_clear (r);
+ gettimeofday(&tv, NULL);
+ mpz_set_ui (seed, tv.tv_sec);
+ mpz_mul_ui (seed, seed, 1000000UL);
+ mpz_add_ui (seed, seed, tv.tv_usec);
}
+#endif /* !NETTLE_USE_MINI_GMP */
void
test_main (void)
{
+ const char *nettle_test_seed;
gmp_randstate_t rands;
+ unsigned count = COUNT;
unsigned i;
gmp_randinit_default (rands);
-
+
+ test_fixed ();
+
+ for (i = 0; ecc_curves[i]; i++)
+ {
+ test_patterns ("p", &ecc_curves[i]->p);
+ test_patterns ("q", &ecc_curves[i]->p);
+ }
+
+#if !NETTLE_USE_MINI_GMP
+ nettle_test_seed = getenv ("NETTLE_TEST_SEED");
+ if (nettle_test_seed && *nettle_test_seed)
+ {
+ mpz_t seed;
+ mpz_init (seed);
+ if (mpz_set_str (seed, nettle_test_seed, 0) < 0
+ || mpz_sgn (seed) < 0)
+ die ("Invalid NETTLE_TEST_SEED: %s\n",
+ nettle_test_seed);
+ if (mpz_sgn (seed) == 0)
+ get_random_seed (seed);
+ fprintf (stderr, "Using NETTLE_TEST_SEED=");
+ mpz_out_str (stderr, 10, seed);
+ fprintf (stderr, "\n");
+
+ gmp_randseed (rands, seed);
+ mpz_clear (seed);
+ count *= 20;
+ }
+#endif /* !NETTLE_USE_MINI_GMP */
+
for (i = 0; ecc_curves[i]; i++)
{
- test_modulo (rands, "p", &ecc_curves[i]->p);
- test_modulo (rands, "q", &ecc_curves[i]->q);
+ test_modulo (rands, "p", &ecc_curves[i]->p, count);
+ test_modulo (rands, "q", &ecc_curves[i]->q, count);
}
gmp_randclear (rands);
}