Codebase list libmath-prime-util-perl / 77b4caf
Fix some edge cases with frobenius(P,Q) and aes with increment > 3 Dana Jacobsen 8 years ago
2 changed file(s) with 27 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
55
66 - sieve_prime_cluster(low,high[,...]) find prime clusters
77
8 [Misc]
9
10 - Small primes used to return false with is_frobenius_pseudoprime given
11 extra arguments, and with a large increment for aes lucas. Both are
12 unusual cases never used by the main system. Fixed.
813
914 0.53 2015-09-05
1015
742742 {
743743 UV P, V, W, d, s, b;
744744
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);
746746 if ((n % 2) == 0 || n == UV_MAX) return 0;
747747 if (increment < 1 || increment > 256)
748748 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);
749753
750754 P = select_extra_strong_parameters(n, increment);
751755 if (P == 0) return 0;
913917 if (P == 0 && Q == 0) {
914918 P = -1; Q = 2;
915919 if (n == 7) P = 1; /* So we don't test kronecker(-7,7) */
916 while (k != -1) {
920 do {
917921 P += 2;
918922 if (P == 3) P = 5; /* P=3,Q=2 -> D=9-8=1 => k=1, so skip */
919923 D = P*P-4*Q;
920924 Du = D >= 0 ? D : -D;
921925 k = kronecker_su(D, n);
922 if (k == 0) return 0;
923926 if (P == 10001 && is_perfect_square(n)) return 0;
924 }
927 } while (k == 1);
928 if (k == 0) return 0;
925929 /* D=P^2-8 will not be a perfect square */
926930 if (_XS_get_verbose()) printf("%"UVuf" Frobenius (%"IVdf",%"IVdf") : x^2 - %"IVdf"x + %"IVdf"\n", n, P, Q, P, Q);
927931 Vcomp = 4;
931935 if (D != 5 && is_perfect_square(Du))
932936 croak("Frobenius invalid P,Q: (%"IVdf",%"IVdf")", P, Q);
933937 }
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 }
939946 if (k == 0) {
940947 k = kronecker_su(D, n);
941948 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 }
944955 }
945956
946957 lucas_seq(&U, &V, &Qk, n, P, Q, n-k);