https://github.com/ncw/iprime
All integer Mersenne prime checker
https://github.com/ncw/iprime
Last synced: 5 months ago
JSON representation
All integer Mersenne prime checker
- Host: GitHub
- URL: https://github.com/ncw/iprime
- Owner: ncw
- License: mit
- Created: 2014-02-07T21:58:32.000Z (over 12 years ago)
- Default Branch: master
- Last Pushed: 2015-12-07T17:37:16.000Z (over 10 years ago)
- Last Synced: 2024-06-20T17:52:42.641Z (about 2 years ago)
- Language: C++
- Size: 1.61 MB
- Stars: 7
- Watchers: 6
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: COPYING
Awesome Lists containing this project
README
iprime
======
This is a Mersenne prime checker using integer only code.
It is written in Go for portability between platforms and the easy of
adding assembler to the code.
The code is working but the FFTs need more work.
There is optimised assembler for ARM and AMD64 architectures.
This code is a port of
[ARMPrime](http://www.craig-wood.com/nick/armprime/) software which ran
on RISC OS only and was never very portable.
I made a first cut at making ARMPrime more portable in
[my ioccc 2012 entry](http://www.craig-wood.com/nick/articles/ioccc-2012-mersenne-prime-checker/) which was written in C.
I decided to re-write again in Go because of the cross platform
support and the fact that Go integrates really nicely with assembler
code. The testing suite has come in really useful as have the
benchmarking suite.
Install
-------
Iprime is a Go program and comes as a single binary file.
Download the relevant binary from
- http://www.craig-wood.com/nick/pub/iprime/
Or alternatively if you have Go installed use
go get github.com/ncw/iprime
and this will build the binary in `$GOPATH/bin`. You can then modify
the source and submit patches.
Usage
-----
Use `iprime -h` to see all the options.
Mersenne prime tester
Usage:
./iprime [options] q
where q = Mersenne exponent to test
Options:
-cpuprofile="": Write cpu profile to file
-fft-size=0: minimum size for FFT (2**n)
-iterations=0: Number of iterations to check run - 0 for full test
The `-iterations` argument to the program allows the number of
iterations to be put in, and using this it has been validated against
the Prime95 test suite.
The program comes with a unit test - run it like
go test -v -short
If if you have lots of time to spare
go test -v
Example output
$ ./iprime 521
Testing 2**521-1 with fft size 2**5 for 0 iterations
Residue 0x0000000000000000
That took 4.424103ms for 519 iterations which is 8.524us per iteration
A residue of 0 after the full number of iterations means you've found
a mersenne prime!
How it works
------------
This program proves the primality of [Mersenne
primes](http://en.wikipedia.org/wiki/Mersenne_prime) of the form `2^p
- 1`. The biggest known primes are of this form because there is an
efficient test for primality - the [Lucas Lehmer
test](http://mathworld.wolfram.com/Lucas-LehmerTest.html).
If you run the program and it produces `0x0000000000000000` (0 in hex)
as an answer then you've found a prime of the form `2^p-1`. If it
produces anything else then `2^p-1` isn't prime. The printed result is
the bottom 64 bits of the last iteration of the Lucas Lehmer test.
The test is implemented using arithmetic module a prime just less than
`2^64`, `0xFFFFFFFF00000001` = `2^64-2^32+1` (p from now on), with
some rather special properties.
The most important of which is that arithmetic modulo p can all be
done without using divisions or modulo operations (which are really
slow).
The next important property is that p-1 has the following factors
2^32 * 3 * 5 * 17 * 257 * 65537
All those factors of 2 make a [Fast Fourier
Transform](http://mathworld.wolfram.com/FastFourierTransform.html)
over the [Galois Field](http://mathworld.wolfram.com/FiniteField.html)
GF(p) which is arithmetic modulo p possible.
To make a truly efficient Mersenne primality prover it implements the
[IBDWT](http://en.wikipedia.org/wiki/Irrational_base_discrete_weighted_transform)
a variant of the FFT using an irrational base. This halves the size
of the FFT array by combining the modulo and multiply steps from the
Lucas Lehmer test into one.
It can use an irrational base in a discrete field where every element
is an integer, because the p chosen has n-th roots of 2 where n is up
to 26, which means that an IBDWT can be defined for FFT sizes up to
`2^26`. 7 is a primitive root of GF(p) so all follows from that!
This all integer IBDWT isn't susceptible to the round off errors that
plague the floating point implementation, but does suffer in the speed
stakes from the fact that modern CPUs have much faster floating point
units than integer units. This is particularly noticeable in the x86
works where 64 bit integer multiplies take 64 cycles. However ARM
chips, which this was originally designed for, 32x32 -> 64 multiples
only take 1 cycle.
For example to check if `2^18000000-1` is prime (a 5,418,539 digit
number) [Prime95](http://www.mersenne.org/freesoft/) (the current
speed demon) uses a `2^20` FFT size and each iteration takes it about
25ms. On similar hardware it this program takes about 1.2s also using
an FFT size of `2^20`!
This program can do an FFT of up to `2^26` entries. Each entry can have
up to 18 bits in (as `2*18+26 <= 63`), which means that the biggest
exponent that it can test for primality is `18*(2^26)-1 = 1,207,959,551`.
This would be number of 363 million decimal digits so could be used to
find a 100 million digit prime and scoop the [EFF $150,000
prize](https://www.eff.org/awards/coop)! It would take rather a long
time though...
Roadmap
-------
Implement
* FFT for small sizes which only have shifts - DONE
* Optimised ffts with shifts - DONE
* Four step fft so can use these ffts and improve cache locality - DONE but needs more work
* Assembler primitives - DONE
* Assembler FFTs - DONE
* New FFT schemes (like the one used in FFTW)
* Save progress
* PrimeNet support
License
-------
This is free software under the terms of MIT license (check COPYING file
included in this package).
Author
------
- Nick Craig-Wood