summaryrefslogtreecommitdiff
path: root/lib/Crypto/SelfTest
diff options
context:
space:
mode:
authorLegrandin <gooksankoo@hoiptorrow.mailexpire.com>2011-10-02 22:30:07 +0200
committerLegrandin <gooksankoo@hoiptorrow.mailexpire.com>2011-10-02 22:37:36 +0200
commit9cb1a2d35d916180dee8351fe6f2ddf4f6dba72d (patch)
treebb891e868546746a8a756ba8052bb70e79100a16 /lib/Crypto/SelfTest
parent02103e2a5aca97b299b63723fb6752c2cbc00b23 (diff)
downloadpycrypto-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.py7
-rw-r--r--lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py16
-rw-r--r--lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py61
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))