goto without block

This commit is contained in:
Francois Perrad 2019-09-04 08:40:39 +02:00
parent b264fb2b16
commit 06ff695b95
11 changed files with 310 additions and 780 deletions

View File

@ -38,24 +38,18 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
mp_set(&tq, 1uL);
n = mp_count_bits(a) - mp_count_bits(b);
if (((err = mp_abs(a, &ta)) != MP_OKAY) ||
((err = mp_abs(b, &tb)) != MP_OKAY) ||
((err = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
((err = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
goto LBL_ERR;
}
if ((err = mp_abs(a, &ta)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_abs(b, &tb)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_mul_2d(&tq, n, &tq)) != MP_OKAY) goto LBL_ERR;
while (n-- >= 0) {
if (mp_cmp(&tb, &ta) != MP_GT) {
if (((err = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
((err = mp_add(&q, &tq, &q)) != MP_OKAY)) {
goto LBL_ERR;
}
}
if (((err = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
((err = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
goto LBL_ERR;
if ((err = mp_sub(&ta, &tb, &ta)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_add(&q, &tq, &q)) != MP_OKAY) goto LBL_ERR;
}
if ((err = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY) goto LBL_ERR;
}
/* now q == quotient and ta == remainder */
@ -119,21 +113,13 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
}
q.used = a->used + 2;
if ((err = mp_init(&t1)) != MP_OKAY) {
goto LBL_Q;
}
if ((err = mp_init(&t1)) != MP_OKAY) goto LBL_Q;
if ((err = mp_init(&t2)) != MP_OKAY) {
goto LBL_T1;
}
if ((err = mp_init(&t2)) != MP_OKAY) goto LBL_T1;
if ((err = mp_init_copy(&x, a)) != MP_OKAY) {
goto LBL_T2;
}
if ((err = mp_init_copy(&x, a)) != MP_OKAY) goto LBL_T2;
if ((err = mp_init_copy(&y, b)) != MP_OKAY) {
goto LBL_X;
}
if ((err = mp_init_copy(&y, b)) != MP_OKAY) goto LBL_X;
/* fix the sign */
neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
@ -143,12 +129,8 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
norm = mp_count_bits(&y) % MP_DIGIT_BIT;
if (norm < (MP_DIGIT_BIT - 1)) {
norm = (MP_DIGIT_BIT - 1) - norm;
if ((err = mp_mul_2d(&x, norm, &x)) != MP_OKAY) {
goto LBL_Y;
}
if ((err = mp_mul_2d(&y, norm, &y)) != MP_OKAY) {
goto LBL_Y;
}
if ((err = mp_mul_2d(&x, norm, &x)) != MP_OKAY) goto LBL_Y;
if ((err = mp_mul_2d(&y, norm, &y)) != MP_OKAY) goto LBL_Y;
} else {
norm = 0;
}
@ -158,15 +140,12 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
t = y.used - 1;
/* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
if ((err = mp_lshd(&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
goto LBL_Y;
}
/* y = y*b**{n-t} */
if ((err = mp_lshd(&y, n - t)) != MP_OKAY) goto LBL_Y;
while (mp_cmp(&x, &y) != MP_LT) {
++(q.dp[n - t]);
if ((err = mp_sub(&x, &y, &x)) != MP_OKAY) {
goto LBL_Y;
}
if ((err = mp_sub(&x, &y, &x)) != MP_OKAY) goto LBL_Y;
}
/* reset y by shifting it back down */
@ -207,9 +186,7 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
t1.dp[0] = ((t - 1) < 0) ? 0u : y.dp[t - 1];
t1.dp[1] = y.dp[t];
t1.used = 2;
if ((err = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
goto LBL_Y;
}
if ((err = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) goto LBL_Y;
/* find right hand */
t2.dp[0] = ((i - 2) < 0) ? 0u : x.dp[i - 2];
@ -219,29 +196,17 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
} while (mp_cmp_mag(&t1, &t2) == MP_GT);
/* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
if ((err = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
goto LBL_Y;
}
if ((err = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) goto LBL_Y;
if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) {
goto LBL_Y;
}
if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) goto LBL_Y;
if ((err = mp_sub(&x, &t1, &x)) != MP_OKAY) {
goto LBL_Y;
}
if ((err = mp_sub(&x, &t1, &x)) != MP_OKAY) goto LBL_Y;
/* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
if (x.sign == MP_NEG) {
if ((err = mp_copy(&y, &t1)) != MP_OKAY) {
goto LBL_Y;
}
if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) {
goto LBL_Y;
}
if ((err = mp_add(&x, &t1, &x)) != MP_OKAY) {
goto LBL_Y;
}
if ((err = mp_copy(&y, &t1)) != MP_OKAY) goto LBL_Y;
if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) goto LBL_Y;
if ((err = mp_add(&x, &t1, &x)) != MP_OKAY) goto LBL_Y;
q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & MP_MASK;
}
@ -261,9 +226,7 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
}
if (d != NULL) {
if ((err = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY) {
goto LBL_Y;
}
if ((err = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY) goto LBL_Y;
mp_exch(&x, d);
}

View File

@ -17,77 +17,41 @@ mp_err mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp
/* initialize, (u1,u2,u3) = (1,0,a) */
mp_set(&u1, 1uL);
if ((err = mp_copy(a, &u3)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(a, &u3)) != MP_OKAY) goto LBL_ERR;
/* initialize, (v1,v2,v3) = (0,1,b) */
mp_set(&v2, 1uL);
if ((err = mp_copy(b, &v3)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(b, &v3)) != MP_OKAY) goto LBL_ERR;
/* loop while v3 != 0 */
while (!MP_IS_ZERO(&v3)) {
/* q = u3/v3 */
if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) goto LBL_ERR;
/* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) goto LBL_ERR;
/* (u1,u2,u3) = (v1,v2,v3) */
if ((err = mp_copy(&v1, &u1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&v2, &u2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&v3, &u3)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&v1, &u1)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_copy(&v2, &u2)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_copy(&v3, &u3)) != MP_OKAY) goto LBL_ERR;
/* (v1,v2,v3) = (t1,t2,t3) */
if ((err = mp_copy(&t1, &v1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&t2, &v2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&t3, &v3)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&t1, &v1)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_copy(&t2, &v2)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_copy(&t3, &v3)) != MP_OKAY) goto LBL_ERR;
}
/* make sure U3 >= 0 */
if (u3.sign == MP_NEG) {
if ((err = mp_neg(&u1, &u1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_neg(&u2, &u2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_neg(&u3, &u3)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_neg(&u1, &u1)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_neg(&u2, &u2)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_neg(&u3, &u3)) != MP_OKAY) goto LBL_ERR;
}
/* copy result out */

View File

@ -45,17 +45,11 @@ mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result)
/* (32764^2 - 4) < 2^31, no bigint for >MP_8BIT needed) */
mp_set_u32(&T1z, (uint32_t)a);
if ((err = mp_sqr(&T1z, &T1z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_sqr(&T1z, &T1z)) != MP_OKAY) goto LBL_FU_ERR;
if ((err = mp_sub_d(&T1z, 4uL, &T1z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_sub_d(&T1z, 4uL, &T1z)) != MP_OKAY) goto LBL_FU_ERR;
if ((err = mp_kronecker(&T1z, N, &j)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_kronecker(&T1z, N, &j)) != MP_OKAY) goto LBL_FU_ERR;
if (j == -1) {
break;
@ -74,18 +68,12 @@ mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result)
/* Composite if N and (a+4)*(2*a+5) are not coprime */
mp_set_u32(&T1z, (uint32_t)((a+4)*((2*a)+5)));
if ((err = mp_gcd(N, &T1z, &T1z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_gcd(N, &T1z, &T1z)) != MP_OKAY) goto LBL_FU_ERR;
if (!((T1z.used == 1) && (T1z.dp[0] == 1u))) {
goto LBL_FU_ERR;
}
if (!((T1z.used == 1) && (T1z.dp[0] == 1u))) goto LBL_FU_ERR;
ap2 = a + 2;
if ((err = mp_add_d(N, 1uL, &Np1z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_add_d(N, 1uL, &Np1z)) != MP_OKAY) goto LBL_FU_ERR;
mp_set(&sz, 1uL);
mp_set(&tz, 2uL);
@ -97,38 +85,20 @@ mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result)
* tz = ((tz-sz)*(tz+sz))%N;
* sz = temp;
*/
if ((err = mp_mul_2(&tz, &T2z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_mul_2(&tz, &T2z)) != MP_OKAY) goto LBL_FU_ERR;
/* a = 0 at about 50% of the cases (non-square and odd input) */
if (a != 0) {
if ((err = mp_mul_d(&sz, (mp_digit)a, &T1z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_add(&T1z, &T2z, &T2z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_mul_d(&sz, (mp_digit)a, &T1z)) != MP_OKAY) goto LBL_FU_ERR;
if ((err = mp_add(&T1z, &T2z, &T2z)) != MP_OKAY) goto LBL_FU_ERR;
}
if ((err = mp_mul(&T2z, &sz, &T1z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_sub(&tz, &sz, &T2z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_add(&sz, &tz, &sz)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_mul(&sz, &T2z, &tz)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_mod(&tz, N, &tz)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_mod(&T1z, N, &sz)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_mul(&T2z, &sz, &T1z)) != MP_OKAY) goto LBL_FU_ERR;
if ((err = mp_sub(&tz, &sz, &T2z)) != MP_OKAY) goto LBL_FU_ERR;
if ((err = mp_add(&sz, &tz, &sz)) != MP_OKAY) goto LBL_FU_ERR;
if ((err = mp_mul(&sz, &T2z, &tz)) != MP_OKAY) goto LBL_FU_ERR;
if ((err = mp_mod(&tz, N, &tz)) != MP_OKAY) goto LBL_FU_ERR;
if ((err = mp_mod(&T1z, N, &sz)) != MP_OKAY) goto LBL_FU_ERR;
if (s_mp_get_bit(&Np1z, (unsigned int)i) == MP_YES) {
/*
* temp = (a+2) * sz + tz
@ -136,34 +106,21 @@ mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result)
* sz = temp
*/
if (a == 0) {
if ((err = mp_mul_2(&sz, &T1z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_mul_2(&sz, &T1z)) != MP_OKAY) goto LBL_FU_ERR;
} else {
if ((err = mp_mul_d(&sz, (mp_digit)ap2, &T1z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
}
if ((err = mp_add(&T1z, &tz, &T1z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_mul_2(&tz, &T2z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_sub(&T2z, &sz, &tz)) != MP_OKAY) {
goto LBL_FU_ERR;
if ((err = mp_mul_d(&sz, (mp_digit)ap2, &T1z)) != MP_OKAY) goto LBL_FU_ERR;
}
if ((err = mp_add(&T1z, &tz, &T1z)) != MP_OKAY) goto LBL_FU_ERR;
if ((err = mp_mul_2(&tz, &T2z)) != MP_OKAY) goto LBL_FU_ERR;
if ((err = mp_sub(&T2z, &sz, &tz)) != MP_OKAY) goto LBL_FU_ERR;
mp_exch(&sz, &T1z);
}
}
mp_set_u32(&T1z, (uint32_t)((2 * a) + 5));
if ((err = mp_mod(&T1z, N, &T1z)) != MP_OKAY) {
goto LBL_FU_ERR;
}
if ((err = mp_mod(&T1z, N, &T1z)) != MP_OKAY) goto LBL_FU_ERR;
if (MP_IS_ZERO(&sz) && (mp_cmp(&tz, &T1z) == MP_EQ)) {
*result = MP_YES;
goto LBL_FU_ERR;
}
LBL_FU_ERR:

View File

@ -84,9 +84,8 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result)
Ds = sign * D;
sign = -sign;
mp_set_u32(&Dz, (uint32_t)D);
if ((err = mp_gcd(a, &Dz, &gcd)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_gcd(a, &Dz, &gcd)) != MP_OKAY) goto LBL_LS_ERR;
/* if 1 < GCD < N then N is composite with factor "D", and
Jacobi(D,N) is technically undefined (but often returned
as zero). */
@ -96,9 +95,7 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result)
if (Ds < 0) {
Dz.sign = MP_NEG;
}
if ((err = mp_kronecker(&Dz, a, &J)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_kronecker(&Dz, a, &J)) != MP_OKAY) goto LBL_LS_ERR;
if (J == -1) {
break;
@ -146,9 +143,7 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result)
Baillie-PSW test based on the strong Lucas-Selfridge test
should be more reliable. */
if ((err = mp_add_d(a, 1uL, &Np1)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_add_d(a, 1uL, &Np1)) != MP_OKAY) goto LBL_LS_ERR;
s = mp_cnt_lsb(&Np1);
/* CZ
@ -158,9 +153,7 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result)
* dividing an even number by two does not produce
* any leftovers.
*/
if ((err = mp_div_2d(&Np1, s, &Dz, NULL)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_div_2d(&Np1, s, &Dz, NULL)) != MP_OKAY) goto LBL_LS_ERR;
/* We must now compute U_d and V_d. Since d is odd, the accumulated
values U and V are initialized to U_1 and V_1 (if the target
index were even, U and V would be initialized instead to U_0=0
@ -178,9 +171,7 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result)
mp_set(&V2mz, (mp_digit)P); /* V_1 */
mp_set_i32(&Qmz, Q);
if ((err = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) goto LBL_LS_ERR;
/* Initializes calculation of Q^d */
mp_set_i32(&Qkdz, Q);
@ -195,32 +186,19 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result)
* V_2m = V_m*V_m - 2*Q^m
*/
if ((err = mp_mul(&U2mz, &V2mz, &U2mz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mod(&U2mz, a, &U2mz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_sqr(&V2mz, &V2mz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_sub(&V2mz, &Q2mz, &V2mz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mod(&V2mz, a, &V2mz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mul(&U2mz, &V2mz, &U2mz)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_mod(&U2mz, a, &U2mz)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_sqr(&V2mz, &V2mz)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_sub(&V2mz, &Q2mz, &V2mz)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_mod(&V2mz, a, &V2mz)) != MP_OKAY) goto LBL_LS_ERR;
/* Must calculate powers of Q for use in V_2m, also for Q^d later */
if ((err = mp_sqr(&Qmz, &Qmz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_sqr(&Qmz, &Qmz)) != MP_OKAY) goto LBL_LS_ERR;
/* prevents overflow */ /* CZ still necessary without a fixed prealloc'd mem.? */
if ((err = mp_mod(&Qmz, a, &Qmz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mod(&Qmz, a, &Qmz)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) goto LBL_LS_ERR;
if (s_mp_get_bit(&Dz, (unsigned int)u) == MP_YES) {
/* Formulas for addition of indices (carried out mod N);
*
@ -229,28 +207,14 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result)
*
* Be careful with division by 2 (mod N)!
*/
if ((err = mp_mul(&U2mz, &Vz, &T1z)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mul(&Uz, &V2mz, &T2z)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mul(&V2mz, &Vz, &T3z)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mul(&U2mz, &Uz, &T4z)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = s_mp_mul_si(&T4z, Ds, &T4z)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_add(&T1z, &T2z, &Uz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mul(&U2mz, &Vz, &T1z)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_mul(&Uz, &V2mz, &T2z)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_mul(&V2mz, &Vz, &T3z)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_mul(&U2mz, &Uz, &T4z)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = s_mp_mul_si(&T4z, Ds, &T4z)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_add(&T1z, &T2z, &Uz)) != MP_OKAY) goto LBL_LS_ERR;
if (MP_IS_ODD(&Uz)) {
if ((err = mp_add(&Uz, a, &Uz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_add(&Uz, a, &Uz)) != MP_OKAY) goto LBL_LS_ERR;
}
/* CZ
* This should round towards negative infinity because
@ -258,44 +222,25 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result)
* But mp_div_2() does not do so, it is truncating instead.
*/
oddness = MP_IS_ODD(&Uz) ? MP_YES : MP_NO;
if ((err = mp_div_2(&Uz, &Uz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_div_2(&Uz, &Uz)) != MP_OKAY) goto LBL_LS_ERR;
if ((Uz.sign == MP_NEG) && (oddness != MP_NO)) {
if ((err = mp_sub_d(&Uz, 1uL, &Uz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
}
if ((err = mp_add(&T3z, &T4z, &Vz)) != MP_OKAY) {
goto LBL_LS_ERR;
if ((err = mp_sub_d(&Uz, 1uL, &Uz)) != MP_OKAY) goto LBL_LS_ERR;
}
if ((err = mp_add(&T3z, &T4z, &Vz)) != MP_OKAY) goto LBL_LS_ERR;
if (MP_IS_ODD(&Vz)) {
if ((err = mp_add(&Vz, a, &Vz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_add(&Vz, a, &Vz)) != MP_OKAY) goto LBL_LS_ERR;
}
oddness = MP_IS_ODD(&Vz) ? MP_YES : MP_NO;
if ((err = mp_div_2(&Vz, &Vz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_div_2(&Vz, &Vz)) != MP_OKAY) goto LBL_LS_ERR;
if ((Vz.sign == MP_NEG) && (oddness != MP_NO)) {
if ((err = mp_sub_d(&Vz, 1uL, &Vz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
}
if ((err = mp_mod(&Uz, a, &Uz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mod(&Vz, a, &Vz)) != MP_OKAY) {
goto LBL_LS_ERR;
if ((err = mp_sub_d(&Vz, 1uL, &Vz)) != MP_OKAY) goto LBL_LS_ERR;
}
if ((err = mp_mod(&Uz, a, &Uz)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_mod(&Vz, a, &Vz)) != MP_OKAY) goto LBL_LS_ERR;
/* Calculating Q^d for later use */
if ((err = mp_mul(&Qkdz, &Qmz, &Qkdz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mod(&Qkdz, a, &Qkdz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mul(&Qkdz, &Qmz, &Qkdz)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_mod(&Qkdz, a, &Qkdz)) != MP_OKAY) goto LBL_LS_ERR;
}
}
@ -318,35 +263,21 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result)
Lucas pseudoprime. */
/* Initialize 2*Q^(d*2^r) for V_2m */
if ((err = mp_mul_2(&Qkdz, &Q2kdz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mul_2(&Qkdz, &Q2kdz)) != MP_OKAY) goto LBL_LS_ERR;
for (r = 1; r < s; r++) {
if ((err = mp_sqr(&Vz, &Vz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_sub(&Vz, &Q2kdz, &Vz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mod(&Vz, a, &Vz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_sqr(&Vz, &Vz)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_sub(&Vz, &Q2kdz, &Vz)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_mod(&Vz, a, &Vz)) != MP_OKAY) goto LBL_LS_ERR;
if (MP_IS_ZERO(&Vz)) {
*result = MP_YES;
goto LBL_LS_ERR;
}
/* Calculate Q^{d*2^r} for next r (final iteration irrelevant). */
if (r < (s - 1)) {
if ((err = mp_sqr(&Qkdz, &Qkdz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mod(&Qkdz, a, &Qkdz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_mul_2(&Qkdz, &Q2kdz)) != MP_OKAY) {
goto LBL_LS_ERR;
}
if ((err = mp_sqr(&Qkdz, &Qkdz)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_mod(&Qkdz, a, &Qkdz)) != MP_OKAY) goto LBL_LS_ERR;
if ((err = mp_mul_2(&Qkdz, &Q2kdz)) != MP_OKAY) goto LBL_LS_ERR;
}
}
LBL_LS_ERR:

View File

@ -63,46 +63,32 @@ mp_err mp_root_u32(const mp_int *a, uint32_t b, mp_int *c)
}
/* Start value must be larger than root */
ilog2 += 2;
if ((err = mp_2expt(&t2,ilog2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_2expt(&t2,ilog2)) != MP_OKAY) goto LBL_ERR;
do {
/* t1 = t2 */
if ((err = mp_copy(&t2, &t1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&t2, &t1)) != MP_OKAY) goto LBL_ERR;
/* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
/* t3 = t1**(b-1) */
if ((err = mp_expt_u32(&t1, b - 1u, &t3)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_expt_u32(&t1, b - 1u, &t3)) != MP_OKAY) goto LBL_ERR;
/* numerator */
/* t2 = t1**b */
if ((err = mp_mul(&t3, &t1, &t2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(&t3, &t1, &t2)) != MP_OKAY) goto LBL_ERR;
/* t2 = t1**b - a */
if ((err = mp_sub(&t2, &a_, &t2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&t2, &a_, &t2)) != MP_OKAY) goto LBL_ERR;
/* denominator */
/* t3 = t1**(b-1) * b */
if ((err = mp_mul_d(&t3, b, &t3)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul_d(&t3, b, &t3)) != MP_OKAY) goto LBL_ERR;
/* t3 = (t1**b - a)/(b * t1**(b-1)) */
if ((err = mp_div(&t2, &t3, &t3, NULL)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div(&t2, &t3, &t3, NULL)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_sub(&t1, &t3, &t2)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_sub(&t1, &t3, &t2)) != MP_OKAY) {
goto LBL_ERR;
}
/*
Number of rounds is at most log_2(root). If it is more it
got stuck, so break out of the loop and do the rest manually.
@ -115,31 +101,23 @@ mp_err mp_root_u32(const mp_int *a, uint32_t b, mp_int *c)
/* result can be off by a few so check */
/* Loop beneath can overshoot by one if found root is smaller than actual root */
for (;;) {
if ((err = mp_expt_u32(&t1, b, &t2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_expt_u32(&t1, b, &t2)) != MP_OKAY) goto LBL_ERR;
cmp = mp_cmp(&t2, &a_);
if (cmp == MP_EQ) {
err = MP_OKAY;
goto LBL_ERR;
}
if (cmp == MP_LT) {
if ((err = mp_add_d(&t1, 1uL, &t1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add_d(&t1, 1uL, &t1)) != MP_OKAY) goto LBL_ERR;
} else {
break;
}
}
/* correct overshoot from above or from recurrence */
for (;;) {
if ((err = mp_expt_u32(&t1, b, &t2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_expt_u32(&t1, b, &t2)) != MP_OKAY) goto LBL_ERR;
if (mp_cmp(&t2, &a_) == MP_GT) {
if ((err = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY) goto LBL_ERR;
} else {
break;
}

View File

@ -57,19 +57,13 @@ mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y
}
/* create mu, used for Barrett reduction */
if ((err = mp_init(&mu)) != MP_OKAY) {
goto LBL_M;
}
if ((err = mp_init(&mu)) != MP_OKAY) goto LBL_M;
if (redmode == 0) {
if ((err = mp_reduce_setup(&mu, P)) != MP_OKAY) {
goto LBL_MU;
}
if ((err = mp_reduce_setup(&mu, P)) != MP_OKAY) goto LBL_MU;
redux = mp_reduce;
} else {
if ((err = mp_reduce_2k_setup_l(P, &mu)) != MP_OKAY) {
goto LBL_MU;
}
if ((err = mp_reduce_2k_setup_l(P, &mu)) != MP_OKAY) goto LBL_MU;
redux = mp_reduce_2k_l;
}
@ -81,46 +75,32 @@ mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y
* The first half of the table is not
* computed though accept for M[0] and M[1]
*/
if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
goto LBL_MU;
}
if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) goto LBL_MU;
/* compute the value at M[1<<(winsize-1)] by squaring
* M[1] (winsize-1) times
*/
if ((err = mp_copy(&M[1], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) {
goto LBL_MU;
}
if ((err = mp_copy(&M[1], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_MU;
for (x = 0; x < (winsize - 1); x++) {
/* square it */
if ((err = mp_sqr(&M[(size_t)1 << (winsize - 1)],
&M[(size_t)1 << (winsize - 1)])) != MP_OKAY) {
goto LBL_MU;
}
&M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_MU;
/* reduce modulo P */
if ((err = redux(&M[(size_t)1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
goto LBL_MU;
}
if ((err = redux(&M[(size_t)1 << (winsize - 1)], P, &mu)) != MP_OKAY) goto LBL_MU;
}
/* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
* for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
*/
for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
if ((err = mp_mul(&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
goto LBL_MU;
}
if ((err = redux(&M[x], P, &mu)) != MP_OKAY) {
goto LBL_MU;
}
if ((err = mp_mul(&M[x - 1], &M[1], &M[x])) != MP_OKAY) goto LBL_MU;
if ((err = redux(&M[x], P, &mu)) != MP_OKAY) goto LBL_MU;
}
/* setup result */
if ((err = mp_init(&res)) != MP_OKAY) {
goto LBL_MU;
}
if ((err = mp_init(&res)) != MP_OKAY) goto LBL_MU;
mp_set(&res, 1uL);
/* set initial mode and bit cnt */
@ -158,12 +138,8 @@ mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y
/* if the bit is zero and mode == 1 then we square */
if ((mode == 1) && (y == 0)) {
if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, &mu)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES;
if ((err = redux(&res, P, &mu)) != MP_OKAY) goto LBL_RES;
continue;
}
@ -175,21 +151,13 @@ mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y
/* ok window is filled so square as required and multiply */
/* square first */
for (x = 0; x < winsize; x++) {
if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, &mu)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES;
if ((err = redux(&res, P, &mu)) != MP_OKAY) goto LBL_RES;
}
/* then multiply */
if ((err = mp_mul(&res, &M[bitbuf], &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, &mu)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_mul(&res, &M[bitbuf], &res)) != MP_OKAY) goto LBL_RES;
if ((err = redux(&res, P, &mu)) != MP_OKAY) goto LBL_RES;
/* empty window and reset */
bitcpy = 0;
@ -202,22 +170,14 @@ mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y
if ((mode == 2) && (bitcpy > 0)) {
/* square then multiply if the bit is set */
for (x = 0; x < bitcpy; x++) {
if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, &mu)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES;
if ((err = redux(&res, P, &mu)) != MP_OKAY) goto LBL_RES;
bitbuf <<= 1;
if ((bitbuf & (1 << winsize)) != 0) {
/* then multiply */
if ((err = mp_mul(&res, &M[1], &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, &mu)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_mul(&res, &M[1], &res)) != MP_OKAY) goto LBL_RES;
if ((err = redux(&res, P, &mu)) != MP_OKAY) goto LBL_RES;
}
}
}

View File

@ -73,9 +73,7 @@ mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_i
if (redmode == 0) {
if (MP_HAS(MP_MONTGOMERY_SETUP)) {
/* now setup montgomery */
if ((err = mp_montgomery_setup(P, &mp)) != MP_OKAY) {
goto LBL_M;
}
if ((err = mp_montgomery_setup(P, &mp)) != MP_OKAY) goto LBL_M;
} else {
err = MP_VAL;
goto LBL_M;
@ -104,9 +102,7 @@ mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_i
}
} else if (MP_HAS(MP_REDUCE_2K_SETUP) && MP_HAS(MP_REDUCE_2K)) {
/* setup DR reduction for moduli of the form 2**k - b */
if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
goto LBL_M;
}
if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) goto LBL_M;
redux = mp_reduce_2k;
} else {
err = MP_VAL;
@ -114,9 +110,7 @@ mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_i
}
/* setup result */
if ((err = mp_init_size(&res, P->alloc)) != MP_OKAY) {
goto LBL_M;
}
if ((err = mp_init_size(&res, P->alloc)) != MP_OKAY) goto LBL_M;
/* create M table
*
@ -128,47 +122,31 @@ mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_i
if (redmode == 0) {
if (MP_HAS(MP_MONTGOMERY_CALC_NORMALIZATION)) {
/* now we need R mod m */
if ((err = mp_montgomery_calc_normalization(&res, P)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_montgomery_calc_normalization(&res, P)) != MP_OKAY) goto LBL_RES;
/* now set M[1] to G * R mod m */
if ((err = mp_mulmod(G, &res, P, &M[1])) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_mulmod(G, &res, P, &M[1])) != MP_OKAY) goto LBL_RES;
} else {
err = MP_VAL;
goto LBL_RES;
}
} else {
mp_set(&res, 1uL);
if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) goto LBL_RES;
}
/* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
if ((err = mp_copy(&M[1], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_copy(&M[1], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_RES;
for (x = 0; x < (winsize - 1); x++) {
if ((err = mp_sqr(&M[(size_t)1 << (winsize - 1)], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&M[(size_t)1 << (winsize - 1)], P, mp)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_sqr(&M[(size_t)1 << (winsize - 1)], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_RES;
if ((err = redux(&M[(size_t)1 << (winsize - 1)], P, mp)) != MP_OKAY) goto LBL_RES;
}
/* create upper table */
for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
if ((err = mp_mul(&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&M[x], P, mp)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_mul(&M[x - 1], &M[1], &M[x])) != MP_OKAY) goto LBL_RES;
if ((err = redux(&M[x], P, mp)) != MP_OKAY) goto LBL_RES;
}
/* set initial mode and bit cnt */
@ -206,12 +184,8 @@ mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_i
/* if the bit is zero and mode == 1 then we square */
if ((mode == 1) && (y == 0)) {
if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES;
if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES;
continue;
}
@ -223,21 +197,13 @@ mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_i
/* ok window is filled so square as required and multiply */
/* square first */
for (x = 0; x < winsize; x++) {
if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES;
if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES;
}
/* then multiply */
if ((err = mp_mul(&res, &M[bitbuf], &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_mul(&res, &M[bitbuf], &res)) != MP_OKAY) goto LBL_RES;
if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES;
/* empty window and reset */
bitcpy = 0;
@ -250,23 +216,15 @@ mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_i
if ((mode == 2) && (bitcpy > 0)) {
/* square then multiply if the bit is set */
for (x = 0; x < bitcpy; x++) {
if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES;
if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES;
/* get next bit of the window */
bitbuf <<= 1;
if ((bitbuf & (1 << winsize)) != 0) {
/* then multiply */
if ((err = mp_mul(&res, &M[1], &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = mp_mul(&res, &M[1], &res)) != MP_OKAY) goto LBL_RES;
if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES;
}
}
}
@ -278,9 +236,7 @@ mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_i
* to reduce one more time to cancel out the factor
* of R.
*/
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES;
}
/* swap res with Y */

View File

@ -26,14 +26,10 @@ mp_err s_mp_invmod_fast(const mp_int *a, const mp_int *b, mp_int *c)
}
/* x == modulus, y == value to invert */
if ((err = mp_copy(b, &x)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(b, &x)) != MP_OKAY) goto LBL_ERR;
/* we need y = |a| */
if ((err = mp_mod(a, b, &y)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mod(a, b, &y)) != MP_OKAY) goto LBL_ERR;
/* if one of x,y is zero return an error! */
if (MP_IS_ZERO(&x) || MP_IS_ZERO(&y)) {
@ -42,71 +38,49 @@ mp_err s_mp_invmod_fast(const mp_int *a, const mp_int *b, mp_int *c)
}
/* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
if ((err = mp_copy(&x, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&y, &v)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&x, &u)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_copy(&y, &v)) != MP_OKAY) goto LBL_ERR;
mp_set(&D, 1uL);
top:
/* 4. while u is even do */
while (MP_IS_EVEN(&u)) {
/* 4.1 u = u/2 */
if ((err = mp_div_2(&u, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2(&u, &u)) != MP_OKAY) goto LBL_ERR;
/* 4.2 if B is odd then */
if (MP_IS_ODD(&B)) {
if ((err = mp_sub(&B, &x, &B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&B, &x, &B)) != MP_OKAY) goto LBL_ERR;
}
/* B = B/2 */
if ((err = mp_div_2(&B, &B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2(&B, &B)) != MP_OKAY) goto LBL_ERR;
}
/* 5. while v is even do */
while (MP_IS_EVEN(&v)) {
/* 5.1 v = v/2 */
if ((err = mp_div_2(&v, &v)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2(&v, &v)) != MP_OKAY) goto LBL_ERR;
/* 5.2 if D is odd then */
if (MP_IS_ODD(&D)) {
/* D = (D-x)/2 */
if ((err = mp_sub(&D, &x, &D)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&D, &x, &D)) != MP_OKAY) goto LBL_ERR;
}
/* D = D/2 */
if ((err = mp_div_2(&D, &D)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2(&D, &D)) != MP_OKAY) goto LBL_ERR;
}
/* 6. if u >= v then */
if (mp_cmp(&u, &v) != MP_LT) {
/* u = u - v, B = B - D */
if ((err = mp_sub(&u, &v, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&u, &v, &u)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_sub(&B, &D, &B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&B, &D, &B)) != MP_OKAY) goto LBL_ERR;
} else {
/* v - v - u, D = D - B */
if ((err = mp_sub(&v, &u, &v)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&v, &u, &v)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_sub(&D, &B, &D)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&D, &B, &D)) != MP_OKAY) goto LBL_ERR;
}
/* if not zero goto step 4 */
@ -125,16 +99,12 @@ top:
/* b is now the inverse */
neg = a->sign;
while (D.sign == MP_NEG) {
if ((err = mp_add(&D, b, &D)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&D, b, &D)) != MP_OKAY) goto LBL_ERR;
}
/* too big */
while (mp_cmp_mag(&D, b) != MP_LT) {
if ((err = mp_sub(&D, b, &D)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&D, b, &D)) != MP_OKAY) goto LBL_ERR;
}
mp_exch(&D, c);

View File

@ -21,12 +21,8 @@ mp_err s_mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c)
}
/* x = a, y = b */
if ((err = mp_mod(a, b, &x)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(b, &y)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mod(a, b, &x)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_copy(b, &y)) != MP_OKAY) goto LBL_ERR;
/* 2. [modified] if x,y are both even then return an error! */
if (MP_IS_EVEN(&x) && MP_IS_EVEN(&y)) {
@ -35,12 +31,8 @@ mp_err s_mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c)
}
/* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
if ((err = mp_copy(&x, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&y, &v)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&x, &u)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_copy(&y, &v)) != MP_OKAY) goto LBL_ERR;
mp_set(&A, 1uL);
mp_set(&D, 1uL);
@ -48,80 +40,50 @@ top:
/* 4. while u is even do */
while (MP_IS_EVEN(&u)) {
/* 4.1 u = u/2 */
if ((err = mp_div_2(&u, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2(&u, &u)) != MP_OKAY) goto LBL_ERR;
/* 4.2 if A or B is odd then */
if (MP_IS_ODD(&A) || MP_IS_ODD(&B)) {
/* A = (A+y)/2, B = (B-x)/2 */
if ((err = mp_add(&A, &y, &A)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&B, &x, &B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&A, &y, &A)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_sub(&B, &x, &B)) != MP_OKAY) goto LBL_ERR;
}
/* A = A/2, B = B/2 */
if ((err = mp_div_2(&A, &A)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2(&B, &B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2(&A, &A)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_div_2(&B, &B)) != MP_OKAY) goto LBL_ERR;
}
/* 5. while v is even do */
while (MP_IS_EVEN(&v)) {
/* 5.1 v = v/2 */
if ((err = mp_div_2(&v, &v)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2(&v, &v)) != MP_OKAY) goto LBL_ERR;
/* 5.2 if C or D is odd then */
if (MP_IS_ODD(&C) || MP_IS_ODD(&D)) {
/* C = (C+y)/2, D = (D-x)/2 */
if ((err = mp_add(&C, &y, &C)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&D, &x, &D)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&C, &y, &C)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_sub(&D, &x, &D)) != MP_OKAY) goto LBL_ERR;
}
/* C = C/2, D = D/2 */
if ((err = mp_div_2(&C, &C)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2(&D, &D)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2(&C, &C)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_div_2(&D, &D)) != MP_OKAY) goto LBL_ERR;
}
/* 6. if u >= v then */
if (mp_cmp(&u, &v) != MP_LT) {
/* u = u - v, A = A - C, B = B - D */
if ((err = mp_sub(&u, &v, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&u, &v, &u)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_sub(&A, &C, &A)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&A, &C, &A)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_sub(&B, &D, &B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&B, &D, &B)) != MP_OKAY) goto LBL_ERR;
} else {
/* v - v - u, C = C - A, D = D - B */
if ((err = mp_sub(&v, &u, &v)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&v, &u, &v)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_sub(&C, &A, &C)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&C, &A, &C)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_sub(&D, &B, &D)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&D, &B, &D)) != MP_OKAY) goto LBL_ERR;
}
/* if not zero goto step 4 */
@ -139,16 +101,12 @@ top:
/* if its too low */
while (mp_cmp_d(&C, 0uL) == MP_LT) {
if ((err = mp_add(&C, b, &C)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&C, b, &C)) != MP_OKAY) goto LBL_ERR;
}
/* too big */
while (mp_cmp_mag(&C, b) != MP_LT) {
if ((err = mp_sub(&C, b, &C)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&C, b, &C)) != MP_OKAY) goto LBL_ERR;
}
/* C is now the inverse */

View File

@ -43,50 +43,39 @@ mp_err s_mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c)
B = MP_MIN(a->used, b->used) / 3;
/** a = a2 * x^2 + a1 * x + a0; */
if ((err = mp_init_size(&a0, B)) != MP_OKAY) {
goto LBL_ERRa0;
}
if ((err = mp_init_size(&a0, B)) != MP_OKAY) goto LBL_ERRa0;
for (count = 0; count < B; count++) {
a0.dp[count] = a->dp[count];
a0.used++;
}
mp_clamp(&a0);
if ((err = mp_init_size(&a1, B)) != MP_OKAY) {
goto LBL_ERRa1;
}
if ((err = mp_init_size(&a1, B)) != MP_OKAY) goto LBL_ERRa1;
for (; count < (2 * B); count++) {
a1.dp[count - B] = a->dp[count];
a1.used++;
}
mp_clamp(&a1);
if ((err = mp_init_size(&a2, B + (a->used - (3 * B)))) != MP_OKAY) {
goto LBL_ERRa2;
}
if ((err = mp_init_size(&a2, B + (a->used - (3 * B)))) != MP_OKAY) goto LBL_ERRa2;
for (; count < a->used; count++) {
a2.dp[count - (2 * B)] = a->dp[count];
a2.used++;
}
/** b = b2 * x^2 + b1 * x + b0; */
if ((err = mp_init_size(&b0, B)) != MP_OKAY) {
goto LBL_ERRb0;
}
if ((err = mp_init_size(&b0, B)) != MP_OKAY) goto LBL_ERRb0;
for (count = 0; count < B; count++) {
b0.dp[count] = b->dp[count];
b0.used++;
}
mp_clamp(&b0);
if ((err = mp_init_size(&b1, B)) != MP_OKAY) {
goto LBL_ERRb1;
}
if ((err = mp_init_size(&b1, B)) != MP_OKAY) goto LBL_ERRb1;
for (; count < (2 * B); count++) {
b1.dp[count - B] = b->dp[count];
b1.used++;
}
mp_clamp(&b1);
if ((err = mp_init_size(&b2, B + (b->used - (3 * B)))) != MP_OKAY) {
goto LBL_ERRb2;
}
if ((err = mp_init_size(&b2, B + (b->used - (3 * B)))) != MP_OKAY) goto LBL_ERRb2;
for (; count < b->used; count++) {
b2.dp[count - (2 * B)] = b->dp[count];
b2.used++;
@ -94,158 +83,111 @@ mp_err s_mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c)
/** \\ S1 = (a2+a1+a0) * (b2+b1+b0); */
/** T1 = a2 + a1; */
if ((err = mp_add(&a2, &a1, &T1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&a2, &a1, &T1)) != MP_OKAY) goto LBL_ERR;
/** S2 = T1 + a0; */
if ((err = mp_add(&T1, &a0, &S2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&T1, &a0, &S2)) != MP_OKAY) goto LBL_ERR;
/** c = b2 + b1; */
if ((err = mp_add(&b2, &b1, c)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&b2, &b1, c)) != MP_OKAY) goto LBL_ERR;
/** S1 = c + b0; */
if ((err = mp_add(c, &b0, &S1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(c, &b0, &S1)) != MP_OKAY) goto LBL_ERR;
/** S1 = S1 * S2; */
if ((err = mp_mul(&S1, &S2, &S1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(&S1, &S2, &S1)) != MP_OKAY) goto LBL_ERR;
/** \\S2 = (4*a2+2*a1+a0) * (4*b2+2*b1+b0); */
/** T1 = T1 + a2; */
if ((err = mp_add(&T1, &a2, &T1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&T1, &a2, &T1)) != MP_OKAY) goto LBL_ERR;
/** T1 = T1 << 1; */
if ((err = mp_mul_2(&T1, &T1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul_2(&T1, &T1)) != MP_OKAY) goto LBL_ERR;
/** T1 = T1 + a0; */
if ((err = mp_add(&T1, &a0, &T1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&T1, &a0, &T1)) != MP_OKAY) goto LBL_ERR;
/** c = c + b2; */
if ((err = mp_add(c, &b2, c)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(c, &b2, c)) != MP_OKAY) goto LBL_ERR;
/** c = c << 1; */
if ((err = mp_mul_2(c, c)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul_2(c, c)) != MP_OKAY) goto LBL_ERR;
/** c = c + b0; */
if ((err = mp_add(c, &b0, c)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(c, &b0, c)) != MP_OKAY) goto LBL_ERR;
/** S2 = T1 * c; */
if ((err = mp_mul(&T1, c, &S2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(&T1, c, &S2)) != MP_OKAY) goto LBL_ERR;
/** \\S3 = (a2-a1+a0) * (b2-b1+b0); */
/** a1 = a2 - a1; */
if ((err = mp_sub(&a2, &a1, &a1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&a2, &a1, &a1)) != MP_OKAY) goto LBL_ERR;
/** a1 = a1 + a0; */
if ((err = mp_add(&a1, &a0, &a1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&a1, &a0, &a1)) != MP_OKAY) goto LBL_ERR;
/** b1 = b2 - b1; */
if ((err = mp_sub(&b2, &b1, &b1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&b2, &b1, &b1)) != MP_OKAY) goto LBL_ERR;
/** b1 = b1 + b0; */
if ((err = mp_add(&b1, &b0, &b1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&b1, &b0, &b1)) != MP_OKAY) goto LBL_ERR;
/** a1 = a1 * b1; */
if ((err = mp_mul(&a1, &b1, &a1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(&a1, &b1, &a1)) != MP_OKAY) goto LBL_ERR;
/** b1 = a2 * b2; */
if ((err = mp_mul(&a2, &b2, &b1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(&a2, &b2, &b1)) != MP_OKAY) goto LBL_ERR;
/** \\S2 = (S2 - S3)/3; */
/** S2 = S2 - a1; */
if ((err = mp_sub(&S2, &a1, &S2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&S2, &a1, &S2)) != MP_OKAY) goto LBL_ERR;
/** S2 = S2 / 3; \\ this is an exact division */
if ((err = mp_div_3(&S2, &S2, NULL)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_3(&S2, &S2, NULL)) != MP_OKAY) goto LBL_ERR;
/** a1 = S1 - a1; */
if ((err = mp_sub(&S1, &a1, &a1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&S1, &a1, &a1)) != MP_OKAY) goto LBL_ERR;
/** a1 = a1 >> 1; */
if ((err = mp_div_2(&a1, &a1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2(&a1, &a1)) != MP_OKAY) goto LBL_ERR;
/** a0 = a0 * b0; */
if ((err = mp_mul(&a0, &b0, &a0)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(&a0, &b0, &a0)) != MP_OKAY) goto LBL_ERR;
/** S1 = S1 - a0; */
if ((err = mp_sub(&S1, &a0, &S1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&S1, &a0, &S1)) != MP_OKAY) goto LBL_ERR;
/** S2 = S2 - S1; */
if ((err = mp_sub(&S2, &S1, &S2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&S2, &S1, &S2)) != MP_OKAY) goto LBL_ERR;
/** S2 = S2 >> 1; */
if ((err = mp_div_2(&S2, &S2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2(&S2, &S2)) != MP_OKAY) goto LBL_ERR;
/** S1 = S1 - a1; */
if ((err = mp_sub(&S1, &a1, &S1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&S1, &a1, &S1)) != MP_OKAY) goto LBL_ERR;
/** S1 = S1 - b1; */
if ((err = mp_sub(&S1, &b1, &S1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&S1, &b1, &S1)) != MP_OKAY) goto LBL_ERR;
/** T1 = b1 << 1; */
if ((err = mp_mul_2(&b1, &T1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul_2(&b1, &T1)) != MP_OKAY) goto LBL_ERR;
/** S2 = S2 - T1; */
if ((err = mp_sub(&S2, &T1, &S2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&S2, &T1, &S2)) != MP_OKAY) goto LBL_ERR;
/** a1 = a1 - S2; */
if ((err = mp_sub(&a1, &S2, &a1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&a1, &S2, &a1)) != MP_OKAY) goto LBL_ERR;
/** P = b1*x^4+ S2*x^3+ S1*x^2+ a1*x + a0; */
if ((err = mp_lshd(&b1, 4 * B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_lshd(&S2, 3 * B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&b1, &S2, &b1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_lshd(&S1, 2 * B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&b1, &S1, &b1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_lshd(&a1, 1 * B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&b1, &a1, &b1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&b1, &a0, c)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_lshd(&b1, 4 * B)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_lshd(&S2, 3 * B)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_add(&b1, &S2, &b1)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_lshd(&S1, 2 * B)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_add(&b1, &S1, &b1)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_lshd(&a1, 1 * B)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_add(&b1, &a1, &b1)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_add(&b1, &a0, c)) != MP_OKAY) goto LBL_ERR;
/** a * b - P */

View File

@ -34,17 +34,13 @@ mp_err s_mp_toom_sqr(const mp_int *a, mp_int *b)
B = a->used / 3;
/** a = a2 * x^2 + a1 * x + a0; */
if ((err = mp_init_size(&a0, B)) != MP_OKAY) {
goto LBL_ERRa0;
}
if ((err = mp_init_size(&a0, B)) != MP_OKAY) goto LBL_ERRa0;
a0.used = B;
if ((err = mp_init_size(&a1, B)) != MP_OKAY) {
goto LBL_ERRa1;
}
if ((err = mp_init_size(&a1, B)) != MP_OKAY) goto LBL_ERRa1;
a1.used = B;
if ((err = mp_init_size(&a2, B + (a->used - (3 * B)))) != MP_OKAY) {
goto LBL_ERRa2;
}
if ((err = mp_init_size(&a2, B + (a->used - (3 * B)))) != MP_OKAY) goto LBL_ERRa2;
tmpa = a->dp;
tmpc = a0.dp;
for (count = 0; count < B; count++) {
@ -63,119 +59,74 @@ mp_err s_mp_toom_sqr(const mp_int *a, mp_int *b)
mp_clamp(&a1);
/** S0 = a0^2; */
if ((err = mp_sqr(&a0, &S0)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sqr(&a0, &S0)) != MP_OKAY) goto LBL_ERR;
/** \\S1 = (a2 + a1 + a0)^2 */
/** \\S2 = (a2 - a1 + a0)^2 */
/** \\S1 = a0 + a2; */
/** a0 = a0 + a2; */
if ((err = mp_add(&a0, &a2, &a0)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&a0, &a2, &a0)) != MP_OKAY) goto LBL_ERR;
/** \\S2 = S1 - a1; */
/** b = a0 - a1; */
if ((err = mp_sub(&a0, &a1, b)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&a0, &a1, b)) != MP_OKAY) goto LBL_ERR;
/** \\S1 = S1 + a1; */
/** a0 = a0 + a1; */
if ((err = mp_add(&a0, &a1, &a0)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&a0, &a1, &a0)) != MP_OKAY) goto LBL_ERR;
/** \\S1 = S1^2; */
/** a0 = a0^2; */
if ((err = mp_sqr(&a0, &a0)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sqr(&a0, &a0)) != MP_OKAY) goto LBL_ERR;
/** \\S2 = S2^2; */
/** b = b^2; */
if ((err = mp_sqr(b, b)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sqr(b, b)) != MP_OKAY) goto LBL_ERR;
/** \\ S3 = 2 * a1 * a2 */
/** \\S3 = a1 * a2; */
/** a1 = a1 * a2; */
if ((err = mp_mul(&a1, &a2, &a1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(&a1, &a2, &a1)) != MP_OKAY) goto LBL_ERR;
/** \\S3 = S3 << 1; */
/** a1 = a1 << 1; */
if ((err = mp_mul_2(&a1, &a1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul_2(&a1, &a1)) != MP_OKAY) goto LBL_ERR;
/** \\S4 = a2^2; */
/** a2 = a2^2; */
if ((err = mp_sqr(&a2, &a2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sqr(&a2, &a2)) != MP_OKAY) goto LBL_ERR;
/** \\ tmp = (S1 + S2)/2 */
/** \\tmp = S1 + S2; */
/** b = a0 + b; */
if ((err = mp_add(&a0, b, b)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&a0, b, b)) != MP_OKAY) goto LBL_ERR;
/** \\tmp = tmp >> 1; */
/** b = b >> 1; */
if ((err = mp_div_2(b, b)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2(b, b)) != MP_OKAY) goto LBL_ERR;
/** \\ S1 = S1 - tmp - S3 */
/** \\S1 = S1 - tmp; */
/** a0 = a0 - b; */
if ((err = mp_sub(&a0, b, &a0)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&a0, b, &a0)) != MP_OKAY) goto LBL_ERR;
/** \\S1 = S1 - S3; */
/** a0 = a0 - a1; */
if ((err = mp_sub(&a0, &a1, &a0)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&a0, &a1, &a0)) != MP_OKAY) goto LBL_ERR;
/** \\S2 = tmp - S4 -S0 */
/** \\S2 = tmp - S4; */
/** b = b - a2; */
if ((err = mp_sub(b, &a2, b)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(b, &a2, b)) != MP_OKAY) goto LBL_ERR;
/** \\S2 = S2 - S0; */
/** b = b - S0; */
if ((err = mp_sub(b, &S0, b)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(b, &S0, b)) != MP_OKAY) goto LBL_ERR;
/** \\P = S4*x^4 + S3*x^3 + S2*x^2 + S1*x + S0; */
/** P = a2*x^4 + a1*x^3 + b*x^2 + a0*x + S0; */
if ((err = mp_lshd(&a2, 4 * B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_lshd(&a1, 3 * B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_lshd(b, 2 * B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_lshd(&a0, 1 * B)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&a2, &a1, &a2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&a2, b, b)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(b, &a0, b)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(b, &S0, b)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_lshd(&a2, 4 * B)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_lshd(&a1, 3 * B)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_lshd(b, 2 * B)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_lshd(&a0, 1 * B)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_add(&a2, &a1, &a2)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_add(&a2, b, b)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_add(b, &a0, b)) != MP_OKAY) goto LBL_ERR;
if ((err = mp_add(b, &S0, b)) != MP_OKAY) goto LBL_ERR;
/** a^2 - P */