mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-04 13:02:47 -05:00
Side-channel-safe rewrite of the Miller-Rabin test.
Thanks to Mark Wooding for explaining the method of doing this. At first glance it seemed _obviously_ impossible to run an algorithm that needs an iteration per factor of 2 in p-1, without a timing leak giving away the number of factors of 2 in p-1. But it's not, because you can do the M-R checks interleaved with each step of your whole modular exponentiation, and they're cheap enough that you can do them in _every_ step, even the ones where the exponent is too small for M-R to be interested in yet, and then do bitwise masking to exclude the spurious results from the final output.
This commit is contained in:
@ -1255,6 +1255,25 @@ class keygen(MyTestBase):
|
||||
assert(pow(2, n-1, n) == 1) # Fermat test would pass, but ...
|
||||
self.assertEqual(miller_rabin_test(mr, 2), "failed") # ... this fails
|
||||
|
||||
# A white-box test for the side-channel-safe M-R
|
||||
# implementation, which has to check a^e against +-1 for every
|
||||
# exponent e of the form floor((n-1) / power of 2), so as to
|
||||
# avoid giving away exactly how many of the trailing values of
|
||||
# that sequence are significant to the test.
|
||||
#
|
||||
# When the power of 2 is large enough that the division was
|
||||
# not exact, the results of these comparisons are _not_
|
||||
# significant to the test, and we're required to ignore them!
|
||||
#
|
||||
# This pair of values has the property that none of the values
|
||||
# legitimately computed by M-R is either +1 _or_ -1, but if
|
||||
# you shift n-1 right by one too many bits (losing the lowest
|
||||
# set bit of 0x6d00 to get 0x36), then _that_ power of the
|
||||
# witness integer is -1. This should not cause a spurious pass.
|
||||
n = 0x6d01
|
||||
mr = miller_rabin_new(n)
|
||||
self.assertEqual(miller_rabin_test(mr, 0x251), "failed")
|
||||
|
||||
class crypt(MyTestBase):
|
||||
def testSSH1Fingerprint(self):
|
||||
# Example key and reference fingerprint value generated by
|
||||
|
Reference in New Issue
Block a user