format with astyle (step 5)
This commit is contained in:
parent
a20d9b102c
commit
f89cda034b
@ -18,13 +18,13 @@
|
||||
/* store in signed [big endian] format */
|
||||
int mp_to_signed_bin(mp_int *a, unsigned char *b)
|
||||
{
|
||||
int res;
|
||||
int res;
|
||||
|
||||
if ((res = mp_to_unsigned_bin(a, b + 1)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
b[0] = (a->sign == MP_ZPOS) ? (unsigned char)0 : (unsigned char)1;
|
||||
return MP_OKAY;
|
||||
if ((res = mp_to_unsigned_bin(a, b + 1)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
b[0] = (a->sign == MP_ZPOS) ? (unsigned char)0 : (unsigned char)1;
|
||||
return MP_OKAY;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -18,28 +18,28 @@
|
||||
/* store in unsigned [big endian] format */
|
||||
int mp_to_unsigned_bin(mp_int *a, unsigned char *b)
|
||||
{
|
||||
int x, res;
|
||||
mp_int t;
|
||||
int x, res;
|
||||
mp_int t;
|
||||
|
||||
if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
while (mp_iszero(&t) == MP_NO) {
|
||||
x = 0;
|
||||
while (mp_iszero(&t) == MP_NO) {
|
||||
#ifndef MP_8BIT
|
||||
b[x++] = (unsigned char)(t.dp[0] & 255);
|
||||
#else
|
||||
b[x++] = (unsigned char)(t.dp[0] | ((t.dp[1] & 0x01) << 7));
|
||||
#endif
|
||||
if ((res = mp_div_2d(&t, 8, &t, NULL)) != MP_OKAY) {
|
||||
mp_clear(&t);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
bn_reverse(b, x);
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
if ((res = mp_div_2d(&t, 8, &t, NULL)) != MP_OKAY) {
|
||||
mp_clear(&t);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
bn_reverse(b, x);
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
454
bn_mp_toom_mul.c
454
bn_mp_toom_mul.c
@ -24,259 +24,259 @@
|
||||
*/
|
||||
int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
|
||||
{
|
||||
mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2;
|
||||
int res, B;
|
||||
mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2;
|
||||
int res, B;
|
||||
|
||||
/* init temps */
|
||||
if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4,
|
||||
&a0, &a1, &a2, &b0, &b1,
|
||||
&b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
/* init temps */
|
||||
if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4,
|
||||
&a0, &a1, &a2, &b0, &b1,
|
||||
&b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/* B */
|
||||
B = MIN(a->used, b->used) / 3;
|
||||
/* B */
|
||||
B = MIN(a->used, b->used) / 3;
|
||||
|
||||
/* a = a2 * B**2 + a1 * B + a0 */
|
||||
if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* a = a2 * B**2 + a1 * B + a0 */
|
||||
if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if ((res = mp_copy(a, &a1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
mp_rshd(&a1, B);
|
||||
if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_copy(a, &a1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
mp_rshd(&a1, B);
|
||||
if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if ((res = mp_copy(a, &a2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
mp_rshd(&a2, B*2);
|
||||
if ((res = mp_copy(a, &a2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
mp_rshd(&a2, B*2);
|
||||
|
||||
/* b = b2 * B**2 + b1 * B + b0 */
|
||||
if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* b = b2 * B**2 + b1 * B + b0 */
|
||||
if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if ((res = mp_copy(b, &b1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
mp_rshd(&b1, B);
|
||||
(void)mp_mod_2d(&b1, DIGIT_BIT * B, &b1);
|
||||
if ((res = mp_copy(b, &b1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
mp_rshd(&b1, B);
|
||||
(void)mp_mod_2d(&b1, DIGIT_BIT * B, &b1);
|
||||
|
||||
if ((res = mp_copy(b, &b2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
mp_rshd(&b2, B*2);
|
||||
if ((res = mp_copy(b, &b2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
mp_rshd(&b2, B*2);
|
||||
|
||||
/* w0 = a0*b0 */
|
||||
if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* w0 = a0*b0 */
|
||||
if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
/* w4 = a2 * b2 */
|
||||
if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* w4 = a2 * b2 */
|
||||
if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
/* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */
|
||||
if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */
|
||||
if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
/* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */
|
||||
if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */
|
||||
if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
|
||||
/* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */
|
||||
if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */
|
||||
if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
/* now solve the matrix
|
||||
/* now solve the matrix
|
||||
|
||||
0 0 0 0 1
|
||||
1 2 4 8 16
|
||||
1 1 1 1 1
|
||||
16 8 4 2 1
|
||||
1 0 0 0 0
|
||||
0 0 0 0 1
|
||||
1 2 4 8 16
|
||||
1 1 1 1 1
|
||||
16 8 4 2 1
|
||||
1 0 0 0 0
|
||||
|
||||
using 12 subtractions, 4 shifts,
|
||||
2 small divisions and 1 small multiplication
|
||||
*/
|
||||
using 12 subtractions, 4 shifts,
|
||||
2 small divisions and 1 small multiplication
|
||||
*/
|
||||
|
||||
/* r1 - r4 */
|
||||
if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - r0 */
|
||||
if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1/2 */
|
||||
if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3/2 */
|
||||
if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r2 - r0 - r4 */
|
||||
if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - r2 */
|
||||
if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - r2 */
|
||||
if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - 8r0 */
|
||||
if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - 8r4 */
|
||||
if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* 3r2 - r1 - r3 */
|
||||
if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - r2 */
|
||||
if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - r2 */
|
||||
if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1/3 */
|
||||
if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3/3 */
|
||||
if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - r4 */
|
||||
if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - r0 */
|
||||
if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1/2 */
|
||||
if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3/2 */
|
||||
if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r2 - r0 - r4 */
|
||||
if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - r2 */
|
||||
if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - r2 */
|
||||
if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - 8r0 */
|
||||
if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - 8r4 */
|
||||
if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* 3r2 - r1 - r3 */
|
||||
if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - r2 */
|
||||
if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - r2 */
|
||||
if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1/3 */
|
||||
if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3/3 */
|
||||
if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
/* at this point shift W[n] by B*n */
|
||||
if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* at this point shift W[n] by B*n */
|
||||
if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
ERR:
|
||||
mp_clear_multi(&w0, &w1, &w2, &w3, &w4,
|
||||
&a0, &a1, &a2, &b0, &b1,
|
||||
&b2, &tmp1, &tmp2, NULL);
|
||||
return res;
|
||||
mp_clear_multi(&w0, &w1, &w2, &w3, &w4,
|
||||
&a0, &a1, &a2, &b0, &b1,
|
||||
&b2, &tmp1, &tmp2, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
358
bn_mp_toom_sqr.c
358
bn_mp_toom_sqr.c
@ -18,206 +18,206 @@
|
||||
/* squaring using Toom-Cook 3-way algorithm */
|
||||
int mp_toom_sqr(mp_int *a, mp_int *b)
|
||||
{
|
||||
mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
|
||||
int res, B;
|
||||
mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
|
||||
int res, B;
|
||||
|
||||
/* init temps */
|
||||
if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
/* init temps */
|
||||
if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/* B */
|
||||
B = a->used / 3;
|
||||
/* B */
|
||||
B = a->used / 3;
|
||||
|
||||
/* a = a2 * B**2 + a1 * B + a0 */
|
||||
if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* a = a2 * B**2 + a1 * B + a0 */
|
||||
if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if ((res = mp_copy(a, &a1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
mp_rshd(&a1, B);
|
||||
if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_copy(a, &a1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
mp_rshd(&a1, B);
|
||||
if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if ((res = mp_copy(a, &a2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
mp_rshd(&a2, B*2);
|
||||
if ((res = mp_copy(a, &a2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
mp_rshd(&a2, B*2);
|
||||
|
||||
/* w0 = a0*a0 */
|
||||
if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* w0 = a0*a0 */
|
||||
if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
/* w4 = a2 * a2 */
|
||||
if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* w4 = a2 * a2 */
|
||||
if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
/* w1 = (a2 + 2(a1 + 2a0))**2 */
|
||||
if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* w1 = (a2 + 2(a1 + 2a0))**2 */
|
||||
if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
/* w3 = (a0 + 2(a1 + 2a2))**2 */
|
||||
if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* w3 = (a0 + 2(a1 + 2a2))**2 */
|
||||
if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
|
||||
/* w2 = (a2 + a1 + a0)**2 */
|
||||
if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* w2 = (a2 + a1 + a0)**2 */
|
||||
if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
/* now solve the matrix
|
||||
/* now solve the matrix
|
||||
|
||||
0 0 0 0 1
|
||||
1 2 4 8 16
|
||||
1 1 1 1 1
|
||||
16 8 4 2 1
|
||||
1 0 0 0 0
|
||||
0 0 0 0 1
|
||||
1 2 4 8 16
|
||||
1 1 1 1 1
|
||||
16 8 4 2 1
|
||||
1 0 0 0 0
|
||||
|
||||
using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
|
||||
*/
|
||||
using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
|
||||
*/
|
||||
|
||||
/* r1 - r4 */
|
||||
if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - r0 */
|
||||
if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1/2 */
|
||||
if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3/2 */
|
||||
if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r2 - r0 - r4 */
|
||||
if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - r2 */
|
||||
if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - r2 */
|
||||
if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - 8r0 */
|
||||
if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - 8r4 */
|
||||
if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* 3r2 - r1 - r3 */
|
||||
if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - r2 */
|
||||
if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - r2 */
|
||||
if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1/3 */
|
||||
if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3/3 */
|
||||
if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - r4 */
|
||||
if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - r0 */
|
||||
if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1/2 */
|
||||
if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3/2 */
|
||||
if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r2 - r0 - r4 */
|
||||
if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - r2 */
|
||||
if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - r2 */
|
||||
if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - 8r0 */
|
||||
if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - 8r4 */
|
||||
if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* 3r2 - r1 - r3 */
|
||||
if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1 - r2 */
|
||||
if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3 - r2 */
|
||||
if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r1/3 */
|
||||
if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* r3/3 */
|
||||
if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
/* at this point shift W[n] by B*n */
|
||||
if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
/* at this point shift W[n] by B*n */
|
||||
if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
ERR:
|
||||
mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
|
||||
return res;
|
||||
mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -18,54 +18,54 @@
|
||||
/* stores a bignum as a ASCII string in a given radix (2..64) */
|
||||
int mp_toradix(mp_int *a, char *str, int radix)
|
||||
{
|
||||
int res, digs;
|
||||
mp_int t;
|
||||
mp_digit d;
|
||||
char *_s = str;
|
||||
int res, digs;
|
||||
mp_int t;
|
||||
mp_digit d;
|
||||
char *_s = str;
|
||||
|
||||
/* check range of the radix */
|
||||
if ((radix < 2) || (radix > 64)) {
|
||||
return MP_VAL;
|
||||
}
|
||||
/* check range of the radix */
|
||||
if ((radix < 2) || (radix > 64)) {
|
||||
return MP_VAL;
|
||||
}
|
||||
|
||||
/* quick out if its zero */
|
||||
if (mp_iszero(a) == MP_YES) {
|
||||
*str++ = '0';
|
||||
*str = '\0';
|
||||
return MP_OKAY;
|
||||
}
|
||||
/* quick out if its zero */
|
||||
if (mp_iszero(a) == MP_YES) {
|
||||
*str++ = '0';
|
||||
*str = '\0';
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/* if it is negative output a - */
|
||||
if (t.sign == MP_NEG) {
|
||||
++_s;
|
||||
*str++ = '-';
|
||||
t.sign = MP_ZPOS;
|
||||
}
|
||||
|
||||
digs = 0;
|
||||
while (mp_iszero(&t) == MP_NO) {
|
||||
if ((res = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
|
||||
mp_clear(&t);
|
||||
if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
*str++ = mp_s_rmap[d];
|
||||
++digs;
|
||||
}
|
||||
}
|
||||
|
||||
/* reverse the digits of the string. In this case _s points
|
||||
* to the first digit [exluding the sign] of the number]
|
||||
*/
|
||||
bn_reverse((unsigned char *)_s, digs);
|
||||
/* if it is negative output a - */
|
||||
if (t.sign == MP_NEG) {
|
||||
++_s;
|
||||
*str++ = '-';
|
||||
t.sign = MP_ZPOS;
|
||||
}
|
||||
|
||||
/* append a NULL so the string is properly terminated */
|
||||
*str = '\0';
|
||||
digs = 0;
|
||||
while (mp_iszero(&t) == MP_NO) {
|
||||
if ((res = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
|
||||
mp_clear(&t);
|
||||
return res;
|
||||
}
|
||||
*str++ = mp_s_rmap[d];
|
||||
++digs;
|
||||
}
|
||||
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
/* reverse the digits of the string. In this case _s points
|
||||
* to the first digit [exluding the sign] of the number]
|
||||
*/
|
||||
bn_reverse((unsigned char *)_s, digs);
|
||||
|
||||
/* append a NULL so the string is properly terminated */
|
||||
*str = '\0';
|
||||
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -21,64 +21,64 @@
|
||||
*/
|
||||
int mp_toradix_n(mp_int *a, char *str, int radix, int maxlen)
|
||||
{
|
||||
int res, digs;
|
||||
mp_int t;
|
||||
mp_digit d;
|
||||
char *_s = str;
|
||||
int res, digs;
|
||||
mp_int t;
|
||||
mp_digit d;
|
||||
char *_s = str;
|
||||
|
||||
/* check range of the maxlen, radix */
|
||||
if ((maxlen < 2) || (radix < 2) || (radix > 64)) {
|
||||
return MP_VAL;
|
||||
}
|
||||
/* check range of the maxlen, radix */
|
||||
if ((maxlen < 2) || (radix < 2) || (radix > 64)) {
|
||||
return MP_VAL;
|
||||
}
|
||||
|
||||
/* quick out if its zero */
|
||||
if (mp_iszero(a) == MP_YES) {
|
||||
*str++ = '0';
|
||||
*str = '\0';
|
||||
return MP_OKAY;
|
||||
}
|
||||
/* quick out if its zero */
|
||||
if (mp_iszero(a) == MP_YES) {
|
||||
*str++ = '0';
|
||||
*str = '\0';
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/* if it is negative output a - */
|
||||
if (t.sign == MP_NEG) {
|
||||
/* we have to reverse our digits later... but not the - sign!! */
|
||||
++_s;
|
||||
|
||||
/* store the flag and mark the number as positive */
|
||||
*str++ = '-';
|
||||
t.sign = MP_ZPOS;
|
||||
|
||||
/* subtract a char */
|
||||
--maxlen;
|
||||
}
|
||||
|
||||
digs = 0;
|
||||
while (mp_iszero(&t) == MP_NO) {
|
||||
if (--maxlen < 1) {
|
||||
/* no more room */
|
||||
break;
|
||||
}
|
||||
if ((res = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
|
||||
mp_clear(&t);
|
||||
if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
*str++ = mp_s_rmap[d];
|
||||
++digs;
|
||||
}
|
||||
}
|
||||
|
||||
/* reverse the digits of the string. In this case _s points
|
||||
* to the first digit [exluding the sign] of the number
|
||||
*/
|
||||
bn_reverse((unsigned char *)_s, digs);
|
||||
/* if it is negative output a - */
|
||||
if (t.sign == MP_NEG) {
|
||||
/* we have to reverse our digits later... but not the - sign!! */
|
||||
++_s;
|
||||
|
||||
/* append a NULL so the string is properly terminated */
|
||||
*str = '\0';
|
||||
/* store the flag and mark the number as positive */
|
||||
*str++ = '-';
|
||||
t.sign = MP_ZPOS;
|
||||
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
/* subtract a char */
|
||||
--maxlen;
|
||||
}
|
||||
|
||||
digs = 0;
|
||||
while (mp_iszero(&t) == MP_NO) {
|
||||
if (--maxlen < 1) {
|
||||
/* no more room */
|
||||
break;
|
||||
}
|
||||
if ((res = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
|
||||
mp_clear(&t);
|
||||
return res;
|
||||
}
|
||||
*str++ = mp_s_rmap[d];
|
||||
++digs;
|
||||
}
|
||||
|
||||
/* reverse the digits of the string. In this case _s points
|
||||
* to the first digit [exluding the sign] of the number
|
||||
*/
|
||||
bn_reverse((unsigned char *)_s, digs);
|
||||
|
||||
/* append a NULL so the string is properly terminated */
|
||||
*str = '\0';
|
||||
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -18,8 +18,8 @@
|
||||
/* get the size for an unsigned equivalent */
|
||||
int mp_unsigned_bin_size(mp_int *a)
|
||||
{
|
||||
int size = mp_count_bits(a);
|
||||
return (size / 8) + (((size & 7) != 0) ? 1 : 0);
|
||||
int size = mp_count_bits(a);
|
||||
return (size / 8) + (((size & 7) != 0) ? 1 : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
44
bn_mp_xor.c
44
bn_mp_xor.c
@ -18,30 +18,30 @@
|
||||
/* XOR two ints together */
|
||||
int mp_xor(mp_int *a, mp_int *b, mp_int *c)
|
||||
{
|
||||
int res, ix, px;
|
||||
mp_int t, *x;
|
||||
int res, ix, px;
|
||||
mp_int t, *x;
|
||||
|
||||
if (a->used > b->used) {
|
||||
if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
px = b->used;
|
||||
x = b;
|
||||
} else {
|
||||
if ((res = mp_init_copy(&t, b)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
px = a->used;
|
||||
x = a;
|
||||
}
|
||||
if (a->used > b->used) {
|
||||
if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
px = b->used;
|
||||
x = b;
|
||||
} else {
|
||||
if ((res = mp_init_copy(&t, b)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
px = a->used;
|
||||
x = a;
|
||||
}
|
||||
|
||||
for (ix = 0; ix < px; ix++) {
|
||||
t.dp[ix] ^= x->dp[ix];
|
||||
}
|
||||
mp_clamp(&t);
|
||||
mp_exch(c, &t);
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
for (ix = 0; ix < px; ix++) {
|
||||
t.dp[ix] ^= x->dp[ix];
|
||||
}
|
||||
mp_clamp(&t);
|
||||
mp_exch(c, &t);
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
16
bn_mp_zero.c
16
bn_mp_zero.c
@ -18,16 +18,16 @@
|
||||
/* set to zero */
|
||||
void mp_zero(mp_int *a)
|
||||
{
|
||||
int n;
|
||||
mp_digit *tmp;
|
||||
int n;
|
||||
mp_digit *tmp;
|
||||
|
||||
a->sign = MP_ZPOS;
|
||||
a->used = 0;
|
||||
a->sign = MP_ZPOS;
|
||||
a->used = 0;
|
||||
|
||||
tmp = a->dp;
|
||||
for (n = 0; n < a->alloc; n++) {
|
||||
*tmp++ = 0;
|
||||
}
|
||||
tmp = a->dp;
|
||||
for (n = 0; n < a->alloc; n++) {
|
||||
*tmp++ = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -15,43 +15,43 @@
|
||||
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
|
||||
*/
|
||||
const mp_digit ltm_prime_tab[] = {
|
||||
0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
|
||||
0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
|
||||
0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
|
||||
0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
|
||||
0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
|
||||
0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
|
||||
0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
|
||||
0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
|
||||
#ifndef MP_8BIT
|
||||
0x0083,
|
||||
0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
|
||||
0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
|
||||
0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
|
||||
0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
|
||||
0x0083,
|
||||
0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
|
||||
0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
|
||||
0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
|
||||
0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
|
||||
|
||||
0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
|
||||
0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
|
||||
0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
|
||||
0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
|
||||
0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
|
||||
0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
|
||||
0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
|
||||
0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
|
||||
0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
|
||||
0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
|
||||
0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
|
||||
0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
|
||||
0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
|
||||
0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
|
||||
0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
|
||||
0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
|
||||
|
||||
0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
|
||||
0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
|
||||
0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
|
||||
0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
|
||||
0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
|
||||
0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
|
||||
0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
|
||||
0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
|
||||
0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
|
||||
0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
|
||||
0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
|
||||
0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
|
||||
0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
|
||||
0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
|
||||
0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
|
||||
0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
|
||||
|
||||
0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
|
||||
0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
|
||||
0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
|
||||
0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
|
||||
0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
|
||||
0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
|
||||
0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
|
||||
0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
|
||||
0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
|
||||
0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
|
||||
0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
|
||||
0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
|
||||
0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
|
||||
0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
|
||||
0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
|
||||
0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
22
bn_reverse.c
22
bn_reverse.c
@ -18,18 +18,18 @@
|
||||
/* reverse an array, used for radix code */
|
||||
void bn_reverse(unsigned char *s, int len)
|
||||
{
|
||||
int ix, iy;
|
||||
unsigned char t;
|
||||
int ix, iy;
|
||||
unsigned char t;
|
||||
|
||||
ix = 0;
|
||||
iy = len - 1;
|
||||
while (ix < iy) {
|
||||
t = s[ix];
|
||||
s[ix] = s[iy];
|
||||
s[iy] = t;
|
||||
++ix;
|
||||
--iy;
|
||||
}
|
||||
ix = 0;
|
||||
iy = len - 1;
|
||||
while (ix < iy) {
|
||||
t = s[ix];
|
||||
s[ix] = s[iy];
|
||||
s[iy] = t;
|
||||
++ix;
|
||||
--iy;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -21,67 +21,67 @@
|
||||
*/
|
||||
int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs)
|
||||
{
|
||||
mp_int t;
|
||||
int res, pa, pb, ix, iy;
|
||||
mp_digit u;
|
||||
mp_word r;
|
||||
mp_digit tmpx, *tmpt, *tmpy;
|
||||
mp_int t;
|
||||
int res, pa, pb, ix, iy;
|
||||
mp_digit u;
|
||||
mp_word r;
|
||||
mp_digit tmpx, *tmpt, *tmpy;
|
||||
|
||||
/* can we use the fast multiplier? */
|
||||
if (((digs) < MP_WARRAY) &&
|
||||
(MIN (a->used, b->used) <
|
||||
(1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
|
||||
return fast_s_mp_mul_digs(a, b, c, digs);
|
||||
}
|
||||
/* can we use the fast multiplier? */
|
||||
if (((digs) < MP_WARRAY) &&
|
||||
(MIN(a->used, b->used) <
|
||||
(1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
|
||||
return fast_s_mp_mul_digs(a, b, c, digs);
|
||||
}
|
||||
|
||||
if ((res = mp_init_size(&t, digs)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
t.used = digs;
|
||||
if ((res = mp_init_size(&t, digs)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
t.used = digs;
|
||||
|
||||
/* compute the digits of the product directly */
|
||||
pa = a->used;
|
||||
for (ix = 0; ix < pa; ix++) {
|
||||
/* set the carry to zero */
|
||||
u = 0;
|
||||
/* compute the digits of the product directly */
|
||||
pa = a->used;
|
||||
for (ix = 0; ix < pa; ix++) {
|
||||
/* set the carry to zero */
|
||||
u = 0;
|
||||
|
||||
/* limit ourselves to making digs digits of output */
|
||||
pb = MIN(b->used, digs - ix);
|
||||
/* limit ourselves to making digs digits of output */
|
||||
pb = MIN(b->used, digs - ix);
|
||||
|
||||
/* setup some aliases */
|
||||
/* copy of the digit from a used within the nested loop */
|
||||
tmpx = a->dp[ix];
|
||||
/* setup some aliases */
|
||||
/* copy of the digit from a used within the nested loop */
|
||||
tmpx = a->dp[ix];
|
||||
|
||||
/* an alias for the destination shifted ix places */
|
||||
tmpt = t.dp + ix;
|
||||
/* an alias for the destination shifted ix places */
|
||||
tmpt = t.dp + ix;
|
||||
|
||||
/* an alias for the digits of b */
|
||||
tmpy = b->dp;
|
||||
/* an alias for the digits of b */
|
||||
tmpy = b->dp;
|
||||
|
||||
/* compute the columns of the output and propagate the carry */
|
||||
for (iy = 0; iy < pb; iy++) {
|
||||
/* compute the column as a mp_word */
|
||||
r = (mp_word)*tmpt +
|
||||
((mp_word)tmpx * (mp_word)*tmpy++) +
|
||||
(mp_word)u;
|
||||
/* compute the columns of the output and propagate the carry */
|
||||
for (iy = 0; iy < pb; iy++) {
|
||||
/* compute the column as a mp_word */
|
||||
r = (mp_word)*tmpt +
|
||||
((mp_word)tmpx * (mp_word)*tmpy++) +
|
||||
(mp_word)u;
|
||||
|
||||
/* the new column is the lower part of the result */
|
||||
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
||||
/* the new column is the lower part of the result */
|
||||
*tmpt++ = (mp_digit)(r & ((mp_word) MP_MASK));
|
||||
|
||||
/* get the carry word from the result */
|
||||
u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
|
||||
}
|
||||
/* set carry if it is placed below digs */
|
||||
if ((ix + iy) < digs) {
|
||||
*tmpt = u;
|
||||
}
|
||||
}
|
||||
/* get the carry word from the result */
|
||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||
}
|
||||
/* set carry if it is placed below digs */
|
||||
if ((ix + iy) < digs) {
|
||||
*tmpt = u;
|
||||
}
|
||||
}
|
||||
|
||||
mp_clamp(&t);
|
||||
mp_exch(&t, c);
|
||||
mp_clamp(&t);
|
||||
mp_exch(&t, c);
|
||||
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -20,58 +20,58 @@
|
||||
*/
|
||||
int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs)
|
||||
{
|
||||
mp_int t;
|
||||
int res, pa, pb, ix, iy;
|
||||
mp_digit u;
|
||||
mp_word r;
|
||||
mp_digit tmpx, *tmpt, *tmpy;
|
||||
mp_int t;
|
||||
int res, pa, pb, ix, iy;
|
||||
mp_digit u;
|
||||
mp_word r;
|
||||
mp_digit tmpx, *tmpt, *tmpy;
|
||||
|
||||
/* can we use the fast multiplier? */
|
||||
/* can we use the fast multiplier? */
|
||||
#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
|
||||
if (((a->used + b->used + 1) < MP_WARRAY)
|
||||
&& (MIN(a->used, b->used) < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
|
||||
return fast_s_mp_mul_high_digs(a, b, c, digs);
|
||||
}
|
||||
if (((a->used + b->used + 1) < MP_WARRAY)
|
||||
&& (MIN(a->used, b->used) < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
|
||||
return fast_s_mp_mul_high_digs(a, b, c, digs);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((res = mp_init_size(&t, a->used + b->used + 1)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
t.used = a->used + b->used + 1;
|
||||
if ((res = mp_init_size(&t, a->used + b->used + 1)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
t.used = a->used + b->used + 1;
|
||||
|
||||
pa = a->used;
|
||||
pb = b->used;
|
||||
for (ix = 0; ix < pa; ix++) {
|
||||
/* clear the carry */
|
||||
u = 0;
|
||||
pa = a->used;
|
||||
pb = b->used;
|
||||
for (ix = 0; ix < pa; ix++) {
|
||||
/* clear the carry */
|
||||
u = 0;
|
||||
|
||||
/* left hand side of A[ix] * B[iy] */
|
||||
tmpx = a->dp[ix];
|
||||
/* left hand side of A[ix] * B[iy] */
|
||||
tmpx = a->dp[ix];
|
||||
|
||||
/* alias to the address of where the digits will be stored */
|
||||
tmpt = &(t.dp[digs]);
|
||||
/* alias to the address of where the digits will be stored */
|
||||
tmpt = &(t.dp[digs]);
|
||||
|
||||
/* alias for where to read the right hand side from */
|
||||
tmpy = b->dp + (digs - ix);
|
||||
/* alias for where to read the right hand side from */
|
||||
tmpy = b->dp + (digs - ix);
|
||||
|
||||
for (iy = digs - ix; iy < pb; iy++) {
|
||||
/* calculate the double precision result */
|
||||
r = (mp_word)*tmpt +
|
||||
((mp_word)tmpx * (mp_word)*tmpy++) +
|
||||
(mp_word)u;
|
||||
for (iy = digs - ix; iy < pb; iy++) {
|
||||
/* calculate the double precision result */
|
||||
r = (mp_word)*tmpt +
|
||||
((mp_word)tmpx * (mp_word)*tmpy++) +
|
||||
(mp_word)u;
|
||||
|
||||
/* get the lower part */
|
||||
*tmpt++ = (mp_digit)(r & ((mp_word) MP_MASK));
|
||||
/* get the lower part */
|
||||
*tmpt++ = (mp_digit)(r & ((mp_word) MP_MASK));
|
||||
|
||||
/* carry the carry */
|
||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||
}
|
||||
*tmpt = u;
|
||||
}
|
||||
mp_clamp(&t);
|
||||
mp_exch(&t, c);
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
/* carry the carry */
|
||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||
}
|
||||
*tmpt = u;
|
||||
}
|
||||
mp_clamp(&t);
|
||||
mp_exch(&t, c);
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -18,64 +18,64 @@
|
||||
/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
|
||||
int s_mp_sqr(mp_int *a, mp_int *b)
|
||||
{
|
||||
mp_int t;
|
||||
int res, ix, iy, pa;
|
||||
mp_word r;
|
||||
mp_digit u, tmpx, *tmpt;
|
||||
mp_int t;
|
||||
int res, ix, iy, pa;
|
||||
mp_word r;
|
||||
mp_digit u, tmpx, *tmpt;
|
||||
|
||||
pa = a->used;
|
||||
if ((res = mp_init_size(&t, (2 * pa) + 1)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
pa = a->used;
|
||||
if ((res = mp_init_size(&t, (2 * pa) + 1)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/* default used is maximum possible size */
|
||||
t.used = (2 * pa) + 1;
|
||||
/* default used is maximum possible size */
|
||||
t.used = (2 * pa) + 1;
|
||||
|
||||
for (ix = 0; ix < pa; ix++) {
|
||||
/* first calculate the digit at 2*ix */
|
||||
/* calculate double precision result */
|
||||
r = (mp_word)t.dp[2*ix] +
|
||||
((mp_word)a->dp[ix] * (mp_word)a->dp[ix]);
|
||||
for (ix = 0; ix < pa; ix++) {
|
||||
/* first calculate the digit at 2*ix */
|
||||
/* calculate double precision result */
|
||||
r = (mp_word)t.dp[2*ix] +
|
||||
((mp_word)a->dp[ix] * (mp_word)a->dp[ix]);
|
||||
|
||||
/* store lower part in result */
|
||||
t.dp[ix+ix] = (mp_digit) (r & ((mp_word)MP_MASK));
|
||||
/* store lower part in result */
|
||||
t.dp[ix+ix] = (mp_digit)(r & ((mp_word)MP_MASK));
|
||||
|
||||
/* get the carry */
|
||||
u = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
|
||||
/* get the carry */
|
||||
u = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
|
||||
|
||||
/* left hand side of A[ix] * A[iy] */
|
||||
tmpx = a->dp[ix];
|
||||
/* left hand side of A[ix] * A[iy] */
|
||||
tmpx = a->dp[ix];
|
||||
|
||||
/* alias for where to store the results */
|
||||
tmpt = t.dp + ((2 * ix) + 1);
|
||||
/* alias for where to store the results */
|
||||
tmpt = t.dp + ((2 * ix) + 1);
|
||||
|
||||
for (iy = ix + 1; iy < pa; iy++) {
|
||||
/* first calculate the product */
|
||||
r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
|
||||
for (iy = ix + 1; iy < pa; iy++) {
|
||||
/* first calculate the product */
|
||||
r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
|
||||
|
||||
/* now calculate the double precision result, note we use
|
||||
* addition instead of *2 since it's easier to optimize
|
||||
*/
|
||||
r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
|
||||
/* now calculate the double precision result, note we use
|
||||
* addition instead of *2 since it's easier to optimize
|
||||
*/
|
||||
r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
|
||||
|
||||
/* store lower part */
|
||||
*tmpt++ = (mp_digit)(r & ((mp_word) MP_MASK));
|
||||
/* store lower part */
|
||||
*tmpt++ = (mp_digit)(r & ((mp_word) MP_MASK));
|
||||
|
||||
/* get carry */
|
||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||
}
|
||||
/* propagate upwards */
|
||||
while (u != ((mp_digit) 0)) {
|
||||
r = ((mp_word) *tmpt) + ((mp_word) u);
|
||||
*tmpt++ = (mp_digit)(r & ((mp_word) MP_MASK));
|
||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||
}
|
||||
}
|
||||
/* get carry */
|
||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||
}
|
||||
/* propagate upwards */
|
||||
while (u != ((mp_digit) 0)) {
|
||||
r = ((mp_word) *tmpt) + ((mp_word) u);
|
||||
*tmpt++ = (mp_digit)(r & ((mp_word) MP_MASK));
|
||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||
}
|
||||
}
|
||||
|
||||
mp_clamp(&t);
|
||||
mp_exch(&t, b);
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
mp_clamp(&t);
|
||||
mp_exch(&t, b);
|
||||
mp_clear(&t);
|
||||
return MP_OKAY;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -18,67 +18,67 @@
|
||||
/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
|
||||
int s_mp_sub(mp_int *a, mp_int *b, mp_int *c)
|
||||
{
|
||||
int olduse, res, min, max;
|
||||
int olduse, res, min, max;
|
||||
|
||||
/* find sizes */
|
||||
min = b->used;
|
||||
max = a->used;
|
||||
/* find sizes */
|
||||
min = b->used;
|
||||
max = a->used;
|
||||
|
||||
/* init result */
|
||||
if (c->alloc < max) {
|
||||
if ((res = mp_grow(c, max)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
olduse = c->used;
|
||||
c->used = max;
|
||||
/* init result */
|
||||
if (c->alloc < max) {
|
||||
if ((res = mp_grow(c, max)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
olduse = c->used;
|
||||
c->used = max;
|
||||
|
||||
{
|
||||
mp_digit u, *tmpa, *tmpb, *tmpc;
|
||||
int i;
|
||||
{
|
||||
mp_digit u, *tmpa, *tmpb, *tmpc;
|
||||
int i;
|
||||
|
||||
/* alias for digit pointers */
|
||||
tmpa = a->dp;
|
||||
tmpb = b->dp;
|
||||
tmpc = c->dp;
|
||||
/* alias for digit pointers */
|
||||
tmpa = a->dp;
|
||||
tmpb = b->dp;
|
||||
tmpc = c->dp;
|
||||
|
||||
/* set carry to zero */
|
||||
u = 0;
|
||||
for (i = 0; i < min; i++) {
|
||||
/* T[i] = A[i] - B[i] - U */
|
||||
*tmpc = (*tmpa++ - *tmpb++) - u;
|
||||
/* set carry to zero */
|
||||
u = 0;
|
||||
for (i = 0; i < min; i++) {
|
||||
/* T[i] = A[i] - B[i] - U */
|
||||
*tmpc = (*tmpa++ - *tmpb++) - u;
|
||||
|
||||
/* U = carry bit of T[i]
|
||||
* Note this saves performing an AND operation since
|
||||
* if a carry does occur it will propagate all the way to the
|
||||
* MSB. As a result a single shift is enough to get the carry
|
||||
*/
|
||||
u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1));
|
||||
/* U = carry bit of T[i]
|
||||
* Note this saves performing an AND operation since
|
||||
* if a carry does occur it will propagate all the way to the
|
||||
* MSB. As a result a single shift is enough to get the carry
|
||||
*/
|
||||
u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1));
|
||||
|
||||
/* Clear carry from T[i] */
|
||||
*tmpc++ &= MP_MASK;
|
||||
}
|
||||
/* Clear carry from T[i] */
|
||||
*tmpc++ &= MP_MASK;
|
||||
}
|
||||
|
||||
/* now copy higher words if any, e.g. if A has more digits than B */
|
||||
for (; i < max; i++) {
|
||||
/* T[i] = A[i] - U */
|
||||
*tmpc = *tmpa++ - u;
|
||||
/* now copy higher words if any, e.g. if A has more digits than B */
|
||||
for (; i < max; i++) {
|
||||
/* T[i] = A[i] - U */
|
||||
*tmpc = *tmpa++ - u;
|
||||
|
||||
/* U = carry bit of T[i] */
|
||||
u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1));
|
||||
/* U = carry bit of T[i] */
|
||||
u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1));
|
||||
|
||||
/* Clear carry from T[i] */
|
||||
*tmpc++ &= MP_MASK;
|
||||
}
|
||||
/* Clear carry from T[i] */
|
||||
*tmpc++ &= MP_MASK;
|
||||
}
|
||||
|
||||
/* clear digits above used (since we may not have grown result above) */
|
||||
for (i = c->used; i < olduse; i++) {
|
||||
*tmpc++ = 0;
|
||||
}
|
||||
}
|
||||
/* clear digits above used (since we may not have grown result above) */
|
||||
for (i = c->used; i < olduse; i++) {
|
||||
*tmpc++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
mp_clamp(c);
|
||||
return MP_OKAY;
|
||||
mp_clamp(c);
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
74
tommath.h
74
tommath.h
@ -47,45 +47,45 @@ extern "C" {
|
||||
* [any size beyond that is ok provided it doesn't overflow the data type]
|
||||
*/
|
||||
#ifdef MP_8BIT
|
||||
typedef uint8_t mp_digit;
|
||||
typedef uint16_t mp_word;
|
||||
typedef uint8_t mp_digit;
|
||||
typedef uint16_t mp_word;
|
||||
# define MP_SIZEOF_MP_DIGIT 1
|
||||
# ifdef DIGIT_BIT
|
||||
# error You must not define DIGIT_BIT when using MP_8BIT
|
||||
# endif
|
||||
#elif defined(MP_16BIT)
|
||||
typedef uint16_t mp_digit;
|
||||
typedef uint32_t mp_word;
|
||||
typedef uint16_t mp_digit;
|
||||
typedef uint32_t mp_word;
|
||||
# define MP_SIZEOF_MP_DIGIT 2
|
||||
# ifdef DIGIT_BIT
|
||||
# error You must not define DIGIT_BIT when using MP_16BIT
|
||||
# endif
|
||||
#elif defined(MP_64BIT)
|
||||
/* for GCC only on supported platforms */
|
||||
typedef uint64_t mp_digit;
|
||||
/* for GCC only on supported platforms */
|
||||
typedef uint64_t mp_digit;
|
||||
# if defined(_WIN32)
|
||||
typedef unsigned __int128 mp_word;
|
||||
typedef unsigned __int128 mp_word;
|
||||
# elif defined(__GNUC__)
|
||||
typedef unsigned long mp_word __attribute__ ((mode(TI)));
|
||||
typedef unsigned long mp_word __attribute__((mode(TI)));
|
||||
# else
|
||||
/* it seems you have a problem
|
||||
* but we assume you can somewhere define your own uint128_t */
|
||||
typedef uint128_t mp_word;
|
||||
/* it seems you have a problem
|
||||
* but we assume you can somewhere define your own uint128_t */
|
||||
typedef uint128_t mp_word;
|
||||
# endif
|
||||
|
||||
# define DIGIT_BIT 60
|
||||
#else
|
||||
/* this is the default case, 28-bit digits */
|
||||
/* this is the default case, 28-bit digits */
|
||||
|
||||
/* this is to make porting into LibTomCrypt easier :-) */
|
||||
typedef uint32_t mp_digit;
|
||||
typedef uint64_t mp_word;
|
||||
/* this is to make porting into LibTomCrypt easier :-) */
|
||||
typedef uint32_t mp_digit;
|
||||
typedef uint64_t mp_word;
|
||||
|
||||
# ifdef MP_31BIT
|
||||
/* this is an extension that uses 31-bit digits */
|
||||
/* this is an extension that uses 31-bit digits */
|
||||
# define DIGIT_BIT 31
|
||||
# else
|
||||
/* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
|
||||
/* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
|
||||
# define DIGIT_BIT 28
|
||||
# define MP_28BIT
|
||||
# endif
|
||||
@ -94,9 +94,9 @@ extern "C" {
|
||||
/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
|
||||
#ifndef DIGIT_BIT
|
||||
# define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */
|
||||
typedef uint_least32_t mp_min_u32;
|
||||
typedef uint_least32_t mp_min_u32;
|
||||
#else
|
||||
typedef mp_digit mp_min_u32;
|
||||
typedef mp_digit mp_min_u32;
|
||||
#endif
|
||||
|
||||
/* use arc4random on platforms that support it */
|
||||
@ -140,9 +140,9 @@ typedef int mp_err;
|
||||
|
||||
/* you'll have to tune these... */
|
||||
extern int KARATSUBA_MUL_CUTOFF,
|
||||
KARATSUBA_SQR_CUTOFF,
|
||||
TOOM_MUL_CUTOFF,
|
||||
TOOM_SQR_CUTOFF;
|
||||
KARATSUBA_SQR_CUTOFF,
|
||||
TOOM_MUL_CUTOFF,
|
||||
TOOM_SQR_CUTOFF;
|
||||
|
||||
/* define this to use lower memory usage routines (exptmods mostly) */
|
||||
/* #define MP_LOW_MEM */
|
||||
@ -161,8 +161,8 @@ extern int KARATSUBA_MUL_CUTOFF,
|
||||
|
||||
/* the infamous mp_int structure */
|
||||
typedef struct {
|
||||
int used, alloc, sign;
|
||||
mp_digit *dp;
|
||||
int used, alloc, sign;
|
||||
mp_digit *dp;
|
||||
} mp_int;
|
||||
|
||||
/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
|
||||
@ -223,19 +223,19 @@ int mp_set_long(mp_int *a, unsigned long b);
|
||||
int mp_set_long_long(mp_int *a, unsigned long long b);
|
||||
|
||||
/* get a 32-bit value */
|
||||
unsigned long mp_get_int(mp_int * a);
|
||||
unsigned long mp_get_int(mp_int *a);
|
||||
|
||||
/* get a platform dependent unsigned long value */
|
||||
unsigned long mp_get_long(mp_int * a);
|
||||
unsigned long mp_get_long(mp_int *a);
|
||||
|
||||
/* get a platform dependent unsigned long long value */
|
||||
unsigned long long mp_get_long_long(mp_int * a);
|
||||
unsigned long long mp_get_long_long(mp_int *a);
|
||||
|
||||
/* initialize and set a digit */
|
||||
int mp_init_set (mp_int * a, mp_digit b);
|
||||
int mp_init_set(mp_int *a, mp_digit b);
|
||||
|
||||
/* initialize and set 32-bit value */
|
||||
int mp_init_set_int (mp_int * a, unsigned long b);
|
||||
int mp_init_set_int(mp_int *a, unsigned long b);
|
||||
|
||||
/* copy, b = a */
|
||||
int mp_copy(mp_int *a, mp_int *b);
|
||||
@ -247,10 +247,10 @@ int mp_init_copy(mp_int *a, mp_int *b);
|
||||
void mp_clamp(mp_int *a);
|
||||
|
||||
/* import binary data */
|
||||
int mp_import(mp_int* rop, size_t count, int order, size_t size, int endian, size_t nails, const void* op);
|
||||
int mp_import(mp_int *rop, size_t count, int order, size_t size, int endian, size_t nails, const void *op);
|
||||
|
||||
/* export binary data */
|
||||
int mp_export(void* rop, size_t* countp, int order, size_t size, int endian, size_t nails, mp_int* op);
|
||||
int mp_export(void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, mp_int *op);
|
||||
|
||||
/* ---> digit manipulation <--- */
|
||||
|
||||
@ -350,7 +350,7 @@ int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
|
||||
|
||||
/* c = a**b */
|
||||
int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
|
||||
int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast);
|
||||
int mp_expt_d_ex(mp_int *a, mp_digit b, mp_int *c, int fast);
|
||||
|
||||
/* c = a mod b, 0 <= c < b */
|
||||
int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
|
||||
@ -386,7 +386,7 @@ int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
|
||||
* returns error if a < 0 and b is even
|
||||
*/
|
||||
int mp_n_root(mp_int *a, mp_digit b, mp_int *c);
|
||||
int mp_n_root_ex (mp_int * a, mp_digit b, mp_int * c, int fast);
|
||||
int mp_n_root_ex(mp_int *a, mp_digit b, mp_int *c, int fast);
|
||||
|
||||
/* special sqrt algo */
|
||||
int mp_sqrt(mp_int *arg, mp_int *ret);
|
||||
@ -529,16 +529,16 @@ int mp_count_bits(mp_int *a);
|
||||
int mp_unsigned_bin_size(mp_int *a);
|
||||
int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c);
|
||||
int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
|
||||
int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
|
||||
int mp_to_unsigned_bin_n(mp_int *a, unsigned char *b, unsigned long *outlen);
|
||||
|
||||
int mp_signed_bin_size(mp_int *a);
|
||||
int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c);
|
||||
int mp_to_signed_bin(mp_int *a, unsigned char *b);
|
||||
int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
|
||||
int mp_to_signed_bin_n(mp_int *a, unsigned char *b, unsigned long *outlen);
|
||||
|
||||
int mp_read_radix(mp_int *a, const char *str, int radix);
|
||||
int mp_toradix(mp_int *a, char *str, int radix);
|
||||
int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen);
|
||||
int mp_toradix_n(mp_int *a, char *str, int radix, int maxlen);
|
||||
int mp_radix_size(mp_int *a, int radix, int *size);
|
||||
|
||||
#ifndef LTM_NO_FILE
|
||||
@ -559,7 +559,7 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream);
|
||||
#define mp_tohex(M, S) mp_toradix((M), (S), 16)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -19,11 +19,11 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -41,17 +41,17 @@ extern "C" {
|
||||
|
||||
/* define heap macros */
|
||||
#ifndef XMALLOC
|
||||
/* default to libc stuff */
|
||||
/* default to libc stuff */
|
||||
# define XMALLOC malloc
|
||||
# define XFREE free
|
||||
# define XREALLOC realloc
|
||||
# define XCALLOC calloc
|
||||
#else
|
||||
/* prototypes for our heap functions */
|
||||
extern void *XMALLOC(size_t n);
|
||||
extern void *XREALLOC(void *p, size_t n);
|
||||
extern void *XCALLOC(size_t n, size_t s);
|
||||
extern void XFREE(void *p);
|
||||
/* prototypes for our heap functions */
|
||||
extern void *XMALLOC(size_t n);
|
||||
extern void *XREALLOC(void *p, size_t n);
|
||||
extern void *XCALLOC(size_t n, size_t s);
|
||||
extern void XFREE(void *p);
|
||||
#endif
|
||||
|
||||
/* lowlevel functions, do not call! */
|
||||
@ -69,10 +69,10 @@ int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_karatsuba_sqr(mp_int *a, mp_int *b);
|
||||
int mp_toom_sqr(mp_int *a, mp_int *b);
|
||||
int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
|
||||
int mp_invmod_slow(mp_int *a, mp_int *b, mp_int *c);
|
||||
int fast_mp_montgomery_reduce(mp_int *x, mp_int *n, mp_digit rho);
|
||||
int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int redmode);
|
||||
int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode);
|
||||
int s_mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int redmode);
|
||||
void bn_reverse(unsigned char *s, int len);
|
||||
|
||||
extern const char *mp_s_rmap;
|
||||
@ -112,7 +112,7 @@ int func_name (mp_int * a, type b) \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -33,13 +33,13 @@
|
||||
# define BN_REVERSE_C
|
||||
# define BN_PRIME_TAB_C
|
||||
|
||||
/* other modifiers */
|
||||
/* other modifiers */
|
||||
# define BN_MP_DIV_SMALL /* Slower division, not critical */
|
||||
|
||||
/* here we are on the last pass so we turn things off. The functions classes are still there
|
||||
* but we remove them specifically from the build. This also invokes tweaks in functions
|
||||
* like removing support for even moduli, etc...
|
||||
*/
|
||||
/* here we are on the last pass so we turn things off. The functions classes are still there
|
||||
* but we remove them specifically from the build. This also invokes tweaks in functions
|
||||
* like removing support for even moduli, etc...
|
||||
*/
|
||||
# ifdef LTM_LAST
|
||||
# undef BN_MP_TOOM_MUL_C
|
||||
# undef BN_MP_TOOM_SQR_C
|
||||
@ -59,11 +59,11 @@
|
||||
# undef BN_FAST_S_MP_MUL_HIGH_DIGS_C
|
||||
# undef BN_FAST_MP_INVMOD_C
|
||||
|
||||
/* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
|
||||
* which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines]
|
||||
* which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
|
||||
* trouble.
|
||||
*/
|
||||
/* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
|
||||
* which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines]
|
||||
* which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
|
||||
* trouble.
|
||||
*/
|
||||
# undef BN_S_MP_MUL_DIGS_C
|
||||
# undef BN_S_MP_SQR_C
|
||||
# undef BN_MP_MONTGOMERY_REDUCE_C
|
||||
|
Loading…
Reference in New Issue
Block a user