Rabin-Miller Primality Tester for .NET 4

Aug 15, 2010

With the release of .NET Framework 4, developers have access to arbitrary precision integer mathematics through the
BigInteger structure in the System.Numerics namespace. With exponentiation/modulus
functions, it is fairly easy to implement number theory computations requiring very large integer mathematics. The most common algorithm
to test for probabilistic primality of a number is the Rabin-Miller method (Ref. 1, 2). This algorithm can indicate with certainty if a number is not prime but can only indicate
the highly-probable prime status of a number with the level of certainty dependent on the number of iterations used with the algorithm. The algorithm does not
provide information on the prime factorization of a number found to be composite.

rabinmiller.cs is a .NET Framework 4 C# console application for WinXP SP3 and higher which attempts to factor a number of ANY size into component
primes using a pre-generated list of small primes. If the factorization into component primes is NOT complete, the application invokes the Rabin-Miller algorithm to check
probablistic primality of the final factor.
The .NET Framework 4
is required for this application since it uses BigInteger functionality. Since .NET 3.5 is included with Windows 7, .NET Framework 4 must be downloaded for all current versions
of Windows to use this application.
The command line form takes at most 3 arguments:

After initial startup, the application loops and prompts the user for more numbers to test. The Rabin-Miller iterations and mode status are fixed at the initial startup values.

(1) If the first argument (numberfile) is a file name (with correct path specification), the application attempts to parse the file as a decimal integer text file. There can be artibrary
spaces and CR/LF sequences in the file which are removed on parsing to an integer value. Any non-numeric characters cause the parsing to fail.
If a file with the specified name isn't found, the number is assumed to be specified directly by the argument. In this case the argument can be parsed as a decimal integer value.
The first argument also supports specifying common numeric expressions in which case the first character of the argument (M, N, R or Q) indicates the expression type
with the remaining numbers indicating the exponent value which must be an int32 value <= 2,147,483,647. For example, the expression forms for an exponent of 127 are:

If the first argument numberstring is "+", "*" or "/", the application prompts for several numbers to add, multiply or divide respectively.

The first argument numberstring also allows specification of a polynomial expression, using "Pm" and further prompting, with up to 3 different powers and a constant:

a0 + a1*b1e1 + a2*b2e2 + a3*b3e3

In this case, a0, a1, a2, a3, b1, b2, b3 can be arbitrarily large numbers. The exponents e1, e2 and e2 must be int32 <= 2,147,483,647. The values a0, a1, a2, a3 can be negative values.
In all cases, the resultant number to be factored must be a positive number greater than one.

(2) The second optional argument is the number of Rabin-Miller iterations which defaults to 64 which provides a certainty for primality of at least 1 - 2-128 .
For numbers that are KNOWN to be properly randomly generated, the number of iterations needed to achieve a required certainty of primality is considerably less than this
upper bound suggests and is dependent on the size of the number. However if the origin of the number to be tested with Rabin-Miller is unknown, as discussed in Ref. 2
the number of iterations associated with the upper bound of probability expression is required.

(3) If three arguments are specified, the final argument simply disables the verbose display so that large prime numbers are not displayed, and the detailed Rabin-Miller
iterations are not shown, but the same test is performed and status of the test is displayed.

Before the Rabin-Miller algorithm is executed, the application uses a list of smaller primes for a simple initial factoring check. If the binary file binprimes is found in
the same directory as rabinmiller.exe, the file is read into an integer array which contains all prime numbers less than 10,000,000, i.e. 664579 primes.
These prime numbers are packed in binprimes as little-endian 4 byte int32 values. If the file binprimes is not found, rabinmiller.exe simple uses a short internal
list of all primes less than 1000. In either case, for a number n, the application tries all small primes in the array up to Sqrt(n) (or to the maximum value prime in the array).
If the number can be factored using the small primes list so that the remaining FINAL factor is less than or equal to the square of the maximum small prime in the list, pmaxsq, the factorization is complete.
However, if the FINAL factor (including the case where no factors are found) is GREATER THAN pmaxsq, then the final factor MAY be prime or composite.
In this case, the Rabin-Miller test is executed and the result displayed.

The application displays (in default verbose mode) the entire number in both decimal (base 10) and hex (base 16) and also indicates the number of bits, bytes and
decimal digits in the number to be tested which can be useful. The progress of the iterations is shown and a final result of either composite certainty or highly probably primality
is reported.