-
Notifications
You must be signed in to change notification settings - Fork 141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(chibi math prime) Miller-Rabin primality test is not correctly implemented #751
Comments
In other news,
And there are well-known formulas for 'totient' and 'aliquot' based on the factorizations that give multiple orders of magnitude speedup (searching for factors is way faster than doing a gcd on every number in the range (gcd takes multiple divisions)).
I think I'll be doing a pull request. |
Hi Roger, thanks very much for the detailed comments and sorry for the slow reply. I had actually been meaning to make the factor optimization you suggest, though had not really thought about optimizing totient or aliquot. I still need to go through the miller rabin code and come up with a suitable test case. |
That may be hard. Unless there's a feature of the test framework to allow sabotaging the innards of the module with |
Non-portable but explicitly setting the state of default-random-source should be deterministic on a given platform. But as you say changing the innards is an option - we can make all of the random-integer calls refer to a random-source from an exported parameter instead of default-random-source, and parameterize that in the tests. |
modular-root-of-one? is replaced with the correct witness tester
no need to go up to sqrt(n), Instead track i^2 and quit when that gets larger than the (remaining) n (i.e., not the original n)
no need to go up to sqrt(n), Instead track i^2 and quit when that gets larger than the (remaining) n (i.e., not the original n)
and done. |
(While I have this swapped in, I thought I'd look at the rest of the module.)
Two aspects of this that are not ideal:
I'll grant that uniformity isn't actually promised but I'm having trouble seeing how a routine like will actually be useful without either a guarantee of uniformity or some kind of statement concerning what the distribution of outcomes is going to be like. And, as it happens, there's a fairly easy way to make this uniform:
it's slower but not that much slower than the current implementation (worst case for numbers < 2^60 is 614889782588491410, (square-free with lots of distinct prime factors, where we seem to be about 3/4 as fast and the expected number of RNG calls is around 8)., and it seems like there ought to be something we can do with the Chinese Remainder Theorem to speed this up.. I'm also pretty sure a similar issue exists with |
The distribution will be skewed by the natural distribution of primes and coprimes - (co)primes coming after longer gaps are more likely. Your approach is probably better, even if slower, but please make it a separate pull request. random-prime is used by the RSA implementation for very large primes, where the slightly skewed distribution is unlikely to be an effective attack vector. |
modular-root-of-one? is replaced with the correct witness tester
no need to go up to sqrt(n), Instead track i^2 and quit when that gets larger than the (remaining) n (i.e., not the original n)
modular-root-of-one? is replaced with the correct witness tester
no need to go up to sqrt(n), Instead track i^2 and quit when that gets larger than the (remaining) n (i.e., not the original n)
(chibi math prime) fix miller-rabin-composite?, factor, etc (issue #751), add factor-alist
(in /lib/chibi/math/prime.scm)
modular-root-of-one?
is not doing the right thing and this will result in further false positives (i.e., numbers deemed prime that actually aren't) beyond what the Miller-Rabin test is normally expected to produce.First of all, the docstring:
does not match up with what the routine is actually doing, which is that it returns true if any of the
a
^(odd
*2^i
) powers encountered are 1 or -1.But what we actually need this to do is return true if either
a
^odd
= 1 (and thence all squares of it are 1 and we're getting no information on square roots of 1) or that we encounter -1 first (and again all squares will be 1). If we encounter 1 first and it's the square of something that's not -1 or 1, then 1 has a third square root, we're not in a field, and so we have a witness,a
, ton
not being prime.An example where
modular-root-of-one?
is going wrong would ben
=15 (neg1
=14,twos
=1,odd
=7) anda
=4,which is an actual witness to 15 not being prime because
a
^7=4 anda
^14=1 (mod 15) and thus we have 4 being a third square root of 1 (along with 1 and 14)Since this routine isn't exported and is only used once, it would probably best for the sake of readability to reverse the sense of it, rename it to
miller-rabin-composite-witness?
, i.e., so that it's returning true when it finds a witness. Meaning we replacewith
in the body of
miller-rabin-composite?
And thenThe text was updated successfully, but these errors were encountered: