Commit b524402c authored by Niels Möller's avatar Niels Möller

Added invert function pointer to struct ecc_modulo.

Updated and renamed sec_modinv -> ecc_mod_inv, and deleted the
ecc_modp_inv and ecc_modq_inv wrapper functions.
parent feec2348
2014-09-22 Niels Möller <nisse@lysator.liu.se> 2014-09-22 Niels Möller <nisse@lysator.liu.se>
* ecc-internal.h (ecc_mod_inv_func): New typedef.
(struct ecc_modulo): Added mp1h constant and invert function
pointer. Updated all callers.
* ecc-modp.c (ecc_modp_inv): Deleted wrapper function.
* ecc-modq.c (ecc_modq_inv): Deleted wrapper function.
* ecc-mod-inv.c (ecc_mod_inv): Renamed file and function. Also
take a struct ecc_modulo * as argument.
* sec-modinv.c (sec_modinv): ... the old names. Deleted.
* Makefile.in (hogweed_SOURCES): Updated accordingly.
* examples/ecc-benchmark.c (bench_modinv_powm, bench_curve): * examples/ecc-benchmark.c (bench_modinv_powm, bench_curve):
Updated benchmarking of mpn_sec_powm. Updated benchmarking of mpn_sec_powm.
......
...@@ -160,9 +160,9 @@ hogweed_SOURCES = sexp.c sexp-format.c \ ...@@ -160,9 +160,9 @@ hogweed_SOURCES = sexp.c sexp-format.c \
dsa2sexp.c sexp2dsa.c \ dsa2sexp.c sexp2dsa.c \
pgp-encode.c rsa2openpgp.c \ pgp-encode.c rsa2openpgp.c \
der-iterator.c der2rsa.c der2dsa.c \ der-iterator.c der2rsa.c der2dsa.c \
sec-add-1.c sec-sub-1.c sec-modinv.c sec-tabselect.c \ sec-add-1.c sec-sub-1.c sec-tabselect.c \
gmp-glue.c cnd-copy.c \ gmp-glue.c cnd-copy.c \
ecc-mod.c \ ecc-mod.c ecc-mod-inv.c \
ecc-modp.c ecc-modq.c ecc-pp1-redc.c ecc-pm1-redc.c \ ecc-modp.c ecc-modq.c ecc-pp1-redc.c ecc-pm1-redc.c \
ecc-192.c ecc-224.c ecc-256.c ecc-384.c ecc-521.c \ ecc-192.c ecc-224.c ecc-256.c ecc-384.c ecc-521.c \
ecc-25519.c \ ecc-25519.c \
......
...@@ -66,7 +66,7 @@ curve25519_eh_to_x (mp_limb_t *xp, const mp_limb_t *p, ...@@ -66,7 +66,7 @@ curve25519_eh_to_x (mp_limb_t *xp, const mp_limb_t *p,
in this case. */ in this case. */
ecc_modp_sub (ecc, t0, wp, vp); ecc_modp_sub (ecc, t0, wp, vp);
/* Needs 3*size scratch, for a total of 5*size */ /* Needs 3*size scratch, for a total of 5*size */
ecc_modp_inv (ecc, t1, t0, t2); ecc->p.invert (&ecc->p, t1, t0, t2);
ecc_modp_add (ecc, t0, wp, vp); ecc_modp_add (ecc, t0, wp, vp);
ecc_modp_mul (ecc, t2, t0, t1); ecc_modp_mul (ecc, t2, t0, t1);
......
...@@ -132,7 +132,7 @@ curve25519_mul (uint8_t *q, const uint8_t *n, const uint8_t *p) ...@@ -132,7 +132,7 @@ curve25519_mul (uint8_t *q, const uint8_t *n, const uint8_t *p)
ecc_modp_addmul_1 (ecc, AA, E, 121665); ecc_modp_addmul_1 (ecc, AA, E, 121665);
ecc_modp_mul (ecc, z2, E, AA); ecc_modp_mul (ecc, z2, E, AA);
} }
ecc_modp_inv (ecc, x3, z2, z3); ecc->p.invert (&ecc->p, x3, z2, z3);
ecc_modp_mul (ecc, z3, x2, x3); ecc_modp_mul (ecc, z3, x2, x3);
cy = mpn_sub_n (x2, z3, ecc->p.m, ecc->p.size); cy = mpn_sub_n (x2, z3, ecc->p.m, ecc->p.size);
cnd_copy (cy, x2, z3, ecc->p.size); cnd_copy (cy, x2, z3, ecc->p.size);
......
...@@ -121,8 +121,11 @@ const struct ecc_curve nettle_secp_192r1 = ...@@ -121,8 +121,11 @@ const struct ecc_curve nettle_secp_192r1 =
ecc_Bmodp, ecc_Bmodp,
ecc_Bmodp_shifted, ecc_Bmodp_shifted,
ecc_redc_ppm1, ecc_redc_ppm1,
ecc_pp1h,
ecc_192_modp, ecc_192_modp,
ecc_192_modp, ecc_192_modp,
ecc_mod_inv,
}, },
{ {
192, 192,
...@@ -133,8 +136,11 @@ const struct ecc_curve nettle_secp_192r1 = ...@@ -133,8 +136,11 @@ const struct ecc_curve nettle_secp_192r1 =
ecc_Bmodq, ecc_Bmodq,
ecc_Bmodq_shifted, ecc_Bmodq_shifted,
NULL, NULL,
ecc_qp1h,
ecc_mod, ecc_mod,
ecc_mod, ecc_mod,
ecc_mod_inv,
}, },
USE_REDC, USE_REDC,
...@@ -154,9 +160,7 @@ const struct ecc_curve nettle_secp_192r1 = ...@@ -154,9 +160,7 @@ const struct ecc_curve nettle_secp_192r1 =
ecc_b, ecc_b,
ecc_g, ecc_g,
NULL, NULL,
ecc_pp1h,
ecc_unit, ecc_unit,
ecc_qp1h,
ecc_table ecc_table
}; };
...@@ -73,8 +73,11 @@ const struct ecc_curve nettle_secp_224r1 = ...@@ -73,8 +73,11 @@ const struct ecc_curve nettle_secp_224r1 =
ecc_Bmodp, ecc_Bmodp,
ecc_Bmodp_shifted, ecc_Bmodp_shifted,
ecc_redc_ppm1, ecc_redc_ppm1,
ecc_pp1h,
ecc_224_modp, ecc_224_modp,
USE_REDC ? ecc_224_redc : ecc_224_modp, USE_REDC ? ecc_224_redc : ecc_224_modp,
ecc_mod_inv,
}, },
{ {
224, 224,
...@@ -85,8 +88,11 @@ const struct ecc_curve nettle_secp_224r1 = ...@@ -85,8 +88,11 @@ const struct ecc_curve nettle_secp_224r1 =
ecc_Bmodq, ecc_Bmodq,
ecc_Bmodq_shifted, ecc_Bmodq_shifted,
NULL, NULL,
ecc_qp1h,
ecc_mod, ecc_mod,
ecc_mod, ecc_mod,
ecc_mod_inv,
}, },
USE_REDC, USE_REDC,
...@@ -106,8 +112,6 @@ const struct ecc_curve nettle_secp_224r1 = ...@@ -106,8 +112,6 @@ const struct ecc_curve nettle_secp_224r1 =
ecc_b, ecc_b,
ecc_g, ecc_g,
NULL, NULL,
ecc_pp1h,
ecc_unit, ecc_unit,
ecc_qp1h,
ecc_table ecc_table
}; };
...@@ -241,8 +241,11 @@ const struct ecc_curve nettle_curve25519 = ...@@ -241,8 +241,11 @@ const struct ecc_curve nettle_curve25519 =
ecc_Bmodp, ecc_Bmodp,
ecc_Bmodp_shifted, ecc_Bmodp_shifted,
NULL, NULL,
ecc_pp1h,
ecc_25519_modp, ecc_25519_modp,
ecc_25519_modp, ecc_25519_modp,
ecc_mod_inv,
}, },
{ {
253, 253,
...@@ -253,8 +256,11 @@ const struct ecc_curve nettle_curve25519 = ...@@ -253,8 +256,11 @@ const struct ecc_curve nettle_curve25519 =
ecc_Bmodq, ecc_Bmodq,
ecc_mBmodq_shifted, /* Use q - 2^{252} instead. */ ecc_mBmodq_shifted, /* Use q - 2^{252} instead. */
NULL, NULL,
ecc_qp1h,
ecc_25519_modq, ecc_25519_modq,
ecc_25519_modq, ecc_25519_modq,
ecc_mod_inv,
}, },
0, /* No redc */ 0, /* No redc */
...@@ -274,8 +280,6 @@ const struct ecc_curve nettle_curve25519 = ...@@ -274,8 +280,6 @@ const struct ecc_curve nettle_curve25519 =
ecc_d, /* Use the Edwards curve constant. */ ecc_d, /* Use the Edwards curve constant. */
ecc_g, ecc_g,
ecc_edwards, ecc_edwards,
ecc_pp1h,
ecc_unit, ecc_unit,
ecc_qp1h,
ecc_table ecc_table
}; };
...@@ -236,8 +236,11 @@ const struct ecc_curve nettle_secp_256r1 = ...@@ -236,8 +236,11 @@ const struct ecc_curve nettle_secp_256r1 =
ecc_Bmodp, ecc_Bmodp,
ecc_Bmodp_shifted, ecc_Bmodp_shifted,
ecc_redc_ppm1, ecc_redc_ppm1,
ecc_pp1h,
ecc_256_modp, ecc_256_modp,
USE_REDC ? ecc_256_redc : ecc_256_modp, USE_REDC ? ecc_256_redc : ecc_256_modp,
ecc_mod_inv,
}, },
{ {
256, 256,
...@@ -248,8 +251,11 @@ const struct ecc_curve nettle_secp_256r1 = ...@@ -248,8 +251,11 @@ const struct ecc_curve nettle_secp_256r1 =
ecc_Bmodq, ecc_Bmodq,
ecc_Bmodq_shifted, ecc_Bmodq_shifted,
NULL, NULL,
ecc_qp1h,
ecc_256_modq, ecc_256_modq,
ecc_256_modq, ecc_256_modq,
ecc_mod_inv,
}, },
USE_REDC, USE_REDC,
...@@ -269,8 +275,6 @@ const struct ecc_curve nettle_secp_256r1 = ...@@ -269,8 +275,6 @@ const struct ecc_curve nettle_secp_256r1 =
ecc_b, ecc_b,
ecc_g, ecc_g,
NULL, NULL,
ecc_pp1h,
ecc_unit, ecc_unit,
ecc_qp1h,
ecc_table ecc_table
}; };
...@@ -158,8 +158,11 @@ const struct ecc_curve nettle_secp_384r1 = ...@@ -158,8 +158,11 @@ const struct ecc_curve nettle_secp_384r1 =
ecc_Bmodp, ecc_Bmodp,
ecc_Bmodp_shifted, ecc_Bmodp_shifted,
ecc_redc_ppm1, ecc_redc_ppm1,
ecc_pp1h,
ecc_384_modp, ecc_384_modp,
ecc_384_modp, ecc_384_modp,
ecc_mod_inv,
}, },
{ {
384, 384,
...@@ -170,8 +173,11 @@ const struct ecc_curve nettle_secp_384r1 = ...@@ -170,8 +173,11 @@ const struct ecc_curve nettle_secp_384r1 =
ecc_Bmodq, ecc_Bmodq,
ecc_Bmodq_shifted, ecc_Bmodq_shifted,
NULL, NULL,
ecc_qp1h,
ecc_mod, ecc_mod,
ecc_mod, ecc_mod,
ecc_mod_inv,
}, },
USE_REDC, USE_REDC,
...@@ -191,8 +197,6 @@ const struct ecc_curve nettle_secp_384r1 = ...@@ -191,8 +197,6 @@ const struct ecc_curve nettle_secp_384r1 =
ecc_b, ecc_b,
ecc_g, ecc_g,
NULL, NULL,
ecc_pp1h,
ecc_unit, ecc_unit,
ecc_qp1h,
ecc_table ecc_table
}; };
...@@ -86,8 +86,11 @@ const struct ecc_curve nettle_secp_521r1 = ...@@ -86,8 +86,11 @@ const struct ecc_curve nettle_secp_521r1 =
ecc_Bmodp, ecc_Bmodp,
ecc_Bmodp_shifted, ecc_Bmodp_shifted,
ecc_redc_ppm1, ecc_redc_ppm1,
ecc_pp1h,
ecc_521_modp, ecc_521_modp,
ecc_521_modp, ecc_521_modp,
ecc_mod_inv,
}, },
{ {
521, 521,
...@@ -98,8 +101,11 @@ const struct ecc_curve nettle_secp_521r1 = ...@@ -98,8 +101,11 @@ const struct ecc_curve nettle_secp_521r1 =
ecc_Bmodq, ecc_Bmodq,
ecc_Bmodq_shifted, ecc_Bmodq_shifted,
NULL, NULL,
ecc_qp1h,
ecc_mod, ecc_mod,
ecc_mod, ecc_mod,
ecc_mod_inv,
}, },
USE_REDC, USE_REDC,
...@@ -119,9 +125,7 @@ const struct ecc_curve nettle_secp_521r1 = ...@@ -119,9 +125,7 @@ const struct ecc_curve nettle_secp_521r1 =
ecc_b, ecc_b,
ecc_g, ecc_g,
NULL, NULL,
ecc_pp1h,
ecc_unit, ecc_unit,
ecc_qp1h,
ecc_table ecc_table
}; };
...@@ -84,7 +84,7 @@ ecc_ecdsa_sign (const struct ecc_curve *ecc, ...@@ -84,7 +84,7 @@ ecc_ecdsa_sign (const struct ecc_curve *ecc,
/* Invert k, uses 5 * ecc->p.size including scratch */ /* Invert k, uses 5 * ecc->p.size including scratch */
mpn_copyi (hp, kp, ecc->p.size); mpn_copyi (hp, kp, ecc->p.size);
ecc_modq_inv (ecc, kinv, hp, tp); ecc->q.invert (&ecc->q, kinv, hp, tp);
/* Process hash digest */ /* Process hash digest */
ecc_hash (ecc, hp, length, digest); ecc_hash (ecc, hp, length, digest);
......
...@@ -108,7 +108,7 @@ ecc_ecdsa_verify (const struct ecc_curve *ecc, ...@@ -108,7 +108,7 @@ ecc_ecdsa_verify (const struct ecc_curve *ecc,
/* Compute sinv, use P2 as scratch */ /* Compute sinv, use P2 as scratch */
mpn_copyi (sinv + ecc->p.size, sp, ecc->p.size); mpn_copyi (sinv + ecc->p.size, sp, ecc->p.size);
ecc_modq_inv (ecc, sinv, sinv + ecc->p.size, P2); ecc->q.invert (&ecc->q, sinv, sinv + ecc->p.size, P2);
/* u2 = r / s, P2 = u2 * Y */ /* u2 = r / s, P2 = u2 * Y */
ecc_modq_mul (ecc, u2, rp, sinv); ecc_modq_mul (ecc, u2, rp, sinv);
......
...@@ -65,7 +65,7 @@ ecc_eh_to_a (const struct ecc_curve *ecc, ...@@ -65,7 +65,7 @@ ecc_eh_to_a (const struct ecc_curve *ecc,
mpn_copyi (tp, zp, ecc->p.size); mpn_copyi (tp, zp, ecc->p.size);
/* Needs 3*size scratch */ /* Needs 3*size scratch */
ecc_modp_inv (ecc, izp, tp, tp + ecc->p.size); ecc->p.invert (&ecc->p, izp, tp, tp + ecc->p.size);
ecc_modp_mul (ecc, tp, xp, izp); ecc_modp_mul (ecc, tp, xp, izp);
cy = mpn_sub_n (r, tp, ecc->p.m, ecc->p.size); cy = mpn_sub_n (r, tp, ecc->p.m, ecc->p.size);
......
...@@ -49,12 +49,11 @@ ...@@ -49,12 +49,11 @@
#define ecc_modp_submul_1 _nettle_ecc_modp_submul_1 #define ecc_modp_submul_1 _nettle_ecc_modp_submul_1
#define ecc_modp_mul _nettle_ecc_modp_mul #define ecc_modp_mul _nettle_ecc_modp_mul
#define ecc_modp_sqr _nettle_ecc_modp_sqr #define ecc_modp_sqr _nettle_ecc_modp_sqr
#define ecc_modp_inv _nettle_ecc_modp_inv
#define ecc_modq_mul _nettle_ecc_modq_mul #define ecc_modq_mul _nettle_ecc_modq_mul
#define ecc_modq_add _nettle_ecc_modq_add #define ecc_modq_add _nettle_ecc_modq_add
#define ecc_modq_inv _nettle_ecc_modq_inv
#define ecc_modq_random _nettle_ecc_modq_random #define ecc_modq_random _nettle_ecc_modq_random
#define ecc_mod _nettle_ecc_mod #define ecc_mod _nettle_ecc_mod
#define ecc_mod_inv _nettle_ecc_mod_inv
#define ecc_hash _nettle_ecc_hash #define ecc_hash _nettle_ecc_hash
#define cnd_copy _nettle_cnd_copy #define cnd_copy _nettle_cnd_copy
#define sec_add_1 _nettle_sec_add_1 #define sec_add_1 _nettle_sec_add_1
...@@ -82,6 +81,10 @@ struct ecc_modulo; ...@@ -82,6 +81,10 @@ struct ecc_modulo;
modp_mul and modp_sqr. */ modp_mul and modp_sqr. */
typedef void ecc_mod_func (const struct ecc_modulo *m, mp_limb_t *rp); typedef void ecc_mod_func (const struct ecc_modulo *m, mp_limb_t *rp);
typedef void ecc_mod_inv_func (const struct ecc_modulo *m,
mp_limb_t *vp, mp_limb_t *ap,
mp_limb_t *scratch);
typedef void ecc_add_func (const struct ecc_curve *ecc, typedef void ecc_add_func (const struct ecc_curve *ecc,
mp_limb_t *r, mp_limb_t *r,
const mp_limb_t *p, const mp_limb_t *q, const mp_limb_t *p, const mp_limb_t *q,
...@@ -115,9 +118,12 @@ struct ecc_modulo ...@@ -115,9 +118,12 @@ struct ecc_modulo
const mp_limb_t *B_shifted; const mp_limb_t *B_shifted;
/* m +/- 1, for redc, excluding redc_size low limbs. */ /* m +/- 1, for redc, excluding redc_size low limbs. */
const mp_limb_t *redc_mpm1; const mp_limb_t *redc_mpm1;
/* (m+1)/2 */
const mp_limb_t *mp1h;
ecc_mod_func *mod; ecc_mod_func *mod;
ecc_mod_func *reduce; ecc_mod_func *reduce;
ecc_mod_inv_func *invert;
}; };
/* Represents an elliptic curve of the form /* Represents an elliptic curve of the form
...@@ -156,14 +162,9 @@ struct ecc_curve ...@@ -156,14 +162,9 @@ struct ecc_curve
equivalent Edwards curve. */ equivalent Edwards curve. */
const mp_limb_t *edwards_root; const mp_limb_t *edwards_root;
/* (p+1)/2 */
const mp_limb_t *pp1h;
/* For redc, same as Bmodp, otherwise 1. */ /* For redc, same as Bmodp, otherwise 1. */
const mp_limb_t *unit; const mp_limb_t *unit;
/* (q+1)/2 */
const mp_limb_t *qp1h;
/* Tables for multiplying by the generator, size determined by k and /* Tables for multiplying by the generator, size determined by k and
c. The first 2^c entries are defined by c. The first 2^c entries are defined by
...@@ -182,6 +183,8 @@ ecc_mod_func ecc_mod; ...@@ -182,6 +183,8 @@ ecc_mod_func ecc_mod;
ecc_mod_func ecc_pp1_redc; ecc_mod_func ecc_pp1_redc;
ecc_mod_func ecc_pm1_redc; ecc_mod_func ecc_pm1_redc;
ecc_mod_inv_func ecc_mod_inv;
void void
ecc_modp_add (const struct ecc_curve *ecc, mp_limb_t *rp, ecc_modp_add (const struct ecc_curve *ecc, mp_limb_t *rp,
const mp_limb_t *ap, const mp_limb_t *bp); const mp_limb_t *ap, const mp_limb_t *bp);
...@@ -209,10 +212,6 @@ void ...@@ -209,10 +212,6 @@ void
ecc_modp_sqr (const struct ecc_curve *ecc, mp_limb_t *rp, ecc_modp_sqr (const struct ecc_curve *ecc, mp_limb_t *rp,
const mp_limb_t *ap); const mp_limb_t *ap);
void
ecc_modp_inv (const struct ecc_curve *ecc, mp_limb_t *rp, mp_limb_t *ap,
mp_limb_t *scratch);
/* mod q operations. */ /* mod q operations. */
void void
ecc_modq_mul (const struct ecc_curve *ecc, mp_limb_t *rp, ecc_modq_mul (const struct ecc_curve *ecc, mp_limb_t *rp,
...@@ -221,10 +220,6 @@ void ...@@ -221,10 +220,6 @@ void
ecc_modq_add (const struct ecc_curve *ecc, mp_limb_t *rp, ecc_modq_add (const struct ecc_curve *ecc, mp_limb_t *rp,
const mp_limb_t *ap, const mp_limb_t *bp); const mp_limb_t *ap, const mp_limb_t *bp);
void
ecc_modq_inv (const struct ecc_curve *ecc, mp_limb_t *rp, mp_limb_t *ap,
mp_limb_t *scratch);
void void
ecc_modq_random (const struct ecc_curve *ecc, mp_limb_t *xp, ecc_modq_random (const struct ecc_curve *ecc, mp_limb_t *xp,
void *ctx, nettle_random_func *random, mp_limb_t *scratch); void *ctx, nettle_random_func *random, mp_limb_t *scratch);
...@@ -248,10 +243,6 @@ sec_tabselect (mp_limb_t *rp, mp_size_t rn, ...@@ -248,10 +243,6 @@ sec_tabselect (mp_limb_t *rp, mp_size_t rn,
const mp_limb_t *table, unsigned tn, const mp_limb_t *table, unsigned tn,
unsigned k); unsigned k);
void
sec_modinv (mp_limb_t *vp, mp_limb_t *ap, mp_size_t n,
const mp_limb_t *mp, const mp_limb_t *mp1h, mp_size_t bit_size,
mp_limb_t *scratch);
int int
ecc_25519_sqrt(mp_limb_t *rp, const mp_limb_t *ap); ecc_25519_sqrt(mp_limb_t *rp, const mp_limb_t *ap);
......
...@@ -77,7 +77,7 @@ ecc_j_to_a (const struct ecc_curve *ecc, ...@@ -77,7 +77,7 @@ ecc_j_to_a (const struct ecc_curve *ecc,
mpn_zero (up + ecc->p.size, ecc->p.size); mpn_zero (up + ecc->p.size, ecc->p.size);
ecc->p.reduce (&ecc->p, up); ecc->p.reduce (&ecc->p, up);
ecc_modp_inv (ecc, izp, up, up + ecc->p.size); ecc->p.invert (&ecc->p, izp, up, up + ecc->p.size);
/* Divide this common factor by B */ /* Divide this common factor by B */
mpn_copyi (izBp, izp, ecc->p.size); mpn_copyi (izBp, izp, ecc->p.size);
...@@ -91,7 +91,7 @@ ecc_j_to_a (const struct ecc_curve *ecc, ...@@ -91,7 +91,7 @@ ecc_j_to_a (const struct ecc_curve *ecc,
/* Set s = p_z^{-1}, r_x = p_x s^2, r_y = p_y s^3 */ /* Set s = p_z^{-1}, r_x = p_x s^2, r_y = p_y s^3 */
mpn_copyi (up, p+2*ecc->p.size, ecc->p.size); /* p_z */ mpn_copyi (up, p+2*ecc->p.size, ecc->p.size); /* p_z */
ecc_modp_inv (ecc, izp, up, up + ecc->p.size); ecc->p.invert (&ecc->p, izp, up, up + ecc->p.size);
ecc_modp_sqr (ecc, iz2p, izp); ecc_modp_sqr (ecc, iz2p, izp);
} }
......
/* sec-modinv.c /* ecc-mod-inv.c
Copyright (C) 2013 Niels Möller Copyright (C) 2013, 2014 Niels Möller
This file is part of GNU Nettle. This file is part of GNU Nettle.
...@@ -57,15 +57,19 @@ cnd_neg (int cnd, mp_limb_t *rp, const mp_limb_t *ap, mp_size_t n) ...@@ -57,15 +57,19 @@ cnd_neg (int cnd, mp_limb_t *rp, const mp_limb_t *ap, mp_size_t n)
/* Compute a^{-1} mod m, with running time depending only on the size. /* 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}. 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. */ Also needs (m+1)/2, and m must be odd. */
/* FIXME: Could use mpn_sec_invert (in GMP-6), but with a bit more
scratch need since it doesn't precompute (m+1)/2. */
void void
sec_modinv (mp_limb_t *vp, mp_limb_t *ap, mp_size_t n, ecc_mod_inv (const struct ecc_modulo *m,
const mp_limb_t *mp, const mp_limb_t *mp1h, mp_size_t bit_size, mp_limb_t *vp, mp_limb_t *ap,
mp_limb_t *scratch) mp_limb_t *scratch)
{ {
#define bp scratch #define bp scratch
#define dp (scratch + n) #define dp (scratch + n)
#define up (scratch + 2*n) #define up (scratch + 2*n)
mp_size_t n = m->size;
/* Avoid the mp_bitcnt_t type for compatibility with older GMP /* Avoid the mp_bitcnt_t type for compatibility with older GMP
versions. */ versions. */
unsigned i; unsigned i;
...@@ -85,10 +89,10 @@ sec_modinv (mp_limb_t *vp, mp_limb_t *ap, mp_size_t n, ...@@ -85,10 +89,10 @@ sec_modinv (mp_limb_t *vp, mp_limb_t *ap, mp_size_t n,
up[0] = 1; up[0] = 1;
mpn_zero (up+1, n - 1); mpn_zero (up+1, n - 1);
mpn_copyi (bp, mp, n); mpn_copyi (bp, m->m, n);
mpn_zero (vp, n); mpn_zero (vp, n);
for (i = bit_size + GMP_NUMB_BITS * n; i-- > 0; ) for (i = m->bit_size + GMP_NUMB_BITS * n; i-- > 0; )
{ {
mp_limb_t odd, swap, cy; mp_limb_t odd, swap, cy;
...@@ -146,17 +150,17 @@ sec_modinv (mp_limb_t *vp, mp_limb_t *ap, mp_size_t n, ...@@ -146,17 +150,17 @@ sec_modinv (mp_limb_t *vp, mp_limb_t *ap, mp_size_t n,
#if 1 #if 1
cnd_swap (swap, up, vp, n); cnd_swap (swap, up, vp, n);
cy = cnd_sub_n (odd, up, vp, n); cy = cnd_sub_n (odd, up, vp, n);
cy -= cnd_add_n (cy, up, mp, n); cy -= cnd_add_n (cy, up, m->m, n);
#else #else
cy = cnd_sub_n (odd, up, vp, n); cy = cnd_sub_n (odd, up, vp, n);
cnd_add_n (swap, vp, up, n); cnd_add_n (swap, vp, up, n);
cnd_neg (swap, up, up, n); cnd_neg (swap, up, up, n);
cnd_add_n (cy ^ swap, up, mp, n); cnd_add_n (cy ^ swap, up, m->p, n);
#endif #endif
cy = mpn_rshift (ap, ap, n, 1); cy = mpn_rshift (ap, ap, n, 1);
assert (cy == 0); assert (cy == 0);