Talk:Miller–Rabin primality test

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia

Misc[edit]

To 203.217.64.49:

  • Please direct questions and other discussion on the talk page, not in the article text.
  • Any nonzero integer is uniquely expressible as an odd multiple of a power of 2. This defines k and m from n. In other words, k is the largest integer such that 2k divides n−1.

-- EJ 11:49, 21 Sep 2004 (UTC)

Don't you get some really large numbers when doing this? I'm trying to write a C++ implementation using 1009, which is prime, as a test number, and I just realized that in larger bases you get very big numbers in the second test. For example, , so for the second test you might have

I haven't stepped through it, but as with all crypto stuff involving modular exponentiation, you can keep reducing it at every step. See modular exponentiation. CryptoDerk July 8, 2005 21:25 (UTC)
You do indeed get really big numbers. To quote a step-by-step implementation (see given link[1]):
"[...] probing 24155007172823 for primality requires the evaluation of 1712077503586411 mod 24155007172823." Gulliveig (talk) 04:14, 20 June 2009 (UTC)[reply]
But you won't ever work with a number larger than 24155007172823^2 using modular exponentiation. CRGreathouse (t | c) 07:13, 20 June 2009 (UTC)[reply]

Not sure if this is appropriate here or not, but I just wanted to thank everyone who works on Wikipedia compsci, math, and crypto pages, especially this one. I have learned so much, just wanted to give a hearty thank you for being clear, including psudocode and step by step instructions. Can2016 (talk) 14:23, 1 July 2019 (UTC)[reply]

Ruby Code[edit]

Wouldn't it be much (well, at least a little, compared to the overall complexity) more efficient to store the value of s instead of shifting until we reach n-1 in the example Ruby code? I do not know Ruby, but it is safe to say that shifting the same values repeatedly is less efficient than storing the value of s in the calculation. Coolv(TalkContribs) 19:11, 15 June 2007 (UTC)[reply]

I'd expect that your proposal would have a very small impact on the runtime, because shift operations are cheap compared to modular multiplication. But your proposal would possibly make the code easier to understand. E.g., it seems that even the author of the code was a little confused. The while loop computes all powers for all while the Miller-Rabin test only calls for the cases with . I'd further propose the following modifications: (1) the functions should not be called prime, since it is only a pseudoprimality test; (2) negative integers should not be declarde prime. 85.2.99.96 16:16, 4 July 2007 (UTC)[reply]

Smallest number for which MR test is uncertain?[edit]

Hello. It seems one could establish by brute force that the MR test gives exactly the right answer for all numbers up to some limit (determined by how long you run the MR test on successive integers). Has anyone done a brute force search like that? Or maybe someone has proved that MR test is correct (i.e., reports N is prime iff N is actually prime) for all numbers up to some bound? -- I'm assuming here that the test is computationally deterministic, i.e., if I run the test twice on the same input, I'll always get the same report. Maybe my understanding of the test is flawed. It seems like the "probabilistic" aspect of the test could be explained at greater length. Many thanks to the authors for their work on this article. 207.174.201.18 18:47, 1 February 2006 (UTC)[reply]

You apparently misunderstood something. Probabilistic tests are explained at greater length in Primality test and Randomized algorithm, which are both prominently linked from the first paragraph of the article.
It would help this article to briefly state what is the import of the fact that Rabin's version is probabilistic. Given the subtlety of the concept, it's not enough to give a link and assume the readers can go figure it out for themselves. 207.174.201.18 00:43, 2 February 2006 (UTC)[reply]
Well, people certainly can go follow the link, and at some point it becomes necessary to assume they do, because it is impossible to repeat everything everywhere. But I'll try to put some summary here, you're right that the concept is confusing. -- EJ 20:16, 3 February 2006 (UTC)[reply]
The probabilistic (Rabin's) version of the algorithm, which is discussed in the article, is provably correct for all composites. It is not deterministic, which is (1) the whole point of the definition of a probabilistic test, and (2) obvious from the description of the algorithm: "pick a randomly in the range [1, n − 1]". I have removed the irrelevant, and wrong as stated, sentence from the "Additional information" section, which might have confused you.
What can be said about Rabin's test if it is implemented on a computer which has deterministic hardware? (I.e., assuming random numbers come from a pseudorandom number generator and not from atomic decay or some other "really random" source.) 207.174.201.18 00:43, 2 February 2006 (UTC)[reply]
That's a very good question, but I'm afraid that nobody knows a satisfactory answer. Derandomization and pseudorandom generators are a big topic in theoretical computer science. However, these constructions of PRG tend to be inefficient (and thus rarely used in practice), and they depend on unproven assumptions about computational hardness of certain functions. PRG used in practice are based on heuristic without any serious analysis. -- EJ 20:16, 3 February 2006 (UTC)[reply]
The deterministic (Miller's) version of the algorithm, which is only briefly mentioned in the introduction, is only conjectured to be correct for all composites. As for brute force verification, it is known e.g. that all numbers n < 341,550,071,728,321 which pass the test for bases a = 2, 3, 5, 7, 11, 13, and 17, are prime [1]. As 17 is well below 2(ln n)2, Miller's test is also correct for these n. The Riemann hypothesis was also verified by brute force for a lot of numbers, but I don't know whether anybody tried similarly to verify the Generalized Riemann Hypothesis for quadratic Dirichlet characters, which is what the Miller test depends on. -- EJ 20:22, 1 February 2006 (UTC)[reply]
OK, thanks a lot for these facts. If I understand correctly, the outcome of the MR test is uncertain only if n >= 341,550,071,728,321 (because for numbers less than that, the test reports a number may be prime iff it is indeed prime). I think this aspect should be mentioned in the article itself. 207.174.201.18 00:43, 2 February 2006 (UTC)[reply]
Bear in mind that these results only concern the deterministic version of the algorithm, they are irrelevant for the randomized version. Also, do not take the bound too seriously, that fact that I could quickly find it does not mean that no better bounds are available.
The current (almost nonexistent) coverage of the deterministic algorithm in the article should be expanded, thanks for the tip. -- EJ 20:16, 3 February 2006 (UTC)[reply]
The ANTS'94 paper by Alford, Granville and Pomerance contains some conjectures about the necessary number of tests needed for a deterministic version. I.e., the expect that tests is sufficient, whereas is not sufficient. 24.228.93.22 05:07, 5 February 2006 (UTC)[reply]
Thanks for the pointer. -- EJ 17:30, 11 February 2006 (UTC)[reply]
Bleichenbacher [2] showed that Miller's test holds for n < 1×1016. That's the best result I've seen; I'd love to know of a better result. Sloane's OEIS doesn't have much information about SPSPs above 1×1013 and nothing above 1×1016 as I recall. CRGreathouse (talkcontribs) 02:38, 6 August 2006 (UTC)[reply]
Unfortunately I can not open the PS files mentioned in your source with any of my software. I tried to e-mail him, but he does not seem to work there anymore. In the meantime, if someone could answer, if Bleichenbacher did work with "Jaeschke's" witnesses a={2,3,...,17} or if he had to include more, it would really be appreciated. - I also tried to contact Jaeschke (via a 3rd party) about progresses (i.e. better results). If I succeed with these attempts, I will update the article accordingly. Gulliveig (talk) 12:57, 20 June 2009 (UTC)[reply]
Meanwhile I did some additional research. Apparently Pomerance, Selfridge, and Wagstaff [PSW 1980] calculated the first 4 values of this sequence, Jaeschke [Jaeschke 1993] calculated the next four, and Zhang and Tang [ZT 2003] provided for more values, not listed yet in the sequence. I added them, incl. reference. With those, we are at 318,665,857,834,031,151,167,461 now. Gulliveig (talk) 13:44, 20 June 2009 (UTC)[reply]
There are several freely available PostScript previewers, for example Ghostscript front-ends such as Ghostview or GSview (see [3]). — Emil J. 13:18, 22 June 2009 (UTC)[reply]
You misunderstand Zhang & Tang. They give upper bounds, not values. They did not prove that there are no failures below those numbers, only that they fail at those numbers. CRGreathouse (t | c) 20:17, 20 June 2009 (UTC)[reply]
Thank you, CR. Now, [4] says, that although it is known that MR holds for n < 1016, for larger number "[...] no counterexamples are known and if any exist, they are expected to occur with extremely small probability (i.e., much less than the probability of a hardware error on a computer performing the test)." -- Do you know, if the source of this claim is known and if it stand on solid grounds? -- Shouldn't at least Bleichenbacher's result and possibly also that claim (if it does stand on solid grounds) be included in the article? Gulliveig (talk) 07:22, 21 June 2009 (UTC)[reply]
The MathWorld comment is solid but not relevant here -- it's talking about the BPSW test, not just a Rabin-Miller. Bleichenbacher's results could be included, perhaps along with Feitsma's -- but it may be better to wait for better sourcing, I'm not sure. CRGreathouse (t | c) 00:33, 22 June 2009 (UTC)[reply]

Some imprecise (wrong) formulations ?[edit]

After reading the article I have the suspicion that some of the formulations are very imprecise (or plain wrong :-)):

"Strong Witness": If I understand this correctly, it means that we found a number for which the following equations hold:

for some

To sum up: is a non-trivial square-root of

Are there any non-trivial square roots of 1, if is a prime ? If there are not, then I assume that "Strong Witness" would be better called "Sure Witness" for the compositeness of . Fruther then at the beginning "Let n be an odd prime, ... Then, one of the following must be true for some a" it should be "... Then, one of the following must be true for EVERY a ..."

Is the above correct ?

213.70.137.66 17:49, 14 February 2006 (UTC)[reply]

You're right that there aren't non-trivial square roots of 1 mod prime p. If x2 = 1 (mod p), then (x-1)(x+1) = 0 (mod p). If x is neither 1 nor -1 mod p, neither x-1 or x+1 is zero mod p, which means we have a nontrivial factorization of p, which is of course impossible. This is how we can claim that taking square roots repeatedly will either always yield 1 or eventually yield -1. In fact, as the pseudocode shows, any failure of the conditions proves compositeness. I've modified the article to read witness of compositeness rather than strong witness. You're also correct that it should say "for all a"; it is for composite numbers that it is only true for some a. Deco 18:24, 14 February 2006 (UTC)[reply]
I've added the lemma about non-trivial square roots of 1 to the page. It's fairly obvious, but it doesn't hurt to spell out everything. Deco 18:53, 14 February 2006 (UTC)[reply]

The phrase "Except for powers of 3 (see page 1393 of [3]), every odd composite n has at least one witness a." it is confuse and it has to be rephrased. Powers of 3 have nothing to do here. This in fact is trivially true: all odd composites have witnesses, at least two (not only one!), including the Carmichael numbers, and *especially* the powers of 3: they ONLY have witnesses (no liars!). One third of the numbers lower then a power of 3 give a zero (the one being 0 mod 3) and the other two thirds are witnesses, ex: n=9, b=3,6: b^8=0 (mod 9); b=2,7: b^8=4 (mod 9); b=4,5: b^8=7 (mod 9); for n=27, b^26 (mod 27) is zero for 3,6,9,12,15,18,21,24, it is 13 for 2 and 25, it is 7 for 4 and 23, etc. Powers of 3 have no LIARS. All the other odd composites have at least two liars (if L is a liar, then -L is one, too). — Preceding unsigned comment added by LaurV (talkcontribs) 03:22, 30 May 2013 (UTC)[reply]

Deterministic variants of the test[edit]

82.6.98.77, the result has been published in a respectable peer-reviewed journal, and as it is referenced by several other sources, it seems to be accepted by the community. If you disagree with the result, you cannot just slap a "this is wrong" notice, you have to bring forth convincing evidence. -- EJ 20:18, 27 April 2006 (UTC)[reply]

Counter example: Take n=7. So n-1 = 6 and s=1,d=3 since 2^1.3 = 6. The article claims it's enough to check a=2,7 and 61. Try a=7. The test described in "deterministic variants" section then says n is composite. -- XYZ, June 8 2006

Could it be that only a in the range 1...(n-1) should be tested? If so, it's not clear from the page. -- XYZ, June 8 20006.

Yes, only a in the interval [1,n-1] should be checked. -- EJ 19:17, 8 June 2006 (UTC)[reply]

Yeah, sorry for my stupid comment. EJ is correct, a must always be smaller than n. In fact, we specify that , which excludes the possibility that . I assume the result of Jaeschke takes this into account - not to say this doesn't deserve clarification. Deco 19:28, 8 June 2006 (UTC)[reply]

Following the deterministic algorithm i found some exception: 49=2^4*3+1 s=4, d=3; if a=18, (18^3) mod 49 = 1 -> 49 prime. Like 49 there is also 121, 289. Kaluppollo (talk) 21:15, 6 July 2009 (UTC)[reply]

Why on earth do you test it only for a = 18? There are several deterministic variants of the test mentioned in the article, and none of the involves 18. The algorithm described by the pseudocode requires you to test all values of a from 2 to 2(ln 49)2 ≈ 30, the Pomerance, Selfridge and Wagstaff result tells you to test a = 2 and a = 3. Either way, 49 is declared composite, because it fails the test already for a = 2. — Emil J. 10:31, 7 July 2009 (UTC)[reply]
I test it for all a from 2 to 30. With a=2, a^3=8 which is not congruent 1 nor -1 mod 49, 2^(2^1*3) mod 49 ≠ -1, 2^(2^2*3) mod 49 ≠ -1, 2^(2^3*3) mod 49 ≠ -1, so it not fail the test and it is a possible composite. If i continue testing with bigger a, when i reach a=18, the if statement is False, so the algorithm won't return composite. Thanks for the attention Kaluppollo (talk) 14:10, 7 July 2009 (UTC)[reply]
You misunderstand the algorithm. Since 223·3 mod 49 ≠ ±1, the algorithm returns "composite" and stops, you do not continue with any further testing. — Emil J. 14:22, 7 July 2009 (UTC)[reply]
sorry, you are right, i misanderstood it. thanks for the help Kaluppollo (talk) 21:47, 7 July 2009 (UTC)[reply]
I see, that this is resolved. However, for future reference: some of the provided links tell you step-by-step what has to be calculated (and why) for any given number, e.g.: [5]. Gulliveig (talk) 04:27, 11 September 2009 (UTC)[reply]

Actually, I'm having some trouble with the pseudocode myself. - bogus walkthrough subsequently deleted - It seems to correctly classify all odd 1<n<41 (or at least a software implementation according to my understanding of the pseudocode does). What am I misunderstanding to make me think the pseudocode yields composite for 41 ? --83.104.46.24 (talk) 14:15, 3 February 2010 (UTC)[reply]

What you apparently misread is the condition for returning composite, which involves . Is it true that for every ? No, it is not, specifically it is false for r = 1, because its negation, , is true for this r. — Emil J. 14:47, 3 February 2010 (UTC)[reply]
Thanks Emil. Yes my walkthrough was completely and utterly bogus. Funnily enough it turns out I'd managed to implement it right in software, but the real reason it was failing on n=41 was because of arithmetic overflow: once it gets up to testing a=11, r=2, is 38 if naively calculated using 64-bit finite precision arithmetic. Using arbitrary precision arithmetic or a "modpow" to keep the range under control fixes the issue and correctly computes 40, avoiding a "composite" result. I hadn't appreciated just how quickly that double exponentiation blows up! --83.104.46.24 (talk) 00:25, 4 February 2010 (UTC)[reply]

Consider the following base sets.

If the number is less than 109838431 it is sufficient to use {73, 1354284263}
If the number is less than 25987132627 it is sufficient to use {2, 5, 11917567}
If the number is less than 1726021172851 it is sufficient to use {2, 2161, 6719, 9001}
If the number is less than 200412882870661 it is sufficient to use {2, 2161, 2333, 4643, 6491}

It is not too difficult to verify the above results. I just don't know if you guys would consider these to be significantly better than the sets that are listed in the main article. — Preceding unsigned comment added by 67.198.189.174 (talk) 13:29, 18 June 2017 (UTC)[reply]

The sets at http://miller-rabin.appspot.com/ are even better, and there is a rather obscure reference to that site in the text. The base sets highlighted in the article are of historical interest and have been published in journals. It is a little unfortunate that the more practically useful sets are not clearly pointed out. DAJ NT (talk) 06:33, 19 June 2017 (UTC)[reply]
The sets you mention use large composite numbers as a base set. I decided to do an exhaustive search restricting the values of the base set to prime numbers. I don't know for sure that restricting them to prime numbers is important. Heuristically speaking, adding two additional values to the base set seems to increase the smallest pseudoprime of the set by x100. (200412882870661 is about 100 times greater than 1726021172851). Given this, there might exist a set of 7 prime numbers that are sufficient to test all numbers less than 2^64.
Also, except for the first few, the base sets I list use small numbers (i.e. numbers less than 10000). — Preceding unsigned comment added by 59.120.231.199 (talk) 08:44, 19 June 2017 (UTC)[reply]
I recently found a way to test any 32 bit integer (more specifically, an integer less than 4957839253) which certainly includes any 32 bit integer) using only two witnesses in the test. Specifically

if (num % 16 == 1) and num < 9758525617 use {5, 1013}
if (num % 16 == 3) and num < 46493311411 use {2, 29}
if (num % 16 == 5) and num < 4957839253 use {149, 443}
if (num % 16 == 7) and num < 14856014167 use {2, 163}
if (num % 16 == 9) and num < 5671240489 use {5, 647}
if (num % 16 == 11) and num < 8749965451 use {2, 37}
if (num % 16 == 13) and num < 9174782189 use {19, 149}
if (num % 16 == 15) and num < 20574244687 use {2, 53}
Fortunately, (num % 16) can easily be computed using a bit shift operation.
This also beats the two witness base sets mentioned at http://miller-rabin.appspot.com/ — Preceding unsigned comment added by 59.120.231.199 (talk) 09:38, 22 June 2017 (UTC)[reply]

I do not think that is correct. For instance, ; however, that number is a strong pseudoprime for both 5 and 1013 bases. Anton Lapounov (talk) 00:25, 15 February 2022 (UTC)[reply]

Strength[edit]

I added the word in bold: "The Miller-Rabin test is strictly stronger than the Solovay-Strassen primality test in the sense the set of strong liars of the Miller-Rabin test is a proper subset of the set of the Solovay-Strassen primality test."

It was removed, which is fine with me. (It was actually changed to "(often proper)", which seems overly pedantic to me, but that's beside the point.) Thinking of the set of all {M-R, S-S} liars grouped by base the inclusion is proper; thinking of a particular base the result isn't proper (but is still inclusion).

However, it we're not going to call the subset proper, we shouldn't use the term "strictly stronger"; it should be stronger. I propose one of the two wordings below (differences bolded):

"The Miller-Rabin test is strictly stronger than the Solovay-Strassen primality test in the sense the set of strong liars of the Miller-Rabin test is a proper subset of the set of the Solovay-Strassen primality test."
"The Miller-Rabin test is stronger than the Solovay-Strassen primality test in the sense the set of strong liars of the Miller-Rabin test is a subset of the set of the Solovay-Strassen primality test."

If there's no feedback, I'm going to make one of these changes in a few days. CRGreathouse (talkcontribs) 17:01, 5 August 2006 (UTC)[reply]

The M-R test is an algorithm, which gets an integer n and a randomly chosen integer a, and tries to use the latter to determine the compositeness of the former. It is strictly stronger than S-S because it is correct whenever S-S is correct, and moreover, there are n and a for which S-S is incorrect, but M-R is correct.
The "set of strong liars", on the other hand, has no absolute meaning. It only makes sense if we fix n, albeit implicitly (as in the offending sentence, in the current version and all versions you proposed). For some n it is a proper subset of Euler liars, for some n it equals the set of Euler liars. We cannot call it proper without further qualification, because that would read as "for every n, the set of strong liars is a proper subset of Euler liars", which is false.
IMO both the original wording and the current wording are OK, in the sense that they are not incorrect, and anyone who understands the concepts will figure out what it exactly means. I disagree with your suggestions, because the first one is incorrect, and the second one fails to mention that M-R is strictly stronger than S-S, which is the whole point of the sentence. If you insist on changing the formulation, the proper way would be
"The Miller-Rabin test is strictly stronger than the Solovay-Strassen primality test in the sense that for every composite n, the set of strong liars for n is a subset of the set of Euler liars for n, and for many n, the subset is proper."
but I think that this is too verbose. -- EJ 18:48, 5 August 2006 (UTC)[reply]
I think that's fine actually and not too verbose. Deco 01:43, 6 August 2006 (UTC)[reply]
OK. CRGreathouse apparently does not object, so I'll put that in. -- EJ 19:42, 13 August 2006 (UTC)[reply]

Broken Algorithm?[edit]

We know 5 is a prime. So s=2, d=1 and n=5. Let's suppose a=4 (it's in the range 1-4) and r=1, since the case r=0 supports the primality. Then we have (1) 4^1 mod 5 = 4, so it is != 1

(2) 4^(2^1 *1) mod 5 = 1, so it is != -1 or 4. Therefore, 5 isn't a prime? —The preceding unsigned comment was added by 84.159.42.147 (talkcontribs) 23:34, 14 July 2007 (UTC)[reply]

For all r means for both r = 0 and r = 1. As you say, taking r = 0 already "supports the primality", hence whatever happens with r = 1 is irrelevant. -- EJ 08:40, 15 July 2007 (UTC)[reply]

Fixed the algorithm. Check Stinson's "Cryptography Theory and Practice" [6] —Preceding unsigned comment added by 72.226.196.71 (talk) 03:37, 9 May 2009 (UTC)[reply]

This algorithm is referenced a lot by rosettacode.org but using many of the examples it says that 31 is a composite number. 203.18.108.226 (talk) 06:09, 11 March 2016 (UTC)[reply]

The code example on RosettaCode did not properly implement the pseudocode. The current pseudocode is similar to Cohen Algorithm 8.2.2. It is similar to Crandall and Pomerance Algorithm 3.5.2 with a difference being the base from 2 to n-2 and the input > 3. DAJ NT (talk) 17:36, 11 March 2016 (UTC)[reply]

Generating coprime a[edit]

In an edit summary, User:EJ said: "The algorithm takes a in full Z/nZ (save the obvious exception a=0), because there is no simple way of generating a's coprime to n."

He's correct that the algorithm as it's normally formulated does not restrict a to a value coprime to n, but I think there is a simple way of generating such a: generate a random a, test GCD with n, and if it exceeds 1 return COMPOSITE, else continue. This isn't needed for correctness though, and provided the value n has (as is typical) been prescreened for small divisors, the chance of hitting a value sharing factors with n is so small as to make this not a useful optimization. Dcoetzee 19:57, 5 November 2007 (UTC)[reply]

You're right that my edit summary was misleading. The actual reason why the algorithm does not restrict a to values coprime to n is that it is a pointless complication: the other a are all compositeness witnesses anyway (they do not need to be explicitly tested for, as the condition implies that a is coprime to n), and in fact, provide a factorization of n. And, as you say, they are too rare to make worrying about them worthwhile (which is, after all, one of the reasons why factoring is conjectured to be hard). -- EJ 10:44, 6 November 2007 (UTC)[reply]
To make the last sentence less confusing: what I was trying to point out was that taking gcd with random numbers is a rather inefficient way of finding factors, it is better to try small divisors in order (if there is a realistic chance that n might have small factors at all). Anyway, forget about factoring, it's irrelevant to Rabin-Miller. -- EJ 11:32, 7 November 2007 (UTC)[reply]
Yup. Dcoetzee 11:36, 7 November 2007 (UTC)[reply]
Correct me if Im wrong, but like the Fermat test, a non-coprime 'a' will fail the test anyway, so there is no point in checking for coprimality. As long as 'a' is less than 'n' then any 'a' indicating compositeness is truthfully doing so, regardless if it is coprime or not. Im not entirely sure what the purpose of such a check would be. Even if it could be done with minimal effort, its hardly an optimization at all. Is this not so or am I missing something? 134.204.1.226 (talk) 19:19, 22 April 2024 (UTC)[reply]

Haskell code[edit]

Why Haskell implementation of the algorithm was removed? It's not true that given pseudocode is sufficient to directly write efficient code on a computer language. And removed Haskell code was not straightforward translation of the pseudocode either. So, I think, we must return Haskell sample or write another pseudocode, better suited for an implementation. —Preceding unsigned comment added by 87.255.1.40 (talk) 17:06, 10 April 2008 (UTC)[reply]

Wikipedia is not a source code repository. The article is supposed to describe the algorithm so that the reader can understand why it works, it is not supposed to give optimized implementations ready for copy&paste. Furthermore, what is or is not efficient heavily depends on the language used, as well as other circumstances (typical size and structure of input data, hardware parameters, etc.) Thus anybody wishing to write an efficient implementation would still have to do it on his/her own, not by copying a random Haskell implementation, especially since he/she is likely to use a completely different language. Finally, the Wikipedia verifiability policy applies to this situation as usual: unless you can supply a reference to published reliable source, your Haskell implementation counts as original research, which is not permitted on WP. You know, why should we take your word on the correctness or efficiency of your code?
If you are just looking for a public place where to post your code, I'm sure you'll be able to find a plenty of internet sites suitable for that purpose. Wikipedia is not one of them. — EJ (talk) 14:48, 14 April 2008 (UTC)[reply]

Thank you[edit]

Excellent article, really. Thank you.

Antonind (talk) 16:50, 6 November 2008 (UTC)[reply]


Notes[edit]

  1. ^ H. Glarner, Miller-Rabin Primality Test, Step by Step, http://www.gandraxa.com/miller_rabin_primality_test.xml, retrieved 2011-08-02

Random range in algorithm[edit]

The pseudocode in Miller–Rabin primality test#Algorithm and running time says:

Input: n > 2, an odd integer to be tested for primality; k, a parameter that determines the accuracy of the test
...
   pick a randomly in the range [2, n − 2]

But if n = 3, then the range is [2, 3-2] = [2, 1] = ∅, and so no such a can be chosen. Is the range incorrect, or is the initial restriction actually n > 3, or have I missed something else? --67.249.56.101 (talk) 01:38, 31 July 2009 (UTC)[reply]

It's really a very bad idea to use a complicated randomized algorithm for testing small integers like 3, any realistic implementation will first use trial division to rule out small prime factors, thus the problem does not occur. As for the theory, the natural analysis of the algorithm works for a randomly uniformly chosen in . Since there is no good way of doing this directly, the next approximation is to choose it uniformly in [1, n − 1]; since all numbers in this interval which are not coprime to n will happen to be witnesses of compositeness anyway, this can only improve the success probability. Now, the version [2, n − 2] which was used in the article is just a trivial optimization, since 1 and −1 (i.e., n − 1) are never compositeness witnesses, hence it is pointless to test them. Thus, the impossibility of choosing a in [2, n − 2] for n = 3 should be understood as that there are no compositeness witnesses, hence 3 is prime. I'll change it to [2, n − 1] so that people do not wonder. — Emil J. 10:47, 6 August 2009 (UTC)[reply]
I think a better change would be to make it "input: n > 3". CRGreathouse (t | c) 17:08, 6 August 2009 (UTC)[reply]

Algorithm complexity[edit]

There is written:

Using modular exponentiation by repeated squaring, the running time of this algorithm is O(k × log3 n).


Shouldn't it be O(k × s × log3 n) ? julekmen (talk) 11:16, 1 October 2009 (UTC)[reply]

No, s is accounted for by one of those log n factors. — Emil J. 11:54, 1 October 2009 (UTC)[reply]

It should be O(k log2) not O(k log3). ad can be calculated in O(log2 d) by modular exponentiation. Since n-1 = 2sd, s = O(log n). The line x = x2 mod p only involves 2 multiplications and 1 mod. So the total is O(k (log2 d + 3s)) = O(k log2 n). Angry bee (talk) 15:29, 26 March 2012 (UTC)[reply]

Please enlighten us how modular exponentiation of log(n)-bit numbers can be done in O(log^2 n) time. I thought O(log^2 n) is the time needed to perform a single multiplication (using the trivial algorithm, nothing fancy like FFT), and then there's another O(log n) factor for repeated squaring. -- X7q (talk) 02:22, 30 March 2012 (UTC)[reply]

Now that integer multiplication in `O(nlog(n))` time has been proven (https://hal.archives-ouvertes.fr/hal-02070778/document), do these runtimes change? — Preceding unsigned comment added by 130.44.167.24 (talk) 04:50, 22 December 2021 (UTC)[reply]

New bounds for the deterministic variant?[edit]

"For example, Pomerance, Selfridge and Wagstaff and Jaeschke have verified that [...] if n < 341,550,071,728,321, it is enough to test a = 2, 3, 5, 7, 11, 13, and 17." - Did someone since extend this range with more potential witnesses (19, ...)? Gulliveig (talk) 05:01, 2 August 2011 (UTC)[reply]

Yes, there have been several extensions -- including one I did several years ago. But I don't know of any that have been published in peer-reviewed sources. CRGreathouse (t | c) 13:28, 2 August 2011 (UTC)[reply]

misleading[edit]

"However, as a caution, note that Arnault [1] gives a 397-digit composite number that would pass a Miller–Rabin test for every base a less than 307. One way to reduce the chance that such a number will be declared probably prime is to combine a Miller–Rabin test with another type of test; this is what the Baillie–PSW primality test does."

I believe this promotes a misunderstanding of the type of probabilistic algorithm the MR test is. For ANY number, the probability of it incorrectly stating that a number is prime decays exponentially with the number of trials. As long as one is comfortable with probabilities on the order of 1/10^100 of an error (or even smaller, if you want to run it for longer), the test is completely fine. For all practical purposes, it will never incorrectly determine the primality of a number, when run with hundreds of iterations.

The result of Arnault was a number for which no small bases worked to disprove primality. But it is still true for this number (like all composite numbers) that most randomly chosen bases would work to disprove primality. Their number failed the Maple primality test because of a weakness with the Maple implementation: it checked just the bases 2,3,5,7,11 instead of choosing random bases to test.

I have reworked this paragraph as a result.Wpegden (talk) 14:56, 10 October 2013 (UTC)[reply]

I like the change. I think this concept is important to keep on the page, because there is still a lot of software being written today (2013) that uses the first N bases instead of random bases, and most people seem to not see the difference. The usual "solution" I've seen is people just raise the number of tests to silly numbers to weasel out of counterexamples, rather than using a BPSW test. 76.115.142.133 (talk) 04:07, 14 October 2013 (UTC)[reply]
  • From this perspective, the result of Arnault is similar to the those of Pomerance—Selfridge—Wagstaff and Jaeschke, mentioned in section Deterministic variants of the test. In particular, they give the number 2,152,302,898,747 as one that passes Miller–Rabin primality test for bases 2, 3, 5, 7, and 11 and thus should also pass Maple primality test. I therefore think that Arnault, Pomerance—Selfridge—Wagstaff, and Jaeschke results should be mentioned in the same place/context — I would suggest moving mention of Arnault to Deterministic variants of the test section. Maxal (talk) 14:09, 14 October 2013 (UTC)[reply]

References

  1. ^ F. Arnault (1995). "Constructing Carmichael Numbers Which Are Strong Pseudoprimes to Several Bases". Journal of Symbolic Computation. 20 (2): 151–161. {{cite journal}}: Unknown parameter |month= ignored (help)

Incorrect logic under Concepts[edit]

Now, let n be prime with n > 2. It follows that n − 1 is even and we can write it as 2s·d, where s and d are positive integers (d is odd).

Isn't this true for all odd n > 2? If n is odd then n - 1 is even. As n - 1 is even, it is divisible by some power of two, the greatest one determines both s and d. Nick Garvey (talk) 22:33, 7 December 2013 (UTC)[reply]

Yes, that part is true for all odd n > 2. Why do you call that incorrect logic? PrimeHunter (talk) 22:58, 7 December 2013 (UTC)[reply]
Ah I misread the part that came after. Sorry, my mistake. Nick Garvey (talk) 23:07, 7 December 2013 (UTC)[reply]

Pseudocode underspecified[edit]

The pseudocode includes the line:

   repeat s − 1 times:

However, s may be zero, in which case that line reads "repeat -1 times". It is reasonable to interpret that as "repeat zero times", but the ambiguity may be confusing.

Indeed, I discovered this problem by translating the pseudocode into a formal specification, then trying to prove an implementation of that spec correct. The spec demanded at least 's' witness squares, but when s==0, there is still one witness to either primality or non-primality. I understand that the pseudocode's job is not to be a formal reference, but my experience indicates that the ambiguity indeed has the potential to confuse readers. Even one reader with an advanced degree in computer science. :)

The line might be rewritten as one of:

   repeat at least s-1 times:
   repeat max(0,s-1) times:
   repeat s-1 times (or none if s==0):

The first variant is least disruptive to the pseudocode, but doesn't do much to hint at why the qualifier is present. The last variant's parenthetical comment clearly explains its own presence, but is unpleasantly distracting. I don't have a strong preference, but I'm enthusiastic about correcting the problem of -1 loops. 76.104.130.32 (talk) 06:05, 14 March 2014 (UTC)jonh[reply]

But n is odd so n-1=2s·d is even with d odd. Hence s is at least 1. — Preceding unsigned comment added by 193.144.198.250 (talk) 12:30, 17 March 2014 (UTC)[reply]

Oh. So it is. That's awkward. :v) Please disregard this comment. 131.107.174.36 (talk) 21:14, 17 March 2014 (UTC)jonh[reply]

Use of Logarithm in in the Miller Algorithm[edit]

I assume that the "deterministic variant" is the Miller test. The pseudocode uses ln, as in "natural logarithm" to set a bound. In computer science matters, I usually assume log2. Shouldn't it be log2 instead? Is this a convention thing or a genuine difference?
Note that "log" appearing within Big-O-Notation doesn't care about the base of the logarithm, because converting to another base is just multiplying by a constant. — Preceding unsigned comment added by 176.199.27.52 (talk) 14:41, 22 June 2014 (UTC)[reply]

About the test "if x = 1 then return composite" in the algorithm[edit]

Hi all, I'm surprised to see that test in the loop. Where does it come from ? That test does not seem to be stated in the text written above. RBossut (talk) 13:01, 24 April 2015 (UTC)[reply]

It is not in Crandall and Pomerance Alg 3.5.2. It is in Cohen (Course in CANT) Algorithm 8.2.2. In Riesel 1994, it is not part of the definition 4.3, but is included in his program. It isn't necessary, just practical as repeated squaring of 1 will not change the result, so can be considered an early exit condition. Cohen structures his loop so this is clearer (repeat r-1 times while x != ± 1). DAJ NT (talk) 18:15, 12 November 2016 (UTC)[reply]

Least strong pseudoprime to base n table[edit]

I think the page would be improved if this were either removed or pushed to the end. It is quite large and breaks up the flow from example to algorithm. My personal feeling is that it adds no value, and at best we should just point to MathWorld's Strong Pseudoprime page and give a quick list of the first few. Lastly, base 1 doesn't make sense (or if you think it does, why 9 and not 1 or 4 as pseudoprimes?). DAJ NT (talk) 07:09, 23 May 2015 (UTC)[reply]

Is 341 prime?[edit]

Suppose n - 1 = 4k where k is odd and for some t, t ^ k = 32 mod n. Can we infer that n is composite? Not, surely, until we have checked that 1024 (i.e. 32 X 32) is not congruent to -1 mod n.

Bukovets (talk) 10:00, 11 June 2017 (UTC)[reply]

@Bukovets: Yeah, I asked myself the same question. It turns out this example was taken directly from the given source[1]: 1402  with some context stripped. In that paper, the GCD of 32−1 and 341 is computed unconditionally, so we know that we get a non‐trivial factor of 341 because we observe this GCD to be neither 1 nor 341. That was not clear in the present article because the algorithm used was not made explicit. I rewrote that part recently, and added the missing step to the example (check that 322 mod 341 = 1). — Maëlan 17:08, 19 February 2019 (UTC)[reply]

References

  1. ^ Robert Baillie; Samuel S. Wagstaff, Jr. (October 1980). "Lucas Pseudoprimes" (PDF). Mathematics of Computation. 35 (152): 1391–1417. doi:10.1090/S0025-5718-1980-0583518-6. MR 0583518.

Pseudocode unnecessary check[edit]

In the pseudocode we have:

WitnessLoop: repeat k times:
   ...
   repeat r − 1 times:
      ...
      if x = 1 then
         return composite
      ...

But x could never become 1 and so the check is unnecessary and misleading. If x is 1 than either its initial value was 1 or its previous value was -1 (n-1). In either case the algorithm would have terminated. — Preceding unsigned comment added by Perchema (talkcontribs) 10:30, 3 May 2018 (UTC)[reply]

@Perchema: Beware that you are assuming 1 and −1 to be the only square roots modulo n of 1. This is true when n is prime, but may be false when n is composite (for example 42 mod 15 = 1).
That said, you are right in saying that this test is unnecessary, as if x becomes 1 at some point, then it will remain 1 until the end of the inner loop, hence will never be −1, and the algorithm will return “composite” nonetheless. So, as is, this test is only a way of short‐circuiting the inner loop, which is not necessary to get the right complexity, and probably does not save anything in practice (as r, the number of iterations of the inner loop, should be very small most of the time).
However, that additional test becomes helpful for finding factors of n. See the section “Variants for finding factors” which I rewrote recently.
Maëlan 16:57, 19 February 2019 (UTC)[reply]

Numbers for which the Miller-Rabin test fails[edit]

The factor database website [1] lists 728,134 composite numbers for which at least ten applications of the Miller-Rabin test failed to detect compositeness. The bases used in the tests were chosen by the mpz_probab_prime_p( ) function in the GNU Multiple Precision Arithmetic Library.

The list of numbers can be viewed and downloaded from [2].

A short calculation shows that none of these 728,134 numbers is a Lucas pseudoprime when Selfridge's "Method A" is used to choose Lucas parameters , , and . Therefore, the Baillie-PSW primality test would correctly declare that all of these numbers are composite. MathPerson (talk) 22:43, 8 September 2020 (UTC)[reply]

Software implementation is not sufficient proof of an algorithm failing, as anyone can write erroneous mathematical code and indeed most do. In the case of mpz_probab_prime_p the selection process is not the same as described by the probabilistic Miller-Rabin variant, therefore the results are irrelevant, and reading the source code would have told Tervooren that. JSory (talk) 22:39, 16 November 2022 (UTC)[reply]

References

  1. ^ Tervooren, Markus. "These numbers passed Miller-Rabin's probabilistic test (order 10 at least), but turned out to be composite". Factor Database. Retrieved September 8, 2020.
  2. ^ Tervooren, Markus. "prooffailed.txt". Factor Database. Retrieved September 8, 2020.

Reducing values of 'a' to primes[edit]

Can 'a' be restricted to only the primes? All of the deterministic "below a certain threshold" variants involve checks against only primes. If 'a' needs to be coprime to the test number then why not just use prime 'a'? Every explanation of the Miller-Rabin test I see online tells me to pull an 'a' from a range [2, n-1] and Im wondering if I just pull primes, am I setting myself up for failure? Can a composite smaller than 'n' catch something that a prime smaller than 'n' cant? I realize Im putting the cart before the horse here because you need to know primes already in order to test for them, so maybe thats why its worded the way it is, but assuming you already know the primes up to a certain point, why not check them only? That is what the deterministic variants are doing, after all. If you were pulling randomly generated 'a' from a very large range [2,n-2], and perform the test 'k' times, then I could understand why you wouldnt do only primes. But barring the pragmatic side of the algorithm, what is the mathematical basis for using composites? Is there one or should we ideally be using only primes? Nothing explicit is said about this. 134.204.1.226 (talk) 16:35, 13 December 2021 (UTC)[reply]

The base a does not need to be coprime to the test number n. In fact, if a happens to have a common divisor with n, it will be a witness for the compositeness of n, because cannot be true. That means you will not need to test any further bases. Moreover, composite bases work a little better in practice. If you look at the best known SPRP bases sets, all bases there are composite, except for 2. And the base 2 is used only because we have calculated a huge table of strong pseudoprimes for that base, which allows us to limit testing other bases to that precalculated list only. Anton Lapounov (talk) 23:52, 14 February 2022 (UTC)[reply]
"Weak" pseudoprimes rather, however Feitsma & Galway's list can be trivially reduced to strong 2-pseudoprimes. JSory (talk) 22:41, 16 November 2022 (UTC)[reply]

Pseudocode incorrect?[edit]

In both the deterministic and non-deterministic pseudocode, there is a check of if y ≠ 1 then return “composite” after the loop over values of s. However, this doesn't make sense, as y may never be defined (take the case n=4; you will never enter the s-loop). I believe the check might be intended to be if x != 1 instead? — Preceding unsigned comment added by Apnorton (talkcontribs) 19:49, 29 May 2023 (UTC)[reply]

n is odd, so s must be > 0. But the code doesn't seem to implement the test as described above. It may be equivalent, but then it is at least a very inefficient variant if you don't use it to squeeze a factor out of it. --109.43.50.204 (talk) 00:52, 18 December 2023 (UTC)[reply]
But does it even make sense to search for a factor in an already known strong probable prime? It may have one if it's not an actual prime, but the article raises more questions than it gives answers. --109.43.50.204 (talk) 01:44, 18 December 2023 (UTC)[reply]
If it is known to be a probable prime, then I don't think it makes sense to search for a factor. However, if you don't know that, I think it is best to check for some small factors first. Bubba73 You talkin' to me? 02:08, 18 December 2023 (UTC)[reply]
The article says that you know it if x == 1. The pseudocode tests for this condition, but continues the loop. And if x == 1 then y will also be 1 and the pseudocode returns the wrong result anyways. --109.43.51.138 (talk) 12:57, 18 December 2023 (UTC)[reply]
At this point in the pseudocode, x is equal to y, because x is given the value of y at the end of each iteration of the inner loop, and there is always at least one iteration because s > 0 (n is odd). So testing x ≠ 1 is the same as testing y ≠ 1.
FYI the pseudocodes have been substantially rewritten one year ago. Here is the old version (mine) and here is the new version (@Maggyero:). I don’t have brain time to check thoroughly for the correctness of the new code, but it is clearly not equivalent to the old. The old version is a direct translation of the mathematical definition of “strong probable prime” given in the article, and it aborts the inner loop (repeated squaring) as soon as x becomes −1. The new version continues the loop in that situation, uselessly, and does redundant tests. IMHO the old version is preferable for both these reasons: clarity and efficiency (it has a bit of ugly unstructured programming, but that can be remedied). Maëlan 14:45, 18 December 2023 (UTC)[reply]
Yes, I'd suggest to restore the old version. --109.43.51.138 (talk) 15:52, 18 December 2023 (UTC)[reply]
"continue WitnessLoop" goes back to the top of that loop, right? Bubba73 You talkin' to me? 16:33, 18 December 2023 (UTC)[reply]
Yes, for the next iteration (draw another random a). We can try to avoid it by turning repeat s−1 times into something along the lines of repeat s−1 times while x ≠ n−1, and putting the return “composite” under a conditional test. Maëlan 16:40, 18 December 2023 (UTC)[reply]

To clarify what I mean: here is my old code (with style slightly updated):

Input #1: n > 3, an odd integer to be tested for primality
Input #2: k, the number of rounds of testing to perform
Output: “composite” if n is found to be composite, “probably prime” otherwise

let s > 0 and d odd > 0 such that n − 1 = 2s·d  # by factoring out powers of 2 from n − 1
WitnessLoop:
repeat k times:
    a ← random integer in the range [2, n − 2]
    xad mod n
    if x = 1 or x = n − 1 then
        continue WitnessLoop
    repeat s − 1 times:
        xx2 mod n
        if x = n − 1 then
            continue WitnessLoop
    returncompositereturnprobably prime

Here is the proposed rewriting that avoids this ugly continue WitnessLoop:

let s > 0 and d odd > 0 such that n − 1 = 2s·d  # by factoring out powers of 2 from n − 1
repeat k times:
    a ← random integer in the range [2, n − 2]
    xad mod n
    if x ≠ 1 and xn − 1 then  # the second conjunct can be removed (redundant with the tests below it)
        i ← 0
        while i < s − 1 and xn − 1:  # repeat squaring n−1 times, or until x becomes −1
            xx2 mod n
            ii + 1
        if xn − 1:
            returncompositereturnprobably prime

I realize I’ve spoken a bit too quickly: my code short-circuits the inner loop if x becomes −1, but it continues it if x becomes +1. Maggyero’s code does the opposite optimization. If deemed useful, it is possible to integrate both shortcuts in my code, by adding a test for x ≠ 1 inside the while loop. In other words:

let s > 0 and d odd > 0 such that n − 1 = 2s·d  # by factoring out powers of 2 from n − 1
repeat k times:
    a ← random integer in the range [2, n − 2]
    xad mod n
    if x ≠ 1 and xn − 1 then  # the second conjunct can be removed (redundant with the tests below it)
        i ← 0
        while i < s − 1 and xn − 1:  # repeat squaring n−1 times, or until x becomes −1
            xx2 mod n
            ii + 1
            if x = 1:  # correct but unnecessary shortcut
                returncompositeif xn − 1:
            returncompositereturnprobably prime

This shortcut is done in the variant of the pseudo-code that tries to find factors (because it’s in this situation that we are able to compute a factor), but I’m not sure whether it brings much to the general case (the shortcut does not trigger often, I think). Maëlan 17:24, 18 December 2023 (UTC)[reply]

To me, pseudocode is clearer if it says "if these conditions are met, do the following" than "if these conditions are not met, continue the loop". Bubba73 You talkin' to me? 20:02, 18 December 2023 (UTC)[reply]
The first version is much clearer. If the continue is really too ugly, a function would be better than these complex conditions. --109.43.51.138 (talk) 00:03, 19 December 2023 (UTC)[reply]
My preference is to not use "continue", but do what you think is best. I avoid using "continue" in programming. If the rest of the loop is relatively short, I use a conditional on it. However, if I'm skipping over a large amount of the loop (say the last 30 lines), then I will use "continue". Bubba73 You talkin' to me? 01:28, 19 December 2023 (UTC)[reply]
In actual code I would use a function indeed, and it does make a lot of sense to isolate the MR-test-with-fixed-a into its own function. IMHO it’s the clearest option. We just have to settle on a pseudo-syntax for it, and accept the extra verbosity. For instance :
function is_strong_probable_prime:

    Input #1: s > 0 and d odd > 0 (describing the odd integer n = 2s·d + 1)
    Input #2: a, the base
    Output: True if n is a strong probable prime to base a, False otherwise

    xad mod n
    if x = 1 or x = n − 1 then
        return True
    repeat s − 1 times:
        xx2 mod n
        if x = n − 1 then
            return True
        if x = 1:  # correct but unnecessary shortcut
            return False
    return False
function miller_rabin_test:

    Input #1: n > 3, an odd integer to be tested for primality
    Input #2: k, the number of rounds of testing to perform
    Output: “composite” if n is found to be composite, “probably prime” otherwise

    let s > 0 and d odd > 0 such that n − 1 = 2s·d  # by factoring out powers of 2 from n − 1
    repeat k times:
        a ← random integer in the range [2, n − 2]
        if not(is_strong_probable_prime(s, d, a)):
            returncompositereturnprobably prime

What do you think? Maëlan 01:07, 21 December 2023 (UTC)[reply]

One downside is that, in the variant that finds factors, we’d have to thread the richer return type down to the auxiliary function, but well. Maëlan 01:12, 21 December 2023 (UTC)[reply]

Prime base 'a'[edit]

Point of inquiry. I have always thought, beginning with Fermat primality test, that arbitrary base 'a' was an inefficiency. Can someone correct me? Is it sufficient to test only bases that are prime? In the section of this article for testing against small subsets, for test numbers 'n' beneath a certain limit, the base 'a' sets always comprise prime numbers. If a base of 2 and a base of 3 are both inconclusive, does a base of 6 provide any more meaningful information? Or would testing it be redundant? If 6 is indeed redundant to testing both 2 and 3 separately, why not just test against some large primorial number?

134.204.1.226 (talk) — Preceding undated comment added 19:24, 22 April 2024 (UTC)[reply]

it doesn't work; a number can be a strong pseudoprime to base b but not to base kb. For example, 703 is a strong pseudoprime to base 3 but not to base 15. - CRGreathouse (t | c) 13:22, 26 April 2024 (UTC)[reply]