742 | 742 |
{
|
743 | 743 |
UV P, V, W, d, s, b;
|
744 | 744 |
|
745 | |
if (n < 7) return (n == 2 || n == 3 || n == 5);
|
|
745 |
if (n < 13) return (n == 2 || n == 3 || n == 5 || n == 7 || n == 11);
|
746 | 746 |
if ((n % 2) == 0 || n == UV_MAX) return 0;
|
747 | 747 |
if (increment < 1 || increment > 256)
|
748 | 748 |
croak("Invalid lucas parameter increment: %"UVuf"\n", increment);
|
|
749 |
|
|
750 |
/* Ensure small primes work with large increments. */
|
|
751 |
if ( (increment >= 16 && n <= 331) || (increment > 148 && n <= 631) )
|
|
752 |
return !!is_prob_prime(n);
|
749 | 753 |
|
750 | 754 |
P = select_extra_strong_parameters(n, increment);
|
751 | 755 |
if (P == 0) return 0;
|
|
913 | 917 |
if (P == 0 && Q == 0) {
|
914 | 918 |
P = -1; Q = 2;
|
915 | 919 |
if (n == 7) P = 1; /* So we don't test kronecker(-7,7) */
|
916 | |
while (k != -1) {
|
|
920 |
do {
|
917 | 921 |
P += 2;
|
918 | 922 |
if (P == 3) P = 5; /* P=3,Q=2 -> D=9-8=1 => k=1, so skip */
|
919 | 923 |
D = P*P-4*Q;
|
920 | 924 |
Du = D >= 0 ? D : -D;
|
921 | 925 |
k = kronecker_su(D, n);
|
922 | |
if (k == 0) return 0;
|
923 | 926 |
if (P == 10001 && is_perfect_square(n)) return 0;
|
924 | |
}
|
|
927 |
} while (k == 1);
|
|
928 |
if (k == 0) return 0;
|
925 | 929 |
/* D=P^2-8 will not be a perfect square */
|
926 | 930 |
if (_XS_get_verbose()) printf("%"UVuf" Frobenius (%"IVdf",%"IVdf") : x^2 - %"IVdf"x + %"IVdf"\n", n, P, Q, P, Q);
|
927 | 931 |
Vcomp = 4;
|
|
931 | 935 |
if (D != 5 && is_perfect_square(Du))
|
932 | 936 |
croak("Frobenius invalid P,Q: (%"IVdf",%"IVdf")", P, Q);
|
933 | 937 |
}
|
934 | |
Pu = P >= 0 ? P : -P;
|
935 | |
Qu = Q >= 0 ? Q : -Q;
|
936 | |
|
937 | |
/* if (n <= Du || n <= Qu || n <= Pu) return !!is_prob_prime(n); */
|
938 | |
if (gcd_ui(n, Pu*Qu*Du) != 1) return 0;
|
|
938 |
Pu = (P >= 0 ? P : -P) % n;
|
|
939 |
Qu = (Q >= 0 ? Q : -Q) % n;
|
|
940 |
|
|
941 |
Qk = gcd_ui(n, Pu*Qu*Du);
|
|
942 |
if (Qk != 1) {
|
|
943 |
if (Qk == n) return !!is_prob_prime(n);
|
|
944 |
return 0;
|
|
945 |
}
|
939 | 946 |
if (k == 0) {
|
940 | 947 |
k = kronecker_su(D, n);
|
941 | 948 |
if (k == 0) return 0;
|
942 | |
Qu = addmod(Qu,Qu,n);
|
943 | |
Vcomp = (k == 1) ? 2 : Q >= 0 ? Qu : n-Qu;
|
|
949 |
if (k == 1) {
|
|
950 |
Vcomp = 2;
|
|
951 |
} else {
|
|
952 |
Qu = addmod(Qu,Qu,n);
|
|
953 |
Vcomp = (Q >= 0) ? Qu : n-Qu;
|
|
954 |
}
|
944 | 955 |
}
|
945 | 956 |
|
946 | 957 |
lucas_seq(&U, &V, &Qk, n, P, Q, n-k);
|