Skip to content

Commit

Permalink
add feature detection macro MP_HAS
Browse files Browse the repository at this point in the history
  • Loading branch information
minad committed May 18, 2019
1 parent 97bc7ca commit 2391fd9
Show file tree
Hide file tree
Showing 12 changed files with 174 additions and 231 deletions.
4 changes: 1 addition & 3 deletions bn_mp_div_d.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,10 @@ mp_err 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 @@ mp_err 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;
mp_err 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 @@ mp_err 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) == MP_YES) ? 1 : 0;
#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) == MP_YES ? 1 : 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) == MP_YES) ? 2 : 0;
}
#endif

/* if the modulus is odd or dr != 0 use the montgomery method */
#ifdef BN_S_MP_EXPTMOD_FAST_C
if (MP_IS_ODD(P) || (dr != 0)) {
if (MP_HAS(S_MP_EXPTMOD_FAST) && (MP_IS_ODD(P) || (dr != 0))) {
return s_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_S_MP_EXPTMOD_FAST_C
}
#endif
}

#endif
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 @@ mp_err mp_invmod(const mp_int *a, const mp_int *b, mp_int *c)
return MP_VAL;
}

#ifdef BN_S_MP_INVMOD_FAST_C
/* if the modulus is odd we can use a faster routine instead */
if (MP_IS_ODD(b)) {
if (MP_HAS(S_MP_INVMOD_FAST) && MP_IS_ODD(b)) {
return s_mp_invmod_fast(a, b, c);
}
#endif

#ifdef BN_S_MP_INVMOD_SLOW_C
return s_mp_invmod_slow(a, b, c);
#else
return MP_VAL;
#endif
return MP_HAS(S_MP_INVMOD_SLOW)
? s_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,80 +6,46 @@
/* high level multiplication (handles sign) */
mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
{
mp_err res;
mp_sign neg;
#ifdef BN_S_MP_BALANCE_MUL_C
int len_b, len_a;
#endif
neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
#ifdef BN_S_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 ((MP_MIN(len_a, len_b) < MP_KARATSUBA_MUL_CUTOFF)
|| ((MP_MAX(len_a, len_b) / 2) < MP_KARATSUBA_MUL_CUTOFF)) {
goto GO_ON;
}
/*
* Not much effect was observed below a ratio of 1:2, but again: YMMV.
*/
if ((MP_MAX(len_a, len_b) / MP_MIN(len_a, len_b)) < 2) {
goto GO_ON;
}

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

GO_ON:
#endif
mp_err res;
int min_len = MP_MIN(a->used, b->used),
max_len = MP_MAX(a->used, b->used),
digs = a->used + b->used + 1;
mp_sign neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;

/* use Toom-Cook? */
#ifdef BN_S_MP_TOOM_MUL_C
if (MP_MIN(a->used, b->used) >= MP_TOOM_MUL_CUTOFF) {
if (MP_HAS(S_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 MP_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 >= MP_KARATSUBA_MUL_CUTOFF) &&
(max_len / 2 >= MP_KARATSUBA_MUL_CUTOFF) &&
/* Not much effect was observed below a ratio of 1:2, but again: YMMV. */
(max_len >= (2 * min_len))) {
res = s_mp_balance_mul(a,b,c);
} else if (MP_HAS(S_MP_TOOM_MUL) &&
(min_len >= MP_TOOM_MUL_CUTOFF)) {
res = s_mp_toom_mul(a, b, c);
} else
#endif
#ifdef BN_S_MP_KARATSUBA_MUL_C
/* use Karatsuba? */
if (MP_MIN(a->used, b->used) >= MP_KARATSUBA_MUL_CUTOFF) {
res = s_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_S_MP_MUL_DIGS_FAST_C
if ((digs < (int)MP_WARRAY) &&
(MP_MIN(a->used, b->used) <= MP_MAXFAST)) {
res = s_mp_mul_digs_fast(a, b, c, digs);
} else
#endif
{
#ifdef BN_S_MP_MUL_DIGS_C
res = s_mp_mul_digs(a, b, c, a->used + b->used + 1);
#else
res = MP_VAL;
#endif
}
}
END:
} else if (MP_HAS(S_MP_KARATSUBA_MUL) &&
(min_len >= MP_KARATSUBA_MUL_CUTOFF)) {
res = s_mp_karatsuba_mul(a, b, c);
} else if (MP_HAS(S_MP_MUL_DIGS_FAST) &&
/* 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 <= MP_MAXFAST)) {
res = s_mp_mul_digs_fast(a, b, c, digs);
} else if (MP_HAS(S_MP_MUL_DIGS)) {
res = s_mp_mul_digs(a, b, c, digs);
} else {
res = MP_VAL;
}
c->sign = (c->used > 0) ? neg : MP_ZPOS;
return res;
}
Expand Down
14 changes: 5 additions & 9 deletions bn_mp_reduce.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,17 @@ mp_err 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_S_MP_MUL_HIGH_DIGS_FAST_C)
} else if (MP_HAS(S_MP_MUL_HIGH_DIGS_FAST)) {
if ((res = s_mp_mul_high_digs_fast(&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
41 changes: 14 additions & 27 deletions bn_mp_sqr.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,21 @@ mp_err mp_sqr(const mp_int *a, mp_int *b)
{
mp_err res;

#ifdef BN_S_MP_TOOM_SQR_C
/* use Toom-Cook? */
if (a->used >= MP_TOOM_SQR_CUTOFF) {
if (MP_HAS(S_MP_TOOM_SQR) && /* use Toom-Cook? */
a->used >= MP_TOOM_SQR_CUTOFF) {
res = s_mp_toom_sqr(a, b);
/* Karatsuba? */
} else
#endif
#ifdef BN_S_MP_KARATSUBA_SQR_C
if (a->used >= MP_KARATSUBA_SQR_CUTOFF) {
res = s_mp_karatsuba_sqr(a, b);
} else
#endif
{
#ifdef BN_S_MP_SQR_FAST_C
/* can we use the fast comba multiplier? */
if ((((a->used * 2) + 1) < (int)MP_WARRAY) &&
(a->used < (MP_MAXFAST / 2))) {
res = s_mp_sqr_fast(a, b);
} else
#endif
{
#ifdef BN_S_MP_SQR_C
res = s_mp_sqr(a, b);
#else
res = MP_VAL;
#endif
}
}
} else if (MP_HAS(S_MP_KARATSUBA_SQR) && /* Karatsuba? */
a->used >= MP_KARATSUBA_SQR_CUTOFF) {
res = s_mp_karatsuba_sqr(a, b);
} else if (MP_HAS(S_MP_SQR_FAST) && /* can we use the fast comba multiplier? */
(((a->used * 2) + 1) < (int)MP_WARRAY) &&
(a->used < (MP_MAXFAST / 2))) {
res = s_mp_sqr_fast(a, b);
} else if (MP_HAS(S_MP_SQR)) {
res = s_mp_sqr(a, b);
} else {
res = MP_VAL;
}
b->sign = MP_ZPOS;
return res;
}
Expand Down
8 changes: 3 additions & 5 deletions bn_s_mp_exptmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

#ifdef MP_LOW_MEM
# define TAB_SIZE 32
# define MAX_WINSIZE 5
#else
# define TAB_SIZE 256
# define MAX_WINSIZE 0
#endif

mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode)
Expand Down Expand Up @@ -35,11 +37,7 @@ mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y
winsize = 8;
}

#ifdef MP_LOW_MEM
if (winsize > 5) {
winsize = 5;
}
#endif
winsize = MAX_WINSIZE ? MP_MIN(MAX_WINSIZE, winsize) : winsize;

/* init M array */
/* init first cell */
Expand Down
Loading

0 comments on commit 2391fd9

Please sign in to comment.