diff options
| author | Legrandin <gooksankoo@hoiptorrow.mailexpire.com> | 2011-10-02 22:30:07 +0200 |
|---|---|---|
| committer | Legrandin <gooksankoo@hoiptorrow.mailexpire.com> | 2011-10-02 22:37:36 +0200 |
| commit | 9cb1a2d35d916180dee8351fe6f2ddf4f6dba72d (patch) | |
| tree | bb891e868546746a8a756ba8052bb70e79100a16 /lib/Crypto/SelfTest | |
| parent | 02103e2a5aca97b299b63723fb6752c2cbc00b23 (diff) | |
| download | pycrypto-9cb1a2d35d916180dee8351fe6f2ddf4f6dba72d.tar.gz | |
To simplify, no RNG needs to be provided with PKCS1 encryption: the one belonging to each RSA key is reused.
Error detection is internally implemented in a simpler (and safer) way for PKCS1 OAEP decryption.
General fixes to documentation for PKCS1.
Diffstat (limited to 'lib/Crypto/SelfTest')
| -rw-r--r-- | lib/Crypto/SelfTest/Cipher/test_pkcs1_15.py | 7 | ||||
| -rw-r--r-- | lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py | 16 | ||||
| -rw-r--r-- | lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py | 61 |
3 files changed, 51 insertions, 33 deletions
diff --git a/lib/Crypto/SelfTest/Cipher/test_pkcs1_15.py b/lib/Crypto/SelfTest/Cipher/test_pkcs1_15.py index f1329b1..1609770 100644 --- a/lib/Crypto/SelfTest/Cipher/test_pkcs1_15.py +++ b/lib/Crypto/SelfTest/Cipher/test_pkcs1_15.py @@ -114,13 +114,14 @@ HKukWBcq9f/UOmS0oEhai/6g+Uf7VHJdWaeO5LzuvwU= self.idx += N return r # The real test - ct = PKCS.encrypt(test[1], key, randGen(t2b(test[3]))) + key._randfunc = randGen(t2b(test[3])) + ct = PKCS.encrypt(test[1], key) self.assertEqual(ct, t2b(test[2])) def testEncrypt2(self): # Verify that encryption fail if plaintext is too long pt = '\x00'*(128-11+1) - self.assertRaises(ValueError, PKCS.encrypt, pt, self.key1024, self.rng) + self.assertRaises(ValueError, PKCS.encrypt, pt, self.key1024) def testVerify1(self): for test in self._testData: @@ -150,7 +151,7 @@ HKukWBcq9f/UOmS0oEhai/6g+Uf7VHJdWaeO5LzuvwU= # and therefore padding [8..117] for pt_len in xrange(0,128-11+1): pt = self.rng(pt_len) - ct = PKCS.encrypt(pt, self.key1024, self.rng) + ct = PKCS.encrypt(pt, self.key1024) pt2 = PKCS.decrypt(ct, self.key1024, "---") self.assertEqual(pt,pt2) diff --git a/lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py b/lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py index cffbd3b..ad1fd91 100644 --- a/lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py +++ b/lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py @@ -280,13 +280,14 @@ class PKCS1_OAEP_Tests(unittest.TestCase): self.idx += N return r # The real test - ct = PKCS.encrypt(t2b(test[1]), key, randGen(t2b(test[3])), test[4]) + key._randfunc = randGen(t2b(test[3])) + ct = PKCS.encrypt(t2b(test[1]), key, test[4]) self.assertEqual(ct, t2b(test[2])) def testEncrypt2(self): # Verify that encryption fails if plaintext is too long pt = '\x00'*(128-2*20-2+1) - self.assertRaises(ValueError, PKCS.encrypt, pt, self.key1024, self.rng) + self.assertRaises(ValueError, PKCS.encrypt, pt, self.key1024) def testDecrypt1(self): # Verify decryption using all test vectors @@ -308,7 +309,7 @@ class PKCS1_OAEP_Tests(unittest.TestCase): # Encrypt/Decrypt messages of length [0..128-2*20-2] for pt_len in xrange(0,128-2*20-2): pt = self.rng(pt_len) - ct = PKCS.encrypt(pt, self.key1024, self.rng) + ct = PKCS.encrypt(pt, self.key1024) pt2 = PKCS.decrypt(ct, self.key1024) self.assertEqual(pt,pt2) @@ -325,15 +326,16 @@ class PKCS1_OAEP_Tests(unittest.TestCase): # as the hash output size asked = 0 pt = self.rng(40) - ct = PKCS.encrypt(pt, self.key1024, localRng, hashmod) + self.key1024._randfunc = localRng + ct = PKCS.encrypt(pt, self.key1024, hashmod) self.assertEqual(PKCS.decrypt(ct, self.key1024, hashmod), pt) - self.assertEqual(asked, hashmod.digest_size) + self.assertTrue(asked > hashmod.digest_size) def testEncryptDecrypt2(self): # Verify that OAEP supports labels pt = self.rng(35) xlabel = self.rng(22) - ct = PKCS.encrypt(pt, self.key1024, self.rng, label=xlabel) + ct = PKCS.encrypt(pt, self.key1024, label=xlabel) self.assertEqual(PKCS.decrypt(ct, self.key1024, label=xlabel), pt) def testEncryptDecrypt3(self): @@ -346,7 +348,7 @@ class PKCS1_OAEP_Tests(unittest.TestCase): return '\x00'*maskLen mgfcalls = 0 pt = self.rng(32) - ct = PKCS.encrypt(pt, self.key1024, self.rng, mgfunc=newMGF) + ct = PKCS.encrypt(pt, self.key1024, mgfunc=newMGF) self.assertEqual(mgfcalls, 2) self.assertEqual(PKCS.decrypt(ct, self.key1024, mgfunc=newMGF), pt) diff --git a/lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py b/lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py index be78d17..5f94b89 100644 --- a/lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py +++ b/lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py @@ -53,6 +53,25 @@ def t2b(t): raise ValueError("Even number of characters expected") return a2b_hex(clean) +# Helper class to count how many bytes have been requested +# from the key's private RNG, w/o counting those used for blinding +class MyKey: + def __init__(self, key): + self._key = key + self.n = key.n + self.asked = 0 + def _randfunc(self, N): + self.asked += N + return self._key._randfunc(N) + def sign(self, m): + return self._key.sign(m) + def decrypt(self, m): + return self._key.decrypt(m) + def verify(self, m, p): + return self._key.verify(m, p) + def encrypt(self, m, p): + return self._key.encrypt(m, p) + class PKCS1_PSS_Tests(unittest.TestCase): # List of tuples with test data for PKCS#1 PSS @@ -325,23 +344,23 @@ class PKCS1_PSS_Tests(unittest.TestCase): for i in range(len(self._testData)): # Build the key comps = [ long(rws(self._testData[i][0][x]),16) for x in ('n','e','d') ] - key = RSA.construct(comps) + key = MyKey(RSA.construct(comps)) # Hash function h = self._testData[i][4].new() # Data to sign h.update(t2b(self._testData[i][1])) # Salt test_salt = t2b(self._testData[i][3]) + key._randfunc = lambda N: test_salt # The real test - randfunc = lambda N: test_salt - s = PKCS.sign(h, key, randfunc) + s = PKCS.sign(h, key) self.assertEqual(s, t2b(self._testData[i][2])) def testVerify1(self): for i in range(len(self._testData)): # Build the key comps = [ long(rws(self._testData[i][0][x]),16) for x in ('n','e') ] - key = RSA.construct(comps) + key = MyKey(RSA.construct(comps)) # Hash function h = self._testData[i][4].new() # Data to sign @@ -349,23 +368,19 @@ class PKCS1_PSS_Tests(unittest.TestCase): # Salt test_salt = t2b(self._testData[i][3]) # The real test + key._randfunc = lambda N: test_salt result = PKCS.verify(h, key, t2b(self._testData[i][2])) self.failUnless(result) def testSignVerify(self): - rng = Random.new().read - key = RSA.generate(1024, rng) - h = SHA1.new() h.update('blah blah blah') - # Helper function to monitor what's request from RNG - global asked, mgfcalls - def localRng(N): - global asked - asked += N - return rng(N) + rng = Random.new().read + key = MyKey(RSA.generate(1024,rng)) + # Helper function to monitor what's request from MGF + global mgfcalls def newMGF(seed,maskLen): global mgfcalls mgfcalls += 1 @@ -378,33 +393,33 @@ class PKCS1_PSS_Tests(unittest.TestCase): # Verify that sign() asks for as many random bytes # as the hash output size - asked = 0 - s = PKCS.sign(h, key, localRng) + key.asked = 0 + s = PKCS.sign(h, key) self.failUnless(PKCS.verify(h, key, s)) - self.assertEqual(asked, h.digest_size) + self.assertEqual(key.asked, h.digest_size) h = SHA1.new() h.update('blah blah blah') # Verify that sign() uses a different salt length for sLen in (0,3,21): - asked = 0 - s = PKCS.sign(h, key, localRng, saltLen=sLen) - self.assertEqual(asked, sLen) + key.asked = 0 + s = PKCS.sign(h, key, saltLen=sLen) + self.assertEqual(key.asked, sLen) self.failUnless(PKCS.verify(h, key, s, saltLen=sLen)) # Verify that sign() uses the custom MGF mgfcalls = 0 - s = PKCS.sign(h, key, rng, newMGF) + s = PKCS.sign(h, key, newMGF) self.assertEqual(mgfcalls, 1) self.failUnless(PKCS.verify(h, key, s, newMGF)) # Verify that sign() does not call the RNG # when salt length is 0, even when a new MGF is provided - asked = 0 + key.asked = 0 mgfcalls = 0 - s = PKCS.sign(h, key, localRng, newMGF, 0) - self.assertEqual(asked,0) + s = PKCS.sign(h, key, newMGF, 0) + self.assertEqual(key.asked,0) self.assertEqual(mgfcalls, 1) self.failUnless(PKCS.verify(h, key, s, newMGF, 0)) |
