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
Incorrect result when using Integer::ModInverse #602
Comments
Python agrees with OpenSSL and Botan when using this one-liner for the modular multiplicative inverse:
|
Thanks @denisbider, @mouse07410, @MarcelRaad, So it looks like two problems. First is a memory error due to
After clearing the memory error:
We have the second problem, which is the incorrect result. |
This patch will need more testing, but it arrives at the correct result for the test case above. The patch also passes I asked WD about the bigint implementation several years ago because I did not recognize it. WD said he created the numerical algorithms, so we don't really have a reference to work with like Knuth, Karatsuba or the HAC. I'm not entirely clear on the preconditions to
|
cryptest.sh revealed a corner case still producing an incorrect result. We need to check for '*this > m', not '*this > 2m-1'. The corner case looks obscure. The failure surfaced as 1 failed self test for about every 2048 tests. It was also in a code path where 'a' was explicitly set to '2m-1', with 'm' random. The test result can be duplicated with 'cryptest.exe v 9996 1521969687'. The value '1521969687' is a seed for the random number generator to reproduce.
Cleared at Commit ff82b5a886d3 and Commit 932f392b2d33. The ff82b5a commit cleared the bulk of the problems, including the memory error. The The 932f392 commit cleared a more obscure corner case. Most runs were OK. About 1 in 13 runs produced 1 failure (each run performs about 2048 individual tests). |
Thanks for this fix, Jeff. :) This explains a mystery that's been on the back of my mind for perhaps 15 years, that I never quite figured out previously. :D |
@denisbider, @mouse07410, @MarcelRaad, I think I should summarize the fix here since the first check-in was incomplete, and we needed a second check-in. In between there were lots of check-ins that added self-tests, so they created a lot of noise. Here was the original code causing problems:
Here is the fixed code. We kept the recursion but we split it into a first/next call. The "first" part validates/fixes the parameters. The "next" part applies the algorithm without the parameter fixes/validations:
The modular reduction in The code also moved to Finally, a lot of tests were checked in to cover this case an more. Also see @randombit also suggested we setup OSS-Fuzz. I started the process yesterday. OSS-Fuzz is a Google project and it requires a GMail address. I tried to register cryptopp@gmail.com but someone else was using it. I wrote to them and asked they give it to us for use with OSS-Fuzz. If we don't get the email address we want then we'll use another GMail address that satisfies OSS-Fuzz and can be shared among folks like @noloader, @denisbider, @mouse07410 and @MarcelRaad. |
This issue was privately reported in an email:
Crypto++ result:
Botan and OpenSSL result:
Here is Integer::InverseMod:
The text was updated successfully, but these errors were encountered: