Skip to content

ncw/iprime

Repository files navigation

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 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 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

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 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.

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 over the Galois Field GF(p) which is arithmetic modulo p possible.

To make a truly efficient Mersenne primality prover it implements the IBDWT 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 (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! 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

About

All integer Mersenne prime checker

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages