-
Notifications
You must be signed in to change notification settings - Fork 7
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
Prime number verification issue. #1
Comments
This crate uses Num-Bigint, meaning the types are You can also use the Feel free to use wolfram alpha to double check primality. Let me know if this helps! |
How could they be the wrong type? They are turned into BigUint using into(). And it did not explain why the program hangs when you try to generate a 14 bit prime number. |
My guess it is something wrong when it comes to how small prime numbers are identified. |
Yes, you are right. I looked into it more and I think I fixed the hang issue when generating 14 bit primes. I still have not been able to fix the identification issue with small primes. I am actually glad you found this as it may mean I can improve performance on getting prime numbers to be generated. Solution For HangThe solution I used to fix the hang is that I added dividing by the number itself. |
Looks like the problem is in the miller-rabin primality test. I am looking into it some more. |
I wonder if it would be faster to have all the small prime numbers in a hash set instead of an array. Then the first thing you could do is this: if small_prime_hash_set.contains(p) {
return true;
} |
A quick look at the code makes me think the issue with identifying small primes is in |
Note that this change still causes the small number to first be found 'non-prime' because its remainder is 0, the second check will never run for |
The problem is not with the I am not certain that the problem is only with small prime numbers. It may also be with larger prime numbers. Since the library is mainly for generation, there is not really a way to tell besides running tests with larger prime numbers. It seems that if the issue was resolved, it may speed up generation as well (not certain of this though). I cannot find the issue with it. Any help would be greatly appreciated. Pull Requests are welcome. |
I just read the new comment above the function and see that the return value does match the expectations for |
@vdeurzen Any luck with fixing anything with miller-rabin's implementation? I cannot seem to fix it. It seems that the problem may be making it mark some probable primes as composite which would reduce the speed by a lot. I am trying to improve performance so it matches that of OpenSSL's prime number generation. What may help is looking at different miller-rabin implementations. For example, here are some resources I have been using: |
I have spent two hours debugging it to see what the problem is. Here is what I have learned so far:
Here is what I have done:
I would greatly appreciate it if you looked at the code (including anyone else who reads this) |
I'd like to provide a data point where a large prime number is not recognized as such by The following prime number was generated with
The Rust code:
Inside Cargo.toml:
On the other hand, I also checked the number with the Python library primality, which I installed with
Which yields |
Thank you so much for adding a data point. The conclusion I get from this is that only a certain set of primes are passing the primality test. I have looked through the code and cannot find the issue. Any help would be greatly appreciated. If this bug is fixed, my guess is prime number generation can be on par with OpenSSL's speed. |
Okay can everyone verify that it is working correctly so I can close this. Thank you all for your help. The primality generation is still slow and not as fast as OpenSSL's generation of primes so if anyone knows anyway to speed things up it would be much appreciated. |
I am working on running a flamegraph but it doesn't seem to like to play nice with WSL. With that, I did do some timestamp testing and I suspect that the bottle next is inside the bigint library itself. I suspect rust-num/num-bigint#169 would be a big help. Outside of the existing big-int library, there are some faster ones but it would require a decent amount of work to do the conversion. iBig looks like a good fit if we do decide to go that route. We probably should make another issues to track the performance. https://crates.io/crates/bigint-benchmark I was able to get about ~15% speed improvement by moving some of the .to_usize().unwrap() executions outside of the loop so I can get a PR for that in the meantime. I am still doing some testing to make sure its not just randomness causing the differences. Edit: It also looks like bumping all the rand and num dependencies has a massive impact on the performance. There must be some new optimizations. Still nowhere near openssl but I believe all of the runtime fat is inside the random number generation and exponentiation of the bit ints. I placed the 2048 bit results below but I tried it with 256, 512, and 2048 bit primes and, with equal iters, the rust version is about 4x slower across the board. Note that openssl always uses 64 iters so keep that in mind when comparing with the rust version's variable iters. Before: 100 runs (2048 bit prime, 8 iters)
After: 100 runs (2048 bit prime, 8 iters)
After: 100 runs(2048 bit prime, 64 iters)
|
I also have ramp-primes which uses RAMP instead of num. However, it currently is broken. It does seem to run faster than num too because it uses assembly. I am really interested in fixing this project up but have been busy lately. Feel free to edit the code some more. |
Has this been fixed? Otherwise I can pull it and fix it. |
Somewhat. I believe it does rightly mark primes but you can try it yourself. Another thing that needs to be worked on is the speed for generating primes. OpenSSL is super fast at this. num-primes is much slower. |
num-bigint is absymal performance. You can also check divisibility a bit faster than trying to use divide on Bigint but that would require writing your own arbitrary-precision library. |
I found this thread when I tried to verify that some small numbers were prime and got unexpected results and/or my program panicked. For example, if I want to verify that 3 is a prime, I got false (is not a prime) or a panic in the Miller-Rabin-Test. From what I can see, the Note that the comment So this causes the input 3 to pass the initial check in If the But the last part is only a problem if the input is three, which it never should be if the |
Use @cmpute 's num-prime or my number-theory (ENT), they are much faster and verified to a extremely high probability of accuracy. (number-theory is weighted to a minimum of 1/2^64 failure rate (primarily the rare fermat number), haven't verified cmpute's implementation) |
When I wrote a little program to check out how this crate works and I found something strange. Now I am not an expert in prime numbers so I might have done something wrong.
And the result I got was:
I expected both 17957 and 5 to be prime numbers. So I tried to generate a 8 bit prime number but then the program hang. I then tried to find the limit of the minimum number of bits for which a prime number could be generated and found that
Generator::new_prime(15)
worked fine butGenerator::new_prime(14)
made the program hang (probably stuck in an infinite loop some where).The text was updated successfully, but these errors were encountered: