Skip to content
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

[WIP] Add an example of generating large primes #33

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

cuviper
Copy link
Member

@cuviper cuviper commented Mar 3, 2018

This example generates large BigUints, then tests for primality.

This is marked WIP because I see a few ways I hope to make this faster by making is_prime part of the API, and improving the implementation with internal details -- like leveraging modpow's Montgomery domain more.

@cuviper
Copy link
Member Author

cuviper commented Mar 3, 2018

My attempts to stay in the Montgomery domain haven't made any difference. The bottleneck is in the actual exponentiation. But I think the first witness of 2 could do a lot better optimized as shifts instead. It's something to try, anyway...

@cuviper
Copy link
Member Author

cuviper commented Mar 3, 2018

Meh. I tried shifting the base up to the size of the modulus, but for N-bit exponent and modulus, this only reduces the number of iterations by log N.

@dignifiedquire
Copy link
Contributor

dignifiedquire commented Jul 18, 2018

hey, this might be of interest to you. I am implementing rsa in rust using this library, porting straight from the golang stdlib as a starting point. I have ported the prime tests already, and getting these numbers.

Source: https://github.com/dignifiedquire/rust-rsa/blob/master/src/prime.rs
Golang: https://github.com/golang/go/blob/master/src/math/big/prime.go

The benchmarks are a 1-1 port, using the same numbers so results should be comparable well.
Note1: golang has an optimized big implementation using a lot of assembler
Note2: I haven't gone through optimizing my code yet, just straight porting and making sure tests are passing, so likely I am missing some low hanging fruit there.

Rust

test bench_prime_lucas        ... bench:  11,991,982 ns/iter (+/- 626,235)
test bench_prime_miller_rabin ... bench:   3,195,908 ns/iter (+/- 347,849)
test probably_prime_0         ... bench:  14,820,231 ns/iter (+/- 1,600,128)
test probably_prime_1         ... bench:  18,727,275 ns/iter (+/- 2,883,921)
test probably_prime_10        ... bench:  48,884,033 ns/iter (+/- 4,318,378)
test probably_prime_20        ... bench:  77,457,939 ns/iter (+/- 1,612,339)
test probably_prime_5         ... bench:  30,915,429 ns/iter (+/- 2,710,209)

golang

BenchmarkProbablyPrime/n=0-4         	     500	   3778513 ns/op
BenchmarkProbablyPrime/n=1-4         	     300	   4386977 ns/op
BenchmarkProbablyPrime/n=5-4         	     200	   6867582 ns/op
BenchmarkProbablyPrime/n=10-4        	     100	  10186901 ns/op
BenchmarkProbablyPrime/n=20-4        	     100	  16642978 ns/op
BenchmarkProbablyPrime/Lucas-4       	     300	   3692549 ns/op
BenchmarkProbablyPrime/MillerRabinBase2-4         	    2000	    677351 ns/op
name go rust
lucas 3,692,549 ns/op 11,991,982 ns/iter
miller_rabin 677,351 ns/op 3,195,908 ns/iter
n_0 3,778,513 ns/op 14,820,231 ns/iter
n_1 4,386,977 ns/op 18,727,275 ns/iter
n_5 6,867,582 ns/op 30,915,429 ns/iter
n_10 10,186,901 ns/op 48,884,033 ns/iter
n_20 16,642,978 ns/op 77,457,939 ns/iter

PS: using a fork as I am missing access to raw limbs, trailing zeros and the Roots impl currently
PPS: if you have time and have ideas on how I can optimize my code, it would be very much appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants