Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions bn_mp_div_d.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,10 @@ int mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d)
return MP_OKAY;
}

#ifdef BN_MP_DIV_3_C
/* three? */
if (b == 3u) {
if (MP_HAS(MP_DIV_3) && b == 3u) {
return mp_div_3(a, c, d);
}
#endif

/* no easy answer [c'est la vie]. Just division */
if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
Expand Down
39 changes: 12 additions & 27 deletions bn_mp_exptmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ int mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y)

/* if exponent X is negative we have to recurse */
if (X->sign == MP_NEG) {
#ifdef BN_MP_INVMOD_C
mp_int tmpG, tmpX;
int err;

if (!MP_HAS(MP_INVMOD)) {
return MP_VAL;
}

/* first compute 1/G mod P */
if ((err = mp_init(&tmpG)) != MP_OKAY) {
return err;
Expand All @@ -46,50 +49,32 @@ int mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y)
err = mp_exptmod(&tmpG, &tmpX, P, Y);
mp_clear_multi(&tmpG, &tmpX, NULL);
return err;
#else
/* no invmod */
return MP_VAL;
#endif
}

/* modified diminished radix reduction */
#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C)
if (mp_reduce_is_2k_l(P) == MP_YES) {
if (MP_HAS(MP_REDUCE_IS_2K_L) && MP_HAS(MP_REDUCE_2K_L) && MP_HAS(S_MP_EXPTMOD) &&
mp_reduce_is_2k_l(P) == MP_YES) {
return s_mp_exptmod(G, X, P, Y, 1);
}
#endif

#ifdef BN_MP_DR_IS_MODULUS_C
/* is it a DR modulus? */
dr = mp_dr_is_modulus(P);
#else
/* default to no */
dr = 0;
#endif
/* is it a DR modulus? default to no */
dr = MP_HAS(MP_DR_IS_MODULUS) ? mp_dr_is_modulus(P) : 0;

#ifdef BN_MP_REDUCE_IS_2K_C
/* if not, is it a unrestricted DR modulus? */
if (dr == 0) {
if (MP_HAS(MP_REDUCE_IS_2K) && dr == 0) {
dr = mp_reduce_is_2k(P) << 1;
}
#endif

/* if the modulus is odd or dr != 0 use the montgomery method */
#ifdef BN_MP_EXPTMOD_FAST_C
if (IS_ODD(P) || (dr != 0)) {
if (MP_HAS(MP_EXPTMOD_FAST) && (IS_ODD(P) || (dr != 0))) {
return mp_exptmod_fast(G, X, P, Y, dr);
} else {
#endif
#ifdef BN_S_MP_EXPTMOD_C
} else if (MP_HAS(S_MP_EXPTMOD)) {
/* otherwise use the generic Barrett reduction technique */
return s_mp_exptmod(G, X, P, Y, 0);
#else
} else {
/* no exptmod for evens */
return MP_VAL;
#endif
#ifdef BN_MP_EXPTMOD_FAST_C
}
#endif
}

#endif
74 changes: 33 additions & 41 deletions bn_mp_exptmod_fast.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,9 @@ int mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y
winsize = 8;
}

#ifdef MP_LOW_MEM
if (winsize > 5) {
if (MP_DEFINED(MP_LOW_MEM) && winsize > 5) {
winsize = 5;
}
#endif

/* init M array */
/* init first cell */
Expand All @@ -72,52 +70,46 @@ int mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y

/* determine and setup reduction code */
if (redmode == 0) {
#ifdef BN_MP_MONTGOMERY_SETUP_C
/* now setup montgomery */
if ((err = mp_montgomery_setup(P, &mp)) != MP_OKAY) {
if (MP_HAS(MP_MONTGOMERY_SETUP)) {
/* now setup montgomery */
if ((err = mp_montgomery_setup(P, &mp)) != MP_OKAY) {
goto LBL_M;
}
} else {
err = MP_VAL;
goto LBL_M;
}
#else
err = MP_VAL;
goto LBL_M;
#endif

/* automatically pick the comba one if available (saves quite a few calls/ifs) */
#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
if ((((P->used * 2) + 1) < (int)MP_WARRAY) &&
if (MP_HAS(FAST_MP_MONTGOMERY_REDUCE) &&
(((P->used * 2) + 1) < (int)MP_WARRAY) &&
(P->used < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
redux = fast_mp_montgomery_reduce;
} else
#endif
{
#ifdef BN_MP_MONTGOMERY_REDUCE_C
} else if (MP_HAS(MP_MONTGOMERY_REDUCE)) {
/* use slower baseline Montgomery method */
redux = mp_montgomery_reduce;
#else
} else {
err = MP_VAL;
goto LBL_M;
#endif
}
} else if (redmode == 1) {
#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
/* setup DR reduction for moduli of the form B**k - b */
mp_dr_setup(P, &mp);
redux = mp_dr_reduce;
#else
err = MP_VAL;
goto LBL_M;
#endif
} else {
#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
if (MP_HAS(MP_DR_SETUP) && MP_HAS(BN_MP_DR_REDUCE)) {
/* setup DR reduction for moduli of the form B**k - b */
mp_dr_setup(P, &mp);
redux = mp_dr_reduce;
} else {
err = MP_VAL;
goto LBL_M;
}
} else if (MP_HAS(MP_REDUCE_2K_SETUP) && MP_HAS(MP_REDUCE_2K)) {
/* setup DR reduction for moduli of the form 2**k - b */
if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
goto LBL_M;
}
redux = mp_reduce_2k;
#else
} else {
err = MP_VAL;
goto LBL_M;
#endif
}

/* setup result */
Expand All @@ -133,20 +125,20 @@ int mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y
*/

if (redmode == 0) {
#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
/* now we need R mod m */
if ((err = mp_montgomery_calc_normalization(&res, P)) != MP_OKAY) {
goto LBL_RES;
}
if (MP_HAS(MP_MONTGOMERY_CALC_NORMALIZATION)) {
/* now we need R mod m */
if ((err = mp_montgomery_calc_normalization(&res, P)) != MP_OKAY) {
goto LBL_RES;
}

/* now set M[1] to G * R mod m */
if ((err = mp_mulmod(G, &res, P, &M[1])) != MP_OKAY) {
/* now set M[1] to G * R mod m */
if ((err = mp_mulmod(G, &res, P, &M[1])) != MP_OKAY) {
goto LBL_RES;
}
} else {
err = MP_VAL;
goto LBL_RES;
}
#else
err = MP_VAL;
goto LBL_RES;
#endif
} else {
mp_set(&res, 1uL);
if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
Expand Down
12 changes: 4 additions & 8 deletions bn_mp_invmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,13 @@ int mp_invmod(const mp_int *a, const mp_int *b, mp_int *c)
return MP_VAL;
}

#ifdef BN_FAST_MP_INVMOD_C
/* if the modulus is odd we can use a faster routine instead */
if (IS_ODD(b)) {
if (MP_HAS(FAST_MP_INVMOD) && IS_ODD(b)) {
return fast_mp_invmod(a, b, c);
}
#endif

#ifdef BN_MP_INVMOD_SLOW_C
return mp_invmod_slow(a, b, c);
#else
return MP_VAL;
#endif
return MP_HAS(MP_INVMOD_SLOW)
? mp_invmod_slow(a, b, c)
: MP_VAL;
}
#endif
110 changes: 38 additions & 72 deletions bn_mp_mul.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,82 +6,48 @@
/* high level multiplication (handles sign) */
int mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
{
int res, neg;
#ifdef BN_MP_BALANCE_MUL_C
int len_b, len_a;
#endif
int res, neg, min_len, max_len, digs;
min_len = MIN(a->used, b->used);
max_len = MAX(a->used, b->used);
digs = a->used + b->used + 1;
neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
#ifdef BN_MP_BALANCE_MUL_C
len_a = a->used;
len_b = b->used;

if (len_a == len_b) {
goto GO_ON;
}
/*
* Check sizes. The smaller one needs to be larger than the Karatsuba cut-off.
* The bigger one needs to be at least about one KARATSUBA_MUL_CUTOFF bigger
* to make some sense, but it depends on architecture, OS, position of the
* stars... so YMMV.
* Using it to cut the input into slices small enough for fast_s_mp_mul_digs
* was actually slower on the author's machine, but YMMV.
*/
if ((MIN(len_a, len_b) < KARATSUBA_MUL_CUTOFF)
|| ((MAX(len_a, len_b)) / 2 < KARATSUBA_MUL_CUTOFF)) {
goto GO_ON;
}
/*
* Not much effect was observed below a ratio of 1:2, but again: YMMV.
*/
if ((MAX(len_a, len_b) / MIN(len_a, len_b)) < 2) {
goto GO_ON;
}

res = mp_balance_mul(a,b,c);
goto END;

GO_ON:
#endif

/* use Toom-Cook? */
#ifdef BN_MP_TOOM_MUL_C
if (MIN(a->used, b->used) >= TOOM_MUL_CUTOFF) {
if (MP_HAS(MP_BALANCE_MUL) &&
/* Check sizes. The smaller one needs to be larger than the Karatsuba cut-off.
* The bigger one needs to be at least about one KARATSUBA_MUL_CUTOFF bigger
* to make some sense, but it depends on architecture, OS, position of the
* stars... so YMMV.
* Using it to cut the input into slices small enough for fast_s_mp_mul_digs
* was actually slower on the author's machine, but YMMV.
*/
(min_len >= KARATSUBA_MUL_CUTOFF) &&
(max_len / 2 >= KARATSUBA_MUL_CUTOFF) &&
/* Not much effect was observed below a ratio of 1:2, but again: YMMV. */
(max_len >= (2 * min_len))) {
res = mp_balance_mul(a,b,c);
} else if (MP_HAS(MP_TOOM_MUL) &&
min_len >= TOOM_MUL_CUTOFF) {
res = mp_toom_mul(a, b, c);
} else
#endif
#ifdef BN_MP_KARATSUBA_MUL_C
/* use Karatsuba? */
if (MIN(a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
res = mp_karatsuba_mul(a, b, c);
} else
#endif
{
/* can we use the fast multiplier?
*
* The fast multiplier can be used if the output will
* have less than MP_WARRAY digits and the number of
* digits won't affect carry propagation
*/
int digs = a->used + b->used + 1;

#ifdef BN_FAST_S_MP_MUL_DIGS_C
if ((digs < (int)MP_WARRAY) &&
(MIN(a->used, b->used) <=
(int)(1u << ((CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) {
res = fast_s_mp_mul_digs(a, b, c, digs);
} else
#endif
{
#ifdef BN_S_MP_MUL_DIGS_C
res = s_mp_mul(a, b, c); /* uses s_mp_mul_digs */
#else
res = MP_VAL;
#endif
}
}
END:
} else if (MP_HAS(MP_KARATSUBA_MUL) &&
min_len >= KARATSUBA_MUL_CUTOFF) {
res = mp_karatsuba_mul(a, b, c);
} else if (MP_HAS(FAST_S_MP_MUL_DIGS) &&
/* can we use the fast multiplier?
*
* The fast multiplier can be used if the output will
* have less than MP_WARRAY digits and the number of
* digits won't affect carry propagation
*/
(digs < (int)MP_WARRAY) &&
(min_len <=
(int)(1u << ((CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) {
res = fast_s_mp_mul_digs(a, b, c, digs);
} else if (MP_HAS(S_MP_MUL_DIGS)) {
res = s_mp_mul(a, b, c); /* uses s_mp_mul_digs */
} else {
res = MP_VAL;
}
c->sign = (c->used > 0) ? neg : MP_ZPOS;
return res;
}
#endif

14 changes: 5 additions & 9 deletions bn_mp_reduce.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,17 @@ int mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu)
if ((res = mp_mul(&q, mu, &q)) != MP_OKAY) {
goto CLEANUP;
}
} else {
#ifdef BN_S_MP_MUL_HIGH_DIGS_C
} else if (MP_HAS(S_MP_MUL_HIGH_DIGS)) {
if ((res = s_mp_mul_high_digs(&q, mu, &q, um)) != MP_OKAY) {
goto CLEANUP;
}
#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
} else if (MP_HAS(FAST_S_MP_MUL_HIGH_DIGS)) {
if ((res = fast_s_mp_mul_high_digs(&q, mu, &q, um)) != MP_OKAY) {
goto CLEANUP;
}
#else
{
res = MP_VAL;
goto CLEANUP;
}
#endif
} else {
res = MP_VAL;
goto CLEANUP;
}

/* q3 = q2 / b**(k+1) */
Expand Down
Loading