format with astyle (step 4)

This commit is contained in:
Francois Perrad 2017-08-30 19:13:53 +02:00
parent 4439fae168
commit a20d9b102c
21 changed files with 487 additions and 487 deletions

View File

@ -25,36 +25,36 @@
*/ */
int mp_prime_fermat(mp_int *a, mp_int *b, int *result) int mp_prime_fermat(mp_int *a, mp_int *b, int *result)
{ {
mp_int t; mp_int t;
int err; int err;
/* default to composite */ /* default to composite */
*result = MP_NO; *result = MP_NO;
/* ensure b > 1 */ /* ensure b > 1 */
if (mp_cmp_d(b, 1) != MP_GT) { if (mp_cmp_d(b, 1) != MP_GT) {
return MP_VAL; return MP_VAL;
} }
/* init t */ /* init t */
if ((err = mp_init(&t)) != MP_OKAY) { if ((err = mp_init(&t)) != MP_OKAY) {
return err; return err;
} }
/* compute t = b**a mod a */ /* compute t = b**a mod a */
if ((err = mp_exptmod(b, a, a, &t)) != MP_OKAY) { if ((err = mp_exptmod(b, a, a, &t)) != MP_OKAY) {
goto LBL_T; goto LBL_T;
} }
/* is it equal to b? */ /* is it equal to b? */
if (mp_cmp(&t, b) == MP_EQ) { if (mp_cmp(&t, b) == MP_EQ) {
*result = MP_YES; *result = MP_YES;
} }
err = MP_OKAY; err = MP_OKAY;
LBL_T: LBL_T:
mp_clear(&t); mp_clear(&t);
return err; return err;
} }
#endif #endif

View File

@ -22,26 +22,26 @@
*/ */
int mp_prime_is_divisible(mp_int *a, int *result) int mp_prime_is_divisible(mp_int *a, int *result)
{ {
int err, ix; int err, ix;
mp_digit res; mp_digit res;
/* default to not */ /* default to not */
*result = MP_NO; *result = MP_NO;
for (ix = 0; ix < PRIME_SIZE; ix++) { for (ix = 0; ix < PRIME_SIZE; ix++) {
/* what is a mod LBL_prime_tab[ix] */ /* what is a mod LBL_prime_tab[ix] */
if ((err = mp_mod_d(a, ltm_prime_tab[ix], &res)) != MP_OKAY) { if ((err = mp_mod_d(a, ltm_prime_tab[ix], &res)) != MP_OKAY) {
return err; return err;
} }
/* is the residue zero? */ /* is the residue zero? */
if (res == 0) { if (res == 0) {
*result = MP_YES; *result = MP_YES;
return MP_OKAY; return MP_OKAY;
} }
} }
return MP_OKAY; return MP_OKAY;
} }
#endif #endif

View File

@ -24,58 +24,58 @@
*/ */
int mp_prime_is_prime(mp_int *a, int t, int *result) int mp_prime_is_prime(mp_int *a, int t, int *result)
{ {
mp_int b; mp_int b;
int ix, err, res; int ix, err, res;
/* default to no */ /* default to no */
*result = MP_NO; *result = MP_NO;
/* valid value of t? */ /* valid value of t? */
if ((t <= 0) || (t > PRIME_SIZE)) { if ((t <= 0) || (t > PRIME_SIZE)) {
return MP_VAL; return MP_VAL;
} }
/* is the input equal to one of the primes in the table? */ /* is the input equal to one of the primes in the table? */
for (ix = 0; ix < PRIME_SIZE; ix++) { for (ix = 0; ix < PRIME_SIZE; ix++) {
if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
*result = 1; *result = 1;
return MP_OKAY; return MP_OKAY;
} }
} }
/* first perform trial division */ /* first perform trial division */
if ((err = mp_prime_is_divisible(a, &res)) != MP_OKAY) { if ((err = mp_prime_is_divisible(a, &res)) != MP_OKAY) {
return err; return err;
} }
/* return if it was trivially divisible */ /* return if it was trivially divisible */
if (res == MP_YES) { if (res == MP_YES) {
return MP_OKAY; return MP_OKAY;
} }
/* now perform the miller-rabin rounds */ /* now perform the miller-rabin rounds */
if ((err = mp_init(&b)) != MP_OKAY) { if ((err = mp_init(&b)) != MP_OKAY) {
return err; return err;
} }
for (ix = 0; ix < t; ix++) { for (ix = 0; ix < t; ix++) {
/* set the prime */ /* set the prime */
mp_set(&b, ltm_prime_tab[ix]); mp_set(&b, ltm_prime_tab[ix]);
if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
goto LBL_B; goto LBL_B;
} }
if (res == MP_NO) { if (res == MP_NO) {
goto LBL_B; goto LBL_B;
} }
} }
/* passed the test */ /* passed the test */
*result = MP_YES; *result = MP_YES;
LBL_B: LBL_B:
mp_clear(&b); mp_clear(&b);
return err; return err;
} }
#endif #endif

View File

@ -38,28 +38,28 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) { if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) {
/* find which prime it is bigger than */ /* find which prime it is bigger than */
for (x = PRIME_SIZE - 2; x >= 0; x--) { for (x = PRIME_SIZE - 2; x >= 0; x--) {
if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) { if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) {
if (bbs_style == 1) { if (bbs_style == 1) {
/* ok we found a prime smaller or /* ok we found a prime smaller or
* equal [so the next is larger] * equal [so the next is larger]
* *
* however, the prime must be * however, the prime must be
* congruent to 3 mod 4 * congruent to 3 mod 4
*/ */
if ((ltm_prime_tab[x + 1] & 3) != 3) { if ((ltm_prime_tab[x + 1] & 3) != 3) {
/* scan upwards for a prime congruent to 3 mod 4 */ /* scan upwards for a prime congruent to 3 mod 4 */
for (y = x + 1; y < PRIME_SIZE; y++) { for (y = x + 1; y < PRIME_SIZE; y++) {
if ((ltm_prime_tab[y] & 3) == 3) { if ((ltm_prime_tab[y] & 3) == 3) {
mp_set(a, ltm_prime_tab[y]); mp_set(a, ltm_prime_tab[y]);
return MP_OKAY; return MP_OKAY;
} }
} }
} }
} else { } else {
mp_set(a, ltm_prime_tab[x + 1]); mp_set(a, ltm_prime_tab[x + 1]);
return MP_OKAY; return MP_OKAY;
} }
} }
} }
/* at this point a maybe 1 */ /* at this point a maybe 1 */
if (mp_cmp_d(a, 1) == MP_EQ) { if (mp_cmp_d(a, 1) == MP_EQ) {
@ -118,18 +118,18 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
/* compute the new residue without using division */ /* compute the new residue without using division */
for (x = 1; x < PRIME_SIZE; x++) { for (x = 1; x < PRIME_SIZE; x++) {
/* add the step to each residue */ /* add the step to each residue */
res_tab[x] += kstep; res_tab[x] += kstep;
/* subtract the modulus [instead of using division] */ /* subtract the modulus [instead of using division] */
if (res_tab[x] >= ltm_prime_tab[x]) { if (res_tab[x] >= ltm_prime_tab[x]) {
res_tab[x] -= ltm_prime_tab[x]; res_tab[x] -= ltm_prime_tab[x];
} }
/* set flag if zero */ /* set flag if zero */
if (res_tab[x] == 0) { if (res_tab[x] == 0) {
y = 1; y = 1;
} }
} }
} while ((y == 1) && (step < ((((mp_digit)1) << DIGIT_BIT) - kstep))); } while ((y == 1) && (step < ((((mp_digit)1) << DIGIT_BIT) - kstep)));
@ -145,13 +145,13 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
/* is this prime? */ /* is this prime? */
for (x = 0; x < t; x++) { for (x = 0; x < t; x++) {
mp_set(&b, ltm_prime_tab[x]); mp_set(&b, ltm_prime_tab[x]);
if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
goto LBL_ERR; goto LBL_ERR;
} }
if (res == MP_NO) { if (res == MP_NO) {
break; break;
} }
} }
if (res == MP_YES) { if (res == MP_YES) {

View File

@ -19,14 +19,14 @@
static const struct { static const struct {
int k, t; int k, t;
} sizes[] = { } sizes[] = {
{ 128, 28 }, { 128, 28 },
{ 256, 16 }, { 256, 16 },
{ 384, 10 }, { 384, 10 },
{ 512, 7 }, { 512, 7 },
{ 640, 6 }, { 640, 6 },
{ 768, 5 }, { 768, 5 },
{ 896, 4 }, { 896, 4 },
{ 1024, 4 } { 1024, 4 }
}; };
/* returns # of RM trials required for a given bit size */ /* returns # of RM trials required for a given bit size */
@ -35,11 +35,11 @@ int mp_prime_rabin_miller_trials(int size)
int x; int x;
for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) { for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
if (sizes[x].k == size) { if (sizes[x].k == size) {
return sizes[x].t; return sizes[x].t;
} else if (sizes[x].k > size) { } else if (sizes[x].k > size) {
return (x == 0) ? sizes[0].t : sizes[x - 1].t; return (x == 0) ? sizes[0].t : sizes[x - 1].t;
} }
} }
return sizes[x-1].t + 1; return sizes[x-1].t + 1;
} }

View File

@ -18,57 +18,57 @@
/* returns size of ASCII reprensentation */ /* returns size of ASCII reprensentation */
int mp_radix_size(mp_int *a, int radix, int *size) int mp_radix_size(mp_int *a, int radix, int *size)
{ {
int res, digs; int res, digs;
mp_int t; mp_int t;
mp_digit d; mp_digit d;
*size = 0; *size = 0;
/* make sure the radix is in range */ /* make sure the radix is in range */
if ((radix < 2) || (radix > 64)) { if ((radix < 2) || (radix > 64)) {
return MP_VAL; return MP_VAL;
} }
if (mp_iszero(a) == MP_YES) { if (mp_iszero(a) == MP_YES) {
*size = 2; *size = 2;
return MP_OKAY; return MP_OKAY;
} }
/* special case for binary */ /* special case for binary */
if (radix == 2) { if (radix == 2) {
*size = mp_count_bits(a) + ((a->sign == MP_NEG) ? 1 : 0) + 1; *size = mp_count_bits(a) + ((a->sign == MP_NEG) ? 1 : 0) + 1;
return MP_OKAY; return MP_OKAY;
} }
/* digs is the digit count */ /* digs is the digit count */
digs = 0; digs = 0;
/* if it's negative add one for the sign */ /* if it's negative add one for the sign */
if (a->sign == MP_NEG) { if (a->sign == MP_NEG) {
++digs; ++digs;
} }
/* init a copy of the input */ /* init a copy of the input */
if ((res = mp_init_copy(&t, a)) != MP_OKAY) { if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
return res;
}
/* force temp to positive */
t.sign = MP_ZPOS;
/* fetch out all of the digits */
while (mp_iszero(&t) == MP_NO) {
if ((res = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
mp_clear(&t);
return res; return res;
} }
++digs;
}
mp_clear(&t);
/* return digs + 1, the 1 is for the NULL byte that would be required. */ /* force temp to positive */
*size = digs + 1; t.sign = MP_ZPOS;
return MP_OKAY;
/* fetch out all of the digits */
while (mp_iszero(&t) == MP_NO) {
if ((res = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
mp_clear(&t);
return res;
}
++digs;
}
mp_clear(&t);
/* return digs + 1, the 1 is for the NULL byte that would be required. */
*size = digs + 1;
return MP_OKAY;
} }
#endif #endif

View File

@ -18,21 +18,21 @@
/* read signed bin, big endian, first byte is 0==positive or 1==negative */ /* read signed bin, big endian, first byte is 0==positive or 1==negative */
int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c) int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c)
{ {
int res; int res;
/* read magnitude */ /* read magnitude */
if ((res = mp_read_unsigned_bin(a, b + 1, c - 1)) != MP_OKAY) { if ((res = mp_read_unsigned_bin(a, b + 1, c - 1)) != MP_OKAY) {
return res; return res;
} }
/* first byte is 0 for positive, non-zero for negative */ /* first byte is 0 for positive, non-zero for negative */
if (b[0] == 0) { if (b[0] == 0) {
a->sign = MP_ZPOS; a->sign = MP_ZPOS;
} else { } else {
a->sign = MP_NEG; a->sign = MP_NEG;
} }
return MP_OKAY; return MP_OKAY;
} }
#endif #endif

View File

@ -18,35 +18,35 @@
/* reads a unsigned char array, assumes the msb is stored first [big endian] */ /* reads a unsigned char array, assumes the msb is stored first [big endian] */
int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c) int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c)
{ {
int res; int res;
/* make sure there are at least two digits */ /* make sure there are at least two digits */
if (a->alloc < 2) { if (a->alloc < 2) {
if ((res = mp_grow(a, 2)) != MP_OKAY) { if ((res = mp_grow(a, 2)) != MP_OKAY) {
return res; return res;
} }
} }
/* zero the int */ /* zero the int */
mp_zero(a); mp_zero(a);
/* read the bytes in */ /* read the bytes in */
while (c-- > 0) { while (c-- > 0) {
if ((res = mp_mul_2d(a, 8, a)) != MP_OKAY) { if ((res = mp_mul_2d(a, 8, a)) != MP_OKAY) {
return res; return res;
} }
#ifndef MP_8BIT #ifndef MP_8BIT
a->dp[0] |= *b++; a->dp[0] |= *b++;
a->used += 1; a->used += 1;
#else #else
a->dp[0] = (*b & MP_MASK); a->dp[0] = (*b & MP_MASK);
a->dp[1] |= ((*b++ >> 7U) & 1); a->dp[1] |= ((*b++ >> 7U) & 1);
a->used += 2; a->used += 2;
#endif #endif
} }
mp_clamp(a); mp_clamp(a);
return MP_OKAY; return MP_OKAY;
} }
#endif #endif

View File

@ -32,14 +32,14 @@ int mp_reduce_is_2k(mp_int *a)
/* Test every bit from the second digit up, must be 1 */ /* Test every bit from the second digit up, must be 1 */
for (ix = DIGIT_BIT; ix < iy; ix++) { for (ix = DIGIT_BIT; ix < iy; ix++) {
if ((a->dp[iw] & iz) == 0) { if ((a->dp[iw] & iz) == 0) {
return MP_NO; return MP_NO;
} }
iz <<= 1; iz <<= 1;
if (iz > (mp_digit)MP_MASK) { if (iz > (mp_digit)MP_MASK) {
++iw; ++iw;
iz = 1; iz = 1;
} }
} }
} }
return MP_YES; return MP_YES;

View File

@ -27,9 +27,9 @@ int mp_reduce_is_2k_l(mp_int *a)
} else if (a->used > 1) { } else if (a->used > 1) {
/* if more than half of the digits are -1 we're sold */ /* if more than half of the digits are -1 we're sold */
for (iy = ix = 0; ix < a->used; ix++) { for (iy = ix = 0; ix < a->used; ix++) {
if (a->dp[ix] == MP_MASK) { if (a->dp[ix] == MP_MASK) {
++iy; ++iy;
} }
} }
return (iy >= (a->used/2)) ? MP_YES : MP_NO; return (iy >= (a->used/2)) ? MP_YES : MP_NO;

View File

@ -20,12 +20,12 @@
*/ */
int mp_reduce_setup(mp_int *a, mp_int *b) int mp_reduce_setup(mp_int *a, mp_int *b)
{ {
int res; int res;
if ((res = mp_2expt(a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { if ((res = mp_2expt(a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
return res; return res;
} }
return mp_div(a, b, a, NULL); return mp_div(a, b, a, NULL);
} }
#endif #endif

View File

@ -18,52 +18,52 @@
/* shift right a certain amount of digits */ /* shift right a certain amount of digits */
void mp_rshd(mp_int *a, int b) void mp_rshd(mp_int *a, int b)
{ {
int x; int x;
/* if b <= 0 then ignore it */ /* if b <= 0 then ignore it */
if (b <= 0) { if (b <= 0) {
return; return;
} }
/* if b > used then simply zero it and return */ /* if b > used then simply zero it and return */
if (a->used <= b) { if (a->used <= b) {
mp_zero(a); mp_zero(a);
return; return;
} }
{ {
mp_digit *bottom, *top; mp_digit *bottom, *top;
/* shift the digits down */ /* shift the digits down */
/* bottom */ /* bottom */
bottom = a->dp; bottom = a->dp;
/* top [offset into digits] */ /* top [offset into digits] */
top = a->dp + b; top = a->dp + b;
/* this is implemented as a sliding window where /* this is implemented as a sliding window where
* the window is b-digits long and digits from * the window is b-digits long and digits from
* the top of the window are copied to the bottom * the top of the window are copied to the bottom
* *
* e.g. * e.g.
b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> b-2 | b-1 | b0 | b1 | b2 | ... | bb | ---->
/\ | ----> /\ | ---->
\-------------------/ ----> \-------------------/ ---->
*/ */
for (x = 0; x < (a->used - b); x++) { for (x = 0; x < (a->used - b); x++) {
*bottom++ = *top++; *bottom++ = *top++;
} }
/* zero the top digits */ /* zero the top digits */
for (; x < a->used; x++) { for (; x < a->used; x++) {
*bottom++ = 0; *bottom++ = 0;
} }
} }
/* remove excess digits */ /* remove excess digits */
a->used -= b; a->used -= b;
} }
#endif #endif

View File

@ -18,9 +18,9 @@
/* set to a digit */ /* set to a digit */
void mp_set(mp_int *a, mp_digit b) void mp_set(mp_int *a, mp_digit b)
{ {
mp_zero(a); mp_zero(a);
a->dp[0] = b & MP_MASK; a->dp[0] = b & MP_MASK;
a->used = (a->dp[0] != 0) ? 1 : 0; a->used = (a->dp[0] != 0) ? 1 : 0;
} }
#endif #endif

View File

@ -18,28 +18,28 @@
/* set a 32-bit const */ /* set a 32-bit const */
int mp_set_int(mp_int *a, unsigned long b) int mp_set_int(mp_int *a, unsigned long b)
{ {
int x, res; int x, res;
mp_zero(a); mp_zero(a);
/* set four bits at a time */ /* set four bits at a time */
for (x = 0; x < 8; x++) { for (x = 0; x < 8; x++) {
/* shift the number up four bits */ /* shift the number up four bits */
if ((res = mp_mul_2d(a, 4, a)) != MP_OKAY) { if ((res = mp_mul_2d(a, 4, a)) != MP_OKAY) {
return res; return res;
} }
/* OR in the top four bits of the source */ /* OR in the top four bits of the source */
a->dp[0] |= (b >> 28) & 15; a->dp[0] |= (b >> 28) & 15;
/* shift the source up to the next four bits */ /* shift the source up to the next four bits */
b <<= 4; b <<= 4;
/* ensure that digits are not clamped off */ /* ensure that digits are not clamped off */
a->used += 1; a->used += 1;
} }
mp_clamp(a); mp_clamp(a);
return MP_OKAY; return MP_OKAY;
} }
#endif #endif

View File

@ -18,21 +18,21 @@
/* shrink a bignum */ /* shrink a bignum */
int mp_shrink(mp_int *a) int mp_shrink(mp_int *a)
{ {
mp_digit *tmp; mp_digit *tmp;
int used = 1; int used = 1;
if (a->used > 0) { if (a->used > 0) {
used = a->used; used = a->used;
} }
if (a->alloc != used) { if (a->alloc != used) {
if ((tmp = OPT_CAST(mp_digit) XREALLOC(a->dp, sizeof (mp_digit) * used)) == NULL) { if ((tmp = OPT_CAST(mp_digit) XREALLOC(a->dp, sizeof(mp_digit) * used)) == NULL) {
return MP_MEM; return MP_MEM;
} }
a->dp = tmp; a->dp = tmp;
a->alloc = used; a->alloc = used;
} }
return MP_OKAY; return MP_OKAY;
} }
#endif #endif

View File

@ -18,7 +18,7 @@
/* get the size for an signed equivalent */ /* get the size for an signed equivalent */
int mp_signed_bin_size(mp_int *a) int mp_signed_bin_size(mp_int *a)
{ {
return 1 + mp_unsigned_bin_size(a); return 1 + mp_unsigned_bin_size(a);
} }
#endif #endif

View File

@ -18,39 +18,39 @@
/* computes b = a*a */ /* computes b = a*a */
int mp_sqr(mp_int *a, mp_int *b) int mp_sqr(mp_int *a, mp_int *b)
{ {
int res; int res;
#ifdef BN_MP_TOOM_SQR_C #ifdef BN_MP_TOOM_SQR_C
/* use Toom-Cook? */ /* use Toom-Cook? */
if (a->used >= TOOM_SQR_CUTOFF) { if (a->used >= TOOM_SQR_CUTOFF) {
res = mp_toom_sqr(a, b); res = mp_toom_sqr(a, b);
/* Karatsuba? */ /* Karatsuba? */
} else } else
#endif #endif
#ifdef BN_MP_KARATSUBA_SQR_C #ifdef BN_MP_KARATSUBA_SQR_C
if (a->used >= KARATSUBA_SQR_CUTOFF) { if (a->used >= KARATSUBA_SQR_CUTOFF) {
res = mp_karatsuba_sqr(a, b); res = mp_karatsuba_sqr(a, b);
} else } else
#endif #endif
{ {
#ifdef BN_FAST_S_MP_SQR_C #ifdef BN_FAST_S_MP_SQR_C
/* can we use the fast comba multiplier? */ /* can we use the fast comba multiplier? */
if ((((a->used * 2) + 1) < MP_WARRAY) && if ((((a->used * 2) + 1) < MP_WARRAY) &&
(a->used < (a->used <
(1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) - 1)))) { (1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) - 1)))) {
res = fast_s_mp_sqr(a, b); res = fast_s_mp_sqr(a, b);
} else } else
#endif #endif
{ {
#ifdef BN_S_MP_SQR_C #ifdef BN_S_MP_SQR_C
res = s_mp_sqr(a, b); res = s_mp_sqr(a, b);
#else #else
res = MP_VAL; res = MP_VAL;
#endif #endif
} }
} }
b->sign = MP_ZPOS; b->sign = MP_ZPOS;
return res; return res;
} }
#endif #endif

View File

@ -18,20 +18,20 @@
/* c = a * a (mod b) */ /* c = a * a (mod b) */
int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c) int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c)
{ {
int res; int res;
mp_int t; mp_int t;
if ((res = mp_init(&t)) != MP_OKAY) { if ((res = mp_init(&t)) != MP_OKAY) {
return res; return res;
} }
if ((res = mp_sqr(a, &t)) != MP_OKAY) { if ((res = mp_sqr(a, &t)) != MP_OKAY) {
mp_clear(&t); mp_clear(&t);
return res; return res;
} }
res = mp_mod(&t, b, c); res = mp_mod(&t, b, c);
mp_clear(&t); mp_clear(&t);
return res; return res;
} }
#endif #endif

View File

@ -17,108 +17,108 @@
int mp_sqrtmod_prime(mp_int *n, mp_int *prime, mp_int *ret) int mp_sqrtmod_prime(mp_int *n, mp_int *prime, mp_int *ret)
{ {
int res, legendre; int res, legendre;
mp_int t1, C, Q, S, Z, M, T, R, two; mp_int t1, C, Q, S, Z, M, T, R, two;
mp_digit i; mp_digit i;
/* first handle the simple cases */ /* first handle the simple cases */
if (mp_cmp_d(n, 0) == MP_EQ) { if (mp_cmp_d(n, 0) == MP_EQ) {
mp_zero(ret); mp_zero(ret);
return MP_OKAY; return MP_OKAY;
} }
if (mp_cmp_d(prime, 2) == MP_EQ) return MP_VAL; /* prime must be odd */ if (mp_cmp_d(prime, 2) == MP_EQ) return MP_VAL; /* prime must be odd */
if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res; if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res;
if (legendre == -1) return MP_VAL; /* quadratic non-residue mod prime */ if (legendre == -1) return MP_VAL; /* quadratic non-residue mod prime */
if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL)) != MP_OKAY) { if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL)) != MP_OKAY) {
return res; return res;
} }
/* SPECIAL CASE: if prime mod 4 == 3 /* SPECIAL CASE: if prime mod 4 == 3
* compute directly: res = n^(prime+1)/4 mod prime * compute directly: res = n^(prime+1)/4 mod prime
* Handbook of Applied Cryptography algorithm 3.36 * Handbook of Applied Cryptography algorithm 3.36
*/ */
if ((res = mp_mod_d(prime, 4, &i)) != MP_OKAY) goto cleanup; if ((res = mp_mod_d(prime, 4, &i)) != MP_OKAY) goto cleanup;
if (i == 3) { if (i == 3) {
if ((res = mp_add_d(prime, 1, &t1)) != MP_OKAY) goto cleanup; if ((res = mp_add_d(prime, 1, &t1)) != MP_OKAY) goto cleanup;
if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup;
if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup;
if ((res = mp_exptmod(n, &t1, prime, ret)) != MP_OKAY) goto cleanup; if ((res = mp_exptmod(n, &t1, prime, ret)) != MP_OKAY) goto cleanup;
res = MP_OKAY;
goto cleanup;
}
/* NOW: Tonelli-Shanks algorithm */
/* factor out powers of 2 from prime-1, defining Q and S as: prime-1 = Q*2^S */
if ((res = mp_copy(prime, &Q)) != MP_OKAY) goto cleanup;
if ((res = mp_sub_d(&Q, 1, &Q)) != MP_OKAY) goto cleanup;
/* Q = prime - 1 */
mp_zero(&S);
/* S = 0 */
while (mp_iseven(&Q) != MP_NO) {
if ((res = mp_div_2(&Q, &Q)) != MP_OKAY) goto cleanup;
/* Q = Q / 2 */
if ((res = mp_add_d(&S, 1, &S)) != MP_OKAY) goto cleanup;
/* S = S + 1 */
}
/* find a Z such that the Legendre symbol (Z|prime) == -1 */
if ((res = mp_set_int(&Z, 2)) != MP_OKAY) goto cleanup;
/* Z = 2 */
while (1) {
if ((res = mp_jacobi(&Z, prime, &legendre)) != MP_OKAY) goto cleanup;
if (legendre == -1) break;
if ((res = mp_add_d(&Z, 1, &Z)) != MP_OKAY) goto cleanup;
/* Z = Z + 1 */
}
if ((res = mp_exptmod(&Z, &Q, prime, &C)) != MP_OKAY) goto cleanup;
/* C = Z ^ Q mod prime */
if ((res = mp_add_d(&Q, 1, &t1)) != MP_OKAY) goto cleanup;
if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup;
/* t1 = (Q + 1) / 2 */
if ((res = mp_exptmod(n, &t1, prime, &R)) != MP_OKAY) goto cleanup;
/* R = n ^ ((Q + 1) / 2) mod prime */
if ((res = mp_exptmod(n, &Q, prime, &T)) != MP_OKAY) goto cleanup;
/* T = n ^ Q mod prime */
if ((res = mp_copy(&S, &M)) != MP_OKAY) goto cleanup;
/* M = S */
if ((res = mp_set_int(&two, 2)) != MP_OKAY) goto cleanup;
res = MP_VAL;
while (1) {
if ((res = mp_copy(&T, &t1)) != MP_OKAY) goto cleanup;
i = 0;
while (1) {
if (mp_cmp_d(&t1, 1) == MP_EQ) break;
if ((res = mp_exptmod(&t1, &two, prime, &t1)) != MP_OKAY) goto cleanup;
i++;
}
if (i == 0) {
if ((res = mp_copy(&R, ret)) != MP_OKAY) goto cleanup;
res = MP_OKAY; res = MP_OKAY;
goto cleanup; goto cleanup;
} }
if ((res = mp_sub_d(&M, i, &t1)) != MP_OKAY) goto cleanup;
if ((res = mp_sub_d(&t1, 1, &t1)) != MP_OKAY) goto cleanup; /* NOW: Tonelli-Shanks algorithm */
if ((res = mp_exptmod(&two, &t1, prime, &t1)) != MP_OKAY) goto cleanup;
/* t1 = 2 ^ (M - i - 1) */ /* factor out powers of 2 from prime-1, defining Q and S as: prime-1 = Q*2^S */
if ((res = mp_exptmod(&C, &t1, prime, &t1)) != MP_OKAY) goto cleanup; if ((res = mp_copy(prime, &Q)) != MP_OKAY) goto cleanup;
/* t1 = C ^ (2 ^ (M - i - 1)) mod prime */ if ((res = mp_sub_d(&Q, 1, &Q)) != MP_OKAY) goto cleanup;
if ((res = mp_sqrmod(&t1, prime, &C)) != MP_OKAY) goto cleanup; /* Q = prime - 1 */
/* C = (t1 * t1) mod prime */ mp_zero(&S);
if ((res = mp_mulmod(&R, &t1, prime, &R)) != MP_OKAY) goto cleanup; /* S = 0 */
/* R = (R * t1) mod prime */ while (mp_iseven(&Q) != MP_NO) {
if ((res = mp_mulmod(&T, &C, prime, &T)) != MP_OKAY) goto cleanup; if ((res = mp_div_2(&Q, &Q)) != MP_OKAY) goto cleanup;
/* T = (T * C) mod prime */ /* Q = Q / 2 */
mp_set(&M, i); if ((res = mp_add_d(&S, 1, &S)) != MP_OKAY) goto cleanup;
/* M = i */ /* S = S + 1 */
} }
/* find a Z such that the Legendre symbol (Z|prime) == -1 */
if ((res = mp_set_int(&Z, 2)) != MP_OKAY) goto cleanup;
/* Z = 2 */
while (1) {
if ((res = mp_jacobi(&Z, prime, &legendre)) != MP_OKAY) goto cleanup;
if (legendre == -1) break;
if ((res = mp_add_d(&Z, 1, &Z)) != MP_OKAY) goto cleanup;
/* Z = Z + 1 */
}
if ((res = mp_exptmod(&Z, &Q, prime, &C)) != MP_OKAY) goto cleanup;
/* C = Z ^ Q mod prime */
if ((res = mp_add_d(&Q, 1, &t1)) != MP_OKAY) goto cleanup;
if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup;
/* t1 = (Q + 1) / 2 */
if ((res = mp_exptmod(n, &t1, prime, &R)) != MP_OKAY) goto cleanup;
/* R = n ^ ((Q + 1) / 2) mod prime */
if ((res = mp_exptmod(n, &Q, prime, &T)) != MP_OKAY) goto cleanup;
/* T = n ^ Q mod prime */
if ((res = mp_copy(&S, &M)) != MP_OKAY) goto cleanup;
/* M = S */
if ((res = mp_set_int(&two, 2)) != MP_OKAY) goto cleanup;
res = MP_VAL;
while (1) {
if ((res = mp_copy(&T, &t1)) != MP_OKAY) goto cleanup;
i = 0;
while (1) {
if (mp_cmp_d(&t1, 1) == MP_EQ) break;
if ((res = mp_exptmod(&t1, &two, prime, &t1)) != MP_OKAY) goto cleanup;
i++;
}
if (i == 0) {
if ((res = mp_copy(&R, ret)) != MP_OKAY) goto cleanup;
res = MP_OKAY;
goto cleanup;
}
if ((res = mp_sub_d(&M, i, &t1)) != MP_OKAY) goto cleanup;
if ((res = mp_sub_d(&t1, 1, &t1)) != MP_OKAY) goto cleanup;
if ((res = mp_exptmod(&two, &t1, prime, &t1)) != MP_OKAY) goto cleanup;
/* t1 = 2 ^ (M - i - 1) */
if ((res = mp_exptmod(&C, &t1, prime, &t1)) != MP_OKAY) goto cleanup;
/* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
if ((res = mp_sqrmod(&t1, prime, &C)) != MP_OKAY) goto cleanup;
/* C = (t1 * t1) mod prime */
if ((res = mp_mulmod(&R, &t1, prime, &R)) != MP_OKAY) goto cleanup;
/* R = (R * t1) mod prime */
if ((res = mp_mulmod(&T, &C, prime, &T)) != MP_OKAY) goto cleanup;
/* T = (T * C) mod prime */
mp_set(&M, i);
/* M = i */
}
cleanup: cleanup:
mp_clear_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL); mp_clear_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL);
return res; return res;
} }
#endif #endif

View File

@ -18,71 +18,71 @@
/* single digit subtraction */ /* single digit subtraction */
int mp_sub_d(mp_int *a, mp_digit b, mp_int *c) int mp_sub_d(mp_int *a, mp_digit b, mp_int *c)
{ {
mp_digit *tmpa, *tmpc, mu; mp_digit *tmpa, *tmpc, mu;
int res, ix, oldused; int res, ix, oldused;
/* grow c as required */ /* grow c as required */
if (c->alloc < (a->used + 1)) { if (c->alloc < (a->used + 1)) {
if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
return res; return res;
} }
} }
/* if a is negative just do an unsigned /* if a is negative just do an unsigned
* addition [with fudged signs] * addition [with fudged signs]
*/ */
if (a->sign == MP_NEG) { if (a->sign == MP_NEG) {
a->sign = MP_ZPOS; a->sign = MP_ZPOS;
res = mp_add_d(a, b, c); res = mp_add_d(a, b, c);
a->sign = c->sign = MP_NEG; a->sign = c->sign = MP_NEG;
/* clamp */ /* clamp */
mp_clamp(c); mp_clamp(c);
return res; return res;
} }
/* setup regs */ /* setup regs */
oldused = c->used; oldused = c->used;
tmpa = a->dp; tmpa = a->dp;
tmpc = c->dp; tmpc = c->dp;
/* if a <= b simply fix the single digit */ /* if a <= b simply fix the single digit */
if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) { if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) {
if (a->used == 1) { if (a->used == 1) {
*tmpc++ = b - *tmpa; *tmpc++ = b - *tmpa;
} else { } else {
*tmpc++ = b; *tmpc++ = b;
} }
ix = 1; ix = 1;
/* negative/1digit */ /* negative/1digit */
c->sign = MP_NEG; c->sign = MP_NEG;
c->used = 1; c->used = 1;
} else { } else {
/* positive/size */ /* positive/size */
c->sign = MP_ZPOS; c->sign = MP_ZPOS;
c->used = a->used; c->used = a->used;
/* subtract first digit */ /* subtract first digit */
*tmpc = *tmpa++ - b; *tmpc = *tmpa++ - b;
mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1);
*tmpc++ &= MP_MASK; *tmpc++ &= MP_MASK;
/* handle rest of the digits */ /* handle rest of the digits */
for (ix = 1; ix < a->used; ix++) { for (ix = 1; ix < a->used; ix++) {
*tmpc = *tmpa++ - mu; *tmpc = *tmpa++ - mu;
mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1);
*tmpc++ &= MP_MASK; *tmpc++ &= MP_MASK;
} }
} }
/* zero excess digits */ /* zero excess digits */
while (ix++ < oldused) { while (ix++ < oldused) {
*tmpc++ = 0; *tmpc++ = 0;
} }
mp_clamp(c); mp_clamp(c);
return MP_OKAY; return MP_OKAY;
} }
#endif #endif

View File

@ -18,21 +18,21 @@
/* d = a - b (mod c) */ /* d = a - b (mod c) */
int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d)
{ {
int res; int res;
mp_int t; mp_int t;
if ((res = mp_init(&t)) != MP_OKAY) { if ((res = mp_init(&t)) != MP_OKAY) {
return res; return res;
} }
if ((res = mp_sub(a, b, &t)) != MP_OKAY) { if ((res = mp_sub(a, b, &t)) != MP_OKAY) {
mp_clear(&t); mp_clear(&t);
return res; return res;
} }
res = mp_mod(&t, c, d); res = mp_mod(&t, c, d);
mp_clear(&t); mp_clear(&t);
return res; return res;
} }
#endif #endif