bugfix in bn_mp_mul_si. Ouch! strong Lucas_selfridge test switched back on
This commit is contained in:
parent
63dc065dc8
commit
6ee0829d62
@ -19,14 +19,16 @@
|
|||||||
int mp_mul_si(const mp_int *a, long d, mp_int *c)
|
int mp_mul_si(const mp_int *a, long d, mp_int *c)
|
||||||
{
|
{
|
||||||
mp_int t;
|
mp_int t;
|
||||||
int err;
|
int err, neg = 0;
|
||||||
|
|
||||||
if ((err = mp_init(&t)) != MP_OKAY) {
|
if ((err = mp_init(&t)) != MP_OKAY) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if (d < 0) {
|
if (d < 0) {
|
||||||
|
neg = 1;
|
||||||
d = -d;
|
d = -d;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mp_digit might be smaller than a long, which excludes
|
// mp_digit might be smaller than a long, which excludes
|
||||||
// the use of mp_mul_d() here.
|
// the use of mp_mul_d() here.
|
||||||
if ((err = mp_set_int(&t, (unsigned long) d)) != MP_OKAY) {
|
if ((err = mp_set_int(&t, (unsigned long) d)) != MP_OKAY) {
|
||||||
@ -35,7 +37,7 @@ int mp_mul_si(const mp_int *a, long d, mp_int *c)
|
|||||||
if ((err = mp_mul(a, &t, c)) != MP_OKAY) {
|
if ((err = mp_mul(a, &t, c)) != MP_OKAY) {
|
||||||
goto LBL_MPMULSI_ERR;
|
goto LBL_MPMULSI_ERR;
|
||||||
}
|
}
|
||||||
if (d < 0) {
|
if (neg == 1) {
|
||||||
c->sign = (a->sign == MP_NEG) ? MP_ZPOS: MP_NEG;
|
c->sign = (a->sign == MP_NEG) ? MP_ZPOS: MP_NEG;
|
||||||
}
|
}
|
||||||
LBL_MPMULSI_ERR:
|
LBL_MPMULSI_ERR:
|
||||||
|
@ -116,15 +116,15 @@ int mp_prime_is_prime(const mp_int *a, int t, int *result)
|
|||||||
t = 8;
|
t = 8;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// switched off, failed a test, said 2^1119 + 53 (a cert. prime) is not prime
|
// commented out for testing purposes
|
||||||
#ifdef LTM_USE_STRONG_LUCAS_SELFRIDGE_TEST
|
//#ifdef LTM_USE_STRONG_LUCAS_SELFRIDGE_TEST
|
||||||
if ((err = mp_prime_strong_lucas_selfridge(a, &res)) != MP_OKAY) {
|
if ((err = mp_prime_strong_lucas_selfridge(a, &res)) != MP_OKAY) {
|
||||||
goto LBL_B;
|
goto LBL_B;
|
||||||
}
|
}
|
||||||
if (res == MP_NO) {
|
if (res == MP_NO) {
|
||||||
goto LBL_B;
|
goto LBL_B;
|
||||||
}
|
}
|
||||||
#endif
|
//#endif
|
||||||
// commented out for testing purposes
|
// commented out for testing purposes
|
||||||
//#ifdef LTM_USE_FROBENIUS_UNDERWOOD_TEST
|
//#ifdef LTM_USE_FROBENIUS_UNDERWOOD_TEST
|
||||||
if ((err = mp_prime_frobenius_underwood(a, &res)) != MP_OKAY) {
|
if ((err = mp_prime_frobenius_underwood(a, &res)) != MP_OKAY) {
|
||||||
|
@ -35,8 +35,8 @@
|
|||||||
*/
|
*/
|
||||||
int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result)
|
int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result)
|
||||||
{
|
{
|
||||||
// TODO: choose better variable names! "Dz" and "dz"? Really?
|
// TODO: choose better variable names!
|
||||||
mp_int Dz, gcd, Np1, dz, Uz, Vz, U2mz, V2mz, Qmz, Q2mz, Qkdz, T1z, T2z, T3z, T4z, Q2kdz;
|
mp_int Dz, gcd, Np1, Uz, Vz, U2mz, V2mz, Qmz, Q2mz, Qkdz, T1z, T2z, T3z, T4z, Q2kdz;
|
||||||
// TODO: Some of them need the full 32 bit, hence the (temporary) exclusion of MP_8BIT
|
// TODO: Some of them need the full 32 bit, hence the (temporary) exclusion of MP_8BIT
|
||||||
int32_t D, Ds, J, sign, P, Q, r, s, u, Nbits;
|
int32_t D, Ds, J, sign, P, Q, r, s, u, Nbits;
|
||||||
int e = MP_OKAY;
|
int e = MP_OKAY;
|
||||||
@ -52,14 +52,14 @@ int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result)
|
|||||||
included.
|
included.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
D = 5;
|
if ((e = mp_init_multi(&Dz, &gcd, &Np1, &Uz, &Vz, &U2mz, &V2mz, &Qmz, &Q2mz, &Qkdz, &T1z, &T2z, &T3z, &T4z, &Q2kdz,
|
||||||
sign = 1;
|
|
||||||
|
|
||||||
if ((e = mp_init_multi(&Dz, &gcd, &Np1, &dz, &Uz, &Vz, &U2mz, &V2mz, &Qmz, &Q2mz, &Qkdz, &T1z, &T2z, &T3z, &T4z, &Q2kdz,
|
|
||||||
NULL)) != MP_OKAY) {
|
NULL)) != MP_OKAY) {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
D = 5;
|
||||||
|
sign = 1;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Ds = sign * D;
|
Ds = sign * D;
|
||||||
sign = -sign;
|
sign = -sign;
|
||||||
@ -72,15 +72,17 @@ int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result)
|
|||||||
/* if 1 < GCD < N then N is composite with factor "D", and
|
/* if 1 < GCD < N then N is composite with factor "D", and
|
||||||
Jacobi(D,N) is technically undefined (but often returned
|
Jacobi(D,N) is technically undefined (but often returned
|
||||||
as zero). */
|
as zero). */
|
||||||
if ((gcd.used > 1 || gcd.dp[0] > 1) && mp_cmp(&gcd,a) == MP_LT) {
|
if ( mp_cmp_d(&gcd,1u) == MP_GT && mp_cmp(&gcd,a) == MP_LT) {
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
|
if (Ds < 0) {
|
||||||
|
Dz.sign = MP_NEG;
|
||||||
|
}
|
||||||
if ((e = mp_kronecker(&Dz, a, &J)) != MP_OKAY) {
|
if ((e = mp_kronecker(&Dz, a, &J)) != MP_OKAY) {
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (J < 0) {
|
if (J == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
D += 2;
|
D += 2;
|
||||||
@ -124,19 +126,17 @@ int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result)
|
|||||||
Baillie-PSW test based on the strong Lucas-Selfridge test
|
Baillie-PSW test based on the strong Lucas-Selfridge test
|
||||||
should be more reliable. */
|
should be more reliable. */
|
||||||
|
|
||||||
if ((e = mp_add_d(a,1,&Np1)) != MP_OKAY) {
|
if ((e = mp_add_d(a,1u,&Np1)) != MP_OKAY) {
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
s = mp_cnt_lsb(&Np1);
|
s = mp_cnt_lsb(&Np1);
|
||||||
|
|
||||||
// this should round towards zero because
|
// this should round towards zero because
|
||||||
// Thomas R. Nicely used GMP's mpz_tdiv_q_2exp()
|
// Thomas R. Nicely used GMP's mpz_tdiv_q_2exp()
|
||||||
// mp_div_2d() does that
|
// and mp_div_2d() is equivalent
|
||||||
if ((e = mp_div_2d(&Np1, s, &dz, NULL)) != MP_OKAY) {
|
if ((e = mp_div_2d(&Np1, s, &Dz, NULL)) != MP_OKAY) {
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* We must now compute U_d and V_d. Since d is odd, the accumulated
|
/* 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
|
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
|
index were even, U and V would be initialized instead to U_0=0
|
||||||
@ -158,22 +158,22 @@ int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result)
|
|||||||
if ((e = mp_set_int(&Qmz, (unsigned long) Q)) != MP_OKAY) {
|
if ((e = mp_set_int(&Qmz, (unsigned long) Q)) != MP_OKAY) {
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
Qmz.sign = MP_NEG;
|
if ((e = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) {
|
||||||
if ((e = mp_set_int(&Q2mz, (unsigned long)(2 * Q))) != MP_OKAY) {
|
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
Q2mz.sign = MP_NEG;
|
|
||||||
/* Initializes calculation of Q^d */
|
/* Initializes calculation of Q^d */
|
||||||
if ((e = mp_set_int(&Qkdz, (unsigned long) Q)) != MP_OKAY) {
|
if ((e = mp_set_int(&Qkdz, (unsigned long) Q)) != MP_OKAY) {
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
|
Qmz.sign = MP_NEG;
|
||||||
|
Q2mz.sign = MP_NEG;
|
||||||
Qkdz.sign = MP_NEG;
|
Qkdz.sign = MP_NEG;
|
||||||
Q = -Q;
|
Q = -Q;
|
||||||
} else {
|
} else {
|
||||||
if ((e = mp_set_int(&Qmz, (unsigned long) Q)) != MP_OKAY) {
|
if ((e = mp_set_int(&Qmz, (unsigned long) Q)) != MP_OKAY) {
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
if ((e = mp_set_int(&Q2mz, (unsigned long)(2 * Q))) != MP_OKAY) {
|
if ((e = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) {
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
/* Initializes calculation of Q^d */
|
/* Initializes calculation of Q^d */
|
||||||
@ -182,8 +182,7 @@ int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Nbits = mp_count_bits(&dz);
|
Nbits = mp_count_bits(&Dz);
|
||||||
|
|
||||||
for (u = 1; u < Nbits; u++) { /* zero bit off, already accounted for */
|
for (u = 1; u < Nbits; u++) { /* zero bit off, already accounted for */
|
||||||
/* Formulas for doubling of indices (carried out mod N). Note that
|
/* Formulas for doubling of indices (carried out mod N). Note that
|
||||||
* the indices denoted as "2m" are actually powers of 2, specifically
|
* the indices denoted as "2m" are actually powers of 2, specifically
|
||||||
@ -220,11 +219,10 @@ int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result)
|
|||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((isset = mp_get_bit(&dz,u)) == MP_VAL) {
|
if ((isset = mp_get_bit(&Dz,u)) == MP_VAL) {
|
||||||
e = isset;
|
e = isset;
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset == MP_YES) {
|
if (isset == MP_YES) {
|
||||||
/* Formulas for addition of indices (carried out mod N);
|
/* Formulas for addition of indices (carried out mod N);
|
||||||
*
|
*
|
||||||
@ -233,6 +231,7 @@ int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result)
|
|||||||
*
|
*
|
||||||
* Be careful with division by 2 (mod N)!
|
* Be careful with division by 2 (mod N)!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((e = mp_mul(&U2mz,&Vz,&T1z)) != MP_OKAY) {
|
if ((e = mp_mul(&U2mz,&Vz,&T1z)) != MP_OKAY) {
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
@ -263,7 +262,7 @@ int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result)
|
|||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
if (Uz.sign == MP_NEG && mp_isodd(&Uz)) {
|
if (Uz.sign == MP_NEG && mp_isodd(&Uz)) {
|
||||||
if ((e = mp_sub_d(&Uz,1,&Uz)) != MP_OKAY) {
|
if ((e = mp_sub_d(&Uz,1u,&Uz)) != MP_OKAY) {
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -278,7 +277,7 @@ int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result)
|
|||||||
if ((e = mp_div_2(&Vz,&Vz)) != MP_OKAY) {
|
if ((e = mp_div_2(&Vz,&Vz)) != MP_OKAY) {
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
if (Vz.sign == MP_NEG) {
|
if (Vz.sign == MP_NEG && mp_isodd(&Vz)) {
|
||||||
if ((e = mp_sub_d(&Vz,1,&Vz)) != MP_OKAY) {
|
if ((e = mp_sub_d(&Vz,1,&Vz)) != MP_OKAY) {
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
@ -337,7 +336,7 @@ int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result)
|
|||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
/* Calculate Q^{d*2^r} for next r (final iteration irrelevant). */
|
/* Calculate Q^{d*2^r} for next r (final iteration irrelevant). */
|
||||||
if (r < s - 1) {
|
if (r < (s - 1)) {
|
||||||
if ((e = mp_sqr(&Qkdz,&Qkdz)) != MP_OKAY) {
|
if ((e = mp_sqr(&Qkdz,&Qkdz)) != MP_OKAY) {
|
||||||
goto LBL_LS_ERR;
|
goto LBL_LS_ERR;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user