summaryrefslogtreecommitdiff
path: root/eccdata.c
diff options
context:
space:
mode:
Diffstat (limited to 'eccdata.c')
-rw-r--r--eccdata.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/eccdata.c b/eccdata.c
index e0726e8d..1d2e1993 100644
--- a/eccdata.c
+++ b/eccdata.c
@@ -1167,11 +1167,19 @@ string_toupper (char *buf, size_t size, const char *s)
abort();
}
+static unsigned
+invert_count (unsigned bit_size) {
+ /* See https://eprint.iacr.org/2019/266.pdf, Theorem 11.2 */
+ return (49 * bit_size + 57) / 17;
+}
+
static void
output_modulo (const char *name, const mpz_t x,
unsigned size, unsigned bits_per_limb)
{
unsigned bit_size;
+ unsigned count;
+ unsigned invert_iterations;
int shift;
char buf[20];
mpz_t t;
@@ -1193,9 +1201,29 @@ output_modulo (const char *name, const mpz_t x,
/ bits_per_limb));
bit_size = mpz_sizeinbase (x, 2);
-
shift = size * bits_per_limb - bit_size;
assert (shift >= 0);
+
+ /* If most significant bit of top limb is zero, input may be one bit
+ larger than the modulo. */
+ count = invert_count (bit_size + (shift > 0));
+ printf("#define ECC_INV%s_COUNT %u\n", buf, count);
+
+ mpz_set_ui (t, 0);
+ mpz_setbit (t, bits_per_limb);
+ mpz_invert (t, x, t);
+
+ printf ("#define ECC_BINV%s 0x", buf);
+ mpz_out_str (stdout, 16, t);
+ printf("%s\n", bits_per_limb > 32 ? "ULL" : "UL");
+
+ invert_iterations = (count + bits_per_limb - 3) / (bits_per_limb - 2);
+ mpz_set_ui (t, 2);
+ mpz_powm_ui (t, t, bits_per_limb * (invert_iterations + size) - count, x);
+ mpz_invert (t, t, x);
+ snprintf (buf, sizeof(buf), "ecc_inv%s_redc_power", name);
+ output_bignum (buf, t, size, bits_per_limb);
+
if (shift > 0)
{
mpz_set_ui (t, 0);
@@ -1292,14 +1320,6 @@ output_curve (const struct ecc_curve *ecc, unsigned bits_per_limb)
output_bignum ("ecc_b", ecc->b, limb_size, bits_per_limb);
- mpz_add_ui (t, ecc->p, 1);
- mpz_fdiv_q_2exp (t, t, 1);
- output_bignum ("ecc_pp1h", t, limb_size, bits_per_limb);
-
- mpz_add_ui (t, ecc->q, 1);
- mpz_fdiv_q_2exp (t, t, 1);
- output_bignum ("ecc_qp1h", t, limb_size, bits_per_limb);
-
/* Trailing zeros in p+1 correspond to trailing ones in p. */
redc_limbs = mpz_scan0 (ecc->p, 0) / bits_per_limb;
if (redc_limbs > 0)