split platform

This commit is contained in:
j 2016-02-06 15:06:57 +05:30
commit 8c9b09577d
2261 changed files with 676163 additions and 0 deletions

View file

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Cipher/__init__.py: Self-test for cipher modules
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test for cipher modules"""
__revision__ = "$Id$"
def get_tests(config={}):
tests = []
from Crypto.SelfTest.Cipher import test_AES; tests += test_AES.get_tests(config=config)
from Crypto.SelfTest.Cipher import test_ARC2; tests += test_ARC2.get_tests(config=config)
from Crypto.SelfTest.Cipher import test_ARC4; tests += test_ARC4.get_tests(config=config)
from Crypto.SelfTest.Cipher import test_Blowfish; tests += test_Blowfish.get_tests(config=config)
from Crypto.SelfTest.Cipher import test_CAST; tests += test_CAST.get_tests(config=config)
from Crypto.SelfTest.Cipher import test_DES3; tests += test_DES3.get_tests(config=config)
from Crypto.SelfTest.Cipher import test_DES; tests += test_DES.get_tests(config=config)
from Crypto.SelfTest.Cipher import test_XOR; tests += test_XOR.get_tests(config=config)
from Crypto.SelfTest.Cipher import test_pkcs1_15; tests += test_pkcs1_15.get_tests(config=config)
from Crypto.SelfTest.Cipher import test_pkcs1_oaep; tests += test_pkcs1_oaep.get_tests(config=config)
return tests
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,399 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/common.py: Common code for Crypto.SelfTest.Hash
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-testing for PyCrypto hash modules"""
__revision__ = "$Id$"
import sys
import unittest
from binascii import a2b_hex, b2a_hex
from Crypto.Util.py3compat import *
# For compatibility with Python 2.1 and Python 2.2
if sys.hexversion < 0x02030000:
# Python 2.1 doesn't have a dict() function
# Python 2.2 dict() function raises TypeError if you do dict(MD5='blah')
def dict(**kwargs):
return kwargs.copy()
else:
dict = dict
class _NoDefault: pass # sentinel object
def _extract(d, k, default=_NoDefault):
"""Get an item from a dictionary, and remove it from the dictionary."""
try:
retval = d[k]
except KeyError:
if default is _NoDefault:
raise
return default
del d[k]
return retval
# Generic cipher test case
class CipherSelfTest(unittest.TestCase):
def __init__(self, module, params):
unittest.TestCase.__init__(self)
self.module = module
# Extract the parameters
params = params.copy()
self.description = _extract(params, 'description')
self.key = b(_extract(params, 'key'))
self.plaintext = b(_extract(params, 'plaintext'))
self.ciphertext = b(_extract(params, 'ciphertext'))
self.module_name = _extract(params, 'module_name', None)
mode = _extract(params, 'mode', None)
self.mode_name = str(mode)
if mode is not None:
# Block cipher
self.mode = getattr(self.module, "MODE_" + mode)
self.iv = _extract(params, 'iv', None)
if self.iv is not None: self.iv = b(self.iv)
# Only relevant for OPENPGP mode
self.encrypted_iv = _extract(params, 'encrypted_iv', None)
if self.encrypted_iv is not None:
self.encrypted_iv = b(self.encrypted_iv)
else:
# Stream cipher
self.mode = None
self.iv = None
self.extra_params = params
def shortDescription(self):
return self.description
def _new(self, do_decryption=0):
params = self.extra_params.copy()
# Handle CTR mode parameters. By default, we use Counter.new(self.module.block_size)
if hasattr(self.module, "MODE_CTR") and self.mode == self.module.MODE_CTR:
from Crypto.Util import Counter
ctr_class = _extract(params, 'ctr_class', Counter.new)
ctr_params = _extract(params, 'ctr_params', {}).copy()
if 'prefix' in ctr_params: ctr_params['prefix'] = a2b_hex(b(ctr_params['prefix']))
if 'suffix' in ctr_params: ctr_params['suffix'] = a2b_hex(b(ctr_params['suffix']))
if 'nbits' not in ctr_params:
ctr_params['nbits'] = 8*(self.module.block_size - len(ctr_params.get('prefix', '')) - len(ctr_params.get('suffix', '')))
params['counter'] = ctr_class(**ctr_params)
if self.mode is None:
# Stream cipher
return self.module.new(a2b_hex(self.key), **params)
elif self.iv is None:
# Block cipher without iv
return self.module.new(a2b_hex(self.key), self.mode, **params)
else:
# Block cipher with iv
if do_decryption and self.mode == self.module.MODE_OPENPGP:
# In PGP mode, the IV to feed for decryption is the *encrypted* one
return self.module.new(a2b_hex(self.key), self.mode, a2b_hex(self.encrypted_iv), **params)
else:
return self.module.new(a2b_hex(self.key), self.mode, a2b_hex(self.iv), **params)
def runTest(self):
plaintext = a2b_hex(self.plaintext)
ciphertext = a2b_hex(self.ciphertext)
ct1 = b2a_hex(self._new().encrypt(plaintext))
pt1 = b2a_hex(self._new(1).decrypt(ciphertext))
ct2 = b2a_hex(self._new().encrypt(plaintext))
pt2 = b2a_hex(self._new(1).decrypt(ciphertext))
if hasattr(self.module, "MODE_OPENPGP") and self.mode == self.module.MODE_OPENPGP:
# In PGP mode, data returned by the first encrypt()
# is prefixed with the encrypted IV.
# Here we check it and then remove it from the ciphertexts.
eilen = len(self.encrypted_iv)
self.assertEqual(self.encrypted_iv, ct1[:eilen])
self.assertEqual(self.encrypted_iv, ct2[:eilen])
ct1 = ct1[eilen:]
ct2 = ct2[eilen:]
self.assertEqual(self.ciphertext, ct1) # encrypt
self.assertEqual(self.ciphertext, ct2) # encrypt (second time)
self.assertEqual(self.plaintext, pt1) # decrypt
self.assertEqual(self.plaintext, pt2) # decrypt (second time)
class CipherStreamingSelfTest(CipherSelfTest):
def shortDescription(self):
desc = self.module_name
if self.mode is not None:
desc += " in %s mode" % (self.mode_name,)
return "%s should behave like a stream cipher" % (desc,)
def runTest(self):
plaintext = a2b_hex(self.plaintext)
ciphertext = a2b_hex(self.ciphertext)
# The cipher should work like a stream cipher
# Test counter mode encryption, 3 bytes at a time
ct3 = []
cipher = self._new()
for i in range(0, len(plaintext), 3):
ct3.append(cipher.encrypt(plaintext[i:i+3]))
ct3 = b2a_hex(b("").join(ct3))
self.assertEqual(self.ciphertext, ct3) # encryption (3 bytes at a time)
# Test counter mode decryption, 3 bytes at a time
pt3 = []
cipher = self._new()
for i in range(0, len(ciphertext), 3):
pt3.append(cipher.encrypt(ciphertext[i:i+3]))
# PY3K: This is meant to be text, do not change to bytes (data)
pt3 = b2a_hex(b("").join(pt3))
self.assertEqual(self.plaintext, pt3) # decryption (3 bytes at a time)
class CTRSegfaultTest(unittest.TestCase):
def __init__(self, module, params):
unittest.TestCase.__init__(self)
self.module = module
self.key = b(params['key'])
self.module_name = params.get('module_name', None)
def shortDescription(self):
return """Regression test: %s.new(key, %s.MODE_CTR) should raise TypeError, not segfault""" % (self.module_name, self.module_name)
def runTest(self):
self.assertRaises(TypeError, self.module.new, a2b_hex(self.key), self.module.MODE_CTR)
class CTRWraparoundTest(unittest.TestCase):
def __init__(self, module, params):
unittest.TestCase.__init__(self)
self.module = module
self.key = b(params['key'])
self.module_name = params.get('module_name', None)
def shortDescription(self):
return """Regression test: %s with MODE_CTR should raise OverflowError on wraparound when shortcut used""" % (self.module_name,)
def runTest(self):
from Crypto.Util import Counter
for disable_shortcut in (0, 1): # (False, True) Test CTR-mode shortcut and PyObject_CallObject code paths
for little_endian in (0, 1): # (False, True) Test both endiannesses
ctr = Counter.new(8*self.module.block_size, initial_value=2**(8*self.module.block_size)-1, little_endian=little_endian, disable_shortcut=disable_shortcut)
cipher = self.module.new(a2b_hex(self.key), self.module.MODE_CTR, counter=ctr)
block = b("\x00") * self.module.block_size
cipher.encrypt(block)
self.assertRaises(OverflowError, cipher.encrypt, block)
class CFBSegmentSizeTest(unittest.TestCase):
def __init__(self, module, params):
unittest.TestCase.__init__(self)
self.module = module
self.key = b(params['key'])
self.description = params['description']
def shortDescription(self):
return self.description
def runTest(self):
"""Regression test: m.new(key, m.MODE_CFB, segment_size=N) should require segment_size to be a multiple of 8 bits"""
for i in range(1, 8):
self.assertRaises(ValueError, self.module.new, a2b_hex(self.key), self.module.MODE_CFB, segment_size=i)
self.module.new(a2b_hex(self.key), self.module.MODE_CFB, "\0"*self.module.block_size, segment_size=8) # should succeed
class RoundtripTest(unittest.TestCase):
def __init__(self, module, params):
from Crypto import Random
unittest.TestCase.__init__(self)
self.module = module
self.iv = Random.get_random_bytes(module.block_size)
self.key = b(params['key'])
self.plaintext = 100 * b(params['plaintext'])
self.module_name = params.get('module_name', None)
def shortDescription(self):
return """%s .decrypt() output of .encrypt() should not be garbled""" % (self.module_name,)
def runTest(self):
for mode in (self.module.MODE_ECB, self.module.MODE_CBC, self.module.MODE_CFB, self.module.MODE_OFB, self.module.MODE_OPENPGP):
encryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv)
ciphertext = encryption_cipher.encrypt(self.plaintext)
if mode != self.module.MODE_OPENPGP:
decryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv)
else:
eiv = ciphertext[:self.module.block_size+2]
ciphertext = ciphertext[self.module.block_size+2:]
decryption_cipher = self.module.new(a2b_hex(self.key), mode, eiv)
decrypted_plaintext = decryption_cipher.decrypt(ciphertext)
self.assertEqual(self.plaintext, decrypted_plaintext)
class PGPTest(unittest.TestCase):
def __init__(self, module, params):
unittest.TestCase.__init__(self)
self.module = module
self.key = b(params['key'])
def shortDescription(self):
return "MODE_PGP was implemented incorrectly and insecurely. It's completely banished now."
def runTest(self):
self.assertRaises(ValueError, self.module.new, a2b_hex(self.key),
self.module.MODE_PGP)
class IVLengthTest(unittest.TestCase):
def __init__(self, module, params):
unittest.TestCase.__init__(self)
self.module = module
self.key = b(params['key'])
def shortDescription(self):
return "Check that all modes except MODE_ECB and MODE_CTR require an IV of the proper length"
def runTest(self):
self.assertRaises(ValueError, self.module.new, a2b_hex(self.key),
self.module.MODE_CBC, "")
self.assertRaises(ValueError, self.module.new, a2b_hex(self.key),
self.module.MODE_CFB, "")
self.assertRaises(ValueError, self.module.new, a2b_hex(self.key),
self.module.MODE_OFB, "")
self.assertRaises(ValueError, self.module.new, a2b_hex(self.key),
self.module.MODE_OPENPGP, "")
self.module.new(a2b_hex(self.key), self.module.MODE_ECB, "")
self.module.new(a2b_hex(self.key), self.module.MODE_CTR, "", counter=self._dummy_counter)
def _dummy_counter(self):
return "\0" * self.module.block_size
def make_block_tests(module, module_name, test_data):
tests = []
extra_tests_added = 0
for i in range(len(test_data)):
row = test_data[i]
# Build the "params" dictionary
params = {'mode': 'ECB'}
if len(row) == 3:
(params['plaintext'], params['ciphertext'], params['key']) = row
elif len(row) == 4:
(params['plaintext'], params['ciphertext'], params['key'], params['description']) = row
elif len(row) == 5:
(params['plaintext'], params['ciphertext'], params['key'], params['description'], extra_params) = row
params.update(extra_params)
else:
raise AssertionError("Unsupported tuple size %d" % (len(row),))
# Build the display-name for the test
p2 = params.copy()
p_key = _extract(p2, 'key')
p_plaintext = _extract(p2, 'plaintext')
p_ciphertext = _extract(p2, 'ciphertext')
p_description = _extract(p2, 'description', None)
p_mode = p2.get('mode', 'ECB')
if p_mode == 'ECB':
_extract(p2, 'mode', 'ECB')
if p_description is not None:
description = p_description
elif p_mode == 'ECB' and not p2:
description = "p=%s, k=%s" % (p_plaintext, p_key)
else:
description = "p=%s, k=%s, %r" % (p_plaintext, p_key, p2)
name = "%s #%d: %s" % (module_name, i+1, description)
params['description'] = name
params['module_name'] = module_name
# Add extra test(s) to the test suite before the current test
if not extra_tests_added:
tests += [
CTRSegfaultTest(module, params),
CTRWraparoundTest(module, params),
CFBSegmentSizeTest(module, params),
RoundtripTest(module, params),
PGPTest(module, params),
IVLengthTest(module, params),
]
extra_tests_added = 1
# Add the current test to the test suite
tests.append(CipherSelfTest(module, params))
# When using CTR mode, test that the interface behaves like a stream cipher
if p_mode == 'CTR':
tests.append(CipherStreamingSelfTest(module, params))
# When using CTR mode, test the non-shortcut code path.
if p_mode == 'CTR' and 'ctr_class' not in params:
params2 = params.copy()
params2['description'] += " (shortcut disabled)"
ctr_params2 = params.get('ctr_params', {}).copy()
params2['ctr_params'] = ctr_params2
if 'disable_shortcut' not in params2['ctr_params']:
params2['ctr_params']['disable_shortcut'] = 1
tests.append(CipherSelfTest(module, params2))
return tests
def make_stream_tests(module, module_name, test_data):
tests = []
for i in range(len(test_data)):
row = test_data[i]
# Build the "params" dictionary
params = {}
if len(row) == 3:
(params['plaintext'], params['ciphertext'], params['key']) = row
elif len(row) == 4:
(params['plaintext'], params['ciphertext'], params['key'], params['description']) = row
elif len(row) == 5:
(params['plaintext'], params['ciphertext'], params['key'], params['description'], extra_params) = row
params.update(extra_params)
else:
raise AssertionError("Unsupported tuple size %d" % (len(row),))
# Build the display-name for the test
p2 = params.copy()
p_key = _extract(p2, 'key')
p_plaintext = _extract(p2, 'plaintext')
p_ciphertext = _extract(p2, 'ciphertext')
p_description = _extract(p2, 'description', None)
if p_description is not None:
description = p_description
elif not p2:
description = "p=%s, k=%s" % (p_plaintext, p_key)
else:
description = "p=%s, k=%s, %r" % (p_plaintext, p_key, p2)
name = "%s #%d: %s" % (module_name, i+1, description)
params['description'] = name
params['module_name'] = module_name
# Add the test to the test suite
tests.append(CipherSelfTest(module, params))
tests.append(CipherStreamingSelfTest(module, params))
return tests
# vim:set ts=4 sw=4 sts=4 expandtab:

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,124 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Cipher/ARC2.py: Self-test for the Alleged-RC2 cipher
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Cipher.ARC2"""
__revision__ = "$Id$"
from .common import dict # For compatibility with Python 2.1 and 2.2
import unittest
from Crypto.Util.py3compat import *
# This is a list of (plaintext, ciphertext, key[, description[, extra_params]]) tuples.
test_data = [
# Test vectors from RFC 2268
# 63-bit effective key length
('0000000000000000', 'ebb773f993278eff', '0000000000000000',
'RFC2268-1', dict(effective_keylen=63)),
# 64-bit effective key length
('ffffffffffffffff', '278b27e42e2f0d49', 'ffffffffffffffff',
'RFC2268-2', dict(effective_keylen=64)),
('1000000000000001', '30649edf9be7d2c2', '3000000000000000',
'RFC2268-3', dict(effective_keylen=64)),
('0000000000000000', '61a8a244adacccf0', '88',
'RFC2268-4', dict(effective_keylen=64)),
('0000000000000000', '6ccf4308974c267f', '88bca90e90875a',
'RFC2268-5', dict(effective_keylen=64)),
('0000000000000000', '1a807d272bbe5db1', '88bca90e90875a7f0f79c384627bafb2',
'RFC2268-6', dict(effective_keylen=64)),
# 128-bit effective key length
('0000000000000000', '2269552ab0f85ca6', '88bca90e90875a7f0f79c384627bafb2',
"RFC2268-7", dict(effective_keylen=128)),
('0000000000000000', '5b78d3a43dfff1f1',
'88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e',
"RFC2268-8", dict(effective_keylen=129)),
# Test vectors from PyCrypto 2.0.1's testdata.py
# 1024-bit effective key length
('0000000000000000', '624fb3e887419e48', '5068696c6970476c617373',
'PCTv201-0'),
('ffffffffffffffff', '79cadef44c4a5a85', '5068696c6970476c617373',
'PCTv201-1'),
('0001020304050607', '90411525b34e4c2c', '5068696c6970476c617373',
'PCTv201-2'),
('0011223344556677', '078656aaba61cbfb', '5068696c6970476c617373',
'PCTv201-3'),
('0000000000000000', 'd7bcc5dbb4d6e56a', 'ffffffffffffffff',
'PCTv201-4'),
('ffffffffffffffff', '7259018ec557b357', 'ffffffffffffffff',
'PCTv201-5'),
('0001020304050607', '93d20a497f2ccb62', 'ffffffffffffffff',
'PCTv201-6'),
('0011223344556677', 'cb15a7f819c0014d', 'ffffffffffffffff',
'PCTv201-7'),
('0000000000000000', '63ac98cdf3843a7a', 'ffffffffffffffff5065746572477265656e6177617953e5ffe553',
'PCTv201-8'),
('ffffffffffffffff', '3fb49e2fa12371dd', 'ffffffffffffffff5065746572477265656e6177617953e5ffe553',
'PCTv201-9'),
('0001020304050607', '46414781ab387d5f', 'ffffffffffffffff5065746572477265656e6177617953e5ffe553',
'PCTv201-10'),
('0011223344556677', 'be09dc81feaca271', 'ffffffffffffffff5065746572477265656e6177617953e5ffe553',
'PCTv201-11'),
('0000000000000000', 'e64221e608be30ab', '53e5ffe553',
'PCTv201-12'),
('ffffffffffffffff', '862bc60fdcd4d9a9', '53e5ffe553',
'PCTv201-13'),
('0001020304050607', '6a34da50fa5e47de', '53e5ffe553',
'PCTv201-14'),
('0011223344556677', '584644c34503122c', '53e5ffe553',
'PCTv201-15'),
]
class BufferOverflowTest(unittest.TestCase):
# Test a buffer overflow found in older versions of PyCrypto
def setUp(self):
global ARC2
from Crypto.Cipher import ARC2
def runTest(self):
"""ARC2 with keylength > 128"""
key = "x" * 16384
mode = ARC2.MODE_ECB
self.assertRaises(ValueError, ARC2.new, key, mode)
def get_tests(config={}):
from Crypto.Cipher import ARC2
from .common import make_block_tests
tests = make_block_tests(ARC2, "ARC2", test_data)
tests.append(BufferOverflowTest())
return tests
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,81 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Cipher/ARC4.py: Self-test for the Alleged-RC4 cipher
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Cipher.ARC4"""
__revision__ = "$Id$"
from Crypto.Util.py3compat import *
# This is a list of (plaintext, ciphertext, key[, description]) tuples.
test_data = [
# Test vectors from Eric Rescorla's message with the subject
# "RC4 compatibility testing", sent to the cipherpunks mailing list on
# September 13, 1994.
# http://cypherpunks.venona.com/date/1994/09/msg00420.html
('0123456789abcdef', '75b7878099e0c596', '0123456789abcdef',
'Test vector 0'),
('0000000000000000', '7494c2e7104b0879', '0123456789abcdef',
'Test vector 1'),
('0000000000000000', 'de188941a3375d3a', '0000000000000000',
'Test vector 2'),
('00000000000000000000', 'd6a141a7ec3c38dfbd61', 'ef012345',
'Test vector 3'),
('01' * 512,
'7595c3e6114a09780c4ad452338e1ffd9a1be9498f813d76533449b6778dcad8'
+ 'c78a8d2ba9ac66085d0e53d59c26c2d1c490c1ebbe0ce66d1b6b1b13b6b919b8'
+ '47c25a91447a95e75e4ef16779cde8bf0a95850e32af9689444fd377108f98fd'
+ 'cbd4e726567500990bcc7e0ca3c4aaa304a387d20f3b8fbbcd42a1bd311d7a43'
+ '03dda5ab078896ae80c18b0af66dff319616eb784e495ad2ce90d7f772a81747'
+ 'b65f62093b1e0db9e5ba532fafec47508323e671327df9444432cb7367cec82f'
+ '5d44c0d00b67d650a075cd4b70dedd77eb9b10231b6b5b741347396d62897421'
+ 'd43df9b42e446e358e9c11a9b2184ecbef0cd8e7a877ef968f1390ec9b3d35a5'
+ '585cb009290e2fcde7b5ec66d9084be44055a619d9dd7fc3166f9487f7cb2729'
+ '12426445998514c15d53a18c864ce3a2b7555793988126520eacf2e3066e230c'
+ '91bee4dd5304f5fd0405b35bd99c73135d3d9bc335ee049ef69b3867bf2d7bd1'
+ 'eaa595d8bfc0066ff8d31509eb0c6caa006c807a623ef84c3d33c195d23ee320'
+ 'c40de0558157c822d4b8c569d849aed59d4e0fd7f379586b4b7ff684ed6a189f'
+ '7486d49b9c4bad9ba24b96abf924372c8a8fffb10d55354900a77a3db5f205e1'
+ 'b99fcd8660863a159ad4abe40fa48934163ddde542a6585540fd683cbfd8c00f'
+ '12129a284deacc4cdefe58be7137541c047126c8d49e2755ab181ab7e940b0c0',
'0123456789abcdef',
"Test vector 4"),
]
def get_tests(config={}):
from Crypto.Cipher import ARC4
from .common import make_stream_tests
return make_stream_tests(ARC4, "ARC4", test_data)
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,113 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Cipher/test_Blowfish.py: Self-test for the Blowfish cipher
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Cipher.Blowfish"""
__revision__ = "$Id$"
from Crypto.Util.py3compat import *
# This is a list of (plaintext, ciphertext, key) tuples.
test_data = [
# Test vectors from http://www.schneier.com/code/vectors.txt
('0000000000000000', '4ef997456198dd78', '0000000000000000'),
('ffffffffffffffff', '51866fd5b85ecb8a', 'ffffffffffffffff'),
('1000000000000001', '7d856f9a613063f2', '3000000000000000'),
('1111111111111111', '2466dd878b963c9d', '1111111111111111'),
('1111111111111111', '61f9c3802281b096', '0123456789abcdef'),
('0123456789abcdef', '7d0cc630afda1ec7', '1111111111111111'),
('0000000000000000', '4ef997456198dd78', '0000000000000000'),
('0123456789abcdef', '0aceab0fc6a0a28d', 'fedcba9876543210'),
('01a1d6d039776742', '59c68245eb05282b', '7ca110454a1a6e57'),
('5cd54ca83def57da', 'b1b8cc0b250f09a0', '0131d9619dc1376e'),
('0248d43806f67172', '1730e5778bea1da4', '07a1133e4a0b2686'),
('51454b582ddf440a', 'a25e7856cf2651eb', '3849674c2602319e'),
('42fd443059577fa2', '353882b109ce8f1a', '04b915ba43feb5b6'),
('059b5e0851cf143a', '48f4d0884c379918', '0113b970fd34f2ce'),
('0756d8e0774761d2', '432193b78951fc98', '0170f175468fb5e6'),
('762514b829bf486a', '13f04154d69d1ae5', '43297fad38e373fe'),
('3bdd119049372802', '2eedda93ffd39c79', '07a7137045da2a16'),
('26955f6835af609a', 'd887e0393c2da6e3', '04689104c2fd3b2f'),
('164d5e404f275232', '5f99d04f5b163969', '37d06bb516cb7546'),
('6b056e18759f5cca', '4a057a3b24d3977b', '1f08260d1ac2465e'),
('004bd6ef09176062', '452031c1e4fada8e', '584023641aba6176'),
('480d39006ee762f2', '7555ae39f59b87bd', '025816164629b007'),
('437540c8698f3cfa', '53c55f9cb49fc019', '49793ebc79b3258f'),
('072d43a077075292', '7a8e7bfa937e89a3', '4fb05e1515ab73a7'),
('02fe55778117f12a', 'cf9c5d7a4986adb5', '49e95d6d4ca229bf'),
('1d9d5c5018f728c2', 'd1abb290658bc778', '018310dc409b26d6'),
('305532286d6f295a', '55cb3774d13ef201', '1c587f1c13924fef'),
('0123456789abcdef', 'fa34ec4847b268b2', '0101010101010101'),
('0123456789abcdef', 'a790795108ea3cae', '1f1f1f1f0e0e0e0e'),
('0123456789abcdef', 'c39e072d9fac631d', 'e0fee0fef1fef1fe'),
('ffffffffffffffff', '014933e0cdaff6e4', '0000000000000000'),
('0000000000000000', 'f21e9a77b71c49bc', 'ffffffffffffffff'),
('0000000000000000', '245946885754369a', '0123456789abcdef'),
('ffffffffffffffff', '6b5c5a9c5d9e0a5a', 'fedcba9876543210'),
('fedcba9876543210', 'f9ad597c49db005e', 'f0'),
('fedcba9876543210', 'e91d21c1d961a6d6', 'f0e1'),
('fedcba9876543210', 'e9c2b70a1bc65cf3', 'f0e1d2'),
('fedcba9876543210', 'be1e639408640f05', 'f0e1d2c3'),
('fedcba9876543210', 'b39e44481bdb1e6e', 'f0e1d2c3b4'),
('fedcba9876543210', '9457aa83b1928c0d', 'f0e1d2c3b4a5'),
('fedcba9876543210', '8bb77032f960629d', 'f0e1d2c3b4a596'),
('fedcba9876543210', 'e87a244e2cc85e82', 'f0e1d2c3b4a59687'),
('fedcba9876543210', '15750e7a4f4ec577', 'f0e1d2c3b4a5968778'),
('fedcba9876543210', '122ba70b3ab64ae0', 'f0e1d2c3b4a596877869'),
('fedcba9876543210', '3a833c9affc537f6', 'f0e1d2c3b4a5968778695a'),
('fedcba9876543210', '9409da87a90f6bf2', 'f0e1d2c3b4a5968778695a4b'),
('fedcba9876543210', '884f80625060b8b4', 'f0e1d2c3b4a5968778695a4b3c'),
('fedcba9876543210', '1f85031c19e11968', 'f0e1d2c3b4a5968778695a4b3c2d'),
('fedcba9876543210', '79d9373a714ca34f', 'f0e1d2c3b4a5968778695a4b3c2d1e'),
('fedcba9876543210', '93142887ee3be15c',
'f0e1d2c3b4a5968778695a4b3c2d1e0f'),
('fedcba9876543210', '03429e838ce2d14b',
'f0e1d2c3b4a5968778695a4b3c2d1e0f00'),
('fedcba9876543210', 'a4299e27469ff67b',
'f0e1d2c3b4a5968778695a4b3c2d1e0f0011'),
('fedcba9876543210', 'afd5aed1c1bc96a8',
'f0e1d2c3b4a5968778695a4b3c2d1e0f001122'),
('fedcba9876543210', '10851c0e3858da9f',
'f0e1d2c3b4a5968778695a4b3c2d1e0f00112233'),
('fedcba9876543210', 'e6f51ed79b9db21f',
'f0e1d2c3b4a5968778695a4b3c2d1e0f0011223344'),
('fedcba9876543210', '64a6e14afd36b46f',
'f0e1d2c3b4a5968778695a4b3c2d1e0f001122334455'),
('fedcba9876543210', '80c7d7d45a5479ad',
'f0e1d2c3b4a5968778695a4b3c2d1e0f00112233445566'),
('fedcba9876543210', '05044b62fa52d080',
'f0e1d2c3b4a5968778695a4b3c2d1e0f0011223344556677'),
]
def get_tests(config={}):
from Crypto.Cipher import Blowfish
from .common import make_block_tests
return make_block_tests(Blowfish, "Blowfish", test_data)
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Cipher/CAST.py: Self-test for the CAST-128 (CAST5) cipher
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Cipher.CAST"""
__revision__ = "$Id$"
from Crypto.Util.py3compat import *
# This is a list of (plaintext, ciphertext, key) tuples.
test_data = [
# Test vectors from RFC 2144, B.1
('0123456789abcdef', '238b4fe5847e44b2',
'0123456712345678234567893456789a',
'128-bit key'),
('0123456789abcdef', 'eb6a711a2c02271b',
'01234567123456782345',
'80-bit key'),
('0123456789abcdef', '7ac816d16e9b302e',
'0123456712',
'40-bit key'),
]
def get_tests(config={}):
from Crypto.Cipher import CAST
from .common import make_block_tests
return make_block_tests(CAST, "CAST", test_data)
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,339 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Cipher/DES.py: Self-test for the (Single) DES cipher
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Cipher.DES"""
__revision__ = "$Id$"
from .common import dict # For compatibility with Python 2.1 and 2.2
from Crypto.Util.py3compat import *
import unittest
# This is a list of (plaintext, ciphertext, key, description) tuples.
SP800_17_B1_KEY = '01' * 8
SP800_17_B2_PT = '00' * 8
test_data = [
# Test vectors from Appendix A of NIST SP 800-17
# "Modes of Operation Validation System (MOVS): Requirements and Procedures"
# http://csrc.nist.gov/publications/nistpubs/800-17/800-17.pdf
# Appendix A - "Sample Round Outputs for the DES"
('0000000000000000', '82dcbafbdeab6602', '10316e028c8f3b4a',
"NIST SP800-17 A"),
# Table B.1 - Variable Plaintext Known Answer Test
('8000000000000000', '95f8a5e5dd31d900', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #0'),
('4000000000000000', 'dd7f121ca5015619', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #1'),
('2000000000000000', '2e8653104f3834ea', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #2'),
('1000000000000000', '4bd388ff6cd81d4f', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #3'),
('0800000000000000', '20b9e767b2fb1456', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #4'),
('0400000000000000', '55579380d77138ef', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #5'),
('0200000000000000', '6cc5defaaf04512f', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #6'),
('0100000000000000', '0d9f279ba5d87260', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #7'),
('0080000000000000', 'd9031b0271bd5a0a', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #8'),
('0040000000000000', '424250b37c3dd951', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #9'),
('0020000000000000', 'b8061b7ecd9a21e5', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #10'),
('0010000000000000', 'f15d0f286b65bd28', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #11'),
('0008000000000000', 'add0cc8d6e5deba1', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #12'),
('0004000000000000', 'e6d5f82752ad63d1', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #13'),
('0002000000000000', 'ecbfe3bd3f591a5e', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #14'),
('0001000000000000', 'f356834379d165cd', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #15'),
('0000800000000000', '2b9f982f20037fa9', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #16'),
('0000400000000000', '889de068a16f0be6', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #17'),
('0000200000000000', 'e19e275d846a1298', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #18'),
('0000100000000000', '329a8ed523d71aec', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #19'),
('0000080000000000', 'e7fce22557d23c97', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #20'),
('0000040000000000', '12a9f5817ff2d65d', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #21'),
('0000020000000000', 'a484c3ad38dc9c19', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #22'),
('0000010000000000', 'fbe00a8a1ef8ad72', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #23'),
('0000008000000000', '750d079407521363', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #24'),
('0000004000000000', '64feed9c724c2faf', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #25'),
('0000002000000000', 'f02b263b328e2b60', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #26'),
('0000001000000000', '9d64555a9a10b852', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #27'),
('0000000800000000', 'd106ff0bed5255d7', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #28'),
('0000000400000000', 'e1652c6b138c64a5', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #29'),
('0000000200000000', 'e428581186ec8f46', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #30'),
('0000000100000000', 'aeb5f5ede22d1a36', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #31'),
('0000000080000000', 'e943d7568aec0c5c', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #32'),
('0000000040000000', 'df98c8276f54b04b', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #33'),
('0000000020000000', 'b160e4680f6c696f', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #34'),
('0000000010000000', 'fa0752b07d9c4ab8', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #35'),
('0000000008000000', 'ca3a2b036dbc8502', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #36'),
('0000000004000000', '5e0905517bb59bcf', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #37'),
('0000000002000000', '814eeb3b91d90726', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #38'),
('0000000001000000', '4d49db1532919c9f', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #39'),
('0000000000800000', '25eb5fc3f8cf0621', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #40'),
('0000000000400000', 'ab6a20c0620d1c6f', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #41'),
('0000000000200000', '79e90dbc98f92cca', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #42'),
('0000000000100000', '866ecedd8072bb0e', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #43'),
('0000000000080000', '8b54536f2f3e64a8', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #44'),
('0000000000040000', 'ea51d3975595b86b', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #45'),
('0000000000020000', 'caffc6ac4542de31', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #46'),
('0000000000010000', '8dd45a2ddf90796c', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #47'),
('0000000000008000', '1029d55e880ec2d0', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #48'),
('0000000000004000', '5d86cb23639dbea9', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #49'),
('0000000000002000', '1d1ca853ae7c0c5f', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #50'),
('0000000000001000', 'ce332329248f3228', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #51'),
('0000000000000800', '8405d1abe24fb942', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #52'),
('0000000000000400', 'e643d78090ca4207', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #53'),
('0000000000000200', '48221b9937748a23', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #54'),
('0000000000000100', 'dd7c0bbd61fafd54', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #55'),
('0000000000000080', '2fbc291a570db5c4', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #56'),
('0000000000000040', 'e07c30d7e4e26e12', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #57'),
('0000000000000020', '0953e2258e8e90a1', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #58'),
('0000000000000010', '5b711bc4ceebf2ee', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #59'),
('0000000000000008', 'cc083f1e6d9e85f6', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #60'),
('0000000000000004', 'd2fd8867d50d2dfe', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #61'),
('0000000000000002', '06e7ea22ce92708f', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #62'),
('0000000000000001', '166b40b44aba4bd6', SP800_17_B1_KEY,
'NIST SP800-17 B.1 #63'),
# Table B.2 - Variable Key Known Answer Test
(SP800_17_B2_PT, '95a8d72813daa94d', '8001010101010101',
'NIST SP800-17 B.2 #0'),
(SP800_17_B2_PT, '0eec1487dd8c26d5', '4001010101010101',
'NIST SP800-17 B.2 #1'),
(SP800_17_B2_PT, '7ad16ffb79c45926', '2001010101010101',
'NIST SP800-17 B.2 #2'),
(SP800_17_B2_PT, 'd3746294ca6a6cf3', '1001010101010101',
'NIST SP800-17 B.2 #3'),
(SP800_17_B2_PT, '809f5f873c1fd761', '0801010101010101',
'NIST SP800-17 B.2 #4'),
(SP800_17_B2_PT, 'c02faffec989d1fc', '0401010101010101',
'NIST SP800-17 B.2 #5'),
(SP800_17_B2_PT, '4615aa1d33e72f10', '0201010101010101',
'NIST SP800-17 B.2 #6'),
(SP800_17_B2_PT, '2055123350c00858', '0180010101010101',
'NIST SP800-17 B.2 #7'),
(SP800_17_B2_PT, 'df3b99d6577397c8', '0140010101010101',
'NIST SP800-17 B.2 #8'),
(SP800_17_B2_PT, '31fe17369b5288c9', '0120010101010101',
'NIST SP800-17 B.2 #9'),
(SP800_17_B2_PT, 'dfdd3cc64dae1642', '0110010101010101',
'NIST SP800-17 B.2 #10'),
(SP800_17_B2_PT, '178c83ce2b399d94', '0108010101010101',
'NIST SP800-17 B.2 #11'),
(SP800_17_B2_PT, '50f636324a9b7f80', '0104010101010101',
'NIST SP800-17 B.2 #12'),
(SP800_17_B2_PT, 'a8468ee3bc18f06d', '0102010101010101',
'NIST SP800-17 B.2 #13'),
(SP800_17_B2_PT, 'a2dc9e92fd3cde92', '0101800101010101',
'NIST SP800-17 B.2 #14'),
(SP800_17_B2_PT, 'cac09f797d031287', '0101400101010101',
'NIST SP800-17 B.2 #15'),
(SP800_17_B2_PT, '90ba680b22aeb525', '0101200101010101',
'NIST SP800-17 B.2 #16'),
(SP800_17_B2_PT, 'ce7a24f350e280b6', '0101100101010101',
'NIST SP800-17 B.2 #17'),
(SP800_17_B2_PT, '882bff0aa01a0b87', '0101080101010101',
'NIST SP800-17 B.2 #18'),
(SP800_17_B2_PT, '25610288924511c2', '0101040101010101',
'NIST SP800-17 B.2 #19'),
(SP800_17_B2_PT, 'c71516c29c75d170', '0101020101010101',
'NIST SP800-17 B.2 #20'),
(SP800_17_B2_PT, '5199c29a52c9f059', '0101018001010101',
'NIST SP800-17 B.2 #21'),
(SP800_17_B2_PT, 'c22f0a294a71f29f', '0101014001010101',
'NIST SP800-17 B.2 #22'),
(SP800_17_B2_PT, 'ee371483714c02ea', '0101012001010101',
'NIST SP800-17 B.2 #23'),
(SP800_17_B2_PT, 'a81fbd448f9e522f', '0101011001010101',
'NIST SP800-17 B.2 #24'),
(SP800_17_B2_PT, '4f644c92e192dfed', '0101010801010101',
'NIST SP800-17 B.2 #25'),
(SP800_17_B2_PT, '1afa9a66a6df92ae', '0101010401010101',
'NIST SP800-17 B.2 #26'),
(SP800_17_B2_PT, 'b3c1cc715cb879d8', '0101010201010101',
'NIST SP800-17 B.2 #27'),
(SP800_17_B2_PT, '19d032e64ab0bd8b', '0101010180010101',
'NIST SP800-17 B.2 #28'),
(SP800_17_B2_PT, '3cfaa7a7dc8720dc', '0101010140010101',
'NIST SP800-17 B.2 #29'),
(SP800_17_B2_PT, 'b7265f7f447ac6f3', '0101010120010101',
'NIST SP800-17 B.2 #30'),
(SP800_17_B2_PT, '9db73b3c0d163f54', '0101010110010101',
'NIST SP800-17 B.2 #31'),
(SP800_17_B2_PT, '8181b65babf4a975', '0101010108010101',
'NIST SP800-17 B.2 #32'),
(SP800_17_B2_PT, '93c9b64042eaa240', '0101010104010101',
'NIST SP800-17 B.2 #33'),
(SP800_17_B2_PT, '5570530829705592', '0101010102010101',
'NIST SP800-17 B.2 #34'),
(SP800_17_B2_PT, '8638809e878787a0', '0101010101800101',
'NIST SP800-17 B.2 #35'),
(SP800_17_B2_PT, '41b9a79af79ac208', '0101010101400101',
'NIST SP800-17 B.2 #36'),
(SP800_17_B2_PT, '7a9be42f2009a892', '0101010101200101',
'NIST SP800-17 B.2 #37'),
(SP800_17_B2_PT, '29038d56ba6d2745', '0101010101100101',
'NIST SP800-17 B.2 #38'),
(SP800_17_B2_PT, '5495c6abf1e5df51', '0101010101080101',
'NIST SP800-17 B.2 #39'),
(SP800_17_B2_PT, 'ae13dbd561488933', '0101010101040101',
'NIST SP800-17 B.2 #40'),
(SP800_17_B2_PT, '024d1ffa8904e389', '0101010101020101',
'NIST SP800-17 B.2 #41'),
(SP800_17_B2_PT, 'd1399712f99bf02e', '0101010101018001',
'NIST SP800-17 B.2 #42'),
(SP800_17_B2_PT, '14c1d7c1cffec79e', '0101010101014001',
'NIST SP800-17 B.2 #43'),
(SP800_17_B2_PT, '1de5279dae3bed6f', '0101010101012001',
'NIST SP800-17 B.2 #44'),
(SP800_17_B2_PT, 'e941a33f85501303', '0101010101011001',
'NIST SP800-17 B.2 #45'),
(SP800_17_B2_PT, 'da99dbbc9a03f379', '0101010101010801',
'NIST SP800-17 B.2 #46'),
(SP800_17_B2_PT, 'b7fc92f91d8e92e9', '0101010101010401',
'NIST SP800-17 B.2 #47'),
(SP800_17_B2_PT, 'ae8e5caa3ca04e85', '0101010101010201',
'NIST SP800-17 B.2 #48'),
(SP800_17_B2_PT, '9cc62df43b6eed74', '0101010101010180',
'NIST SP800-17 B.2 #49'),
(SP800_17_B2_PT, 'd863dbb5c59a91a0', '0101010101010140',
'NIST SP800-17 B.2 #50'),
(SP800_17_B2_PT, 'a1ab2190545b91d7', '0101010101010120',
'NIST SP800-17 B.2 #51'),
(SP800_17_B2_PT, '0875041e64c570f7', '0101010101010110',
'NIST SP800-17 B.2 #52'),
(SP800_17_B2_PT, '5a594528bebef1cc', '0101010101010108',
'NIST SP800-17 B.2 #53'),
(SP800_17_B2_PT, 'fcdb3291de21f0c0', '0101010101010104',
'NIST SP800-17 B.2 #54'),
(SP800_17_B2_PT, '869efd7f9f265a09', '0101010101010102',
'NIST SP800-17 B.2 #55'),
]
class RonRivestTest(unittest.TestCase):
""" Ronald L. Rivest's DES test, see
http://people.csail.mit.edu/rivest/Destest.txt
ABSTRACT
--------
We present a simple way to test the correctness of a DES implementation:
Use the recurrence relation:
X0 = 9474B8E8C73BCA7D (hexadecimal)
X(i+1) = IF (i is even) THEN E(Xi,Xi) ELSE D(Xi,Xi)
to compute a sequence of 64-bit values: X0, X1, X2, ..., X16. Here
E(X,K) denotes the DES encryption of X using key K, and D(X,K) denotes
the DES decryption of X using key K. If you obtain
X16 = 1B1A2DDB4C642438
your implementation does not have any of the 36,568 possible single-fault
errors described herein.
"""
def runTest(self):
from Crypto.Cipher import DES
from binascii import b2a_hex
X = []
X[0:] = [b('\x94\x74\xB8\xE8\xC7\x3B\xCA\x7D')]
for i in range(16):
c = DES.new(X[i],DES.MODE_ECB)
if not (i&1): # (num&1) returns 1 for odd numbers
X[i+1:] = [c.encrypt(X[i])] # even
else:
X[i+1:] = [c.decrypt(X[i])] # odd
self.assertEqual(b2a_hex(X[16]),
b2a_hex(b('\x1B\x1A\x2D\xDB\x4C\x64\x24\x38')))
def get_tests(config={}):
from Crypto.Cipher import DES
from .common import make_block_tests
return make_block_tests(DES, "DES", test_data) + [RonRivestTest()]
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,333 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Cipher/DES3.py: Self-test for the Triple-DES cipher
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Cipher.DES3"""
__revision__ = "$Id$"
from .common import dict # For compatibility with Python 2.1 and 2.2
from Crypto.Util.py3compat import *
from binascii import hexlify
# This is a list of (plaintext, ciphertext, key, description) tuples.
SP800_20_A1_KEY = '01' * 24
SP800_20_A2_PT = '00' * 8
test_data = [
# Test vector from Appendix B of NIST SP 800-67
# "Recommendation for the Triple Data Encryption Algorithm (TDEA) Block
# Cipher"
# http://csrc.nist.gov/publications/nistpubs/800-67/SP800-67.pdf
('54686520717566636b2062726f776e20666f78206a756d70',
'a826fd8ce53b855fcce21c8112256fe668d5c05dd9b6b900',
'0123456789abcdef23456789abcdef01456789abcdef0123',
'NIST SP800-67 B.1'),
# Test vectors "The Multi-block Message Test (MMT) for DES and TDES"
# http://csrc.nist.gov/groups/STM/cavp/documents/des/DESMMT.pdf
('326a494cd33fe756', 'b22b8d66de970692',
'627f460e08104a1043cd265d5840eaf1313edf97df2a8a8c',
'DESMMT #1', dict(mode='CBC', iv='8e29f75ea77e5475')),
('84401f78fe6c10876d8ea23094ea5309', '7b1f7c7e3b1c948ebd04a75ffba7d2f5',
'37ae5ebf46dff2dc0754b94f31cbb3855e7fd36dc870bfae',
'DESMMT #2', dict(mode='CBC', iv='3d1de3cc132e3b65')),
# Test vectors from Appendix A of NIST SP 800-20
# "Modes of Operation Validation System for the Triple Data Encryption
# Algorithm (TMOVS): Requirements and Procedures"
# http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf
# Table A.1 - Variable Plaintext Known Answer Test
('8000000000000000', '95f8a5e5dd31d900', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #0'),
('4000000000000000', 'dd7f121ca5015619', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #1'),
('2000000000000000', '2e8653104f3834ea', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #2'),
('1000000000000000', '4bd388ff6cd81d4f', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #3'),
('0800000000000000', '20b9e767b2fb1456', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #4'),
('0400000000000000', '55579380d77138ef', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #5'),
('0200000000000000', '6cc5defaaf04512f', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #6'),
('0100000000000000', '0d9f279ba5d87260', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #7'),
('0080000000000000', 'd9031b0271bd5a0a', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #8'),
('0040000000000000', '424250b37c3dd951', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #9'),
('0020000000000000', 'b8061b7ecd9a21e5', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #10'),
('0010000000000000', 'f15d0f286b65bd28', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #11'),
('0008000000000000', 'add0cc8d6e5deba1', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #12'),
('0004000000000000', 'e6d5f82752ad63d1', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #13'),
('0002000000000000', 'ecbfe3bd3f591a5e', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #14'),
('0001000000000000', 'f356834379d165cd', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #15'),
('0000800000000000', '2b9f982f20037fa9', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #16'),
('0000400000000000', '889de068a16f0be6', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #17'),
('0000200000000000', 'e19e275d846a1298', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #18'),
('0000100000000000', '329a8ed523d71aec', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #19'),
('0000080000000000', 'e7fce22557d23c97', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #20'),
('0000040000000000', '12a9f5817ff2d65d', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #21'),
('0000020000000000', 'a484c3ad38dc9c19', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #22'),
('0000010000000000', 'fbe00a8a1ef8ad72', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #23'),
('0000008000000000', '750d079407521363', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #24'),
('0000004000000000', '64feed9c724c2faf', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #25'),
('0000002000000000', 'f02b263b328e2b60', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #26'),
('0000001000000000', '9d64555a9a10b852', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #27'),
('0000000800000000', 'd106ff0bed5255d7', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #28'),
('0000000400000000', 'e1652c6b138c64a5', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #29'),
('0000000200000000', 'e428581186ec8f46', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #30'),
('0000000100000000', 'aeb5f5ede22d1a36', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #31'),
('0000000080000000', 'e943d7568aec0c5c', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #32'),
('0000000040000000', 'df98c8276f54b04b', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #33'),
('0000000020000000', 'b160e4680f6c696f', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #34'),
('0000000010000000', 'fa0752b07d9c4ab8', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #35'),
('0000000008000000', 'ca3a2b036dbc8502', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #36'),
('0000000004000000', '5e0905517bb59bcf', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #37'),
('0000000002000000', '814eeb3b91d90726', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #38'),
('0000000001000000', '4d49db1532919c9f', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #39'),
('0000000000800000', '25eb5fc3f8cf0621', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #40'),
('0000000000400000', 'ab6a20c0620d1c6f', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #41'),
('0000000000200000', '79e90dbc98f92cca', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #42'),
('0000000000100000', '866ecedd8072bb0e', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #43'),
('0000000000080000', '8b54536f2f3e64a8', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #44'),
('0000000000040000', 'ea51d3975595b86b', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #45'),
('0000000000020000', 'caffc6ac4542de31', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #46'),
('0000000000010000', '8dd45a2ddf90796c', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #47'),
('0000000000008000', '1029d55e880ec2d0', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #48'),
('0000000000004000', '5d86cb23639dbea9', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #49'),
('0000000000002000', '1d1ca853ae7c0c5f', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #50'),
('0000000000001000', 'ce332329248f3228', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #51'),
('0000000000000800', '8405d1abe24fb942', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #52'),
('0000000000000400', 'e643d78090ca4207', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #53'),
('0000000000000200', '48221b9937748a23', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #54'),
('0000000000000100', 'dd7c0bbd61fafd54', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #55'),
('0000000000000080', '2fbc291a570db5c4', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #56'),
('0000000000000040', 'e07c30d7e4e26e12', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #57'),
('0000000000000020', '0953e2258e8e90a1', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #58'),
('0000000000000010', '5b711bc4ceebf2ee', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #59'),
('0000000000000008', 'cc083f1e6d9e85f6', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #60'),
('0000000000000004', 'd2fd8867d50d2dfe', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #61'),
('0000000000000002', '06e7ea22ce92708f', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #62'),
('0000000000000001', '166b40b44aba4bd6', SP800_20_A1_KEY,
'NIST SP800-20 A.1 #63'),
# Table A.2 - Variable Key Known Answer Test
(SP800_20_A2_PT, '95a8d72813daa94d', '8001010101010101'*3,
'NIST SP800-20 A.2 #0'),
(SP800_20_A2_PT, '0eec1487dd8c26d5', '4001010101010101'*3,
'NIST SP800-20 A.2 #1'),
(SP800_20_A2_PT, '7ad16ffb79c45926', '2001010101010101'*3,
'NIST SP800-20 A.2 #2'),
(SP800_20_A2_PT, 'd3746294ca6a6cf3', '1001010101010101'*3,
'NIST SP800-20 A.2 #3'),
(SP800_20_A2_PT, '809f5f873c1fd761', '0801010101010101'*3,
'NIST SP800-20 A.2 #4'),
(SP800_20_A2_PT, 'c02faffec989d1fc', '0401010101010101'*3,
'NIST SP800-20 A.2 #5'),
(SP800_20_A2_PT, '4615aa1d33e72f10', '0201010101010101'*3,
'NIST SP800-20 A.2 #6'),
(SP800_20_A2_PT, '2055123350c00858', '0180010101010101'*3,
'NIST SP800-20 A.2 #7'),
(SP800_20_A2_PT, 'df3b99d6577397c8', '0140010101010101'*3,
'NIST SP800-20 A.2 #8'),
(SP800_20_A2_PT, '31fe17369b5288c9', '0120010101010101'*3,
'NIST SP800-20 A.2 #9'),
(SP800_20_A2_PT, 'dfdd3cc64dae1642', '0110010101010101'*3,
'NIST SP800-20 A.2 #10'),
(SP800_20_A2_PT, '178c83ce2b399d94', '0108010101010101'*3,
'NIST SP800-20 A.2 #11'),
(SP800_20_A2_PT, '50f636324a9b7f80', '0104010101010101'*3,
'NIST SP800-20 A.2 #12'),
(SP800_20_A2_PT, 'a8468ee3bc18f06d', '0102010101010101'*3,
'NIST SP800-20 A.2 #13'),
(SP800_20_A2_PT, 'a2dc9e92fd3cde92', '0101800101010101'*3,
'NIST SP800-20 A.2 #14'),
(SP800_20_A2_PT, 'cac09f797d031287', '0101400101010101'*3,
'NIST SP800-20 A.2 #15'),
(SP800_20_A2_PT, '90ba680b22aeb525', '0101200101010101'*3,
'NIST SP800-20 A.2 #16'),
(SP800_20_A2_PT, 'ce7a24f350e280b6', '0101100101010101'*3,
'NIST SP800-20 A.2 #17'),
(SP800_20_A2_PT, '882bff0aa01a0b87', '0101080101010101'*3,
'NIST SP800-20 A.2 #18'),
(SP800_20_A2_PT, '25610288924511c2', '0101040101010101'*3,
'NIST SP800-20 A.2 #19'),
(SP800_20_A2_PT, 'c71516c29c75d170', '0101020101010101'*3,
'NIST SP800-20 A.2 #20'),
(SP800_20_A2_PT, '5199c29a52c9f059', '0101018001010101'*3,
'NIST SP800-20 A.2 #21'),
(SP800_20_A2_PT, 'c22f0a294a71f29f', '0101014001010101'*3,
'NIST SP800-20 A.2 #22'),
(SP800_20_A2_PT, 'ee371483714c02ea', '0101012001010101'*3,
'NIST SP800-20 A.2 #23'),
(SP800_20_A2_PT, 'a81fbd448f9e522f', '0101011001010101'*3,
'NIST SP800-20 A.2 #24'),
(SP800_20_A2_PT, '4f644c92e192dfed', '0101010801010101'*3,
'NIST SP800-20 A.2 #25'),
(SP800_20_A2_PT, '1afa9a66a6df92ae', '0101010401010101'*3,
'NIST SP800-20 A.2 #26'),
(SP800_20_A2_PT, 'b3c1cc715cb879d8', '0101010201010101'*3,
'NIST SP800-20 A.2 #27'),
(SP800_20_A2_PT, '19d032e64ab0bd8b', '0101010180010101'*3,
'NIST SP800-20 A.2 #28'),
(SP800_20_A2_PT, '3cfaa7a7dc8720dc', '0101010140010101'*3,
'NIST SP800-20 A.2 #29'),
(SP800_20_A2_PT, 'b7265f7f447ac6f3', '0101010120010101'*3,
'NIST SP800-20 A.2 #30'),
(SP800_20_A2_PT, '9db73b3c0d163f54', '0101010110010101'*3,
'NIST SP800-20 A.2 #31'),
(SP800_20_A2_PT, '8181b65babf4a975', '0101010108010101'*3,
'NIST SP800-20 A.2 #32'),
(SP800_20_A2_PT, '93c9b64042eaa240', '0101010104010101'*3,
'NIST SP800-20 A.2 #33'),
(SP800_20_A2_PT, '5570530829705592', '0101010102010101'*3,
'NIST SP800-20 A.2 #34'),
(SP800_20_A2_PT, '8638809e878787a0', '0101010101800101'*3,
'NIST SP800-20 A.2 #35'),
(SP800_20_A2_PT, '41b9a79af79ac208', '0101010101400101'*3,
'NIST SP800-20 A.2 #36'),
(SP800_20_A2_PT, '7a9be42f2009a892', '0101010101200101'*3,
'NIST SP800-20 A.2 #37'),
(SP800_20_A2_PT, '29038d56ba6d2745', '0101010101100101'*3,
'NIST SP800-20 A.2 #38'),
(SP800_20_A2_PT, '5495c6abf1e5df51', '0101010101080101'*3,
'NIST SP800-20 A.2 #39'),
(SP800_20_A2_PT, 'ae13dbd561488933', '0101010101040101'*3,
'NIST SP800-20 A.2 #40'),
(SP800_20_A2_PT, '024d1ffa8904e389', '0101010101020101'*3,
'NIST SP800-20 A.2 #41'),
(SP800_20_A2_PT, 'd1399712f99bf02e', '0101010101018001'*3,
'NIST SP800-20 A.2 #42'),
(SP800_20_A2_PT, '14c1d7c1cffec79e', '0101010101014001'*3,
'NIST SP800-20 A.2 #43'),
(SP800_20_A2_PT, '1de5279dae3bed6f', '0101010101012001'*3,
'NIST SP800-20 A.2 #44'),
(SP800_20_A2_PT, 'e941a33f85501303', '0101010101011001'*3,
'NIST SP800-20 A.2 #45'),
(SP800_20_A2_PT, 'da99dbbc9a03f379', '0101010101010801'*3,
'NIST SP800-20 A.2 #46'),
(SP800_20_A2_PT, 'b7fc92f91d8e92e9', '0101010101010401'*3,
'NIST SP800-20 A.2 #47'),
(SP800_20_A2_PT, 'ae8e5caa3ca04e85', '0101010101010201'*3,
'NIST SP800-20 A.2 #48'),
(SP800_20_A2_PT, '9cc62df43b6eed74', '0101010101010180'*3,
'NIST SP800-20 A.2 #49'),
(SP800_20_A2_PT, 'd863dbb5c59a91a0', '0101010101010140'*3,
'NIST SP800-20 A.2 #50'),
(SP800_20_A2_PT, 'a1ab2190545b91d7', '0101010101010120'*3,
'NIST SP800-20 A.2 #51'),
(SP800_20_A2_PT, '0875041e64c570f7', '0101010101010110'*3,
'NIST SP800-20 A.2 #52'),
(SP800_20_A2_PT, '5a594528bebef1cc', '0101010101010108'*3,
'NIST SP800-20 A.2 #53'),
(SP800_20_A2_PT, 'fcdb3291de21f0c0', '0101010101010104'*3,
'NIST SP800-20 A.2 #54'),
(SP800_20_A2_PT, '869efd7f9f265a09', '0101010101010102'*3,
'NIST SP800-20 A.2 #55'),
# "Two-key 3DES". Test vector generated using PyCrypto 2.0.1.
# This test is designed to test the DES3 API, not the correctness of the
# output.
('21e81b7ade88a259', '5c577d4d9b20c0f8',
'9b397ebf81b1181e282f4bb8adbadc6b', 'Two-key 3DES'),
# The following test vectors have been generated with gpg v1.4.0.
# The command line used was:
# gpg -c -z 0 --cipher-algo 3DES --passphrase secret_passphrase \
# --disable-mdc --s2k-mode 0 --output ct pt
# For an explanation, see test_AES.py .
( 'ac1762037074324fb53ba3596f73656d69746556616c6c6579', # Plaintext, 'YosemiteValley'
'9979238528357b90e2e0be549cb0b2d5999b9a4a447e5c5c7d', # Ciphertext
'7ade65b460f5ea9be35f9e14aa883a2048e3824aa616c0b2', # Key (hash of 'BearsAhead')
'GPG Test Vector #1',
dict(mode='OPENPGP', iv='cd47e2afb8b7e4b0', encrypted_iv='6a7eef0b58050e8b904a' ) ),
]
def get_tests(config={}):
from Crypto.Cipher import DES3
from .common import make_block_tests
return make_block_tests(DES3, "DES3", test_data)
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Cipher/XOR.py: Self-test for the XOR "cipher"
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Cipher.XOR"""
import unittest
__revision__ = "$Id$"
from Crypto.Util.py3compat import *
# This is a list of (plaintext, ciphertext, key) tuples.
test_data = [
# Test vectors written from scratch. (Nobody posts XOR test vectors on the web? How disappointing.)
('01', '01',
'00',
'zero key'),
('0102040810204080', '0003050911214181',
'01',
'1-byte key'),
('0102040810204080', 'cda8c8a2dc8a8c2a',
'ccaa',
'2-byte key'),
('ff'*64, 'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0'*2,
'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f',
'32-byte key'),
]
class TruncationSelfTest(unittest.TestCase):
def runTest(self):
"""33-byte key (should raise ValueError under current implementation)"""
# Crypto.Cipher.XOR previously truncated its inputs at 32 bytes. Now
# it should raise a ValueError if the length is too long.
self.assertRaises(ValueError, XOR.new, "x"*33)
def get_tests(config={}):
global XOR
from Crypto.Cipher import XOR
from .common import make_stream_tests
return make_stream_tests(XOR, "XOR", test_data) + [TruncationSelfTest()]
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,174 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Cipher/test_pkcs1_15.py: Self-test for PKCS#1 v1.5 encryption
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
__revision__ = "$Id$"
import unittest
import sys
from Crypto.PublicKey import RSA
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
from Crypto import Random
from Crypto.Cipher import PKCS1_v1_5 as PKCS
from Crypto.Util.py3compat import *
def rws(t):
"""Remove white spaces, tabs, and new lines from a string"""
for c in ['\n', '\t', ' ']:
t = t.replace(c,'')
return t
def t2b(t):
"""Convert a text string with bytes in hex form to a byte string"""
clean = b(rws(t))
if len(clean)%2 == 1:
print(clean)
raise ValueError("Even number of characters expected")
return a2b_hex(clean)
class PKCS1_15_Tests(unittest.TestCase):
def setUp(self):
self.rng = Random.new().read
self.key1024 = RSA.generate(1024, self.rng)
# List of tuples with test data for PKCS#1 v1.5.
# Each tuple is made up by:
# Item #0: dictionary with RSA key component, or key to import
# Item #1: plaintext
# Item #2: ciphertext
# Item #3: random data
_testData = (
#
# Generated with openssl 0.9.8o
#
(
# Private key
'''-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDAiAnvIAOvqVwJTaYzsKnefZftgtXGE2hPJppGsWl78yz9jeXY
W/FxX/gTPURArNhdnhP6n3p2ZaDIBrO2zizbgIXs0IsljTTcr4vnI8fMXzyNUOjA
zP3nzMqZDZK6757XQAobOssMkBFqRWwilT/3DsBhRpl3iMUhF+wvpTSHewIDAQAB
AoGAC4HV/inOrpgTvSab8Wj0riyZgQOZ3U3ZpSlsfR8ra9Ib9Uee3jCYnKscu6Gk
y6zI/cdt8EPJ4PuwAWSNJzbpbVaDvUq25OD+CX8/uRT08yBS4J8TzBitZJTD4lS7
atdTnKT0Wmwk+u8tDbhvMKwnUHdJLcuIsycts9rwJVapUtkCQQDvDpx2JMun0YKG
uUttjmL8oJ3U0m3ZvMdVwBecA0eebZb1l2J5PvI3EJD97eKe91Nsw8T3lwpoN40k
IocSVDklAkEAzi1HLHE6EzVPOe5+Y0kGvrIYRRhncOb72vCvBZvD6wLZpQgqo6c4
d3XHFBBQWA6xcvQb5w+VVEJZzw64y25sHwJBAMYReRl6SzL0qA0wIYrYWrOt8JeQ
8mthulcWHXmqTgC6FEXP9Es5GD7/fuKl4wqLKZgIbH4nqvvGay7xXLCXD/ECQH9a
1JYNMtRen5unSAbIOxRcKkWz92F0LKpm9ZW/S9vFHO+mBcClMGoKJHiuQxLBsLbT
NtEZfSJZAeS2sUtn3/0CQDb2M2zNBTF8LlM0nxmh0k9VGm5TVIyBEMcipmvOgqIs
HKukWBcq9f/UOmS0oEhai/6g+Uf7VHJdWaeO5LzuvwU=
-----END RSA PRIVATE KEY-----''',
# Plaintext
'''THIS IS PLAINTEXT\x0A''',
# Ciphertext
'''3f dc fd 3c cd 5c 9b 12 af 65 32 e3 f7 d0 da 36
8f 8f d9 e3 13 1c 7f c8 b3 f9 c1 08 e4 eb 79 9c
91 89 1f 96 3b 94 77 61 99 a4 b1 ee 5d e6 17 c9
5d 0a b5 63 52 0a eb 00 45 38 2a fb b0 71 3d 11
f7 a1 9e a7 69 b3 af 61 c0 bb 04 5b 5d 4b 27 44
1f 5b 97 89 ba 6a 08 95 ee 4f a2 eb 56 64 e5 0f
da 7c f9 9a 61 61 06 62 ed a0 bc 5f aa 6c 31 78
70 28 1a bb 98 3c e3 6a 60 3c d1 0b 0f 5a f4 75''',
# Random data
'''eb d7 7d 86 a4 35 23 a3 54 7e 02 0b 42 1d
61 6c af 67 b8 4e 17 56 80 66 36 04 64 34 26 8a
47 dd 44 b3 1a b2 17 60 f4 91 2e e2 b5 95 64 cc
f9 da c8 70 94 54 86 4c ef 5b 08 7d 18 c4 ab 8d
04 06 33 8f ca 15 5f 52 60 8a a1 0c f5 08 b5 4c
bb 99 b8 94 25 04 9c e6 01 75 e6 f9 63 7a 65 61
13 8a a7 47 77 81 ae 0d b8 2c 4d 50 a5'''
),
)
def testEncrypt1(self):
for test in self._testData:
# Build the key
key = RSA.importKey(test[0])
# RNG that takes its random numbers from a pool given
# at initialization
class randGen:
def __init__(self, data):
self.data = data
self.idx = 0
def __call__(self, N):
r = self.data[self.idx:N]
self.idx += N
return r
# The real test
key._randfunc = randGen(t2b(test[3]))
cipher = PKCS.new(key)
ct = cipher.encrypt(b(test[1]))
self.assertEqual(ct, t2b(test[2]))
def testEncrypt2(self):
# Verify that encryption fail if plaintext is too long
pt = '\x00'*(128-11+1)
cipher = PKCS.new(self.key1024)
self.assertRaises(ValueError, cipher.encrypt, pt)
def testVerify1(self):
for test in self._testData:
# Build the key
key = RSA.importKey(test[0])
# The real test
cipher = PKCS.new(key)
pt = cipher.decrypt(t2b(test[2]), "---")
self.assertEqual(pt, b(test[1]))
def testVerify2(self):
# Verify that decryption fails if ciphertext is not as long as
# RSA modulus
cipher = PKCS.new(self.key1024)
self.assertRaises(ValueError, cipher.decrypt, '\x00'*127, "---")
self.assertRaises(ValueError, cipher.decrypt, '\x00'*129, "---")
# Verify that decryption fails if there are less then 8 non-zero padding
# bytes
pt = b('\x00\x02' + '\xFF'*7 + '\x00' + '\x45'*118)
ct = self.key1024.encrypt(pt, 0)[0]
ct = b('\x00'*(128-len(ct))) + ct
self.assertEqual("---", cipher.decrypt(ct, "---"))
def testEncryptVerify1(self):
# Encrypt/Verify messages of length [0..RSAlen-11]
# and therefore padding [8..117]
for pt_len in range(0,128-11+1):
pt = self.rng(pt_len)
cipher = PKCS.new(self.key1024)
ct = cipher.encrypt(pt)
pt2 = cipher.decrypt(ct, "---")
self.assertEqual(pt,pt2)
def get_tests(config={}):
tests = []
tests += list_test_cases(PKCS1_15_Tests)
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,372 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Cipher/test_pkcs1_oaep.py: Self-test for PKCS#1 OAEP encryption
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
__revision__ = "$Id$"
import unittest
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
from Crypto.Util.py3compat import *
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP as PKCS
from Crypto.Hash import MD2,MD5,SHA as SHA1,SHA256,RIPEMD
from Crypto import Random
def rws(t):
"""Remove white spaces, tabs, and new lines from a string"""
for c in ['\n', '\t', ' ']:
t = t.replace(c,'')
return t
def t2b(t):
"""Convert a text string with bytes in hex form to a byte string"""
clean = rws(t)
if len(clean)%2 == 1:
raise ValueError("Even number of characters expected")
return a2b_hex(clean)
class PKCS1_OAEP_Tests(unittest.TestCase):
def setUp(self):
self.rng = Random.new().read
self.key1024 = RSA.generate(1024, self.rng)
# List of tuples with test data for PKCS#1 OAEP
# Each tuple is made up by:
# Item #0: dictionary with RSA key component
# Item #1: plaintext
# Item #2: ciphertext
# Item #3: random data (=seed)
# Item #4: hash object
_testData = (
#
# From in oaep-int.txt to be found in
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''bb f8 2f 09 06 82 ce 9c 23 38 ac 2b 9d a8 71 f7
36 8d 07 ee d4 10 43 a4 40 d6 b6 f0 74 54 f5 1f
b8 df ba af 03 5c 02 ab 61 ea 48 ce eb 6f cd 48
76 ed 52 0d 60 e1 ec 46 19 71 9d 8a 5b 8b 80 7f
af b8 e0 a3 df c7 37 72 3e e6 b4 b7 d9 3a 25 84
ee 6a 64 9d 06 09 53 74 88 34 b2 45 45 98 39 4e
e0 aa b1 2d 7b 61 a5 1f 52 7a 9a 41 f6 c1 68 7f
e2 53 72 98 ca 2a 8f 59 46 f8 e5 fd 09 1d bd cb''',
# Public key
'e':'11',
# In the test vector, only p and q were given...
# d is computed offline as e^{-1} mod (p-1)(q-1)
'd':'''a5dafc5341faf289c4b988db30c1cdf83f31251e0
668b42784813801579641b29410b3c7998d6bc465745e5c3
92669d6870da2c082a939e37fdcb82ec93edac97ff3ad595
0accfbc111c76f1a9529444e56aaf68c56c092cd38dc3bef
5d20a939926ed4f74a13eddfbe1a1cecc4894af9428c2b7b
8883fe4463a4bc85b1cb3c1'''
}
,
# Plaintext
'''d4 36 e9 95 69 fd 32 a7 c8 a0 5b bc 90 d3 2c 49''',
# Ciphertext
'''12 53 e0 4d c0 a5 39 7b b4 4a 7a b8 7e 9b f2 a0
39 a3 3d 1e 99 6f c8 2a 94 cc d3 00 74 c9 5d f7
63 72 20 17 06 9e 52 68 da 5d 1c 0b 4f 87 2c f6
53 c1 1d f8 23 14 a6 79 68 df ea e2 8d ef 04 bb
6d 84 b1 c3 1d 65 4a 19 70 e5 78 3b d6 eb 96 a0
24 c2 ca 2f 4a 90 fe 9f 2e f5 c9 c1 40 e5 bb 48
da 95 36 ad 87 00 c8 4f c9 13 0a de a7 4e 55 8d
51 a7 4d df 85 d8 b5 0d e9 68 38 d6 06 3e 09 55''',
# Random
'''aa fd 12 f6 59 ca e6 34 89 b4 79 e5 07 6d de c2
f0 6c b5 8f''',
# Hash
SHA1,
),
#
# From in oaep-vect.txt to be found in Example 1.1
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''a8 b3 b2 84 af 8e b5 0b 38 70 34 a8 60 f1 46 c4
91 9f 31 87 63 cd 6c 55 98 c8 ae 48 11 a1 e0 ab
c4 c7 e0 b0 82 d6 93 a5 e7 fc ed 67 5c f4 66 85
12 77 2c 0c bc 64 a7 42 c6 c6 30 f5 33 c8 cc 72
f6 2a e8 33 c4 0b f2 58 42 e9 84 bb 78 bd bf 97
c0 10 7d 55 bd b6 62 f5 c4 e0 fa b9 84 5c b5 14
8e f7 39 2d d3 aa ff 93 ae 1e 6b 66 7b b3 d4 24
76 16 d4 f5 ba 10 d4 cf d2 26 de 88 d3 9f 16 fb''',
'e':'''01 00 01''',
'd':'''53 33 9c fd b7 9f c8 46 6a 65 5c 73 16 ac a8 5c
55 fd 8f 6d d8 98 fd af 11 95 17 ef 4f 52 e8 fd
8e 25 8d f9 3f ee 18 0f a0 e4 ab 29 69 3c d8 3b
15 2a 55 3d 4a c4 d1 81 2b 8b 9f a5 af 0e 7f 55
fe 73 04 df 41 57 09 26 f3 31 1f 15 c4 d6 5a 73
2c 48 31 16 ee 3d 3d 2d 0a f3 54 9a d9 bf 7c bf
b7 8a d8 84 f8 4d 5b eb 04 72 4d c7 36 9b 31 de
f3 7d 0c f5 39 e9 cf cd d3 de 65 37 29 ea d5 d1 '''
}
,
# Plaintext
'''66 28 19 4e 12 07 3d b0 3b a9 4c da 9e f9 53 23
97 d5 0d ba 79 b9 87 00 4a fe fe 34''',
# Ciphertext
'''35 4f e6 7b 4a 12 6d 5d 35 fe 36 c7 77 79 1a 3f
7b a1 3d ef 48 4e 2d 39 08 af f7 22 fa d4 68 fb
21 69 6d e9 5d 0b e9 11 c2 d3 17 4f 8a fc c2 01
03 5f 7b 6d 8e 69 40 2d e5 45 16 18 c2 1a 53 5f
a9 d7 bf c5 b8 dd 9f c2 43 f8 cf 92 7d b3 13 22
d6 e8 81 ea a9 1a 99 61 70 e6 57 a0 5a 26 64 26
d9 8c 88 00 3f 84 77 c1 22 70 94 a0 d9 fa 1e 8c
40 24 30 9c e1 ec cc b5 21 00 35 d4 7a c7 2e 8a''',
# Random
'''18 b7 76 ea 21 06 9d 69 77 6a 33 e9 6b ad 48 e1
dd a0 a5 ef''',
SHA1
),
#
# From in oaep-vect.txt to be found in Example 2.1
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''01 94 7c 7f ce 90 42 5f 47 27 9e 70 85 1f 25 d5
e6 23 16 fe 8a 1d f1 93 71 e3 e6 28 e2 60 54 3e
49 01 ef 60 81 f6 8c 0b 81 41 19 0d 2a e8 da ba
7d 12 50 ec 6d b6 36 e9 44 ec 37 22 87 7c 7c 1d
0a 67 f1 4b 16 94 c5 f0 37 94 51 a4 3e 49 a3 2d
de 83 67 0b 73 da 91 a1 c9 9b c2 3b 43 6a 60 05
5c 61 0f 0b af 99 c1 a0 79 56 5b 95 a3 f1 52 66
32 d1 d4 da 60 f2 0e da 25 e6 53 c4 f0 02 76 6f
45''',
'e':'''01 00 01''',
'd':'''08 23 f2 0f ad b5 da 89 08 8a 9d 00 89 3e 21 fa
4a 1b 11 fb c9 3c 64 a3 be 0b aa ea 97 fb 3b 93
c3 ff 71 37 04 c1 9c 96 3c 1d 10 7a ae 99 05 47
39 f7 9e 02 e1 86 de 86 f8 7a 6d de fe a6 d8 cc
d1 d3 c8 1a 47 bf a7 25 5b e2 06 01 a4 a4 b2 f0
8a 16 7b 5e 27 9d 71 5b 1b 45 5b dd 7e ab 24 59
41 d9 76 8b 9a ce fb 3c cd a5 95 2d a3 ce e7 25
25 b4 50 16 63 a8 ee 15 c9 e9 92 d9 24 62 fe 39'''
},
# Plaintext
'''8f f0 0c aa 60 5c 70 28 30 63 4d 9a 6c 3d 42 c6
52 b5 8c f1 d9 2f ec 57 0b ee e7''',
# Ciphertext
'''01 81 af 89 22 b9 fc b4 d7 9d 92 eb e1 98 15 99
2f c0 c1 43 9d 8b cd 49 13 98 a0 f4 ad 3a 32 9a
5b d9 38 55 60 db 53 26 83 c8 b7 da 04 e4 b1 2a
ed 6a ac df 47 1c 34 c9 cd a8 91 ad dc c2 df 34
56 65 3a a6 38 2e 9a e5 9b 54 45 52 57 eb 09 9d
56 2b be 10 45 3f 2b 6d 13 c5 9c 02 e1 0f 1f 8a
bb 5d a0 d0 57 09 32 da cf 2d 09 01 db 72 9d 0f
ef cc 05 4e 70 96 8e a5 40 c8 1b 04 bc ae fe 72
0e''',
# Random
'''8c 40 7b 5e c2 89 9e 50 99 c5 3e 8c e7 93 bf 94
e7 1b 17 82''',
SHA1
),
#
# From in oaep-vect.txt to be found in Example 10.1
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''ae 45 ed 56 01 ce c6 b8 cc 05 f8 03 93 5c 67 4d
db e0 d7 5c 4c 09 fd 79 51 fc 6b 0c ae c3 13 a8
df 39 97 0c 51 8b ff ba 5e d6 8f 3f 0d 7f 22 a4
02 9d 41 3f 1a e0 7e 4e be 9e 41 77 ce 23 e7 f5
40 4b 56 9e 4e e1 bd cf 3c 1f b0 3e f1 13 80 2d
4f 85 5e b9 b5 13 4b 5a 7c 80 85 ad ca e6 fa 2f
a1 41 7e c3 76 3b e1 71 b0 c6 2b 76 0e de 23 c1
2a d9 2b 98 08 84 c6 41 f5 a8 fa c2 6b da d4 a0
33 81 a2 2f e1 b7 54 88 50 94 c8 25 06 d4 01 9a
53 5a 28 6a fe b2 71 bb 9b a5 92 de 18 dc f6 00
c2 ae ea e5 6e 02 f7 cf 79 fc 14 cf 3b dc 7c d8
4f eb bb f9 50 ca 90 30 4b 22 19 a7 aa 06 3a ef
a2 c3 c1 98 0e 56 0c d6 4a fe 77 95 85 b6 10 76
57 b9 57 85 7e fd e6 01 09 88 ab 7d e4 17 fc 88
d8 f3 84 c4 e6 e7 2c 3f 94 3e 0c 31 c0 c4 a5 cc
36 f8 79 d8 a3 ac 9d 7d 59 86 0e aa da 6b 83 bb''',
'e':'''01 00 01''',
'd':'''05 6b 04 21 6f e5 f3 54 ac 77 25 0a 4b 6b 0c 85
25 a8 5c 59 b0 bd 80 c5 64 50 a2 2d 5f 43 8e 59
6a 33 3a a8 75 e2 91 dd 43 f4 8c b8 8b 9d 5f c0
d4 99 f9 fc d1 c3 97 f9 af c0 70 cd 9e 39 8c 8d
19 e6 1d b7 c7 41 0a 6b 26 75 df bf 5d 34 5b 80
4d 20 1a dd 50 2d 5c e2 df cb 09 1c e9 99 7b be
be 57 30 6f 38 3e 4d 58 81 03 f0 36 f7 e8 5d 19
34 d1 52 a3 23 e4 a8 db 45 1d 6f 4a 5b 1b 0f 10
2c c1 50 e0 2f ee e2 b8 8d ea 4a d4 c1 ba cc b2
4d 84 07 2d 14 e1 d2 4a 67 71 f7 40 8e e3 05 64
fb 86 d4 39 3a 34 bc f0 b7 88 50 1d 19 33 03 f1
3a 22 84 b0 01 f0 f6 49 ea f7 93 28 d4 ac 5c 43
0a b4 41 49 20 a9 46 0e d1 b7 bc 40 ec 65 3e 87
6d 09 ab c5 09 ae 45 b5 25 19 01 16 a0 c2 61 01
84 82 98 50 9c 1c 3b f3 a4 83 e7 27 40 54 e1 5e
97 07 50 36 e9 89 f6 09 32 80 7b 52 57 75 1e 79'''
},
# Plaintext
'''8b ba 6b f8 2a 6c 0f 86 d5 f1 75 6e 97 95 68 70
b0 89 53 b0 6b 4e b2 05 bc 16 94 ee''',
# Ciphertext
'''53 ea 5d c0 8c d2 60 fb 3b 85 85 67 28 7f a9 15
52 c3 0b 2f eb fb a2 13 f0 ae 87 70 2d 06 8d 19
ba b0 7f e5 74 52 3d fb 42 13 9d 68 c3 c5 af ee
e0 bf e4 cb 79 69 cb f3 82 b8 04 d6 e6 13 96 14
4e 2d 0e 60 74 1f 89 93 c3 01 4b 58 b9 b1 95 7a
8b ab cd 23 af 85 4f 4c 35 6f b1 66 2a a7 2b fc
c7 e5 86 55 9d c4 28 0d 16 0c 12 67 85 a7 23 eb
ee be ff 71 f1 15 94 44 0a ae f8 7d 10 79 3a 87
74 a2 39 d4 a0 4c 87 fe 14 67 b9 da f8 52 08 ec
6c 72 55 79 4a 96 cc 29 14 2f 9a 8b d4 18 e3 c1
fd 67 34 4b 0c d0 82 9d f3 b2 be c6 02 53 19 62
93 c6 b3 4d 3f 75 d3 2f 21 3d d4 5c 62 73 d5 05
ad f4 cc ed 10 57 cb 75 8f c2 6a ee fa 44 12 55
ed 4e 64 c1 99 ee 07 5e 7f 16 64 61 82 fd b4 64
73 9b 68 ab 5d af f0 e6 3e 95 52 01 68 24 f0 54
bf 4d 3c 8c 90 a9 7b b6 b6 55 32 84 eb 42 9f cc''',
# Random
'''47 e1 ab 71 19 fe e5 6c 95 ee 5e aa d8 6f 40 d0
aa 63 bd 33''',
SHA1
),
)
def testEncrypt1(self):
# Verify encryption using all test vectors
for test in self._testData:
# Build the key
comps = [ int(rws(test[0][x]),16) for x in ('n','e') ]
key = RSA.construct(comps)
# RNG that takes its random numbers from a pool given
# at initialization
class randGen:
def __init__(self, data):
self.data = data
self.idx = 0
def __call__(self, N):
r = self.data[self.idx:N]
self.idx += N
return r
# The real test
key._randfunc = randGen(t2b(test[3]))
cipher = PKCS.new(key, test[4])
ct = cipher.encrypt(t2b(test[1]))
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)
cipher = PKCS.new(self.key1024)
self.assertRaises(ValueError, cipher.encrypt, pt)
def testDecrypt1(self):
# Verify decryption using all test vectors
for test in self._testData:
# Build the key
comps = [ int(rws(test[0][x]),16) for x in ('n','e','d') ]
key = RSA.construct(comps)
# The real test
cipher = PKCS.new(key, test[4])
pt = cipher.decrypt(t2b(test[2]))
self.assertEqual(pt, t2b(test[1]))
def testDecrypt2(self):
# Simplest possible negative tests
for ct_size in (127,128,129):
cipher = PKCS.new(self.key1024)
self.assertRaises(ValueError, cipher.decrypt, bchr(0x00)*ct_size)
def testEncryptDecrypt1(self):
# Encrypt/Decrypt messages of length [0..128-2*20-2]
for pt_len in range(0,128-2*20-2):
pt = self.rng(pt_len)
ct = PKCS.encrypt(pt, self.key1024)
pt2 = PKCS.decrypt(ct, self.key1024)
self.assertEqual(pt,pt2)
def testEncryptDecrypt1(self):
# Helper function to monitor what's requested from RNG
global asked
def localRng(N):
global asked
asked += N
return self.rng(N)
# Verify that OAEP is friendly to all hashes
for hashmod in (MD2,MD5,SHA1,SHA256,RIPEMD):
# Verify that encrypt() asks for as many random bytes
# as the hash output size
asked = 0
pt = self.rng(40)
self.key1024._randfunc = localRng
cipher = PKCS.new(self.key1024, hashmod)
ct = cipher.encrypt(pt)
self.assertEqual(cipher.decrypt(ct), pt)
self.assertTrue(asked > hashmod.digest_size)
def testEncryptDecrypt2(self):
# Verify that OAEP supports labels
pt = self.rng(35)
xlabel = self.rng(22)
cipher = PKCS.new(self.key1024, label=xlabel)
ct = cipher.encrypt(pt)
self.assertEqual(cipher.decrypt(ct), pt)
def testEncryptDecrypt3(self):
# Verify that encrypt() uses the custom MGF
global mgfcalls
# Helper function to monitor what's requested from MGF
def newMGF(seed,maskLen):
global mgfcalls
mgfcalls += 1
return bchr(0x00)*maskLen
mgfcalls = 0
pt = self.rng(32)
cipher = PKCS.new(self.key1024, mgfunc=newMGF)
ct = cipher.encrypt(pt)
self.assertEqual(mgfcalls, 2)
self.assertEqual(cipher.decrypt(ct), pt)
def get_tests(config={}):
tests = []
tests += list_test_cases(PKCS1_OAEP_Tests)
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/__init__.py: Self-test for hash modules
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test for hash modules"""
__revision__ = "$Id$"
def get_tests(config={}):
tests = []
from Crypto.SelfTest.Hash import test_HMAC; tests += test_HMAC.get_tests(config=config)
from Crypto.SelfTest.Hash import test_MD2; tests += test_MD2.get_tests(config=config)
from Crypto.SelfTest.Hash import test_MD4; tests += test_MD4.get_tests(config=config)
from Crypto.SelfTest.Hash import test_MD5; tests += test_MD5.get_tests(config=config)
from Crypto.SelfTest.Hash import test_RIPEMD; tests += test_RIPEMD.get_tests(config=config)
from Crypto.SelfTest.Hash import test_SHA; tests += test_SHA.get_tests(config=config)
from Crypto.SelfTest.Hash import test_SHA256; tests += test_SHA256.get_tests(config=config)
try:
from Crypto.SelfTest.Hash import test_SHA224; tests += test_SHA224.get_tests(config=config)
from Crypto.SelfTest.Hash import test_SHA384; tests += test_SHA384.get_tests(config=config)
from Crypto.SelfTest.Hash import test_SHA512; tests += test_SHA512.get_tests(config=config)
except ImportError:
import sys
sys.stderr.write("SelfTest: warning: not testing SHA224/SHA384/SHA512 modules (not available)\n")
return tests
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,197 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/common.py: Common code for Crypto.SelfTest.Hash
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-testing for PyCrypto hash modules"""
__revision__ = "$Id$"
import sys
import unittest
import binascii
from Crypto.Util.py3compat import *
# For compatibility with Python 2.1 and Python 2.2
if sys.hexversion < 0x02030000:
# Python 2.1 doesn't have a dict() function
# Python 2.2 dict() function raises TypeError if you do dict(MD5='blah')
def dict(**kwargs):
return kwargs.copy()
else:
dict = dict
class HashDigestSizeSelfTest(unittest.TestCase):
def __init__(self, hashmod, description, expected):
unittest.TestCase.__init__(self)
self.hashmod = hashmod
self.expected = expected
self.description = description
def shortDescription(self):
return self.description
def runTest(self):
self.assertTrue(hasattr(self.hashmod, "digest_size"))
self.assertEqual(self.hashmod.digest_size, self.expected)
h = self.hashmod.new()
self.assertTrue(hasattr(h, "digest_size"))
self.assertEqual(h.digest_size, self.expected)
class HashSelfTest(unittest.TestCase):
def __init__(self, hashmod, description, expected, input):
unittest.TestCase.__init__(self)
self.hashmod = hashmod
self.expected = expected
self.input = input
self.description = description
def shortDescription(self):
return self.description
def runTest(self):
h = self.hashmod.new()
h.update(self.input)
out1 = binascii.b2a_hex(h.digest())
out2 = h.hexdigest()
h = self.hashmod.new(self.input)
out3 = h.hexdigest()
out4 = binascii.b2a_hex(h.digest())
# PY3K: hexdigest() should return str(), and digest() bytes
self.assertEqual(self.expected, out1) # h = .new(); h.update(data); h.digest()
if sys.version_info[0] == 2:
self.assertEqual(self.expected, out2) # h = .new(); h.update(data); h.hexdigest()
self.assertEqual(self.expected, out3) # h = .new(data); h.hexdigest()
else:
self.assertEqual(self.expected.decode(), out2) # h = .new(); h.update(data); h.hexdigest()
self.assertEqual(self.expected.decode(), out3) # h = .new(data); h.hexdigest()
self.assertEqual(self.expected, out4) # h = .new(data); h.digest()
# Verify that new() object method produces a fresh hash object
h2 = h.new()
h2.update(self.input)
out5 = binascii.b2a_hex(h2.digest())
self.assertEqual(self.expected, out5)
class HashTestOID(unittest.TestCase):
def __init__(self, hashmod, oid):
unittest.TestCase.__init__(self)
self.hashmod = hashmod
self.oid = oid
def runTest(self):
h = self.hashmod.new()
if self.oid==None:
try:
raised = 0
a = h.oid
except AttributeError:
raised = 1
self.assertEqual(raised,1)
else:
self.assertEqual(h.oid, self.oid)
class MACSelfTest(unittest.TestCase):
def __init__(self, hashmod, description, expected_dict, input, key, hashmods):
unittest.TestCase.__init__(self)
self.hashmod = hashmod
self.expected_dict = expected_dict
self.input = input
self.key = key
self.hashmods = hashmods
self.description = description
def shortDescription(self):
return self.description
def runTest(self):
for hashname in list(self.expected_dict.keys()):
hashmod = self.hashmods[hashname]
key = binascii.a2b_hex(b(self.key))
data = binascii.a2b_hex(b(self.input))
# Strip whitespace from the expected string (which should be in lowercase-hex)
expected = b("".join(self.expected_dict[hashname].split()))
h = self.hashmod.new(key, digestmod=hashmod)
h.update(data)
out1 = binascii.b2a_hex(h.digest())
out2 = h.hexdigest()
h = self.hashmod.new(key, data, hashmod)
out3 = h.hexdigest()
out4 = binascii.b2a_hex(h.digest())
# Test .copy()
h2 = h.copy()
h.update(b("blah blah blah")) # Corrupt the original hash object
out5 = binascii.b2a_hex(h2.digest()) # The copied hash object should return the correct result
# PY3K: hexdigest() should return str(), and digest() bytes
self.assertEqual(expected, out1)
if sys.version_info[0] == 2:
self.assertEqual(expected, out2)
self.assertEqual(expected, out3)
else:
self.assertEqual(expected.decode(), out2)
self.assertEqual(expected.decode(), out3)
self.assertEqual(expected, out4)
self.assertEqual(expected, out5)
def make_hash_tests(module, module_name, test_data, digest_size, oid=None):
tests = []
for i in range(len(test_data)):
row = test_data[i]
(expected, input) = list(map(b,row[0:2]))
if len(row) < 3:
description = repr(input)
else:
description = row[2].encode('latin-1')
name = "%s #%d: %s" % (module_name, i+1, description)
tests.append(HashSelfTest(module, name, expected, input))
if oid is not None:
oid = b(oid)
name = "%s #%d: digest_size" % (module_name, i+1)
tests.append(HashDigestSizeSelfTest(module, name, digest_size))
tests.append(HashTestOID(module, oid))
return tests
def make_mac_tests(module, module_name, test_data, hashmods):
tests = []
for i in range(len(test_data)):
row = test_data[i]
(key, data, results, description) = row
name = "%s #%d: %s" % (module_name, i+1, description)
tests.append(MACSelfTest(module, name, results, data, key, hashmods))
return tests
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,223 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/HMAC.py: Self-test for the HMAC module
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Hash.HMAC"""
__revision__ = "$Id$"
from .common import dict # For compatibility with Python 2.1 and 2.2
from Crypto.Util.py3compat import *
# This is a list of (key, data, results, description) tuples.
test_data = [
## Test vectors from RFC 2202 ##
# Test that the default hashmod is MD5
('0b' * 16,
'4869205468657265',
dict(default='9294727a3638bb1c13f48ef8158bfc9d'),
'default-is-MD5'),
# Test case 1 (MD5)
('0b' * 16,
'4869205468657265',
dict(MD5='9294727a3638bb1c13f48ef8158bfc9d'),
'RFC 2202 #1-MD5 (HMAC-MD5)'),
# Test case 1 (SHA1)
('0b' * 20,
'4869205468657265',
dict(SHA1='b617318655057264e28bc0b6fb378c8ef146be00'),
'RFC 2202 #1-SHA1 (HMAC-SHA1)'),
# Test case 2
('4a656665',
'7768617420646f2079612077616e7420666f72206e6f7468696e673f',
dict(MD5='750c783e6ab0b503eaa86e310a5db738',
SHA1='effcdf6ae5eb2fa2d27416d5f184df9c259a7c79'),
'RFC 2202 #2 (HMAC-MD5/SHA1)'),
# Test case 3 (MD5)
('aa' * 16,
'dd' * 50,
dict(MD5='56be34521d144c88dbb8c733f0e8b3f6'),
'RFC 2202 #3-MD5 (HMAC-MD5)'),
# Test case 3 (SHA1)
('aa' * 20,
'dd' * 50,
dict(SHA1='125d7342b9ac11cd91a39af48aa17b4f63f175d3'),
'RFC 2202 #3-SHA1 (HMAC-SHA1)'),
# Test case 4
('0102030405060708090a0b0c0d0e0f10111213141516171819',
'cd' * 50,
dict(MD5='697eaf0aca3a3aea3a75164746ffaa79',
SHA1='4c9007f4026250c6bc8414f9bf50c86c2d7235da'),
'RFC 2202 #4 (HMAC-MD5/SHA1)'),
# Test case 5 (MD5)
('0c' * 16,
'546573742057697468205472756e636174696f6e',
dict(MD5='56461ef2342edc00f9bab995690efd4c'),
'RFC 2202 #5-MD5 (HMAC-MD5)'),
# Test case 5 (SHA1)
# NB: We do not implement hash truncation, so we only test the full hash here.
('0c' * 20,
'546573742057697468205472756e636174696f6e',
dict(SHA1='4c1a03424b55e07fe7f27be1d58bb9324a9a5a04'),
'RFC 2202 #5-SHA1 (HMAC-SHA1)'),
# Test case 6
('aa' * 80,
'54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a'
+ '65204b6579202d2048617368204b6579204669727374',
dict(MD5='6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd',
SHA1='aa4ae5e15272d00e95705637ce8a3b55ed402112'),
'RFC 2202 #6 (HMAC-MD5/SHA1)'),
# Test case 7
('aa' * 80,
'54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a'
+ '65204b657920616e64204c6172676572205468616e204f6e6520426c6f636b2d'
+ '53697a652044617461',
dict(MD5='6f630fad67cda0ee1fb1f562db3aa53e',
SHA1='e8e99d0f45237d786d6bbaa7965c7808bbff1a91'),
'RFC 2202 #7 (HMAC-MD5/SHA1)'),
## Test vectors from RFC 4231 ##
# 4.2. Test Case 1
('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b',
'4869205468657265',
dict(SHA256='''
b0344c61d8db38535ca8afceaf0bf12b
881dc200c9833da726e9376c2e32cff7
'''),
'RFC 4231 #1 (HMAC-SHA256)'),
# 4.3. Test Case 2 - Test with a key shorter than the length of the HMAC
# output.
('4a656665',
'7768617420646f2079612077616e7420666f72206e6f7468696e673f',
dict(SHA256='''
5bdcc146bf60754e6a042426089575c7
5a003f089d2739839dec58b964ec3843
'''),
'RFC 4231 #2 (HMAC-SHA256)'),
# 4.4. Test Case 3 - Test with a combined length of key and data that is
# larger than 64 bytes (= block-size of SHA-224 and SHA-256).
('aa' * 20,
'dd' * 50,
dict(SHA256='''
773ea91e36800e46854db8ebd09181a7
2959098b3ef8c122d9635514ced565fe
'''),
'RFC 4231 #3 (HMAC-SHA256)'),
# 4.5. Test Case 4 - Test with a combined length of key and data that is
# larger than 64 bytes (= block-size of SHA-224 and SHA-256).
('0102030405060708090a0b0c0d0e0f10111213141516171819',
'cd' * 50,
dict(SHA256='''
82558a389a443c0ea4cc819899f2083a
85f0faa3e578f8077a2e3ff46729665b
'''),
'RFC 4231 #4 (HMAC-SHA256)'),
# 4.6. Test Case 5 - Test with a truncation of output to 128 bits.
#
# Not included because we do not implement hash truncation.
#
# 4.7. Test Case 6 - Test with a key larger than 128 bytes (= block-size of
# SHA-384 and SHA-512).
('aa' * 131,
'54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a'
+ '65204b6579202d2048617368204b6579204669727374',
dict(SHA256='''
60e431591ee0b67f0d8a26aacbf5b77f
8e0bc6213728c5140546040f0ee37f54
'''),
'RFC 4231 #6 (HMAC-SHA256)'),
# 4.8. Test Case 7 - Test with a key and data that is larger than 128 bytes
# (= block-size of SHA-384 and SHA-512).
('aa' * 131,
'5468697320697320612074657374207573696e672061206c6172676572207468'
+ '616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074'
+ '68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565'
+ '647320746f20626520686173686564206265666f7265206265696e6720757365'
+ '642062792074686520484d414320616c676f726974686d2e',
dict(SHA256='''
9b09ffa71b942fcb27635fbcd5b0e944
bfdc63644f0713938a7f51535c3a35e2
'''),
'RFC 4231 #7 (HMAC-SHA256)'),
]
hashlib_test_data = [
# Test case 8 (SHA224)
('4a656665',
'7768617420646f2079612077616e74'
+ '20666f72206e6f7468696e673f',
dict(SHA224='a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44'),
'RFC 4634 8.4 SHA224 (HMAC-SHA224)'),
# Test case 9 (SHA384)
('4a656665',
'7768617420646f2079612077616e74'
+ '20666f72206e6f7468696e673f',
dict(SHA384='af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649'),
'RFC 4634 8.4 SHA384 (HMAC-SHA384)'),
# Test case 10 (SHA512)
('4a656665',
'7768617420646f2079612077616e74'
+ '20666f72206e6f7468696e673f',
dict(SHA512='164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737'),
'RFC 4634 8.4 SHA512 (HMAC-SHA512)'),
]
def get_tests(config={}):
global test_data
from Crypto.Hash import HMAC, MD5, SHA as SHA1, SHA256
from .common import make_mac_tests
hashmods = dict(MD5=MD5, SHA1=SHA1, SHA256=SHA256, default=None)
try:
from Crypto.Hash import SHA224, SHA384, SHA512
hashmods.update(dict(SHA224=SHA224, SHA384=SHA384, SHA512=SHA512))
test_data += hashlib_test_data
except ImportError:
import sys
sys.stderr.write("SelfTest: warning: not testing HMAC-SHA224/384/512 (not available)\n")
return make_mac_tests(HMAC, "HMAC", test_data, hashmods)
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/MD2.py: Self-test for the MD2 hash function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Hash.MD2"""
__revision__ = "$Id$"
from Crypto.Util.py3compat import *
# This is a list of (expected_result, input[, description]) tuples.
test_data = [
# Test vectors from RFC 1319
('8350e5a3e24c153df2275c9f80692773', '', "'' (empty string)"),
('32ec01ec4a6dac72c0ab96fb34c0b5d1', 'a'),
('da853b0d3f88d99b30283a69e6ded6bb', 'abc'),
('ab4f496bfb2a530b219ff33031fe06b0', 'message digest'),
('4e8ddff3650292ab5a4108c3aa47940b', 'abcdefghijklmnopqrstuvwxyz',
'a-z'),
('da33def2a42df13975352846c30338cd',
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
'A-Z, a-z, 0-9'),
('d5976f79d83d3a0dc9806c3c66f3efd8',
'1234567890123456789012345678901234567890123456'
+ '7890123456789012345678901234567890',
"'1234567890' * 8"),
]
def get_tests(config={}):
from Crypto.Hash import MD2
from .common import make_hash_tests
return make_hash_tests(MD2, "MD2", test_data,
digest_size=16,
oid="\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02")
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/MD4.py: Self-test for the MD4 hash function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Hash.MD4"""
__revision__ = "$Id$"
from Crypto.Util.py3compat import *
# This is a list of (expected_result, input[, description]) tuples.
test_data = [
# Test vectors from RFC 1320
('31d6cfe0d16ae931b73c59d7e0c089c0', '', "'' (empty string)"),
('bde52cb31de33e46245e05fbdbd6fb24', 'a'),
('a448017aaf21d8525fc10ae87aa6729d', 'abc'),
('d9130a8164549fe818874806e1c7014b', 'message digest'),
('d79e1c308aa5bbcdeea8ed63df412da9', 'abcdefghijklmnopqrstuvwxyz',
'a-z'),
('043f8582f241db351ce627e153e7f0e4',
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
'A-Z, a-z, 0-9'),
('e33b4ddc9c38f2199c3e7b164fcc0536',
'1234567890123456789012345678901234567890123456'
+ '7890123456789012345678901234567890',
"'1234567890' * 8"),
]
def get_tests(config={}):
from Crypto.Hash import MD4
from .common import make_hash_tests
return make_hash_tests(MD4, "MD4", test_data,
digest_size=16,
oid="\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x04")
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/MD5.py: Self-test for the MD5 hash function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Hash.MD5"""
__revision__ = "$Id$"
from Crypto.Util.py3compat import *
# This is a list of (expected_result, input[, description]) tuples.
test_data = [
# Test vectors from RFC 1321
('d41d8cd98f00b204e9800998ecf8427e', '', "'' (empty string)"),
('0cc175b9c0f1b6a831c399e269772661', 'a'),
('900150983cd24fb0d6963f7d28e17f72', 'abc'),
('f96b697d7cb7938d525a2f31aaf161d0', 'message digest'),
('c3fcd3d76192e4007dfb496cca67e13b', 'abcdefghijklmnopqrstuvwxyz',
'a-z'),
('d174ab98d277d9f5a5611c2c9f419d9f',
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
'A-Z, a-z, 0-9'),
('57edf4a22be3c955ac49da2e2107b67a',
'1234567890123456789012345678901234567890123456'
+ '7890123456789012345678901234567890',
"'1234567890' * 8"),
]
def get_tests(config={}):
from Crypto.Hash import MD5
from .common import make_hash_tests
return make_hash_tests(MD5, "MD5", test_data,
digest_size=16,
oid="\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05")
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/test_RIPEMD.py: Self-test for the RIPEMD-160 hash function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
#"""Self-test suite for Crypto.Hash.RIPEMD"""
__revision__ = "$Id$"
from Crypto.Util.py3compat import *
# This is a list of (expected_result, input[, description]) tuples.
test_data = [
# Test vectors downloaded 2008-09-12 from
# http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
('9c1185a5c5e9fc54612808977ee8f548b2258d31', '', "'' (empty string)"),
('0bdc9d2d256b3ee9daae347be6f4dc835a467ffe', 'a'),
('8eb208f7e05d987a9b044a8e98c6b087f15a0bfc', 'abc'),
('5d0689ef49d2fae572b881b123a85ffa21595f36', 'message digest'),
('f71c27109c692c1b56bbdceb5b9d2865b3708dbc',
'abcdefghijklmnopqrstuvwxyz',
'a-z'),
('12a053384a9c0c88e405a06c27dcf49ada62eb2b',
'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq',
'abcdbcd...pnopq'),
('b0e20b6e3116640286ed3a87a5713079b21f5189',
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
'A-Z, a-z, 0-9'),
('9b752e45573d4b39f4dbd3323cab82bf63326bfb',
'1234567890' * 8,
"'1234567890' * 8"),
('52783243c1697bdbe16d37f97f68f08325dc1528',
'a' * 10**6,
'"a" * 10**6'),
]
def get_tests(config={}):
from Crypto.Hash import RIPEMD
from .common import make_hash_tests
return make_hash_tests(RIPEMD, "RIPEMD", test_data,
digest_size=20,
oid="\x06\x05\x2b\x24\x03\02\x01")
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/SHA.py: Self-test for the SHA-1 hash function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Hash.SHA"""
__revision__ = "$Id$"
from Crypto.Util.py3compat import *
# Test vectors from various sources
# This is a list of (expected_result, input[, description]) tuples.
test_data = [
# FIPS PUB 180-2, A.1 - "One-Block Message"
('a9993e364706816aba3e25717850c26c9cd0d89d', 'abc'),
# FIPS PUB 180-2, A.2 - "Multi-Block Message"
('84983e441c3bd26ebaae4aa1f95129e5e54670f1',
'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'),
# FIPS PUB 180-2, A.3 - "Long Message"
# ('34aa973cd4c4daa4f61eeb2bdbad27316534016f',
# 'a' * 10**6,
# '"a" * 10**6'),
# RFC 3174: Section 7.3, "TEST4" (multiple of 512 bits)
('dea356a2cddd90c7a7ecedc5ebb563934f460452',
'01234567' * 80,
'"01234567" * 80'),
]
def get_tests(config={}):
from Crypto.Hash import SHA
from .common import make_hash_tests
return make_hash_tests(SHA, "SHA", test_data,
digest_size=20,
oid="\x06\x05\x2B\x0E\x03\x02\x1A")
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/test_SHA224.py: Self-test for the SHA-224 hash function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Hash.SHA224"""
__revision__ = "$Id$"
# Test vectors from various sources
# This is a list of (expected_result, input[, description]) tuples.
test_data = [
# RFC 3874: Section 3.1, "Test Vector #1
('23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7', 'abc'),
# RFC 3874: Section 3.2, "Test Vector #2
('75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525', 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'),
# RFC 3874: Section 3.3, "Test Vector #3
('20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67', 'a' * 10**6, "'a' * 10**6"),
# Examples from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm
('d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f', ''),
('49b08defa65e644cbf8a2dd9270bdededabc741997d1dadd42026d7b',
'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'),
('58911e7fccf2971a7d07f93162d8bd13568e71aa8fc86fc1fe9043d1',
'Frank jagt im komplett verwahrlosten Taxi quer durch Bayern'),
]
def get_tests(config={}):
from Crypto.Hash import SHA224
from .common import make_hash_tests
return make_hash_tests(SHA224, "SHA224", test_data,
digest_size=28,
oid='\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04')
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,96 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/test_SHA256.py: Self-test for the SHA-256 hash function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Hash.SHA256"""
__revision__ = "$Id$"
import unittest
from Crypto.Util.py3compat import *
class LargeSHA256Test(unittest.TestCase):
def runTest(self):
"""SHA256: 512/520 MiB test"""
from Crypto.Hash import SHA256
zeros = bchr(0x00) * (1024*1024)
h = SHA256.new(zeros)
for i in range(511):
h.update(zeros)
# This test vector is from PyCrypto's old testdata.py file.
self.assertEqual('9acca8e8c22201155389f65abbf6bc9723edc7384ead80503839f49dcc56d767', h.hexdigest()) # 512 MiB
for i in range(8):
h.update(zeros)
# This test vector is from PyCrypto's old testdata.py file.
self.assertEqual('abf51ad954b246009dfe5a50ecd582fd5b8f1b8b27f30393853c3ef721e7fa6e', h.hexdigest()) # 520 MiB
def get_tests(config={}):
# Test vectors from FIPS PUB 180-2
# This is a list of (expected_result, input[, description]) tuples.
test_data = [
# FIPS PUB 180-2, B.1 - "One-Block Message"
('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad',
'abc'),
# FIPS PUB 180-2, B.2 - "Multi-Block Message"
('248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1',
'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'),
# FIPS PUB 180-2, B.3 - "Long Message"
('cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0',
'a' * 10**6,
'"a" * 10**6'),
# Test for an old PyCrypto bug.
('f7fd017a3c721ce7ff03f3552c0813adcc48b7f33f07e5e2ba71e23ea393d103',
'This message is precisely 55 bytes long, to test a bug.',
'Length = 55 (mod 64)'),
# Example from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm
('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', ''),
('d32b568cd1b96d459e7291ebf4b25d007f275c9f13149beeb782fac0716613f8',
'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'),
]
from Crypto.Hash import SHA256
from .common import make_hash_tests
tests = make_hash_tests(SHA256, "SHA256", test_data,
digest_size=32,
oid="\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01")
if config.get('slow_tests'):
tests += [LargeSHA256Test()]
return tests
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/test_SHA.py: Self-test for the SHA-384 hash function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Hash.SHA384"""
__revision__ = "$Id$"
# Test vectors from various sources
# This is a list of (expected_result, input[, description]) tuples.
test_data = [
# RFC 4634: Section Page 8.4, "Test 1"
('cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7', 'abc'),
# RFC 4634: Section Page 8.4, "Test 2.2"
('09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039', 'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu'),
# RFC 4634: Section Page 8.4, "Test 3"
('9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985', 'a' * 10**6, "'a' * 10**6"),
# Taken from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm
('38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b', ''),
# Example from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm
('71e8383a4cea32d6fd6877495db2ee353542f46fa44bc23100bca48f3366b84e809f0708e81041f427c6d5219a286677',
'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'),
]
def get_tests(config={}):
from Crypto.Hash import SHA384
from .common import make_hash_tests
return make_hash_tests(SHA384, "SHA384", test_data,
digest_size=48,
oid='\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02')
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/test_SHA512.py: Self-test for the SHA-512 hash function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Hash.SHA512"""
__revision__ = "$Id$"
# Test vectors from various sources
# This is a list of (expected_result, input[, description]) tuples.
test_data = [
# RFC 4634: Section Page 8.4, "Test 1"
('ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f', 'abc'),
# RFC 4634: Section Page 8.4, "Test 2.1"
('8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909', 'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu'),
# RFC 4634: Section Page 8.4, "Test 3"
('e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b', 'a' * 10**6, "'a' * 10**6"),
# Taken from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm
('cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e', ''),
('af9ed2de700433b803240a552b41b5a472a6ef3fe1431a722b2063c75e9f07451f67a28e37d09cde769424c96aea6f8971389db9e1993d6c565c3c71b855723c', 'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'),
]
def get_tests(config={}):
from Crypto.Hash import SHA512
from .common import make_hash_tests
return make_hash_tests(SHA512, "SHA512", test_data,
digest_size=64,
oid="\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03")
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Protocol/__init__.py: Self-tests for Crypto.Protocol
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test for Crypto.Protocol"""
__revision__ = "$Id$"
def get_tests(config={}):
tests = []
from Crypto.SelfTest.Protocol import test_chaffing; tests += test_chaffing.get_tests(config=config)
from Crypto.SelfTest.Protocol import test_rfc1751; tests += test_rfc1751.get_tests(config=config)
from Crypto.SelfTest.Protocol import test_AllOrNothing; tests += test_AllOrNothing.get_tests(config=config)
return tests
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,76 @@
#
# Test script for Crypto.Protocol.AllOrNothing
#
# Part of the Python Cryptography Toolkit
#
# Written by Andrew Kuchling and others
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
__revision__ = "$Id$"
import unittest
from Crypto.Protocol import AllOrNothing
from Crypto.Util.py3compat import *
text = b("""\
When in the Course of human events, it becomes necessary for one people to
dissolve the political bands which have connected them with another, and to
assume among the powers of the earth, the separate and equal station to which
the Laws of Nature and of Nature's God entitle them, a decent respect to the
opinions of mankind requires that they should declare the causes which impel
them to the separation.
We hold these truths to be self-evident, that all men are created equal, that
they are endowed by their Creator with certain unalienable Rights, that among
these are Life, Liberty, and the pursuit of Happiness. That to secure these
rights, Governments are instituted among Men, deriving their just powers from
the consent of the governed. That whenever any Form of Government becomes
destructive of these ends, it is the Right of the People to alter or to
abolish it, and to institute new Government, laying its foundation on such
principles and organizing its powers in such form, as to them shall seem most
likely to effect their Safety and Happiness.
""")
class AllOrNothingTest (unittest.TestCase):
def runTest(self):
"Simple test of AllOrNothing"
from Crypto.Cipher import AES
import base64
# The current AllOrNothing will fail
# every so often. Repeat the test
# several times to force this.
for i in range(50):
x = AllOrNothing.AllOrNothing(AES)
msgblocks = x.digest(text)
# get a new undigest-only object so there's no leakage
y = AllOrNothing.AllOrNothing(AES)
text2 = y.undigest(msgblocks)
self.assertEqual(text, text2)
def get_tests(config={}):
return [AllOrNothingTest()]
if __name__ == "__main__":
unittest.main()

View file

@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Protocol/test_KDF.py: Self-test for key derivation functions
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
__revision__ = "$Id$"
import unittest
from binascii import unhexlify
from Crypto.SelfTest.st_common import list_test_cases
from Crypto.Hash import SHA as SHA1,HMAC
from Crypto.Protocol.KDF import *
def t2b(t): return unhexlify(b(t))
class PBKDF1_Tests(unittest.TestCase):
# List of tuples with test data.
# Each tuple is made up by:
# Item #0: a pass phrase
# Item #1: salt (8 bytes encoded in hex)
# Item #2: output key length
# Item #3: iterations to use
# Item #4: expected result (encoded in hex)
_testData = (
# From http://www.di-mgt.com.au/cryptoKDFs.html#examplespbkdf
("password","78578E5A5D63CB06",16,1000,"DC19847E05C64D2FAF10EBFB4A3D2A20"),
)
def test1(self):
v = self._testData[0]
res = PBKDF1(v[0], t2b(v[1]), v[2], v[3], SHA1)
self.assertEqual(res, t2b(v[4]))
class PBKDF2_Tests(unittest.TestCase):
# List of tuples with test data.
# Each tuple is made up by:
# Item #0: a pass phrase
# Item #1: salt (encoded in hex)
# Item #2: output key length
# Item #3: iterations to use
# Item #4: expected result (encoded in hex)
_testData = (
# From http://www.di-mgt.com.au/cryptoKDFs.html#examplespbkdf
("password","78578E5A5D63CB06",24,2048,"BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643"),
# From RFC 6050
("password","73616c74", 20, 1, "0c60c80f961f0e71f3a9b524af6012062fe037a6"),
("password","73616c74", 20, 2, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"),
("password","73616c74", 20, 4096, "4b007901b765489abead49d926f721d065a429c1"),
("passwordPASSWORDpassword","73616c7453414c5473616c7453414c5473616c7453414c5473616c7453414c5473616c74",
25, 4096, "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"),
( 'pass\x00word',"7361006c74",16,4096, "56fa6aa75548099dcc37d7f03425e0c3"),
)
def test1(self):
# Test only for HMAC-SHA1 as PRF
def prf(p,s):
return HMAC.new(p,s,SHA1).digest()
for i in range(len(self._testData)):
v = self._testData[i]
res = PBKDF2(v[0], t2b(v[1]), v[2], v[3])
res2 = PBKDF2(v[0], t2b(v[1]), v[2], v[3], prf)
self.assertEqual(res, t2b(v[4]))
self.assertEqual(res, res2)
def get_tests(config={}):
tests = []
tests += list_test_cases(PBKDF1_Tests)
tests += list_test_cases(PBKDF2_Tests)
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4

View file

@ -0,0 +1,74 @@
#
# Test script for Crypto.Protocol.Chaffing
#
# Part of the Python Cryptography Toolkit
#
# Written by Andrew Kuchling and others
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
__revision__ = "$Id$"
import unittest
from Crypto.Protocol import Chaffing
text = """\
When in the Course of human events, it becomes necessary for one people to
dissolve the political bands which have connected them with another, and to
assume among the powers of the earth, the separate and equal station to which
the Laws of Nature and of Nature's God entitle them, a decent respect to the
opinions of mankind requires that they should declare the causes which impel
them to the separation.
We hold these truths to be self-evident, that all men are created equal, that
they are endowed by their Creator with certain unalienable Rights, that among
these are Life, Liberty, and the pursuit of Happiness. That to secure these
rights, Governments are instituted among Men, deriving their just powers from
the consent of the governed. That whenever any Form of Government becomes
destructive of these ends, it is the Right of the People to alter or to
abolish it, and to institute new Government, laying its foundation on such
principles and organizing its powers in such form, as to them shall seem most
likely to effect their Safety and Happiness.
"""
class ChaffingTest (unittest.TestCase):
def runTest(self):
"Simple tests of chaffing and winnowing"
# Test constructors
Chaffing.Chaff()
Chaffing.Chaff(0.5, 1)
self.assertRaises(ValueError, Chaffing.Chaff, factor=-1)
self.assertRaises(ValueError, Chaffing.Chaff, blocksper=-1)
data = [(1, 'data1', 'data1'), (2, 'data2', 'data2')]
c = Chaffing.Chaff(1.0, 1)
c.chaff(data)
chaff = c.chaff(data)
self.assertEqual(len(chaff), 4)
c = Chaffing.Chaff(0.0, 1)
chaff = c.chaff(data)
self.assertEqual(len(chaff), 2)
def get_tests(config={}):
return [ChaffingTest()]
if __name__ == "__main__":
unittest.main()

View file

@ -0,0 +1,62 @@
#
# Test script for Crypto.Util.RFC1751.
#
# Part of the Python Cryptography Toolkit
#
# Written by Andrew Kuchling and others
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
__revision__ = "$Id$"
import binascii
import unittest
from Crypto.Util import RFC1751
from Crypto.Util.py3compat import *
test_data = [('EB33F77EE73D4053', 'TIDE ITCH SLOW REIN RULE MOT'),
('CCAC2AED591056BE4F90FD441C534766',
'RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE'),
('EFF81F9BFBC65350920CDD7416DE8009',
'TROD MUTE TAIL WARM CHAR KONG HAAG CITY BORE O TEAL AWL')
]
class RFC1751Test_k2e (unittest.TestCase):
def runTest (self):
"Check converting keys to English"
for key, words in test_data:
key=binascii.a2b_hex(b(key))
self.assertEqual(RFC1751.key_to_english(key), words)
class RFC1751Test_e2k (unittest.TestCase):
def runTest (self):
"Check converting English strings to keys"
for key, words in test_data:
key=binascii.a2b_hex(b(key))
self.assertEqual(RFC1751.english_to_key(words), key)
# class RFC1751Test
def get_tests(config={}):
return [RFC1751Test_k2e(), RFC1751Test_e2k()]
if __name__ == "__main__":
unittest.main()

View file

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
#
# SelfTest/PublicKey/__init__.py: Self-test for public key crypto
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test for public-key crypto"""
__revision__ = "$Id$"
import os
def get_tests(config={}):
tests = []
from Crypto.SelfTest.PublicKey import test_DSA; tests += test_DSA.get_tests(config=config)
from Crypto.SelfTest.PublicKey import test_RSA; tests += test_RSA.get_tests(config=config)
from Crypto.SelfTest.PublicKey import test_importKey; tests += test_importKey.get_tests(config=config)
from Crypto.SelfTest.PublicKey import test_ElGamal; tests += test_ElGamal.get_tests(config=config)
return tests
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,244 @@
# -*- coding: utf-8 -*-
#
# SelfTest/PublicKey/test_DSA.py: Self-test for the DSA primitive
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.PublicKey.DSA"""
__revision__ = "$Id$"
import sys
import os
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
from Crypto.Util.py3compat import *
import unittest
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
def _sws(s):
"""Remove whitespace from a text or byte string"""
if isinstance(s,str):
return "".join(s.split())
else:
return b("").join(s.split())
class DSATest(unittest.TestCase):
# Test vector from "Appendix 5. Example of the DSA" of
# "Digital Signature Standard (DSS)",
# U.S. Department of Commerce/National Institute of Standards and Technology
# FIPS 186-2 (+Change Notice), 2000 January 27.
# http://csrc.nist.gov/publications/fips/fips186-2/fips186-2-change1.pdf
y = _sws("""19131871 d75b1612 a819f29d 78d1b0d7 346f7aa7 7bb62a85
9bfd6c56 75da9d21 2d3a36ef 1672ef66 0b8c7c25 5cc0ec74
858fba33 f44c0669 9630a76b 030ee333""")
g = _sws("""626d0278 39ea0a13 413163a5 5b4cb500 299d5522 956cefcb
3bff10f3 99ce2c2e 71cb9de5 fa24babf 58e5b795 21925c9c
c42e9f6f 464b088c c572af53 e6d78802""")
p = _sws("""8df2a494 492276aa 3d25759b b06869cb eac0d83a fb8d0cf7
cbb8324f 0d7882e5 d0762fc5 b7210eaf c2e9adac 32ab7aac
49693dfb f83724c2 ec0736ee 31c80291""")
q = _sws("""c773218c 737ec8ee 993b4f2d ed30f48e dace915f""")
x = _sws("""2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614""")
k = _sws("""358dad57 1462710f 50e254cf 1a376b2b deaadfbf""")
k_inverse = _sws("""0d516729 8202e49b 4116ac10 4fc3f415 ae52f917""")
m = b2a_hex(b("abc"))
m_hash = _sws("""a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d""")
r = _sws("""8bac1ab6 6410435c b7181f95 b16ab97c 92b341c0""")
s = _sws("""41e2345f 1f56df24 58f426d1 55b4ba2d b6dcd8c8""")
def setUp(self):
global DSA, Random, bytes_to_long, size
from Crypto.PublicKey import DSA
from Crypto import Random
from Crypto.Util.number import bytes_to_long, inverse, size
self.dsa = DSA
def test_generate_1arg(self):
"""DSA (default implementation) generated key (1 argument)"""
dsaObj = self.dsa.generate(1024)
self._check_private_key(dsaObj)
pub = dsaObj.publickey()
self._check_public_key(pub)
def test_generate_2arg(self):
"""DSA (default implementation) generated key (2 arguments)"""
dsaObj = self.dsa.generate(1024, Random.new().read)
self._check_private_key(dsaObj)
pub = dsaObj.publickey()
self._check_public_key(pub)
def test_construct_4tuple(self):
"""DSA (default implementation) constructed key (4-tuple)"""
(y, g, p, q) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q)]
dsaObj = self.dsa.construct((y, g, p, q))
self._test_verification(dsaObj)
def test_construct_5tuple(self):
"""DSA (default implementation) constructed key (5-tuple)"""
(y, g, p, q, x) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q, self.x)]
dsaObj = self.dsa.construct((y, g, p, q, x))
self._test_signing(dsaObj)
self._test_verification(dsaObj)
def _check_private_key(self, dsaObj):
# Check capabilities
self.assertEqual(1, dsaObj.has_private())
self.assertEqual(1, dsaObj.can_sign())
self.assertEqual(0, dsaObj.can_encrypt())
self.assertEqual(0, dsaObj.can_blind())
# Check dsaObj.[ygpqx] -> dsaObj.key.[ygpqx] mapping
self.assertEqual(dsaObj.y, dsaObj.key.y)
self.assertEqual(dsaObj.g, dsaObj.key.g)
self.assertEqual(dsaObj.p, dsaObj.key.p)
self.assertEqual(dsaObj.q, dsaObj.key.q)
self.assertEqual(dsaObj.x, dsaObj.key.x)
# Sanity check key data
self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q
self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits
self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1
self.assertEqual(dsaObj.y, pow(dsaObj.g, dsaObj.x, dsaObj.p)) # y == g**x mod p
self.assertEqual(1, 0 < dsaObj.x < dsaObj.q) # 0 < x < q
def _check_public_key(self, dsaObj):
k = a2b_hex(self.k)
m_hash = a2b_hex(self.m_hash)
# Check capabilities
self.assertEqual(0, dsaObj.has_private())
self.assertEqual(1, dsaObj.can_sign())
self.assertEqual(0, dsaObj.can_encrypt())
self.assertEqual(0, dsaObj.can_blind())
# Check dsaObj.[ygpq] -> dsaObj.key.[ygpq] mapping
self.assertEqual(dsaObj.y, dsaObj.key.y)
self.assertEqual(dsaObj.g, dsaObj.key.g)
self.assertEqual(dsaObj.p, dsaObj.key.p)
self.assertEqual(dsaObj.q, dsaObj.key.q)
# Check that private parameters are all missing
self.assertEqual(0, hasattr(dsaObj, 'x'))
self.assertEqual(0, hasattr(dsaObj.key, 'x'))
# Sanity check key data
self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q
self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits
self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1
# Public-only key objects should raise an error when .sign() is called
self.assertRaises(TypeError, dsaObj.sign, m_hash, k)
# Check __eq__ and __ne__
self.assertEqual(dsaObj.publickey() == dsaObj.publickey(),True) # assert_
self.assertEqual(dsaObj.publickey() != dsaObj.publickey(),False) # failIf
def _test_signing(self, dsaObj):
k = a2b_hex(self.k)
m_hash = a2b_hex(self.m_hash)
r = bytes_to_long(a2b_hex(self.r))
s = bytes_to_long(a2b_hex(self.s))
(r_out, s_out) = dsaObj.sign(m_hash, k)
self.assertEqual((r, s), (r_out, s_out))
def _test_verification(self, dsaObj):
m_hash = a2b_hex(self.m_hash)
r = bytes_to_long(a2b_hex(self.r))
s = bytes_to_long(a2b_hex(self.s))
self.assertEqual(1, dsaObj.verify(m_hash, (r, s)))
self.assertEqual(0, dsaObj.verify(m_hash + b("\0"), (r, s)))
class DSAFastMathTest(DSATest):
def setUp(self):
DSATest.setUp(self)
self.dsa = DSA.DSAImplementation(use_fast_math=True)
def test_generate_1arg(self):
"""DSA (_fastmath implementation) generated key (1 argument)"""
DSATest.test_generate_1arg(self)
def test_generate_2arg(self):
"""DSA (_fastmath implementation) generated key (2 arguments)"""
DSATest.test_generate_2arg(self)
def test_construct_4tuple(self):
"""DSA (_fastmath implementation) constructed key (4-tuple)"""
DSATest.test_construct_4tuple(self)
def test_construct_5tuple(self):
"""DSA (_fastmath implementation) constructed key (5-tuple)"""
DSATest.test_construct_5tuple(self)
class DSASlowMathTest(DSATest):
def setUp(self):
DSATest.setUp(self)
self.dsa = DSA.DSAImplementation(use_fast_math=False)
def test_generate_1arg(self):
"""DSA (_slowmath implementation) generated key (1 argument)"""
DSATest.test_generate_1arg(self)
def test_generate_2arg(self):
"""DSA (_slowmath implementation) generated key (2 arguments)"""
DSATest.test_generate_2arg(self)
def test_construct_4tuple(self):
"""DSA (_slowmath implementation) constructed key (4-tuple)"""
DSATest.test_construct_4tuple(self)
def test_construct_5tuple(self):
"""DSA (_slowmath implementation) constructed key (5-tuple)"""
DSATest.test_construct_5tuple(self)
def get_tests(config={}):
tests = []
tests += list_test_cases(DSATest)
try:
from Crypto.PublicKey import _fastmath
tests += list_test_cases(DSAFastMathTest)
except ImportError:
from distutils.sysconfig import get_config_var
import inspect
_fm_path = os.path.normpath(os.path.dirname(os.path.abspath(
inspect.getfile(inspect.currentframe())))
+"/../../PublicKey/_fastmath"+get_config_var("SO"))
if os.path.exists(_fm_path):
raise ImportError("While the _fastmath module exists, importing "+
"it failed. This may point to the gmp or mpir shared library "+
"not being in the path. _fastmath was found at "+_fm_path)
tests += list_test_cases(DSASlowMathTest)
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,210 @@
# -*- coding: utf-8 -*-
#
# SelfTest/PublicKey/test_ElGamal.py: Self-test for the ElGamal primitive
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.PublicKey.ElGamal"""
__revision__ = "$Id$"
import unittest
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
from Crypto import Random
from Crypto.PublicKey import ElGamal
from Crypto.Util.number import *
from Crypto.Util.py3compat import *
class ElGamalTest(unittest.TestCase):
#
# Test vectors
#
# There seem to be no real ElGamal test vectors available in the
# public domain. The following test vectors have been generated
# with libgcrypt 1.5.0.
#
# Encryption
tve=[
{
# 256 bits
'p' :'BA4CAEAAED8CBE952AFD2126C63EB3B345D65C2A0A73D2A3AD4138B6D09BD933',
'g' :'05',
'y' :'60D063600ECED7C7C55146020E7A31C4476E9793BEAED420FEC9E77604CAE4EF',
'x' :'1D391BA2EE3C37FE1BA175A69B2C73A11238AD77675932',
'k' :'F5893C5BAB4131264066F57AB3D8AD89E391A0B68A68A1',
'pt' :'48656C6C6F207468657265',
'ct1':'32BFD5F487966CEA9E9356715788C491EC515E4ED48B58F0F00971E93AAA5EC7',
'ct2':'7BE8FBFF317C93E82FCEF9BD515284BA506603FEA25D01C0CB874A31F315EE68'
},
{
# 512 bits
'p' :'F1B18AE9F7B4E08FDA9A04832F4E919D89462FD31BF12F92791A93519F75076D6CE3942689CDFF2F344CAFF0F82D01864F69F3AECF566C774CBACF728B81A227',
'g' :'07',
'y' :'688628C676E4F05D630E1BE39D0066178CA7AA83836B645DE5ADD359B4825A12B02EF4252E4E6FA9BEC1DB0BE90F6D7C8629CABB6E531F472B2664868156E20C',
'x' :'14E60B1BDFD33436C0DA8A22FDC14A2CCDBBED0627CE68',
'k' :'38DBF14E1F319BDA9BAB33EEEADCAF6B2EA5250577ACE7',
'pt' :'48656C6C6F207468657265',
'ct1':'290F8530C2CC312EC46178724F196F308AD4C523CEABB001FACB0506BFED676083FE0F27AC688B5C749AB3CB8A80CD6F7094DBA421FB19442F5A413E06A9772B',
'ct2':'1D69AAAD1DC50493FB1B8E8721D621D683F3BF1321BE21BC4A43E11B40C9D4D9C80DE3AAC2AB60D31782B16B61112E68220889D53C4C3136EE6F6CE61F8A23A0'
}
]
# Signature
tvs=[
{
# 256 bits
'p' :'D2F3C41EA66530838A704A48FFAC9334F4701ECE3A97CEE4C69DD01AE7129DD7',
'g' :'05',
'y' :'C3F9417DC0DAFEA6A05C1D2333B7A95E63B3F4F28CC962254B3256984D1012E7',
'x' :'165E4A39BE44D5A2D8B1332D416BC559616F536BC735BB',
'k' :'C7F0C794A7EAD726E25A47FF8928013680E73C51DD3D7D99BFDA8F492585928F',
'h' :'48656C6C6F207468657265',
'sig1':'35CA98133779E2073EF31165AFCDEB764DD54E96ADE851715495F9C635E1E7C2',
'sig2':'0135B88B1151279FE5D8078D4FC685EE81177EE9802AB123A73925FC1CB059A7',
},
{
# 512 bits
'p' :'E24CF3A4B8A6AF749DCA6D714282FE4AABEEE44A53BB6ED15FBE32B5D3C3EF9CC4124A2ECA331F3C1C1B667ACA3766825217E7B5F9856648D95F05330C6A19CF',
'g' :'0B',
'y' :'2AD3A1049CA5D4ED207B2431C79A8719BB4073D4A94E450EA6CEE8A760EB07ADB67C0D52C275EE85D7B52789061EE45F2F37D9B2AE522A51C28329766BFE68AC',
'x' :'16CBB4F46D9ECCF24FF9F7E63CAA3BD8936341555062AB',
'k' :'8A3D89A4E429FD2476D7D717251FB79BF900FFE77444E6BB8299DC3F84D0DD57ABAB50732AE158EA52F5B9E7D8813E81FD9F79470AE22F8F1CF9AEC820A78C69',
'h' :'48656C6C6F207468657265',
'sig1':'BE001AABAFFF976EC9016198FBFEA14CBEF96B000CCC0063D3324016F9E91FE80D8F9325812ED24DDB2B4D4CF4430B169880B3CE88313B53255BD4EC0378586F',
'sig2':'5E266F3F837BA204E3BBB6DBECC0611429D96F8C7CE8F4EFDF9D4CB681C2A954468A357BF4242CEC7418B51DFC081BCD21299EF5B5A0DDEF3A139A1817503DDE',
}
]
def test_generate_128(self):
self._test_random_key(128)
def test_generate_512(self):
self._test_random_key(512)
def test_encryption(self):
for tv in self.tve:
for as_longs in (0,1):
d = self.convert_tv(tv, as_longs)
key = ElGamal.construct(d['key'])
ct = key.encrypt(d['pt'], d['k'])
self.assertEqual(ct[0], d['ct1'])
self.assertEqual(ct[1], d['ct2'])
def test_decryption(self):
for tv in self.tve:
for as_longs in (0,1):
d = self.convert_tv(tv, as_longs)
key = ElGamal.construct(d['key'])
pt = key.decrypt((d['ct1'], d['ct2']))
self.assertEqual(pt, d['pt'])
def test_signing(self):
for tv in self.tvs:
for as_longs in (0,1):
d = self.convert_tv(tv, as_longs)
key = ElGamal.construct(d['key'])
sig1, sig2 = key.sign(d['h'], d['k'])
self.assertEqual(sig1, d['sig1'])
self.assertEqual(sig2, d['sig2'])
def test_verification(self):
for tv in self.tvs:
for as_longs in (0,1):
d = self.convert_tv(tv, as_longs)
key = ElGamal.construct(d['key'])
# Positive test
res = key.verify( d['h'], (d['sig1'],d['sig2']) )
self.assertTrue(res)
# Negative test
res = key.verify( d['h'], (d['sig1']+1,d['sig2']) )
self.assertFalse(res)
def convert_tv(self, tv, as_longs=0):
"""Convert a test vector from textual form (hexadecimal ascii
to either integers or byte strings."""
key_comps = 'p','g','y','x'
tv2 = {}
for c in list(tv.keys()):
tv2[c] = a2b_hex(tv[c])
if as_longs or c in key_comps or c in ('sig1','sig2'):
tv2[c] = bytes_to_long(tv2[c])
tv2['key']=[]
for c in key_comps:
tv2['key'] += [tv2[c]]
del tv2[c]
return tv2
def _test_random_key(self, bits):
elgObj = ElGamal.generate(bits, Random.new().read)
self._check_private_key(elgObj)
self._exercise_primitive(elgObj)
pub = elgObj.publickey()
self._check_public_key(pub)
self._exercise_public_primitive(elgObj)
def _check_private_key(self, elgObj):
# Check capabilities
self.assertTrue(elgObj.has_private())
self.assertTrue(elgObj.can_sign())
self.assertTrue(elgObj.can_encrypt())
# Sanity check key data
self.assertTrue(1<elgObj.g<(elgObj.p-1))
self.assertEqual(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
self.assertTrue(1<elgObj.x<(elgObj.p-1))
self.assertEqual(pow(elgObj.g, elgObj.x, elgObj.p), elgObj.y)
def _check_public_key(self, elgObj):
# Check capabilities
self.assertFalse(elgObj.has_private())
self.assertTrue(elgObj.can_sign())
self.assertTrue(elgObj.can_encrypt())
# Sanity check key data
self.assertTrue(1<elgObj.g<(elgObj.p-1))
self.assertEqual(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
def _exercise_primitive(self, elgObj):
# Test encryption/decryption
plaintext = b("Test")
ciphertext = elgObj.encrypt(plaintext, 123456789)
plaintextP = elgObj.decrypt(ciphertext)
self.assertEqual(plaintext, plaintextP)
# Test signature/verification
signature = elgObj.sign(plaintext, 987654321)
elgObj.verify(plaintext, signature)
def _exercise_public_primitive(self, elgObj):
plaintext = b("Test")
ciphertext = elgObj.encrypt(plaintext, 123456789)
def get_tests(config={}):
tests = []
tests += list_test_cases(ElGamalTest)
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')

View file

@ -0,0 +1,415 @@
# -*- coding: utf-8 -*-
#
# SelfTest/PublicKey/test_RSA.py: Self-test for the RSA primitive
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.PublicKey.RSA"""
__revision__ = "$Id$"
import sys
import os
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
from Crypto.Util.py3compat import *
import unittest
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
class RSATest(unittest.TestCase):
# Test vectors from "RSA-OAEP and RSA-PSS test vectors (.zip file)"
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
# See RSADSI's PKCS#1 page at
# http://www.rsa.com/rsalabs/node.asp?id=2125
# from oaep-int.txt
# TODO: PyCrypto treats the message as starting *after* the leading "00"
# TODO: That behaviour should probably be changed in the future.
plaintext = """
eb 7a 19 ac e9 e3 00 63 50 e3 29 50 4b 45 e2
ca 82 31 0b 26 dc d8 7d 5c 68 f1 ee a8 f5 52 67
c3 1b 2e 8b b4 25 1f 84 d7 e0 b2 c0 46 26 f5 af
f9 3e dc fb 25 c9 c2 b3 ff 8a e1 0e 83 9a 2d db
4c dc fe 4f f4 77 28 b4 a1 b7 c1 36 2b aa d2 9a
b4 8d 28 69 d5 02 41 21 43 58 11 59 1b e3 92 f9
82 fb 3e 87 d0 95 ae b4 04 48 db 97 2f 3a c1 4f
7b c2 75 19 52 81 ce 32 d2 f1 b7 6d 4d 35 3e 2d
"""
ciphertext = """
12 53 e0 4d c0 a5 39 7b b4 4a 7a b8 7e 9b f2 a0
39 a3 3d 1e 99 6f c8 2a 94 cc d3 00 74 c9 5d f7
63 72 20 17 06 9e 52 68 da 5d 1c 0b 4f 87 2c f6
53 c1 1d f8 23 14 a6 79 68 df ea e2 8d ef 04 bb
6d 84 b1 c3 1d 65 4a 19 70 e5 78 3b d6 eb 96 a0
24 c2 ca 2f 4a 90 fe 9f 2e f5 c9 c1 40 e5 bb 48
da 95 36 ad 87 00 c8 4f c9 13 0a de a7 4e 55 8d
51 a7 4d df 85 d8 b5 0d e9 68 38 d6 06 3e 09 55
"""
modulus = """
bb f8 2f 09 06 82 ce 9c 23 38 ac 2b 9d a8 71 f7
36 8d 07 ee d4 10 43 a4 40 d6 b6 f0 74 54 f5 1f
b8 df ba af 03 5c 02 ab 61 ea 48 ce eb 6f cd 48
76 ed 52 0d 60 e1 ec 46 19 71 9d 8a 5b 8b 80 7f
af b8 e0 a3 df c7 37 72 3e e6 b4 b7 d9 3a 25 84
ee 6a 64 9d 06 09 53 74 88 34 b2 45 45 98 39 4e
e0 aa b1 2d 7b 61 a5 1f 52 7a 9a 41 f6 c1 68 7f
e2 53 72 98 ca 2a 8f 59 46 f8 e5 fd 09 1d bd cb
"""
e = 0x11 # public exponent
prime_factor = """
c9 7f b1 f0 27 f4 53 f6 34 12 33 ea aa d1 d9 35
3f 6c 42 d0 88 66 b1 d0 5a 0f 20 35 02 8b 9d 86
98 40 b4 16 66 b4 2e 92 ea 0d a3 b4 32 04 b5 cf
ce 33 52 52 4d 04 16 a5 a4 41 e7 00 af 46 15 03
"""
def setUp(self):
global RSA, Random, bytes_to_long
from Crypto.PublicKey import RSA
from Crypto import Random
from Crypto.Util.number import bytes_to_long, inverse
self.n = bytes_to_long(a2b_hex(self.modulus))
self.p = bytes_to_long(a2b_hex(self.prime_factor))
# Compute q, d, and u from n, e, and p
self.q = divmod(self.n, self.p)[0]
self.d = inverse(self.e, (self.p-1)*(self.q-1))
self.u = inverse(self.p, self.q) # u = e**-1 (mod q)
self.rsa = RSA
def test_generate_1arg(self):
"""RSA (default implementation) generated key (1 argument)"""
rsaObj = self.rsa.generate(1024)
self._check_private_key(rsaObj)
self._exercise_primitive(rsaObj)
pub = rsaObj.publickey()
self._check_public_key(pub)
self._exercise_public_primitive(rsaObj)
def test_generate_2arg(self):
"""RSA (default implementation) generated key (2 arguments)"""
rsaObj = self.rsa.generate(1024, Random.new().read)
self._check_private_key(rsaObj)
self._exercise_primitive(rsaObj)
pub = rsaObj.publickey()
self._check_public_key(pub)
self._exercise_public_primitive(rsaObj)
def test_generate_3args(self):
rsaObj = self.rsa.generate(1024, Random.new().read,e=65537)
self._check_private_key(rsaObj)
self._exercise_primitive(rsaObj)
pub = rsaObj.publickey()
self._check_public_key(pub)
self._exercise_public_primitive(rsaObj)
self.assertEqual(65537,rsaObj.e)
def test_construct_2tuple(self):
"""RSA (default implementation) constructed key (2-tuple)"""
pub = self.rsa.construct((self.n, self.e))
self._check_public_key(pub)
self._check_encryption(pub)
self._check_verification(pub)
def test_construct_3tuple(self):
"""RSA (default implementation) constructed key (3-tuple)"""
rsaObj = self.rsa.construct((self.n, self.e, self.d))
self._check_encryption(rsaObj)
self._check_decryption(rsaObj)
self._check_signing(rsaObj)
self._check_verification(rsaObj)
def test_construct_4tuple(self):
"""RSA (default implementation) constructed key (4-tuple)"""
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p))
self._check_encryption(rsaObj)
self._check_decryption(rsaObj)
self._check_signing(rsaObj)
self._check_verification(rsaObj)
def test_construct_5tuple(self):
"""RSA (default implementation) constructed key (5-tuple)"""
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q))
self._check_private_key(rsaObj)
self._check_encryption(rsaObj)
self._check_decryption(rsaObj)
self._check_signing(rsaObj)
self._check_verification(rsaObj)
def test_construct_6tuple(self):
"""RSA (default implementation) constructed key (6-tuple)"""
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q, self.u))
self._check_private_key(rsaObj)
self._check_encryption(rsaObj)
self._check_decryption(rsaObj)
self._check_signing(rsaObj)
self._check_verification(rsaObj)
def test_factoring(self):
rsaObj = self.rsa.construct([self.n, self.e, self.d])
self.assertTrue(rsaObj.p==self.p or rsaObj.p==self.q)
self.assertTrue(rsaObj.q==self.p or rsaObj.q==self.q)
self.assertTrue(rsaObj.q*rsaObj.p == self.n)
self.assertRaises(ValueError, self.rsa.construct, [self.n, self.e, self.n-1])
def _check_private_key(self, rsaObj):
# Check capabilities
self.assertEqual(1, rsaObj.has_private())
self.assertEqual(1, rsaObj.can_sign())
self.assertEqual(1, rsaObj.can_encrypt())
self.assertEqual(1, rsaObj.can_blind())
# Check rsaObj.[nedpqu] -> rsaObj.key.[nedpqu] mapping
self.assertEqual(rsaObj.n, rsaObj.key.n)
self.assertEqual(rsaObj.e, rsaObj.key.e)
self.assertEqual(rsaObj.d, rsaObj.key.d)
self.assertEqual(rsaObj.p, rsaObj.key.p)
self.assertEqual(rsaObj.q, rsaObj.key.q)
self.assertEqual(rsaObj.u, rsaObj.key.u)
# Sanity check key data
self.assertEqual(rsaObj.n, rsaObj.p * rsaObj.q) # n = pq
self.assertEqual(1, rsaObj.d * rsaObj.e % ((rsaObj.p-1) * (rsaObj.q-1))) # ed = 1 (mod (p-1)(q-1))
self.assertEqual(1, rsaObj.p * rsaObj.u % rsaObj.q) # pu = 1 (mod q)
self.assertEqual(1, rsaObj.p > 1) # p > 1
self.assertEqual(1, rsaObj.q > 1) # q > 1
self.assertEqual(1, rsaObj.e > 1) # e > 1
self.assertEqual(1, rsaObj.d > 1) # d > 1
def _check_public_key(self, rsaObj):
ciphertext = a2b_hex(self.ciphertext)
# Check capabilities
self.assertEqual(0, rsaObj.has_private())
self.assertEqual(1, rsaObj.can_sign())
self.assertEqual(1, rsaObj.can_encrypt())
self.assertEqual(1, rsaObj.can_blind())
# Check rsaObj.[ne] -> rsaObj.key.[ne] mapping
self.assertEqual(rsaObj.n, rsaObj.key.n)
self.assertEqual(rsaObj.e, rsaObj.key.e)
# Check that private parameters are all missing
self.assertEqual(0, hasattr(rsaObj, 'd'))
self.assertEqual(0, hasattr(rsaObj, 'p'))
self.assertEqual(0, hasattr(rsaObj, 'q'))
self.assertEqual(0, hasattr(rsaObj, 'u'))
self.assertEqual(0, hasattr(rsaObj.key, 'd'))
self.assertEqual(0, hasattr(rsaObj.key, 'p'))
self.assertEqual(0, hasattr(rsaObj.key, 'q'))
self.assertEqual(0, hasattr(rsaObj.key, 'u'))
# Sanity check key data
self.assertEqual(1, rsaObj.e > 1) # e > 1
# Public keys should not be able to sign or decrypt
self.assertRaises(TypeError, rsaObj.sign, ciphertext, b(""))
self.assertRaises(TypeError, rsaObj.decrypt, ciphertext)
# Check __eq__ and __ne__
self.assertEqual(rsaObj.publickey() == rsaObj.publickey(),True) # assert_
self.assertEqual(rsaObj.publickey() != rsaObj.publickey(),False) # failIf
def _exercise_primitive(self, rsaObj):
# Since we're using a randomly-generated key, we can't check the test
# vector, but we can make sure encryption and decryption are inverse
# operations.
ciphertext = a2b_hex(self.ciphertext)
# Test decryption
plaintext = rsaObj.decrypt((ciphertext,))
# Test encryption (2 arguments)
(new_ciphertext2,) = rsaObj.encrypt(plaintext, b(""))
self.assertEqual(b2a_hex(ciphertext), b2a_hex(new_ciphertext2))
# Test blinded decryption
blinding_factor = Random.new().read(len(ciphertext)-1)
blinded_ctext = rsaObj.blind(ciphertext, blinding_factor)
blinded_ptext = rsaObj.decrypt((blinded_ctext,))
unblinded_plaintext = rsaObj.unblind(blinded_ptext, blinding_factor)
self.assertEqual(b2a_hex(plaintext), b2a_hex(unblinded_plaintext))
# Test signing (2 arguments)
signature2 = rsaObj.sign(ciphertext, b(""))
self.assertEqual((bytes_to_long(plaintext),), signature2)
# Test verification
self.assertEqual(1, rsaObj.verify(ciphertext, (bytes_to_long(plaintext),)))
def _exercise_public_primitive(self, rsaObj):
plaintext = a2b_hex(self.plaintext)
# Test encryption (2 arguments)
(new_ciphertext2,) = rsaObj.encrypt(plaintext, b(""))
# Exercise verification
rsaObj.verify(new_ciphertext2, (bytes_to_long(plaintext),))
def _check_encryption(self, rsaObj):
plaintext = a2b_hex(self.plaintext)
ciphertext = a2b_hex(self.ciphertext)
# Test encryption (2 arguments)
(new_ciphertext2,) = rsaObj.encrypt(plaintext, b(""))
self.assertEqual(b2a_hex(ciphertext), b2a_hex(new_ciphertext2))
def _check_decryption(self, rsaObj):
plaintext = a2b_hex(self.plaintext)
ciphertext = a2b_hex(self.ciphertext)
# Test plain decryption
new_plaintext = rsaObj.decrypt((ciphertext,))
self.assertEqual(b2a_hex(plaintext), b2a_hex(new_plaintext))
# Test blinded decryption
blinding_factor = Random.new().read(len(ciphertext)-1)
blinded_ctext = rsaObj.blind(ciphertext, blinding_factor)
blinded_ptext = rsaObj.decrypt((blinded_ctext,))
unblinded_plaintext = rsaObj.unblind(blinded_ptext, blinding_factor)
self.assertEqual(b2a_hex(plaintext), b2a_hex(unblinded_plaintext))
def _check_verification(self, rsaObj):
signature = bytes_to_long(a2b_hex(self.plaintext))
message = a2b_hex(self.ciphertext)
# Test verification
t = (signature,) # rsaObj.verify expects a tuple
self.assertEqual(1, rsaObj.verify(message, t))
# Test verification with overlong tuple (this is a
# backward-compatibility hack to support some harmless misuse of the
# API)
t2 = (signature, '')
self.assertEqual(1, rsaObj.verify(message, t2)) # extra garbage at end of tuple
def _check_signing(self, rsaObj):
signature = bytes_to_long(a2b_hex(self.plaintext))
message = a2b_hex(self.ciphertext)
# Test signing (2 argument)
self.assertEqual((signature,), rsaObj.sign(message, b("")))
class RSAFastMathTest(RSATest):
def setUp(self):
RSATest.setUp(self)
self.rsa = RSA.RSAImplementation(use_fast_math=True)
def test_generate_1arg(self):
"""RSA (_fastmath implementation) generated key (1 argument)"""
RSATest.test_generate_1arg(self)
def test_generate_2arg(self):
"""RSA (_fastmath implementation) generated key (2 arguments)"""
RSATest.test_generate_2arg(self)
def test_construct_2tuple(self):
"""RSA (_fastmath implementation) constructed key (2-tuple)"""
RSATest.test_construct_2tuple(self)
def test_construct_3tuple(self):
"""RSA (_fastmath implementation) constructed key (3-tuple)"""
RSATest.test_construct_3tuple(self)
def test_construct_4tuple(self):
"""RSA (_fastmath implementation) constructed key (4-tuple)"""
RSATest.test_construct_4tuple(self)
def test_construct_5tuple(self):
"""RSA (_fastmath implementation) constructed key (5-tuple)"""
RSATest.test_construct_5tuple(self)
def test_construct_6tuple(self):
"""RSA (_fastmath implementation) constructed key (6-tuple)"""
RSATest.test_construct_6tuple(self)
def test_factoring(self):
RSATest.test_factoring(self)
class RSASlowMathTest(RSATest):
def setUp(self):
RSATest.setUp(self)
self.rsa = RSA.RSAImplementation(use_fast_math=False)
def test_generate_1arg(self):
"""RSA (_slowmath implementation) generated key (1 argument)"""
RSATest.test_generate_1arg(self)
def test_generate_2arg(self):
"""RSA (_slowmath implementation) generated key (2 arguments)"""
RSATest.test_generate_2arg(self)
def test_construct_2tuple(self):
"""RSA (_slowmath implementation) constructed key (2-tuple)"""
RSATest.test_construct_2tuple(self)
def test_construct_3tuple(self):
"""RSA (_slowmath implementation) constructed key (3-tuple)"""
RSATest.test_construct_3tuple(self)
def test_construct_4tuple(self):
"""RSA (_slowmath implementation) constructed key (4-tuple)"""
RSATest.test_construct_4tuple(self)
def test_construct_5tuple(self):
"""RSA (_slowmath implementation) constructed key (5-tuple)"""
RSATest.test_construct_5tuple(self)
def test_construct_6tuple(self):
"""RSA (_slowmath implementation) constructed key (6-tuple)"""
RSATest.test_construct_6tuple(self)
def test_factoring(self):
RSATest.test_factoring(self)
def get_tests(config={}):
tests = []
tests += list_test_cases(RSATest)
try:
from Crypto.PublicKey import _fastmath
tests += list_test_cases(RSAFastMathTest)
except ImportError:
from distutils.sysconfig import get_config_var
import inspect
_fm_path = os.path.normpath(os.path.dirname(os.path.abspath(
inspect.getfile(inspect.currentframe())))
+"/../../PublicKey/_fastmath"+get_config_var("SO"))
if os.path.exists(_fm_path):
raise ImportError("While the _fastmath module exists, importing "+
"it failed. This may point to the gmp or mpir shared library "+
"not being in the path. _fastmath was found at "+_fm_path)
if config.get('slow_tests',1):
tests += list_test_cases(RSASlowMathTest)
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,345 @@
# -*- coding: utf-8 -*-
#
# SelfTest/PublicKey/test_importKey.py: Self-test for importing RSA keys
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
__revision__ = "$Id$"
import unittest
from Crypto.PublicKey import RSA
from Crypto.SelfTest.st_common import *
from Crypto.Util.py3compat import *
from Crypto.Util.number import inverse
from Crypto.Util import asn1
def der2pem(der, text='PUBLIC'):
import binascii
chunks = [ binascii.b2a_base64(der[i:i+48]) for i in range(0, len(der), 48) ]
pem = b('-----BEGIN %s KEY-----\n' % text)
pem += b('').join(chunks)
pem += b('-----END %s KEY-----' % text)
return pem
class ImportKeyTests(unittest.TestCase):
# 512-bit RSA key generated with openssl
rsaKeyPEM = '''-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+TLr7UkvEtFrRhDDKMtuII
q19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQJACUSDEp8RTe32ftq8IwG8
Wojl5mAd1wFiIOrZ/Uv8b963WJOJiuQcVN29vxU5+My9GPZ7RA3hrDBEAoHUDPrI
OQIhAPIPLz4dphiD9imAkivY31Rc5AfHJiQRA7XixTcjEkojAiEAyh/pJHks/Mlr
+rdPNEpotBjfV4M4BkgGAA/ipcmaAjcCIQCHvhwwKVBLzzTscT2HeUdEeBMoiXXK
JACAr3sJQJGxIQIgarRp+m1WSKV1MciwMaTOnbU7wxFs9DP1pva76lYBzgUCIQC9
n0CnZCJ6IZYqSt0H5N7+Q+2Ro64nuwV/OSQfM6sBwQ==
-----END RSA PRIVATE KEY-----'''
# As above, but this is actually an unencrypted PKCS#8 key
rsaKeyPEM8 = '''-----BEGIN PRIVATE KEY-----
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvx4nkAqgiyNRGlwS
ga5tkzEsPv6RP5MuvtSS8S0WtGEMMoy24girX0WsvilQgzKY8xIsGfeEkt7fQPDj
wZAzhQIDAQABAkAJRIMSnxFN7fZ+2rwjAbxaiOXmYB3XAWIg6tn9S/xv3rdYk4mK
5BxU3b2/FTn4zL0Y9ntEDeGsMEQCgdQM+sg5AiEA8g8vPh2mGIP2KYCSK9jfVFzk
B8cmJBEDteLFNyMSSiMCIQDKH+kkeSz8yWv6t080Smi0GN9XgzgGSAYAD+KlyZoC
NwIhAIe+HDApUEvPNOxxPYd5R0R4EyiJdcokAICvewlAkbEhAiBqtGn6bVZIpXUx
yLAxpM6dtTvDEWz0M/Wm9rvqVgHOBQIhAL2fQKdkInohlipK3Qfk3v5D7ZGjrie7
BX85JB8zqwHB
-----END PRIVATE KEY-----'''
# The same RSA private key as in rsaKeyPEM, but now encrypted
rsaKeyEncryptedPEM=(
# With DES and passphrase 'test'
('test', '''-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-CBC,AF8F9A40BD2FA2FC
Ckl9ex1kaVEWhYC2QBmfaF+YPiR4NFkRXA7nj3dcnuFEzBnY5XULupqQpQI3qbfA
u8GYS7+b3toWWiHZivHbAAUBPDIZG9hKDyB9Sq2VMARGsX1yW1zhNvZLIiVJzUHs
C6NxQ1IJWOXzTew/xM2I26kPwHIvadq+/VaT8gLQdjdH0jOiVNaevjWnLgrn1mLP
BCNRMdcexozWtAFNNqSzfW58MJL2OdMi21ED184EFytIc1BlB+FZiGZduwKGuaKy
9bMbdb/1PSvsSzPsqW7KSSrTw6MgJAFJg6lzIYvR5F4poTVBxwBX3+EyEmShiaNY
IRX3TgQI0IjrVuLmvlZKbGWP18FXj7I7k9tSsNOOzllTTdq3ny5vgM3A+ynfAaxp
dysKznQ6P+IoqML1WxAID4aGRMWka+uArOJ148Rbj9s=
-----END RSA PRIVATE KEY-----''',
"\xAF\x8F\x9A\x40\xBD\x2F\xA2\xFC"),
# With Triple-DES and passphrase 'rocking'
('rocking', '''-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,C05D6C07F7FC02F6
w4lwQrXaVoTTJ0GgwY566htTA2/t1YlimhxkxYt9AEeCcidS5M0Wq9ClPiPz9O7F
m6K5QpM1rxo1RUE/ZyI85gglRNPdNwkeTOqit+kum7nN73AToX17+irVmOA4Z9E+
4O07t91GxGMcjUSIFk0ucwEU4jgxRvYscbvOMvNbuZszGdVNzBTVddnShKCsy9i7
nJbPlXeEKYi/OkRgO4PtfqqWQu5GIEFVUf9ev1QV7AvC+kyWTR1wWYnHX265jU5c
sopxQQtP8XEHIJEdd5/p1oieRcWTCNyY8EkslxDSsrf0OtZp6mZH9N+KU47cgQtt
9qGORmlWnsIoFFKcDohbtOaWBTKhkj5h6OkLjFjfU/sBeV1c+7wDT3dAy5tawXjG
YSxC7qDQIT/RECvV3+oQKEcmpEujn45wAnkTi12BH30=
-----END RSA PRIVATE KEY-----''',
"\xC0\x5D\x6C\x07\xF7\xFC\x02\xF6"),
)
rsaPublicKeyPEM = '''-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+T
Lr7UkvEtFrRhDDKMtuIIq19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQ==
-----END PUBLIC KEY-----'''
# Obtained using 'ssh-keygen -i -m PKCS8 -f rsaPublicKeyPEM'
rsaPublicKeyOpenSSH = '''ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQC/HieQCqCLI1EaXBKBrm2TMSw+/pE/ky6+1JLxLRa0YQwyjLbiCKtfRay+KVCDMpjzEiwZ94SS3t9A8OPBkDOF comment\n'''
# The private key, in PKCS#1 format encoded with DER
rsaKeyDER = a2b_hex(
'''3082013b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe
913f932ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f312
2c19f78492dedf40f0e3c190338502030100010240094483129f114dedf6
7edabc2301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c
54ddbdbf1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f
2f3e1da61883f62980922bd8df545ce407c726241103b5e2c53723124a23
022100ca1fe924792cfcc96bfab74f344a68b418df578338064806000fe2
a5c99a023702210087be1c3029504bcf34ec713d877947447813288975ca
240080af7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53b
c3116cf433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07
e4defe43ed91a3ae27bb057f39241f33ab01c1
'''.replace(" ",""))
# The private key, in unencrypted PKCS#8 format encoded with DER
rsaKeyDER8 = a2b_hex(
'''30820155020100300d06092a864886f70d01010105000482013f3082013
b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe913f932
ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f3122c19f78
492dedf40f0e3c190338502030100010240094483129f114dedf67edabc2
301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c54ddbdb
f1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f2f3e1da
61883f62980922bd8df545ce407c726241103b5e2c53723124a23022100c
a1fe924792cfcc96bfab74f344a68b418df578338064806000fe2a5c99a0
23702210087be1c3029504bcf34ec713d877947447813288975ca240080a
f7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53bc3116cf
433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07e4defe4
3ed91a3ae27bb057f39241f33ab01c1
'''.replace(" ",""))
rsaPublicKeyDER = a2b_hex(
'''305c300d06092a864886f70d0101010500034b003048024100bf1e27900a
a08b23511a5c1281ae6d93312c3efe913f932ebed492f12d16b4610c328c
b6e208ab5f45acbe2950833298f3122c19f78492dedf40f0e3c190338502
03010001
'''.replace(" ",""))
n = int('BF 1E 27 90 0A A0 8B 23 51 1A 5C 12 81 AE 6D 93 31 2C 3E FE 91 3F 93 2E BE D4 92 F1 2D 16 B4 61 0C 32 8C B6 E2 08 AB 5F 45 AC BE 29 50 83 32 98 F3 12 2C 19 F7 84 92 DE DF 40 F0 E3 C1 90 33 85'.replace(" ",""),16)
e = 65537
d = int('09 44 83 12 9F 11 4D ED F6 7E DA BC 23 01 BC 5A 88 E5 E6 60 1D D7 01 62 20 EA D9 FD 4B FC 6F DE B7 58 93 89 8A E4 1C 54 DD BD BF 15 39 F8 CC BD 18 F6 7B 44 0D E1 AC 30 44 02 81 D4 0C FA C8 39'.replace(" ",""),16)
p = int('00 F2 0F 2F 3E 1D A6 18 83 F6 29 80 92 2B D8 DF 54 5C E4 07 C7 26 24 11 03 B5 E2 C5 37 23 12 4A 23'.replace(" ",""),16)
q = int('00 CA 1F E9 24 79 2C FC C9 6B FA B7 4F 34 4A 68 B4 18 DF 57 83 38 06 48 06 00 0F E2 A5 C9 9A 02 37'.replace(" ",""),16)
# This is q^{-1} mod p). fastmath and slowmath use pInv (p^{-1}
# mod q) instead!
qInv = int('00 BD 9F 40 A7 64 22 7A 21 96 2A 4A DD 07 E4 DE FE 43 ED 91 A3 AE 27 BB 05 7F 39 24 1F 33 AB 01 C1'.replace(" ",""),16)
pInv = inverse(p,q)
def testImportKey1(self):
"""Verify import of RSAPrivateKey DER SEQUENCE"""
key = self.rsa.importKey(self.rsaKeyDER)
self.assertTrue(key.has_private())
self.assertEqual(key.n, self.n)
self.assertEqual(key.e, self.e)
self.assertEqual(key.d, self.d)
self.assertEqual(key.p, self.p)
self.assertEqual(key.q, self.q)
def testImportKey2(self):
"""Verify import of SubjectPublicKeyInfo DER SEQUENCE"""
key = self.rsa.importKey(self.rsaPublicKeyDER)
self.assertFalse(key.has_private())
self.assertEqual(key.n, self.n)
self.assertEqual(key.e, self.e)
def testImportKey3unicode(self):
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode"""
key = RSA.importKey(self.rsaKeyPEM)
self.assertEqual(key.has_private(),True) # assert_
self.assertEqual(key.n, self.n)
self.assertEqual(key.e, self.e)
self.assertEqual(key.d, self.d)
self.assertEqual(key.p, self.p)
self.assertEqual(key.q, self.q)
def testImportKey3bytes(self):
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as byte string"""
key = RSA.importKey(b(self.rsaKeyPEM))
self.assertEqual(key.has_private(),True) # assert_
self.assertEqual(key.n, self.n)
self.assertEqual(key.e, self.e)
self.assertEqual(key.d, self.d)
self.assertEqual(key.p, self.p)
self.assertEqual(key.q, self.q)
def testImportKey4unicode(self):
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode"""
key = RSA.importKey(self.rsaPublicKeyPEM)
self.assertEqual(key.has_private(),False) # failIf
self.assertEqual(key.n, self.n)
self.assertEqual(key.e, self.e)
def testImportKey4bytes(self):
"""Verify import of SubjectPublicKeyInfo DER SEQUENCE, encoded with PEM as byte string"""
key = RSA.importKey(b(self.rsaPublicKeyPEM))
self.assertEqual(key.has_private(),False) # failIf
self.assertEqual(key.n, self.n)
self.assertEqual(key.e, self.e)
def testImportKey5(self):
"""Verifies that the imported key is still a valid RSA pair"""
key = RSA.importKey(self.rsaKeyPEM)
idem = key.encrypt(key.decrypt(b("Test")),0)
self.assertEqual(idem[0],b("Test"))
def testImportKey6(self):
"""Verifies that the imported key is still a valid RSA pair"""
key = RSA.importKey(self.rsaKeyDER)
idem = key.encrypt(key.decrypt(b("Test")),0)
self.assertEqual(idem[0],b("Test"))
def testImportKey7(self):
"""Verify import of OpenSSH public key"""
key = self.rsa.importKey(self.rsaPublicKeyOpenSSH)
self.assertEqual(key.n, self.n)
self.assertEqual(key.e, self.e)
def testImportKey8(self):
"""Verify import of encrypted PrivateKeyInfo DER SEQUENCE"""
for t in self.rsaKeyEncryptedPEM:
key = self.rsa.importKey(t[1], t[0])
self.assertTrue(key.has_private())
self.assertEqual(key.n, self.n)
self.assertEqual(key.e, self.e)
self.assertEqual(key.d, self.d)
self.assertEqual(key.p, self.p)
self.assertEqual(key.q, self.q)
def testImportKey9(self):
"""Verify import of unencrypted PrivateKeyInfo DER SEQUENCE"""
key = self.rsa.importKey(self.rsaKeyDER8)
self.assertTrue(key.has_private())
self.assertEqual(key.n, self.n)
self.assertEqual(key.e, self.e)
self.assertEqual(key.d, self.d)
self.assertEqual(key.p, self.p)
self.assertEqual(key.q, self.q)
def testImportKey10(self):
"""Verify import of unencrypted PrivateKeyInfo DER SEQUENCE, encoded with PEM"""
key = self.rsa.importKey(self.rsaKeyPEM8)
self.assertTrue(key.has_private())
self.assertEqual(key.n, self.n)
self.assertEqual(key.e, self.e)
self.assertEqual(key.d, self.d)
self.assertEqual(key.p, self.p)
self.assertEqual(key.q, self.q)
def testImportKey11(self):
"""Verify import of RSAPublicKey DER SEQUENCE"""
der = asn1.DerSequence([17, 3]).encode()
key = self.rsa.importKey(der)
self.assertEqual(key.n, 17)
self.assertEqual(key.e, 3)
def testImportKey12(self):
"""Verify import of RSAPublicKey DER SEQUENCE, encoded with PEM"""
der = asn1.DerSequence([17, 3]).encode()
pem = der2pem(der)
key = self.rsa.importKey(pem)
self.assertEqual(key.n, 17)
self.assertEqual(key.e, 3)
###
def testExportKey1(self):
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
derKey = key.exportKey("DER")
self.assertEqual(derKey, self.rsaKeyDER)
def testExportKey2(self):
key = self.rsa.construct([self.n, self.e])
derKey = key.exportKey("DER")
self.assertEqual(derKey, self.rsaPublicKeyDER)
def testExportKey3(self):
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
pemKey = key.exportKey("PEM")
self.assertEqual(pemKey, b(self.rsaKeyPEM))
def testExportKey4(self):
key = self.rsa.construct([self.n, self.e])
pemKey = key.exportKey("PEM")
self.assertEqual(pemKey, b(self.rsaPublicKeyPEM))
def testExportKey5(self):
key = self.rsa.construct([self.n, self.e])
openssh_1 = key.exportKey("OpenSSH").split()
openssh_2 = self.rsaPublicKeyOpenSSH.split()
self.assertEqual(openssh_1[0], openssh_2[0])
self.assertEqual(openssh_1[1], openssh_2[1])
def testExportKey4(self):
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
# Tuple with index #1 is encrypted with 3DES
t = list(map(b,self.rsaKeyEncryptedPEM[1]))
# Force the salt being used when exporting
key._randfunc = lambda N: (t[2]*divmod(N+len(t[2]),len(t[2]))[0])[:N]
pemKey = key.exportKey("PEM", t[0])
self.assertEqual(pemKey, t[1])
def testExportKey5(self):
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
derKey = key.exportKey("DER", pkcs=8)
self.assertEqual(derKey, self.rsaKeyDER8)
def testExportKey6(self):
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
pemKey = key.exportKey("PEM", pkcs=8)
self.assertEqual(pemKey, b(self.rsaKeyPEM8))
class ImportKeyTestsSlow(ImportKeyTests):
def setUp(self):
self.rsa = RSA.RSAImplementation(use_fast_math=0)
class ImportKeyTestsFast(ImportKeyTests):
def setUp(self):
self.rsa = RSA.RSAImplementation(use_fast_math=1)
if __name__ == '__main__':
unittest.main()
def get_tests(config={}):
tests = []
try:
from Crypto.PublicKey import _fastmath
tests += list_test_cases(ImportKeyTestsFast)
except ImportError:
pass
tests += list_test_cases(ImportKeyTestsSlow)
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Random/Fortuna/__init__.py: Self-test for Fortuna modules
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test for the Crypto.Random.Fortuna package"""
__revision__ = "$Id$"
import os
def get_tests(config={}):
tests = []
from Crypto.SelfTest.Random.Fortuna import test_FortunaAccumulator; tests += test_FortunaAccumulator.get_tests(config=config)
from Crypto.SelfTest.Random.Fortuna import test_FortunaGenerator; tests += test_FortunaGenerator.get_tests(config=config)
from Crypto.SelfTest.Random.Fortuna import test_SHAd256; tests += test_SHAd256.get_tests(config=config)
return tests
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,189 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Random/Fortuna/test_FortunaAccumulator.py: Self-test for the FortunaAccumulator module
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-tests for Crypto.Random.Fortuna.FortunaAccumulator"""
__revision__ = "$Id$"
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
from Crypto.Util.py3compat import *
import unittest
from binascii import b2a_hex
class FortunaAccumulatorTests(unittest.TestCase):
def setUp(self):
global FortunaAccumulator
from Crypto.Random.Fortuna import FortunaAccumulator
def test_FortunaPool(self):
"""FortunaAccumulator.FortunaPool"""
pool = FortunaAccumulator.FortunaPool()
self.assertEqual(0, pool.length)
self.assertEqual("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456", pool.hexdigest())
pool.append(b('abc'))
self.assertEqual(3, pool.length)
self.assertEqual("4f8b42c22dd3729b519ba6f68d2da7cc5b2d606d05daed5ad5128cc03e6c6358", pool.hexdigest())
pool.append(b("dbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"))
self.assertEqual(56, pool.length)
self.assertEqual(b('0cffe17f68954dac3a84fb1458bd5ec99209449749b2b308b7cb55812f9563af'), b2a_hex(pool.digest()))
pool.reset()
self.assertEqual(0, pool.length)
pool.append(b('a') * 10**6)
self.assertEqual(10**6, pool.length)
self.assertEqual(b('80d1189477563e1b5206b2749f1afe4807e5705e8bd77887a60187a712156688'), b2a_hex(pool.digest()))
def test_which_pools(self):
"""FortunaAccumulator.which_pools"""
# which_pools(0) should fail
self.assertRaises(AssertionError, FortunaAccumulator.which_pools, 0)
self.assertEqual(FortunaAccumulator.which_pools(1), [0])
self.assertEqual(FortunaAccumulator.which_pools(2), [0, 1])
self.assertEqual(FortunaAccumulator.which_pools(3), [0])
self.assertEqual(FortunaAccumulator.which_pools(4), [0, 1, 2])
self.assertEqual(FortunaAccumulator.which_pools(5), [0])
self.assertEqual(FortunaAccumulator.which_pools(6), [0, 1])
self.assertEqual(FortunaAccumulator.which_pools(7), [0])
self.assertEqual(FortunaAccumulator.which_pools(8), [0, 1, 2, 3])
for i in range(1, 32):
self.assertEqual(FortunaAccumulator.which_pools(2**i-1), [0])
self.assertEqual(FortunaAccumulator.which_pools(2**i), list(range(i+1)))
self.assertEqual(FortunaAccumulator.which_pools(2**i+1), [0])
self.assertEqual(FortunaAccumulator.which_pools(2**31), list(range(32)))
self.assertEqual(FortunaAccumulator.which_pools(2**32), list(range(32)))
self.assertEqual(FortunaAccumulator.which_pools(2**33), list(range(32)))
self.assertEqual(FortunaAccumulator.which_pools(2**34), list(range(32)))
self.assertEqual(FortunaAccumulator.which_pools(2**35), list(range(32)))
self.assertEqual(FortunaAccumulator.which_pools(2**36), list(range(32)))
self.assertEqual(FortunaAccumulator.which_pools(2**64), list(range(32)))
self.assertEqual(FortunaAccumulator.which_pools(2**128), list(range(32)))
def test_accumulator(self):
"""FortunaAccumulator.FortunaAccumulator"""
fa = FortunaAccumulator.FortunaAccumulator()
# This should fail, because we haven't seeded the PRNG yet
self.assertRaises(AssertionError, fa.random_data, 1)
# Spread some test data across the pools (source number 42)
# This would be horribly insecure in a real system.
for p in range(32):
fa.add_random_event(42, p, b("X") * 32)
self.assertEqual(32+2, fa.pools[p].length)
# This should still fail, because we haven't seeded the PRNG with 64 bytes yet
self.assertRaises(AssertionError, fa.random_data, 1)
# Add more data
for p in range(32):
fa.add_random_event(42, p, b("X") * 32)
self.assertEqual((32+2)*2, fa.pools[p].length)
# The underlying RandomGenerator should get seeded with Pool 0
# s = SHAd256(chr(42) + chr(32) + "X"*32 + chr(42) + chr(32) + "X"*32)
# = SHA256(h'edd546f057b389155a31c32e3975e736c1dec030ddebb137014ecbfb32ed8c6f')
# = h'aef42a5dcbddab67e8efa118e1b47fde5d697f89beb971b99e6e8e5e89fbf064'
# The counter and the key before reseeding is:
# C_0 = 0
# K_0 = "\x00" * 32
# The counter after reseeding is 1, and the new key after reseeding is
# C_1 = 1
# K_1 = SHAd256(K_0 || s)
# = SHA256(h'0eae3e401389fab86640327ac919ecfcb067359d95469e18995ca889abc119a6')
# = h'aafe9d0409fbaaafeb0a1f2ef2014a20953349d3c1c6e6e3b962953bea6184dd'
# The first block of random data, therefore, is
# r_1 = AES-256(K_1, 1)
# = AES-256(K_1, h'01000000000000000000000000000000')
# = h'b7b86bd9a27d96d7bb4add1b6b10d157'
# The second block of random data is
# r_2 = AES-256(K_1, 2)
# = AES-256(K_1, h'02000000000000000000000000000000')
# = h'2350b1c61253db2f8da233be726dc15f'
# The third and fourth blocks of random data (which become the new key) are
# r_3 = AES-256(K_1, 3)
# = AES-256(K_1, h'03000000000000000000000000000000')
# = h'f23ad749f33066ff53d307914fbf5b21'
# r_4 = AES-256(K_1, 4)
# = AES-256(K_1, h'04000000000000000000000000000000')
# = h'da9667c7e86ba247655c9490e9d94a7c'
# K_2 = r_3 || r_4
# = h'f23ad749f33066ff53d307914fbf5b21da9667c7e86ba247655c9490e9d94a7c'
# The final counter value is 5.
self.assertEqual("aef42a5dcbddab67e8efa118e1b47fde5d697f89beb971b99e6e8e5e89fbf064",
fa.pools[0].hexdigest())
self.assertEqual(None, fa.generator.key)
self.assertEqual(0, fa.generator.counter.next_value())
result = fa.random_data(32)
self.assertEqual(b("b7b86bd9a27d96d7bb4add1b6b10d157" "2350b1c61253db2f8da233be726dc15f"), b2a_hex(result))
self.assertEqual(b("f23ad749f33066ff53d307914fbf5b21da9667c7e86ba247655c9490e9d94a7c"), b2a_hex(fa.generator.key))
self.assertEqual(5, fa.generator.counter.next_value())
def test_accumulator_pool_length(self):
"""FortunaAccumulator.FortunaAccumulator minimum pool length"""
fa = FortunaAccumulator.FortunaAccumulator()
# This test case is hard-coded to assume that FortunaAccumulator.min_pool_size is 64.
self.assertEqual(fa.min_pool_size, 64)
# The PRNG should not allow us to get random data from it yet
self.assertRaises(AssertionError, fa.random_data, 1)
# Add 60 bytes, 4 at a time (2 header + 2 payload) to each of the 32 pools
for i in range(15):
for p in range(32):
# Add the bytes to the pool
fa.add_random_event(2, p, b("XX"))
# The PRNG should not allow us to get random data from it yet
self.assertRaises(AssertionError, fa.random_data, 1)
# Add 4 more bytes to pool 0
fa.add_random_event(2, 0, b("XX"))
# We should now be able to get data from the accumulator
fa.random_data(1)
def get_tests(config={}):
from Crypto.SelfTest.st_common import list_test_cases
return list_test_cases(FortunaAccumulatorTests)
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Random/Fortuna/test_FortunaGenerator.py: Self-test for the FortunaGenerator module
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-tests for Crypto.Random.Fortuna.FortunaGenerator"""
__revision__ = "$Id$"
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
from Crypto.Util.py3compat import *
import unittest
from binascii import b2a_hex
class FortunaGeneratorTests(unittest.TestCase):
def setUp(self):
global FortunaGenerator
from Crypto.Random.Fortuna import FortunaGenerator
def test_generator(self):
"""FortunaGenerator.AESGenerator"""
fg = FortunaGenerator.AESGenerator()
# We shouldn't be able to read data until we've seeded the generator
self.assertRaises(Exception, fg.pseudo_random_data, 1)
self.assertEqual(0, fg.counter.next_value())
# Seed the generator, which should set the key and increment the counter.
fg.reseed(b("Hello"))
self.assertEqual(b("0ea6919d4361551364242a4ba890f8f073676e82cf1a52bb880f7e496648b565"), b2a_hex(fg.key))
self.assertEqual(1, fg.counter.next_value())
# Read 2 full blocks from the generator
self.assertEqual(b("7cbe2c17684ac223d08969ee8b565616") + # counter=1
b("717661c0d2f4758bd6ba140bf3791abd"), # counter=2
b2a_hex(fg.pseudo_random_data(32)))
# Meanwhile, the generator will have re-keyed itself and incremented its counter
self.assertEqual(b("33a1bb21987859caf2bbfc5615bef56d") + # counter=3
b("e6b71ff9f37112d0c193a135160862b7"), # counter=4
b2a_hex(fg.key))
self.assertEqual(5, fg.counter.next_value())
# Read another 2 blocks from the generator
self.assertEqual(b("fd6648ba3086e919cee34904ef09a7ff") + # counter=5
b("021f77580558b8c3e9248275f23042bf"), # counter=6
b2a_hex(fg.pseudo_random_data(32)))
# Try to read more than 2**20 bytes using the internal function. This should fail.
self.assertRaises(AssertionError, fg._pseudo_random_data, 2**20+1)
def get_tests(config={}):
from Crypto.SelfTest.st_common import list_test_cases
return list_test_cases(FortunaGeneratorTests)
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Random/Fortuna/test_SHAd256.py: Self-test for the SHAd256 hash function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Random.Fortuna.SHAd256"""
__revision__ = "$Id$"
from Crypto.Util.py3compat import *
# This is a list of (expected_result, input[, description]) tuples.
test_data = [
# I could not find any test vectors for SHAd256, so I made these vectors by
# feeding some sample data into several plain SHA256 implementations
# (including OpenSSL, the "sha256sum" tool, and this implementation).
# This is a subset of the resulting test vectors. The complete list can be
# found at: http://www.dlitz.net/crypto/shad256-test-vectors/
('5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456',
'', "'' (empty string)"),
('4f8b42c22dd3729b519ba6f68d2da7cc5b2d606d05daed5ad5128cc03e6c6358',
'abc'),
('0cffe17f68954dac3a84fb1458bd5ec99209449749b2b308b7cb55812f9563af',
'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')
]
def get_tests(config={}):
from Crypto.Random.Fortuna import SHAd256
from Crypto.SelfTest.Hash.common import make_hash_tests
return make_hash_tests(SHAd256, "SHAd256", test_data, 32)
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Random/OSRNG/__init__.py: Self-test for OSRNG modules
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test for Crypto.Random.OSRNG package"""
__revision__ = "$Id$"
import os
def get_tests(config={}):
tests = []
if os.name == 'nt':
from Crypto.SelfTest.Random.OSRNG import test_nt; tests += test_nt.get_tests(config=config)
from Crypto.SelfTest.Random.OSRNG import test_winrandom; tests += test_winrandom.get_tests(config=config)
elif os.name == 'posix':
from Crypto.SelfTest.Random.OSRNG import test_posix; tests += test_posix.get_tests(config=config)
if hasattr(os, 'urandom'):
from Crypto.SelfTest.Random.OSRNG import test_fallback; tests += test_fallback.get_tests(config=config)
from Crypto.SelfTest.Random.OSRNG import test_generic; tests += test_generic.get_tests(config=config)
return tests
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Util/test_fallback.py: Self-test for the OSRNG.fallback.new() function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Random.OSRNG.fallback"""
__revision__ = "$Id$"
import unittest
class SimpleTest(unittest.TestCase):
def runTest(self):
"""Crypto.Random.OSRNG.fallback.new()"""
# Import the OSRNG.nt module and try to use it
import Crypto.Random.OSRNG.fallback
randobj = Crypto.Random.OSRNG.fallback.new()
x = randobj.read(16)
y = randobj.read(16)
self.assertNotEqual(x, y)
def get_tests(config={}):
return [SimpleTest()]
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Util/test_generic.py: Self-test for the OSRNG.new() function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Random.OSRNG"""
__revision__ = "$Id$"
import unittest
class SimpleTest(unittest.TestCase):
def runTest(self):
"""Crypto.Random.OSRNG.new()"""
# Import the OSRNG module and try to use it
import Crypto.Random.OSRNG
randobj = Crypto.Random.OSRNG.new()
x = randobj.read(16)
y = randobj.read(16)
self.assertNotEqual(x, y)
def get_tests(config={}):
return [SimpleTest()]
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Util/test_generic.py: Self-test for the OSRNG.nt.new() function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Random.OSRNG.nt"""
__revision__ = "$Id$"
import unittest
class SimpleTest(unittest.TestCase):
def runTest(self):
"""Crypto.Random.OSRNG.nt.new()"""
# Import the OSRNG.nt module and try to use it
import Crypto.Random.OSRNG.nt
randobj = Crypto.Random.OSRNG.nt.new()
x = randobj.read(16)
y = randobj.read(16)
self.assertNotEqual(x, y)
def get_tests(config={}):
return [SimpleTest()]
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Util/test_posix.py: Self-test for the OSRNG.posix.new() function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Random.OSRNG.posix"""
__revision__ = "$Id$"
import unittest
class SimpleTest(unittest.TestCase):
def runTest(self):
"""Crypto.Random.OSRNG.posix.new()"""
# Import the OSRNG.nt module and try to use it
import Crypto.Random.OSRNG.posix
randobj = Crypto.Random.OSRNG.posix.new()
x = randobj.read(16)
y = randobj.read(16)
self.assertNotEqual(x, y)
def get_tests(config={}):
return [SimpleTest()]
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Util/test_winrandom.py: Self-test for the winrandom module
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Random.OSRNG.winrandom"""
__revision__ = "$Id$"
import unittest
class SimpleTest(unittest.TestCase):
def runTest(self):
"""Crypto.Random.OSRNG.winrandom"""
# Import the winrandom module and try to use it
from Crypto.Random.OSRNG import winrandom
randobj = winrandom.new()
x = randobj.get_bytes(16)
y = randobj.get_bytes(16)
self.assertNotEqual(x, y)
def get_tests(config={}):
return [SimpleTest()]
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Random/__init__.py: Self-test for random number generation modules
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test for random number generators"""
__revision__ = "$Id$"
def get_tests(config={}):
tests = []
from Crypto.SelfTest.Random import Fortuna; tests += Fortuna.get_tests(config=config)
from Crypto.SelfTest.Random import OSRNG; tests += OSRNG.get_tests(config=config)
from Crypto.SelfTest.Random import test_random; tests += test_random.get_tests(config=config)
from Crypto.SelfTest.Random import test_rpoolcompat; tests += test_rpoolcompat.get_tests(config=config)
from Crypto.SelfTest.Random import test__UserFriendlyRNG; tests += test__UserFriendlyRNG.get_tests(config=config)
return tests
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,171 @@
# -*- coding: utf-8 -*-
# Self-tests for the user-friendly Crypto.Random interface
#
# Written in 2013 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for generic Crypto.Random stuff """
__revision__ = "$Id$"
import binascii
import pprint
import unittest
import os
import time
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
from Crypto.Util.py3compat import *
try:
import multiprocessing
except ImportError:
multiprocessing = None
import Crypto.Random._UserFriendlyRNG
import Crypto.Random.random
class RNGForkTest(unittest.TestCase):
def _get_reseed_count(self):
"""
Get `FortunaAccumulator.reseed_count`, the global count of the
number of times that the PRNG has been reseeded.
"""
rng_singleton = Crypto.Random._UserFriendlyRNG._get_singleton()
rng_singleton._lock.acquire()
try:
return rng_singleton._fa.reseed_count
finally:
rng_singleton._lock.release()
def runTest(self):
# Regression test for CVE-2013-1445. We had a bug where, under the
# right conditions, two processes might see the same random sequence.
if sys.platform.startswith('win'): # windows can't fork
assert not hasattr(os, 'fork') # ... right?
return
# Wait 150 ms so that we don't trigger the rate-limit prematurely.
time.sleep(0.15)
reseed_count_before = self._get_reseed_count()
# One or both of these calls together should trigger a reseed right here.
Crypto.Random._UserFriendlyRNG._get_singleton().reinit()
Crypto.Random.get_random_bytes(1)
reseed_count_after = self._get_reseed_count()
self.assertNotEqual(reseed_count_before, reseed_count_after) # sanity check: test should reseed parent before forking
rfiles = []
for i in range(10):
rfd, wfd = os.pipe()
if os.fork() == 0:
# child
os.close(rfd)
f = os.fdopen(wfd, "wb")
Crypto.Random.atfork()
data = Crypto.Random.get_random_bytes(16)
f.write(data)
f.close()
os._exit(0)
# parent
os.close(wfd)
rfiles.append(os.fdopen(rfd, "rb"))
results = []
results_dict = {}
for f in rfiles:
data = binascii.hexlify(f.read())
results.append(data)
results_dict[data] = 1
f.close()
if len(results) != len(list(results_dict.keys())):
raise AssertionError("RNG output duplicated across fork():\n%s" %
(pprint.pformat(results)))
# For RNGMultiprocessingForkTest
def _task_main(q):
a = Crypto.Random.get_random_bytes(16)
time.sleep(0.1) # wait 100 ms
b = Crypto.Random.get_random_bytes(16)
q.put(binascii.b2a_hex(a))
q.put(binascii.b2a_hex(b))
q.put(None) # Wait for acknowledgment
class RNGMultiprocessingForkTest(unittest.TestCase):
def runTest(self):
# Another regression test for CVE-2013-1445. This is basically the
# same as RNGForkTest, but less compatible with old versions of Python,
# and a little easier to read.
n_procs = 5
manager = multiprocessing.Manager()
queues = [manager.Queue(1) for i in range(n_procs)]
# Reseed the pool
time.sleep(0.15)
Crypto.Random._UserFriendlyRNG._get_singleton().reinit()
Crypto.Random.get_random_bytes(1)
# Start the child processes
pool = multiprocessing.Pool(processes=n_procs, initializer=Crypto.Random.atfork)
map_result = pool.map_async(_task_main, queues)
# Get the results, ensuring that no pool processes are reused.
aa = [queues[i].get(30) for i in range(n_procs)]
bb = [queues[i].get(30) for i in range(n_procs)]
res = list(zip(aa, bb))
# Shut down the pool
map_result.get(30)
pool.close()
pool.join()
# Check that the results are unique
if len(set(aa)) != len(aa) or len(set(res)) != len(res):
raise AssertionError("RNG output duplicated across fork():\n%s" %
(pprint.pformat(res),))
def get_tests(config={}):
tests = []
tests += [RNGForkTest()]
if multiprocessing is not None:
tests += [RNGMultiprocessingForkTest()]
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,171 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Util/test_generic.py: Self-test for the Crypto.Random.new() function
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Random.new()"""
__revision__ = "$Id$"
import unittest
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
from Crypto.Util.py3compat import *
class SimpleTest(unittest.TestCase):
def runTest(self):
"""Crypto.Random.new()"""
# Import the Random module and try to use it
from Crypto import Random
randobj = Random.new()
x = randobj.read(16)
y = randobj.read(16)
self.assertNotEqual(x, y)
z = Random.get_random_bytes(16)
self.assertNotEqual(x, z)
self.assertNotEqual(y, z)
# Test the Random.random module, which
# implements a subset of Python's random API
# Not implemented:
# seed(), getstate(), setstate(), jumpahead()
# random(), uniform(), triangular(), betavariate()
# expovariate(), gammavariate(), gauss(),
# longnormvariate(), normalvariate(),
# vonmisesvariate(), paretovariate()
# weibullvariate()
# WichmannHill(), whseed(), SystemRandom()
from Crypto.Random import random
x = random.getrandbits(16*8)
y = random.getrandbits(16*8)
self.assertNotEqual(x, y)
# Test randrange
if x>y:
start = y
stop = x
else:
start = x
stop = y
for step in range(1,10):
x = random.randrange(start,stop,step)
y = random.randrange(start,stop,step)
self.assertNotEqual(x, y)
self.assertEqual(start <= x < stop, True)
self.assertEqual(start <= y < stop, True)
self.assertEqual((x - start) % step, 0)
self.assertEqual((y - start) % step, 0)
for i in range(10):
self.assertEqual(random.randrange(1,2), 1)
self.assertRaises(ValueError, random.randrange, start, start)
self.assertRaises(ValueError, random.randrange, stop, start, step)
self.assertRaises(TypeError, random.randrange, start, stop, step, step)
self.assertRaises(TypeError, random.randrange, start, stop, "1")
self.assertRaises(TypeError, random.randrange, "1", stop, step)
self.assertRaises(TypeError, random.randrange, 1, "2", step)
self.assertRaises(ValueError, random.randrange, start, stop, 0)
# Test randint
x = random.randint(start,stop)
y = random.randint(start,stop)
self.assertNotEqual(x, y)
self.assertEqual(start <= x <= stop, True)
self.assertEqual(start <= y <= stop, True)
for i in range(10):
self.assertEqual(random.randint(1,1), 1)
self.assertRaises(ValueError, random.randint, stop, start)
self.assertRaises(TypeError, random.randint, start, stop, step)
self.assertRaises(TypeError, random.randint, "1", stop)
self.assertRaises(TypeError, random.randint, 1, "2")
# Test choice
seq = list(range(10000))
x = random.choice(seq)
y = random.choice(seq)
self.assertNotEqual(x, y)
self.assertEqual(x in seq, True)
self.assertEqual(y in seq, True)
for i in range(10):
self.assertEqual(random.choice((1,2,3)) in (1,2,3), True)
self.assertEqual(random.choice([1,2,3]) in [1,2,3], True)
if sys.version_info[0] is 3:
self.assertEqual(random.choice(bytearray(b('123'))) in bytearray(b('123')), True)
self.assertEqual(1, random.choice([1]))
self.assertRaises(IndexError, random.choice, [])
self.assertRaises(TypeError, random.choice, 1)
# Test shuffle. Lacks random parameter to specify function.
# Make copies of seq
seq = list(range(500))
x = list(seq)
y = list(seq)
random.shuffle(x)
random.shuffle(y)
self.assertNotEqual(x, y)
self.assertEqual(len(seq), len(x))
self.assertEqual(len(seq), len(y))
for i in range(len(seq)):
self.assertEqual(x[i] in seq, True)
self.assertEqual(y[i] in seq, True)
self.assertEqual(seq[i] in x, True)
self.assertEqual(seq[i] in y, True)
z = [1]
random.shuffle(z)
self.assertEqual(z, [1])
if sys.version_info[0] == 3:
z = bytearray(b('12'))
random.shuffle(z)
self.assertEqual(b('1') in z, True)
self.assertRaises(TypeError, random.shuffle, b('12'))
self.assertRaises(TypeError, random.shuffle, 1)
self.assertRaises(TypeError, random.shuffle, "1")
self.assertRaises(TypeError, random.shuffle, (1,2))
# 2to3 wraps a list() around it, alas - but I want to shoot
# myself in the foot here! :D
# if sys.version_info[0] == 3:
# self.assertRaises(TypeError, random.shuffle, range(3))
# Test sample
x = random.sample(seq, 20)
y = random.sample(seq, 20)
self.assertNotEqual(x, y)
for i in range(20):
self.assertEqual(x[i] in seq, True)
self.assertEqual(y[i] in seq, True)
z = random.sample([1], 1)
self.assertEqual(z, [1])
z = random.sample((1,2,3), 1)
self.assertEqual(z[0] in (1,2,3), True)
z = random.sample("123", 1)
self.assertEqual(z[0] in "123", True)
z = random.sample(list(range(3)), 1)
self.assertEqual(z[0] in range(3), True)
if sys.version_info[0] == 3:
z = random.sample(b("123"), 1)
self.assertEqual(z[0] in b("123"), True)
z = random.sample(bytearray(b("123")), 1)
self.assertEqual(z[0] in bytearray(b("123")), True)
self.assertRaises(TypeError, random.sample, 1)
def get_tests(config={}):
return [SimpleTest()]
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Util/test_winrandom.py: Self-test for the winrandom module
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test for the Crypto.Util.randpool.RandomPool wrapper class"""
__revision__ = "$Id$"
import sys
import unittest
class SimpleTest(unittest.TestCase):
def runTest(self):
"""Crypto.Util.randpool.RandomPool"""
# Import the winrandom module and try to use it
from Crypto.Util.randpool import RandomPool
sys.stderr.write("SelfTest: You can ignore the RandomPool_DeprecationWarning that follows.\n")
rpool = RandomPool()
x = rpool.get_bytes(16)
y = rpool.get_bytes(16)
self.assertNotEqual(x, y)
self.assertNotEqual(rpool.entropy, 0)
rpool.randomize()
rpool.stir('foo')
rpool.add_event('foo')
def get_tests(config={}):
return [SimpleTest()]
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Signature/__init__.py: Self-test for signature modules
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test for signature modules"""
__revision__ = "$Id$"
import os
def get_tests(config={}):
tests = []
from . import test_pkcs1_15; tests += test_pkcs1_15.get_tests(config=config)
from . import test_pkcs1_pss; tests += test_pkcs1_pss.get_tests(config=config)
return tests
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,219 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Signature/test_pkcs1_15.py: Self-test for PKCS#1 v1.5 signatures
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
__revision__ = "$Id$"
import unittest
from Crypto.PublicKey import RSA
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
from Crypto.Hash import *
from Crypto import Random
from Crypto.Signature import PKCS1_v1_5 as PKCS
from Crypto.Util.py3compat import *
def isStr(s):
t = ''
try:
t += s
except TypeError:
return 0
return 1
def rws(t):
"""Remove white spaces, tabs, and new lines from a string"""
for c in ['\n', '\t', ' ']:
t = t.replace(c,'')
return t
def t2b(t):
"""Convert a text string with bytes in hex form to a byte string"""
clean = b(rws(t))
if len(clean)%2 == 1:
raise ValueError("Even number of characters expected")
return a2b_hex(clean)
class PKCS1_15_Tests(unittest.TestCase):
# List of tuples with test data for PKCS#1 v1.5.
# Each tuple is made up by:
# Item #0: dictionary with RSA key component, or key to import
# Item #1: data to hash and sign
# Item #2: signature of the data #1, done with the key #0, after
# hashing it with #3
# Item #3: hash object generator
_testData = (
#
# Taken from ftp://ftp.rsa.com/pub/pkcs/ascii/examples.asc
# "Some Examples of the PKCS Standards", 1999
#
(
# Private key, from 2.1
{
'n':'''0a 66 79 1d c6 98 81 68 de 7a b7 74 19 bb 7f b0 c0 01 c6
27 10 27 00 75 14 29 42 e1 9a 8d 8c 51 d0 53 b3 e3 78 2a 1d
e5 dc 5a f4 eb e9 94 68 17 01 14 a1 df e6 7c dc 9a 9a f5 5d
65 56 20 bb ab''',
'e':'''01 00
01''',
'd':'''01 23 c5 b6 1b a3 6e db 1d 36 79 90 41 99 a8 9e a8 0c 09
b9 12 2e 14 00 c0 9a dc f7 78 46 76 d0 1d 23 35 6a 7d 44 d6
bd 8b d5 0e 94 bf c7 23 fa 87 d8 86 2b 75 17 76 91 c1 1d 75
76 92 df 88 81'''
},
# Data to sign, from 3.1
'''30 81 a4 02 01 00 30 42 31 0b 30 09 06
03 55 04 06 13 02 55 53 31 1d 30 1b 06 03 55 04 0a 13 14
45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61 74 69 6f
6e 31 14 30 12 06 03 55 04 03 13 0b 54 65 73 74 20 55 73
65 72 20 31 30 5b 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01
05 00 03 4a 00 30 47 02 40
0a 66 79 1d c6 98 81 68 de 7a b7 74 19 bb 7f b0
c0 01 c6 27 10 27 00 75 14 29 42 e1 9a 8d 8c 51
d0 53 b3 e3 78 2a 1d e5 dc 5a f4 eb e9 94 68 17
01 14 a1 df e6 7c dc 9a 9a f5 5d 65 56 20 bb ab
02 03 01 00 01''',
# Signature, from 3.2 (at the very end)
'''06 db 36 cb 18 d3 47 5b 9c 01 db 3c 78 95 28 08
02 79 bb ae ff 2b 7d 55 8e d6 61 59 87 c8 51 86
3f 8a 6c 2c ff bc 89 c3 f7 5a 18 d9 6b 12 7c 71
7d 54 d0 d8 04 8d a8 a0 54 46 26 d1 7a 2a 8f be''',
MD2
),
#
# RSA keypair generated with openssl
#
(
"""-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+TLr7UkvEtFrRhDDKMtuII
q19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQJACUSDEp8RTe32ftq8IwG8
Wojl5mAd1wFiIOrZ/Uv8b963WJOJiuQcVN29vxU5+My9GPZ7RA3hrDBEAoHUDPrI
OQIhAPIPLz4dphiD9imAkivY31Rc5AfHJiQRA7XixTcjEkojAiEAyh/pJHks/Mlr
+rdPNEpotBjfV4M4BkgGAA/ipcmaAjcCIQCHvhwwKVBLzzTscT2HeUdEeBMoiXXK
JACAr3sJQJGxIQIgarRp+m1WSKV1MciwMaTOnbU7wxFs9DP1pva76lYBzgUCIQC9
n0CnZCJ6IZYqSt0H5N7+Q+2Ro64nuwV/OSQfM6sBwQ==
-----END RSA PRIVATE KEY-----""",
"This is a test\x0a",
#
# PKCS#1 signature computed with openssl
#
'''4a700a16432a291a3194646952687d5316458b8b86fb0a25aa30e0dcecdb
442676759ac63d56ec1499c3ae4c0013c2053cabd5b5804848994541ac16
fa243a4d''',
SHA
),
#
# Test vector from http://www.di-mgt.com.au/rsa_alg.html#signpkcs1
#
(
{
'n':'''E08973398DD8F5F5E88776397F4EB005BB5383DE0FB7ABDC7DC775290D052E6D
12DFA68626D4D26FAA5829FC97ECFA82510F3080BEB1509E4644F12CBBD832CF
C6686F07D9B060ACBEEE34096A13F5F7050593DF5EBA3556D961FF197FC981E6
F86CEA874070EFAC6D2C749F2DFA553AB9997702A648528C4EF357385774575F''',
'e':'''010001''',
'd':'''00A403C327477634346CA686B57949014B2E8AD2C862B2C7D748096A8B91F736
F275D6E8CD15906027314735644D95CD6763CEB49F56AC2F376E1CEE0EBF282D
F439906F34D86E085BD5656AD841F313D72D395EFE33CBFF29E4030B3D05A28F
B7F18EA27637B07957D32F2BDE8706227D04665EC91BAF8B1AC3EC9144AB7F21'''
},
"abc",
'''60AD5A78FB4A4030EC542C8974CD15F55384E836554CEDD9A322D5F4135C6267
A9D20970C54E6651070B0144D43844C899320DD8FA7819F7EBC6A7715287332E
C8675C136183B3F8A1F81EF969418267130A756FDBB2C71D9A667446E34E0EAD
9CF31BFB66F816F319D0B7E430A5F2891553986E003720261C7E9022C0D9F11F''',
SHA
)
)
def testSign1(self):
for i in range(len(self._testData)):
row = self._testData[i]
# Build the key
if isStr(row[0]):
key = RSA.importKey(row[0])
else:
comps = [ int(rws(row[0][x]),16) for x in ('n','e','d') ]
key = RSA.construct(comps)
h = row[3].new()
# Data to sign can either be in hex form or not
try:
h.update(t2b(row[1]))
except:
h.update(b(row[1]))
# The real test
signer = PKCS.new(key)
self.assertTrue(signer.can_sign())
s = signer.sign(h)
self.assertEqual(s, t2b(row[2]))
def testVerify1(self):
for i in range(len(self._testData)):
row = self._testData[i]
# Build the key
if isStr(row[0]):
key = RSA.importKey(row[0]).publickey()
else:
comps = [ int(rws(row[0][x]),16) for x in ('n','e') ]
key = RSA.construct(comps)
h = row[3].new()
# Data to sign can either be in hex form or not
try:
h.update(t2b(row[1]))
except:
h.update(b(row[1]))
# The real test
verifier = PKCS.new(key)
self.assertFalse(verifier.can_sign())
result = verifier.verify(h, t2b(row[2]))
self.assertTrue(result)
def testSignVerify(self):
rng = Random.new().read
key = RSA.generate(1024, rng)
for hashmod in (MD2,MD5,SHA,SHA224,SHA256,SHA384,SHA512,RIPEMD):
h = hashmod.new()
h.update(b('blah blah blah'))
signer = PKCS.new(key)
s = signer.sign(h)
result = signer.verify(h, s)
self.assertTrue(result)
def get_tests(config={}):
tests = []
tests += list_test_cases(PKCS1_15_Tests)
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,446 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Signature/test_pkcs1_pss.py: Self-test for PKCS#1 PSS signatures
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
__revision__ = "$Id$"
import unittest
from Crypto.PublicKey import RSA
from Crypto import Random
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
from Crypto.Hash import *
from Crypto.Signature import PKCS1_PSS as PKCS
from Crypto.Util.py3compat import *
def isStr(s):
t = ''
try:
t += s
except TypeError:
return 0
return 1
def rws(t):
"""Remove white spaces, tabs, and new lines from a string"""
for c in ['\t', '\n', ' ']:
t = t.replace(c,'')
return t
def t2b(t):
"""Convert a text string with bytes in hex form to a byte string"""
clean = b(rws(t))
if len(clean)%2 == 1:
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 has_private(self):
return self._key.has_private()
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
# Each tuple is made up by:
# Item #0: dictionary with RSA key component, or key to import
# Item #1: data to hash and sign
# Item #2: signature of the data #1, done with the key #0,
# and salt #3 after hashing it with #4
# Item #3: salt
# Item #4: hash object generator
_testData = (
#
# From in pss-vect.txt to be found in
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''a2 ba 40 ee 07 e3 b2 bd 2f 02 ce 22 7f 36 a1 95
02 44 86 e4 9c 19 cb 41 bb bd fb ba 98 b2 2b 0e
57 7c 2e ea ff a2 0d 88 3a 76 e6 5e 39 4c 69 d4
b3 c0 5a 1e 8f ad da 27 ed b2 a4 2b c0 00 fe 88
8b 9b 32 c2 2d 15 ad d0 cd 76 b3 e7 93 6e 19 95
5b 22 0d d1 7d 4e a9 04 b1 ec 10 2b 2e 4d e7 75
12 22 aa 99 15 10 24 c7 cb 41 cc 5e a2 1d 00 ee
b4 1f 7c 80 08 34 d2 c6 e0 6b ce 3b ce 7e a9 a5''',
'e':'''01 00 01''',
# In the test vector, only p and q were given...
# d is computed offline as e^{-1} mod (p-1)(q-1)
'd':'''50e2c3e38d886110288dfc68a9533e7e12e27d2aa56
d2cdb3fb6efa990bcff29e1d2987fb711962860e7391b1ce01
ebadb9e812d2fbdfaf25df4ae26110a6d7a26f0b810f54875e
17dd5c9fb6d641761245b81e79f8c88f0e55a6dcd5f133abd3
5f8f4ec80adf1bf86277a582894cb6ebcd2162f1c7534f1f49
47b129151b71'''
},
# Data to sign
'''85 9e ef 2f d7 8a ca 00 30 8b dc 47 11 93 bf 55
bf 9d 78 db 8f 8a 67 2b 48 46 34 f3 c9 c2 6e 64
78 ae 10 26 0f e0 dd 8c 08 2e 53 a5 29 3a f2 17
3c d5 0c 6d 5d 35 4f eb f7 8b 26 02 1c 25 c0 27
12 e7 8c d4 69 4c 9f 46 97 77 e4 51 e7 f8 e9 e0
4c d3 73 9c 6b bf ed ae 48 7f b5 56 44 e9 ca 74
ff 77 a5 3c b7 29 80 2f 6e d4 a5 ff a8 ba 15 98
90 fc''',
# Signature
'''8d aa 62 7d 3d e7 59 5d 63 05 6c 7e c6 59 e5 44
06 f1 06 10 12 8b aa e8 21 c8 b2 a0 f3 93 6d 54
dc 3b dc e4 66 89 f6 b7 95 1b b1 8e 84 05 42 76
97 18 d5 71 5d 21 0d 85 ef bb 59 61 92 03 2c 42
be 4c 29 97 2c 85 62 75 eb 6d 5a 45 f0 5f 51 87
6f c6 74 3d ed dd 28 ca ec 9b b3 0e a9 9e 02 c3
48 82 69 60 4f e4 97 f7 4c cd 7c 7f ca 16 71 89
71 23 cb d3 0d ef 5d 54 a2 b5 53 6a d9 0a 74 7e''',
# Salt
'''e3 b5 d5 d0 02 c1 bc e5 0c 2b 65 ef 88 a1 88 d8
3b ce 7e 61''',
# Hash algorithm
SHA
),
#
# Example 1.1 to be found in
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''a5 6e 4a 0e 70 10 17 58 9a 51 87 dc 7e a8 41 d1
56 f2 ec 0e 36 ad 52 a4 4d fe b1 e6 1f 7a d9 91
d8 c5 10 56 ff ed b1 62 b4 c0 f2 83 a1 2a 88 a3
94 df f5 26 ab 72 91 cb b3 07 ce ab fc e0 b1 df
d5 cd 95 08 09 6d 5b 2b 8b 6d f5 d6 71 ef 63 77
c0 92 1c b2 3c 27 0a 70 e2 59 8e 6f f8 9d 19 f1
05 ac c2 d3 f0 cb 35 f2 92 80 e1 38 6b 6f 64 c4
ef 22 e1 e1 f2 0d 0c e8 cf fb 22 49 bd 9a 21 37''',
'e':'''01 00 01''',
'd':'''33 a5 04 2a 90 b2 7d 4f 54 51 ca 9b bb d0 b4 47
71 a1 01 af 88 43 40 ae f9 88 5f 2a 4b be 92 e8
94 a7 24 ac 3c 56 8c 8f 97 85 3a d0 7c 02 66 c8
c6 a3 ca 09 29 f1 e8 f1 12 31 88 44 29 fc 4d 9a
e5 5f ee 89 6a 10 ce 70 7c 3e d7 e7 34 e4 47 27
a3 95 74 50 1a 53 26 83 10 9c 2a ba ca ba 28 3c
31 b4 bd 2f 53 c3 ee 37 e3 52 ce e3 4f 9e 50 3b
d8 0c 06 22 ad 79 c6 dc ee 88 35 47 c6 a3 b3 25'''
},
# Message
'''cd c8 7d a2 23 d7 86 df 3b 45 e0 bb bc 72 13 26
d1 ee 2a f8 06 cc 31 54 75 cc 6f 0d 9c 66 e1 b6
23 71 d4 5c e2 39 2e 1a c9 28 44 c3 10 10 2f 15
6a 0d 8d 52 c1 f4 c4 0b a3 aa 65 09 57 86 cb 76
97 57 a6 56 3b a9 58 fe d0 bc c9 84 e8 b5 17 a3
d5 f5 15 b2 3b 8a 41 e7 4a a8 67 69 3f 90 df b0
61 a6 e8 6d fa ae e6 44 72 c0 0e 5f 20 94 57 29
cb eb e7 7f 06 ce 78 e0 8f 40 98 fb a4 1f 9d 61
93 c0 31 7e 8b 60 d4 b6 08 4a cb 42 d2 9e 38 08
a3 bc 37 2d 85 e3 31 17 0f cb f7 cc 72 d0 b7 1c
29 66 48 b3 a4 d1 0f 41 62 95 d0 80 7a a6 25 ca
b2 74 4f d9 ea 8f d2 23 c4 25 37 02 98 28 bd 16
be 02 54 6f 13 0f d2 e3 3b 93 6d 26 76 e0 8a ed
1b 73 31 8b 75 0a 01 67 d0''',
# Signature
'''90 74 30 8f b5 98 e9 70 1b 22 94 38 8e 52 f9 71
fa ac 2b 60 a5 14 5a f1 85 df 52 87 b5 ed 28 87
e5 7c e7 fd 44 dc 86 34 e4 07 c8 e0 e4 36 0b c2
26 f3 ec 22 7f 9d 9e 54 63 8e 8d 31 f5 05 12 15
df 6e bb 9c 2f 95 79 aa 77 59 8a 38 f9 14 b5 b9
c1 bd 83 c4 e2 f9 f3 82 a0 d0 aa 35 42 ff ee 65
98 4a 60 1b c6 9e b2 8d eb 27 dc a1 2c 82 c2 d4
c3 f6 6c d5 00 f1 ff 2b 99 4d 8a 4e 30 cb b3 3c''',
# Salt
'''de e9 59 c7 e0 64 11 36 14 20 ff 80 18 5e d5 7f
3e 67 76 af''',
# Hash
SHA
),
#
# Example 1.2 to be found in
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''a5 6e 4a 0e 70 10 17 58 9a 51 87 dc 7e a8 41 d1
56 f2 ec 0e 36 ad 52 a4 4d fe b1 e6 1f 7a d9 91
d8 c5 10 56 ff ed b1 62 b4 c0 f2 83 a1 2a 88 a3
94 df f5 26 ab 72 91 cb b3 07 ce ab fc e0 b1 df
d5 cd 95 08 09 6d 5b 2b 8b 6d f5 d6 71 ef 63 77
c0 92 1c b2 3c 27 0a 70 e2 59 8e 6f f8 9d 19 f1
05 ac c2 d3 f0 cb 35 f2 92 80 e1 38 6b 6f 64 c4
ef 22 e1 e1 f2 0d 0c e8 cf fb 22 49 bd 9a 21 37''',
'e':'''01 00 01''',
'd':'''33 a5 04 2a 90 b2 7d 4f 54 51 ca 9b bb d0 b4 47
71 a1 01 af 88 43 40 ae f9 88 5f 2a 4b be 92 e8
94 a7 24 ac 3c 56 8c 8f 97 85 3a d0 7c 02 66 c8
c6 a3 ca 09 29 f1 e8 f1 12 31 88 44 29 fc 4d 9a
e5 5f ee 89 6a 10 ce 70 7c 3e d7 e7 34 e4 47 27
a3 95 74 50 1a 53 26 83 10 9c 2a ba ca ba 28 3c
31 b4 bd 2f 53 c3 ee 37 e3 52 ce e3 4f 9e 50 3b
d8 0c 06 22 ad 79 c6 dc ee 88 35 47 c6 a3 b3 25'''
},
# Message
'''85 13 84 cd fe 81 9c 22 ed 6c 4c cb 30 da eb 5c
f0 59 bc 8e 11 66 b7 e3 53 0c 4c 23 3e 2b 5f 8f
71 a1 cc a5 82 d4 3e cc 72 b1 bc a1 6d fc 70 13
22 6b 9e''',
# Signature
'''3e f7 f4 6e 83 1b f9 2b 32 27 41 42 a5 85 ff ce
fb dc a7 b3 2a e9 0d 10 fb 0f 0c 72 99 84 f0 4e
f2 9a 9d f0 78 07 75 ce 43 73 9b 97 83 83 90 db
0a 55 05 e6 3d e9 27 02 8d 9d 29 b2 19 ca 2c 45
17 83 25 58 a5 5d 69 4a 6d 25 b9 da b6 60 03 c4
cc cd 90 78 02 19 3b e5 17 0d 26 14 7d 37 b9 35
90 24 1b e5 1c 25 05 5f 47 ef 62 75 2c fb e2 14
18 fa fe 98 c2 2c 4d 4d 47 72 4f db 56 69 e8 43''',
# Salt
'''ef 28 69 fa 40 c3 46 cb 18 3d ab 3d 7b ff c9 8f
d5 6d f4 2d''',
# Hash
SHA
),
#
# Example 2.1 to be found in
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''01 d4 0c 1b cf 97 a6 8a e7 cd bd 8a 7b f3 e3 4f
a1 9d cc a4 ef 75 a4 74 54 37 5f 94 51 4d 88 fe
d0 06 fb 82 9f 84 19 ff 87 d6 31 5d a6 8a 1f f3
a0 93 8e 9a bb 34 64 01 1c 30 3a d9 91 99 cf 0c
7c 7a 8b 47 7d ce 82 9e 88 44 f6 25 b1 15 e5 e9
c4 a5 9c f8 f8 11 3b 68 34 33 6a 2f d2 68 9b 47
2c bb 5e 5c ab e6 74 35 0c 59 b6 c1 7e 17 68 74
fb 42 f8 fc 3d 17 6a 01 7e dc 61 fd 32 6c 4b 33
c9''',
'e':'''01 00 01''',
'd':'''02 7d 14 7e 46 73 05 73 77 fd 1e a2 01 56 57 72
17 6a 7d c3 83 58 d3 76 04 56 85 a2 e7 87 c2 3c
15 57 6b c1 6b 9f 44 44 02 d6 bf c5 d9 8a 3e 88
ea 13 ef 67 c3 53 ec a0 c0 dd ba 92 55 bd 7b 8b
b5 0a 64 4a fd fd 1d d5 16 95 b2 52 d2 2e 73 18
d1 b6 68 7a 1c 10 ff 75 54 5f 3d b0 fe 60 2d 5f
2b 7f 29 4e 36 01 ea b7 b9 d1 ce cd 76 7f 64 69
2e 3e 53 6c a2 84 6c b0 c2 dd 48 6a 39 fa 75 b1'''
},
# Message
'''da ba 03 20 66 26 3f ae db 65 98 48 11 52 78 a5
2c 44 fa a3 a7 6f 37 51 5e d3 36 32 10 72 c4 0a
9d 9b 53 bc 05 01 40 78 ad f5 20 87 51 46 aa e7
0f f0 60 22 6d cb 7b 1f 1f c2 7e 93 60''',
# Signature
'''01 4c 5b a5 33 83 28 cc c6 e7 a9 0b f1 c0 ab 3f
d6 06 ff 47 96 d3 c1 2e 4b 63 9e d9 13 6a 5f ec
6c 16 d8 88 4b dd 99 cf dc 52 14 56 b0 74 2b 73
68 68 cf 90 de 09 9a db 8d 5f fd 1d ef f3 9b a4
00 7a b7 46 ce fd b2 2d 7d f0 e2 25 f5 46 27 dc
65 46 61 31 72 1b 90 af 44 53 63 a8 35 8b 9f 60
76 42 f7 8f ab 0a b0 f4 3b 71 68 d6 4b ae 70 d8
82 78 48 d8 ef 1e 42 1c 57 54 dd f4 2c 25 89 b5
b3''',
# Salt
'''57 bf 16 0b cb 02 bb 1d c7 28 0c f0 45 85 30 b7
d2 83 2f f7''',
SHA
),
#
# Example 8.1 to be found in
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''49 53 70 a1 fb 18 54 3c 16 d3 63 1e 31 63 25 5d
f6 2b e6 ee e8 90 d5 f2 55 09 e4 f7 78 a8 ea 6f
bb bc df 85 df f6 4e 0d 97 20 03 ab 36 81 fb ba
6d d4 1f d5 41 82 9b 2e 58 2d e9 f2 a4 a4 e0 a2
d0 90 0b ef 47 53 db 3c ee 0e e0 6c 7d fa e8 b1
d5 3b 59 53 21 8f 9c ce ea 69 5b 08 66 8e de aa
dc ed 94 63 b1 d7 90 d5 eb f2 7e 91 15 b4 6c ad
4d 9a 2b 8e fa b0 56 1b 08 10 34 47 39 ad a0 73
3f''',
'e':'''01 00 01''',
'd':'''6c 66 ff e9 89 80 c3 8f cd ea b5 15 98 98 83 61
65 f4 b4 b8 17 c4 f6 a8 d4 86 ee 4e a9 13 0f e9
b9 09 2b d1 36 d1 84 f9 5f 50 4a 60 7e ac 56 58
46 d2 fd d6 59 7a 89 67 c7 39 6e f9 5a 6e ee bb
45 78 a6 43 96 6d ca 4d 8e e3 de 84 2d e6 32 79
c6 18 15 9c 1a b5 4a 89 43 7b 6a 61 20 e4 93 0a
fb 52 a4 ba 6c ed 8a 49 47 ac 64 b3 0a 34 97 cb
e7 01 c2 d6 26 6d 51 72 19 ad 0e c6 d3 47 db e9'''
},
# Message
'''81 33 2f 4b e6 29 48 41 5e a1 d8 99 79 2e ea cf
6c 6e 1d b1 da 8b e1 3b 5c ea 41 db 2f ed 46 70
92 e1 ff 39 89 14 c7 14 25 97 75 f5 95 f8 54 7f
73 56 92 a5 75 e6 92 3a f7 8f 22 c6 99 7d db 90
fb 6f 72 d7 bb 0d d5 74 4a 31 de cd 3d c3 68 58
49 83 6e d3 4a ec 59 63 04 ad 11 84 3c 4f 88 48
9f 20 97 35 f5 fb 7f da f7 ce c8 ad dc 58 18 16
8f 88 0a cb f4 90 d5 10 05 b7 a8 e8 4e 43 e5 42
87 97 75 71 dd 99 ee a4 b1 61 eb 2d f1 f5 10 8f
12 a4 14 2a 83 32 2e db 05 a7 54 87 a3 43 5c 9a
78 ce 53 ed 93 bc 55 08 57 d7 a9 fb''',
# Signature
'''02 62 ac 25 4b fa 77 f3 c1 ac a2 2c 51 79 f8 f0
40 42 2b 3c 5b af d4 0a 8f 21 cf 0f a5 a6 67 cc
d5 99 3d 42 db af b4 09 c5 20 e2 5f ce 2b 1e e1
e7 16 57 7f 1e fa 17 f3 da 28 05 2f 40 f0 41 9b
23 10 6d 78 45 aa f0 11 25 b6 98 e7 a4 df e9 2d
39 67 bb 00 c4 d0 d3 5b a3 55 2a b9 a8 b3 ee f0
7c 7f ec db c5 42 4a c4 db 1e 20 cb 37 d0 b2 74
47 69 94 0e a9 07 e1 7f bb ca 67 3b 20 52 23 80
c5''',
# Salt
'''1d 65 49 1d 79 c8 64 b3 73 00 9b e6 f6 f2 46 7b
ac 4c 78 fa''',
SHA
)
)
def testSign1(self):
for i in range(len(self._testData)):
# Build the key
comps = [ int(rws(self._testData[i][0][x]),16) for x in ('n','e','d') ]
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
signer = PKCS.new(key)
self.assertTrue(signer.can_sign())
s = signer.sign(h)
self.assertEqual(s, t2b(self._testData[i][2]))
def testVerify1(self):
for i in range(len(self._testData)):
# Build the key
comps = [ int(rws(self._testData[i][0][x]),16) for x in ('n','e') ]
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])
# The real test
key._randfunc = lambda N: test_salt
verifier = PKCS.new(key)
self.assertFalse(verifier.can_sign())
result = verifier.verify(h, t2b(self._testData[i][2]))
self.assertTrue(result)
def testSignVerify(self):
h = SHA.new()
h.update(b('blah blah blah'))
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
return bchr(0x00)*maskLen
# Verify that PSS is friendly to all ciphers
for hashmod in (MD2,MD5,SHA,SHA224,SHA256,SHA384,RIPEMD):
h = hashmod.new()
h.update(b('blah blah blah'))
# Verify that sign() asks for as many random bytes
# as the hash output size
key.asked = 0
signer = PKCS.new(key)
s = signer.sign(h)
self.assertTrue(signer.verify(h, s))
self.assertEqual(key.asked, h.digest_size)
h = SHA.new()
h.update(b('blah blah blah'))
# Verify that sign() uses a different salt length
for sLen in (0,3,21):
key.asked = 0
signer = PKCS.new(key, saltLen=sLen)
s = signer.sign(h)
self.assertEqual(key.asked, sLen)
self.assertTrue(signer.verify(h, s))
# Verify that sign() uses the custom MGF
mgfcalls = 0
signer = PKCS.new(key, newMGF)
s = signer.sign(h)
self.assertEqual(mgfcalls, 1)
self.assertTrue(signer.verify(h, s))
# Verify that sign() does not call the RNG
# when salt length is 0, even when a new MGF is provided
key.asked = 0
mgfcalls = 0
signer = PKCS.new(key, newMGF, 0)
s = signer.sign(h)
self.assertEqual(key.asked,0)
self.assertEqual(mgfcalls, 1)
self.assertTrue(signer.verify(h, s))
def get_tests(config={}):
tests = []
tests += list_test_cases(PKCS1_PSS_Tests)
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4

View file

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Util/__init__.py: Self-test for utility modules
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test for utility modules"""
__revision__ = "$Id$"
import os
def get_tests(config={}):
tests = []
if os.name == 'nt':
from Crypto.SelfTest.Util import test_winrandom; tests += test_winrandom.get_tests(config=config)
from Crypto.SelfTest.Util import test_number; tests += test_number.get_tests(config=config)
from Crypto.SelfTest.Util import test_Counter; tests += test_Counter.get_tests(config=config)
return tests
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,165 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Util/test_Counter: Self-test for the Crypto.Util.Counter module
#
# Written in 2009 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-tests for Crypto.Util.Counter"""
__revision__ = "$Id$"
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
from Crypto.Util.py3compat import *
import unittest
class CounterTests(unittest.TestCase):
def setUp(self):
global Counter
from Crypto.Util import Counter
def test_BE_shortcut(self):
"""Big endian, shortcut enabled"""
c = Counter.new(128)
self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_
c = Counter.new(128, little_endian=False)
self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_
c = Counter.new(128, disable_shortcut=False)
self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_
c = Counter.new(128, little_endian=False, disable_shortcut=False)
self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_
def test_LE_shortcut(self):
"""Little endian, shortcut enabled"""
c = Counter.new(128, little_endian=True)
self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_
c = Counter.new(128, little_endian=True, disable_shortcut=False)
self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_
def test_BE_no_shortcut(self):
"""Big endian, shortcut disabled"""
c = Counter.new(128, disable_shortcut=True)
self.assertRaises(AttributeError, getattr, c, '__PCT_CTR_SHORTCUT__')
c = Counter.new(128, little_endian=False, disable_shortcut=True)
self.assertRaises(AttributeError, getattr, c, '__PCT_CTR_SHORTCUT__')
def test_LE_no_shortcut(self):
"""Little endian, shortcut disabled"""
c = Counter.new(128, little_endian=True, disable_shortcut=True)
self.assertRaises(AttributeError, getattr, c, '__PCT_CTR_SHORTCUT__')
def test_BE_defaults(self):
"""128-bit, Big endian, defaults"""
c = Counter.new(128)
self.assertEqual(1, c.next_value())
self.assertEqual(b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"), c())
self.assertEqual(2, c.next_value())
self.assertEqual(b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"), c())
for i in range(3, 256):
self.assertEqual(i, c.next_value())
self.assertEqual(b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")+bchr(i), c())
self.assertEqual(256, c.next_value())
self.assertEqual(b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00"), c())
def test_LE_defaults(self):
"""128-bit, Little endian, defaults"""
c = Counter.new(128, little_endian=True)
self.assertEqual(1, c.next_value())
self.assertEqual(b("\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), c())
self.assertEqual(2, c.next_value())
self.assertEqual(b("\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), c())
for i in range(3, 256):
self.assertEqual(i, c.next_value())
self.assertEqual(bchr(i)+b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), c())
self.assertEqual(256, c.next_value())
self.assertEqual(b("\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), c())
def test_BE8_wraparound(self):
"""8-bit, Big endian, wraparound"""
c = Counter.new(8)
for i in range(1, 256):
self.assertEqual(i, c.next_value())
self.assertEqual(bchr(i), c())
self.assertRaises(OverflowError, c.next_value)
self.assertRaises(OverflowError, c)
self.assertRaises(OverflowError, c.next_value)
self.assertRaises(OverflowError, c)
def test_LE8_wraparound(self):
"""8-bit, Little endian, wraparound"""
c = Counter.new(8, little_endian=True)
for i in range(1, 256):
self.assertEqual(i, c.next_value())
self.assertEqual(bchr(i), c())
self.assertRaises(OverflowError, c.next_value)
self.assertRaises(OverflowError, c)
self.assertRaises(OverflowError, c.next_value)
self.assertRaises(OverflowError, c)
def test_BE8_wraparound_allowed(self):
"""8-bit, Big endian, wraparound with allow_wraparound=True"""
c = Counter.new(8, allow_wraparound=True)
for i in range(1, 256):
self.assertEqual(i, c.next_value())
self.assertEqual(bchr(i), c())
self.assertEqual(0, c.next_value())
self.assertEqual(b("\x00"), c())
self.assertEqual(1, c.next_value())
def test_LE8_wraparound_allowed(self):
"""8-bit, Little endian, wraparound with allow_wraparound=True"""
c = Counter.new(8, little_endian=True, allow_wraparound=True)
for i in range(1, 256):
self.assertEqual(i, c.next_value())
self.assertEqual(bchr(i), c())
self.assertEqual(0, c.next_value())
self.assertEqual(b("\x00"), c())
self.assertEqual(1, c.next_value())
def test_BE8_carry(self):
"""8-bit, Big endian, carry attribute"""
c = Counter.new(8)
for i in range(1, 256):
self.assertEqual(0, c.carry)
self.assertEqual(i, c.next_value())
self.assertEqual(bchr(i), c())
self.assertEqual(1, c.carry)
def test_LE8_carry(self):
"""8-bit, Little endian, carry attribute"""
c = Counter.new(8, little_endian=True)
for i in range(1, 256):
self.assertEqual(0, c.carry)
self.assertEqual(i, c.next_value())
self.assertEqual(bchr(i), c())
self.assertEqual(1, c.carry)
def get_tests(config={}):
from Crypto.SelfTest.st_common import list_test_cases
return list_test_cases(CounterTests)
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,293 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Util/test_asn.py: Self-test for the Crypto.Util.asn1 module
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-tests for Crypto.Util.asn1"""
__revision__ = "$Id$"
import unittest
import sys
from Crypto.Util.py3compat import *
from Crypto.Util.asn1 import DerSequence, DerObject
class DerObjectTests(unittest.TestCase):
def testObjEncode1(self):
# No payload
der = DerObject(b('\x33'))
self.assertEqual(der.encode(), b('\x33\x00'))
# Small payload
der.payload = b('\x45')
self.assertEqual(der.encode(), b('\x33\x01\x45'))
# Invariant
self.assertEqual(der.encode(), b('\x33\x01\x45'))
# Initialize with numerical tag
der = DerObject(b(0x33))
der.payload = b('\x45')
self.assertEqual(der.encode(), b('\x33\x01\x45'))
def testObjEncode2(self):
# Known types
der = DerObject('SEQUENCE')
self.assertEqual(der.encode(), b('\x30\x00'))
der = DerObject('BIT STRING')
self.assertEqual(der.encode(), b('\x03\x00'))
def testObjEncode3(self):
# Long payload
der = DerObject(b('\x34'))
der.payload = b("0")*128
self.assertEqual(der.encode(), b('\x34\x81\x80' + "0"*128))
def testObjDecode1(self):
# Decode short payload
der = DerObject()
der.decode(b('\x20\x02\x01\x02'))
self.assertEqual(der.payload, b("\x01\x02"))
self.assertEqual(der.typeTag, 0x20)
def testObjDecode2(self):
# Decode short payload
der = DerObject()
der.decode(b('\x22\x81\x80' + "1"*128))
self.assertEqual(der.payload, b("1")*128)
self.assertEqual(der.typeTag, 0x22)
class DerSequenceTests(unittest.TestCase):
def testEncode1(self):
# Empty sequence
der = DerSequence()
self.assertEqual(der.encode(), b('0\x00'))
self.assertFalse(der.hasOnlyInts())
# One single-byte integer (zero)
der.append(0)
self.assertEqual(der.encode(), b('0\x03\x02\x01\x00'))
self.assertTrue(der.hasOnlyInts())
# Invariant
self.assertEqual(der.encode(), b('0\x03\x02\x01\x00'))
def testEncode2(self):
# One single-byte integer (non-zero)
der = DerSequence()
der.append(127)
self.assertEqual(der.encode(), b('0\x03\x02\x01\x7f'))
# Indexing
der[0] = 1
self.assertEqual(len(der),1)
self.assertEqual(der[0],1)
self.assertEqual(der[-1],1)
self.assertEqual(der.encode(), b('0\x03\x02\x01\x01'))
#
der[:] = [1]
self.assertEqual(len(der),1)
self.assertEqual(der[0],1)
self.assertEqual(der.encode(), b('0\x03\x02\x01\x01'))
def testEncode3(self):
# One multi-byte integer (non-zero)
der = DerSequence()
der.append(0x180)
self.assertEqual(der.encode(), b('0\x04\x02\x02\x01\x80'))
def testEncode4(self):
# One very long integer
der = DerSequence()
der.append(2**2048)
self.assertEqual(der.encode(), b('0\x82\x01\x05')+
b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
def testEncode5(self):
# One single-byte integer (looks negative)
der = DerSequence()
der.append(0xFF)
self.assertEqual(der.encode(), b('0\x04\x02\x02\x00\xff'))
def testEncode6(self):
# Two integers
der = DerSequence()
der.append(0x180)
der.append(0xFF)
self.assertEqual(der.encode(), b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff'))
self.assertTrue(der.hasOnlyInts())
#
der.append(0x01)
der[1:] = [9,8]
self.assertEqual(len(der),3)
self.assertEqual(der[1:],[9,8])
self.assertEqual(der[1:-1],[9])
self.assertEqual(der.encode(), b('0\x0A\x02\x02\x01\x80\x02\x01\x09\x02\x01\x08'))
def testEncode6(self):
# One integer and another type (no matter what it is)
der = DerSequence()
der.append(0x180)
der.append(b('\x00\x02\x00\x00'))
self.assertEqual(der.encode(), b('0\x08\x02\x02\x01\x80\x00\x02\x00\x00'))
self.assertFalse(der.hasOnlyInts())
####
def testDecode1(self):
# Empty sequence
der = DerSequence()
der.decode(b('0\x00'))
self.assertEqual(len(der),0)
# One single-byte integer (zero)
der.decode(b('0\x03\x02\x01\x00'))
self.assertEqual(len(der),1)
self.assertEqual(der[0],0)
# Invariant
der.decode(b('0\x03\x02\x01\x00'))
self.assertEqual(len(der),1)
self.assertEqual(der[0],0)
def testDecode2(self):
# One single-byte integer (non-zero)
der = DerSequence()
der.decode(b('0\x03\x02\x01\x7f'))
self.assertEqual(len(der),1)
self.assertEqual(der[0],127)
def testDecode3(self):
# One multi-byte integer (non-zero)
der = DerSequence()
der.decode(b('0\x04\x02\x02\x01\x80'))
self.assertEqual(len(der),1)
self.assertEqual(der[0],0x180)
def testDecode4(self):
# One very long integer
der = DerSequence()
der.decode(b('0\x82\x01\x05')+
b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
b('\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
self.assertEqual(len(der),1)
self.assertEqual(der[0],2**2048)
def testDecode5(self):
# One single-byte integer (looks negative)
der = DerSequence()
der.decode(b('0\x04\x02\x02\x00\xff'))
self.assertEqual(len(der),1)
self.assertEqual(der[0],0xFF)
def testDecode6(self):
# Two integers
der = DerSequence()
der.decode(b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff'))
self.assertEqual(len(der),2)
self.assertEqual(der[0],0x180)
self.assertEqual(der[1],0xFF)
def testDecode7(self):
# One integer and 2 other types
der = DerSequence()
der.decode(b('0\x0A\x02\x02\x01\x80\x24\x02\xb6\x63\x12\x00'))
self.assertEqual(len(der),3)
self.assertEqual(der[0],0x180)
self.assertEqual(der[1],b('\x24\x02\xb6\x63'))
self.assertEqual(der[2],b('\x12\x00'))
def testDecode8(self):
# Only 2 other types
der = DerSequence()
der.decode(b('0\x06\x24\x02\xb6\x63\x12\x00'))
self.assertEqual(len(der),2)
self.assertEqual(der[0],b('\x24\x02\xb6\x63'))
self.assertEqual(der[1],b('\x12\x00'))
def testErrDecode1(self):
# Not a sequence
der = DerSequence()
self.assertRaises(ValueError, der.decode, b(''))
self.assertRaises(ValueError, der.decode, b('\x00'))
self.assertRaises(ValueError, der.decode, b('\x30'))
def testErrDecode2(self):
# Wrong payload type
der = DerSequence()
self.assertRaises(ValueError, der.decode, b('\x30\x00\x00'), True)
def testErrDecode3(self):
# Wrong length format
der = DerSequence()
self.assertRaises(ValueError, der.decode, b('\x30\x04\x02\x01\x01\x00'))
self.assertRaises(ValueError, der.decode, b('\x30\x81\x03\x02\x01\x01'))
self.assertRaises(ValueError, der.decode, b('\x30\x04\x02\x81\x01\x01'))
def testErrDecode4(self):
# Wrong integer format
der = DerSequence()
# Multi-byte encoding for zero
#self.assertRaises(ValueError, der.decode, '\x30\x04\x02\x02\x00\x00')
# Negative integer
self.assertRaises(ValueError, der.decode, b('\x30\x04\x02\x01\xFF'))
def get_tests(config={}):
from Crypto.SelfTest.st_common import list_test_cases
listTests = []
listTests += list_test_cases(DerObjectTests)
listTests += list_test_cases(DerSequenceTests)
return listTests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,295 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Util/test_number.py: Self-test for parts of the Crypto.Util.number module
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-tests for (some of) Crypto.Util.number"""
__revision__ = "$Id$"
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
import unittest
# NB: In some places, we compare tuples instead of just output values so that
# if any inputs cause a test failure, we'll be able to tell which ones.
class MiscTests(unittest.TestCase):
def setUp(self):
global number, math
from Crypto.Util import number
import math
def test_ceil_shift(self):
"""Util.number.ceil_shift"""
self.assertRaises(AssertionError, number.ceil_shift, -1, 1)
self.assertRaises(AssertionError, number.ceil_shift, 1, -1)
# b = 0
self.assertEqual(0, number.ceil_shift(0, 0))
self.assertEqual(1, number.ceil_shift(1, 0))
self.assertEqual(2, number.ceil_shift(2, 0))
self.assertEqual(3, number.ceil_shift(3, 0))
# b = 1
self.assertEqual(0, number.ceil_shift(0, 1))
self.assertEqual(1, number.ceil_shift(1, 1))
self.assertEqual(1, number.ceil_shift(2, 1))
self.assertEqual(2, number.ceil_shift(3, 1))
# b = 2
self.assertEqual(0, number.ceil_shift(0, 2))
self.assertEqual(1, number.ceil_shift(1, 2))
self.assertEqual(1, number.ceil_shift(2, 2))
self.assertEqual(1, number.ceil_shift(3, 2))
self.assertEqual(1, number.ceil_shift(4, 2))
self.assertEqual(2, number.ceil_shift(5, 2))
self.assertEqual(2, number.ceil_shift(6, 2))
self.assertEqual(2, number.ceil_shift(7, 2))
self.assertEqual(2, number.ceil_shift(8, 2))
self.assertEqual(3, number.ceil_shift(9, 2))
for b in range(3, 1+129, 3): # 3, 6, ... , 129
self.assertEqual(0, number.ceil_shift(0, b))
n = 1
while n <= 2**(b+2):
(q, r) = divmod(n-1, 2**b)
expected = q + int(not not r)
self.assertEqual((n-1, b, expected),
(n-1, b, number.ceil_shift(n-1, b)))
(q, r) = divmod(n, 2**b)
expected = q + int(not not r)
self.assertEqual((n, b, expected),
(n, b, number.ceil_shift(n, b)))
(q, r) = divmod(n+1, 2**b)
expected = q + int(not not r)
self.assertEqual((n+1, b, expected),
(n+1, b, number.ceil_shift(n+1, b)))
n *= 2
def test_ceil_div(self):
"""Util.number.ceil_div"""
self.assertRaises(TypeError, number.ceil_div, "1", 1)
self.assertRaises(ZeroDivisionError, number.ceil_div, 1, 0)
self.assertRaises(ZeroDivisionError, number.ceil_div, -1, 0)
# b = -1
self.assertEqual(0, number.ceil_div(0, -1))
self.assertEqual(-1, number.ceil_div(1, -1))
self.assertEqual(-2, number.ceil_div(2, -1))
self.assertEqual(-3, number.ceil_div(3, -1))
# b = 1
self.assertEqual(0, number.ceil_div(0, 1))
self.assertEqual(1, number.ceil_div(1, 1))
self.assertEqual(2, number.ceil_div(2, 1))
self.assertEqual(3, number.ceil_div(3, 1))
# b = 2
self.assertEqual(0, number.ceil_div(0, 2))
self.assertEqual(1, number.ceil_div(1, 2))
self.assertEqual(1, number.ceil_div(2, 2))
self.assertEqual(2, number.ceil_div(3, 2))
self.assertEqual(2, number.ceil_div(4, 2))
self.assertEqual(3, number.ceil_div(5, 2))
# b = 3
self.assertEqual(0, number.ceil_div(0, 3))
self.assertEqual(1, number.ceil_div(1, 3))
self.assertEqual(1, number.ceil_div(2, 3))
self.assertEqual(1, number.ceil_div(3, 3))
self.assertEqual(2, number.ceil_div(4, 3))
self.assertEqual(2, number.ceil_div(5, 3))
self.assertEqual(2, number.ceil_div(6, 3))
self.assertEqual(3, number.ceil_div(7, 3))
# b = 4
self.assertEqual(0, number.ceil_div(0, 4))
self.assertEqual(1, number.ceil_div(1, 4))
self.assertEqual(1, number.ceil_div(2, 4))
self.assertEqual(1, number.ceil_div(3, 4))
self.assertEqual(1, number.ceil_div(4, 4))
self.assertEqual(2, number.ceil_div(5, 4))
self.assertEqual(2, number.ceil_div(6, 4))
self.assertEqual(2, number.ceil_div(7, 4))
self.assertEqual(2, number.ceil_div(8, 4))
self.assertEqual(3, number.ceil_div(9, 4))
# b = -4
self.assertEqual(3, number.ceil_div(-9, -4))
self.assertEqual(2, number.ceil_div(-8, -4))
self.assertEqual(2, number.ceil_div(-7, -4))
self.assertEqual(2, number.ceil_div(-6, -4))
self.assertEqual(2, number.ceil_div(-5, -4))
self.assertEqual(1, number.ceil_div(-4, -4))
self.assertEqual(1, number.ceil_div(-3, -4))
self.assertEqual(1, number.ceil_div(-2, -4))
self.assertEqual(1, number.ceil_div(-1, -4))
self.assertEqual(0, number.ceil_div(0, -4))
self.assertEqual(0, number.ceil_div(1, -4))
self.assertEqual(0, number.ceil_div(2, -4))
self.assertEqual(0, number.ceil_div(3, -4))
self.assertEqual(-1, number.ceil_div(4, -4))
self.assertEqual(-1, number.ceil_div(5, -4))
self.assertEqual(-1, number.ceil_div(6, -4))
self.assertEqual(-1, number.ceil_div(7, -4))
self.assertEqual(-2, number.ceil_div(8, -4))
self.assertEqual(-2, number.ceil_div(9, -4))
def test_exact_log2(self):
"""Util.number.exact_log2"""
self.assertRaises(TypeError, number.exact_log2, "0")
self.assertRaises(ValueError, number.exact_log2, -1)
self.assertRaises(ValueError, number.exact_log2, 0)
self.assertEqual(0, number.exact_log2(1))
self.assertEqual(1, number.exact_log2(2))
self.assertRaises(ValueError, number.exact_log2, 3)
self.assertEqual(2, number.exact_log2(4))
self.assertRaises(ValueError, number.exact_log2, 5)
self.assertRaises(ValueError, number.exact_log2, 6)
self.assertRaises(ValueError, number.exact_log2, 7)
e = 3
n = 8
while e < 16:
if n == 2**e:
self.assertEqual(e, number.exact_log2(n), "expected=2**%d, n=%d" % (e, n))
e += 1
else:
self.assertRaises(ValueError, number.exact_log2, n)
n += 1
for e in range(16, 1+64, 2):
self.assertRaises(ValueError, number.exact_log2, 2**e-1)
self.assertEqual(e, number.exact_log2(2**e))
self.assertRaises(ValueError, number.exact_log2, 2**e+1)
def test_exact_div(self):
"""Util.number.exact_div"""
# Positive numbers
self.assertEqual(1, number.exact_div(1, 1))
self.assertRaises(ValueError, number.exact_div, 1, 2)
self.assertEqual(1, number.exact_div(2, 2))
self.assertRaises(ValueError, number.exact_div, 3, 2)
self.assertEqual(2, number.exact_div(4, 2))
# Negative numbers
self.assertEqual(-1, number.exact_div(-1, 1))
self.assertEqual(-1, number.exact_div(1, -1))
self.assertRaises(ValueError, number.exact_div, -1, 2)
self.assertEqual(1, number.exact_div(-2, -2))
self.assertEqual(-2, number.exact_div(-4, 2))
# Zero dividend
self.assertEqual(0, number.exact_div(0, 1))
self.assertEqual(0, number.exact_div(0, 2))
# Zero divisor (allow_divzero == False)
self.assertRaises(ZeroDivisionError, number.exact_div, 0, 0)
self.assertRaises(ZeroDivisionError, number.exact_div, 1, 0)
# Zero divisor (allow_divzero == True)
self.assertEqual(0, number.exact_div(0, 0, allow_divzero=True))
self.assertRaises(ValueError, number.exact_div, 1, 0, allow_divzero=True)
def test_floor_div(self):
"""Util.number.floor_div"""
self.assertRaises(TypeError, number.floor_div, "1", 1)
for a in range(-10, 10):
for b in range(-10, 10):
if b == 0:
self.assertRaises(ZeroDivisionError, number.floor_div, a, b)
else:
self.assertEqual((a, b, int(math.floor(float(a) / b))),
(a, b, number.floor_div(a, b)))
def test_getStrongPrime(self):
"""Util.number.getStrongPrime"""
self.assertRaises(ValueError, number.getStrongPrime, 256)
self.assertRaises(ValueError, number.getStrongPrime, 513)
bits = 512
x = number.getStrongPrime(bits)
self.assertNotEqual(x % 2, 0)
self.assertEqual(x > (1 << bits-1)-1, 1)
self.assertEqual(x < (1 << bits), 1)
e = 2**16+1
x = number.getStrongPrime(bits, e)
self.assertEqual(number.GCD(x-1, e), 1)
self.assertNotEqual(x % 2, 0)
self.assertEqual(x > (1 << bits-1)-1, 1)
self.assertEqual(x < (1 << bits), 1)
e = 2**16+2
x = number.getStrongPrime(bits, e)
self.assertEqual(number.GCD((x-1)>>1, e), 1)
self.assertNotEqual(x % 2, 0)
self.assertEqual(x > (1 << bits-1)-1, 1)
self.assertEqual(x < (1 << bits), 1)
def test_isPrime(self):
"""Util.number.isPrime"""
self.assertEqual(number.isPrime(-3), False) # Regression test: negative numbers should not be prime
self.assertEqual(number.isPrime(-2), False) # Regression test: negative numbers should not be prime
self.assertEqual(number.isPrime(1), False) # Regression test: isPrime(1) caused some versions of PyCrypto to crash.
self.assertEqual(number.isPrime(2), True)
self.assertEqual(number.isPrime(3), True)
self.assertEqual(number.isPrime(4), False)
self.assertEqual(number.isPrime(2**1279-1), True)
self.assertEqual(number.isPrime(-(2**1279-1)), False) # Regression test: negative numbers should not be prime
# test some known gmp pseudo-primes taken from
# http://www.trnicely.net/misc/mpzspsp.html
for composite in (43 * 127 * 211, 61 * 151 * 211, 15259 * 30517,
346141 * 692281, 1007119 * 2014237, 3589477 * 7178953,
4859419 * 9718837, 2730439 * 5460877,
245127919 * 490255837, 963939391 * 1927878781,
4186358431 * 8372716861, 1576820467 * 3153640933):
self.assertEqual(number.isPrime(int(composite)), False)
def test_size(self):
self.assertEqual(number.size(2),2)
self.assertEqual(number.size(3),2)
self.assertEqual(number.size(0xa2),8)
self.assertEqual(number.size(0xa2ba40),8*3)
self.assertEqual(number.size(0xa2ba40ee07e3b2bd2f02ce227f36a195024486e49c19cb41bbbdfbba98b22b0e577c2eeaffa20d883a76e65e394c69d4b3c05a1e8fadda27edb2a42bc000fe888b9b32c22d15add0cd76b3e7936e19955b220dd17d4ea904b1ec102b2e4de7751222aa99151024c7cb41cc5ea21d00eeb41f7c800834d2c6e06bce3bce7ea9a5), 1024)
def test_negative_number_roundtrip_mpzToLongObj_longObjToMPZ(self):
"""Test that mpzToLongObj and longObjToMPZ (internal functions) roundtrip negative numbers correctly."""
n = -100000000000000000000000000000000000
e = 2
k = number._fastmath.rsa_construct(n, e)
self.assertEqual(n, k.n)
self.assertEqual(e, k.e)
def get_tests(config={}):
from Crypto.SelfTest.st_common import list_test_cases
return list_test_cases(MiscTests)
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
#
# SelfTest/Util/test_winrandom.py: Self-test for the winrandom module
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self-test suite for Crypto.Util.winrandom"""
__revision__ = "$Id$"
import unittest
class WinRandomImportTest(unittest.TestCase):
def runTest(self):
"""winrandom: simple test"""
# Import the winrandom module and try to use it
from Crypto.Util import winrandom
randobj = winrandom.new()
x = randobj.get_bytes(16)
y = randobj.get_bytes(16)
self.assertNotEqual(x, y)
def get_tests(config={}):
return [WinRandomImportTest()]
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
#
# SelfTest/__init__.py: Self-test for PyCrypto
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Self tests
These tests should perform quickly and can ideally be used every time an
application runs.
"""
__revision__ = "$Id$"
import sys
import unittest
from io import StringIO
class SelfTestError(Exception):
def __init__(self, message, result):
Exception.__init__(self, message, result)
self.message = message
self.result = result
def run(module=None, verbosity=0, stream=None, tests=None, config=None, **kwargs):
"""Execute self-tests.
This raises SelfTestError if any test is unsuccessful.
You may optionally pass in a sub-module of SelfTest if you only want to
perform some of the tests. For example, the following would test only the
hash modules:
Crypto.SelfTest.run(Crypto.SelfTest.Hash)
"""
if config is None:
config = {}
suite = unittest.TestSuite()
if module is None:
if tests is None:
tests = get_tests(config=config)
suite.addTests(tests)
else:
if tests is None:
suite.addTests(module.get_tests(config=config))
else:
raise ValueError("'module' and 'tests' arguments are mutually exclusive")
if stream is None:
kwargs['stream'] = StringIO()
runner = unittest.TextTestRunner(verbosity=verbosity, **kwargs)
result = runner.run(suite)
if not result.wasSuccessful():
if stream is None:
sys.stderr.write(stream.getvalue())
raise SelfTestError("Self-test failed", result)
return result
def get_tests(config={}):
tests = []
from Crypto.SelfTest import Cipher; tests += Cipher.get_tests(config=config)
from Crypto.SelfTest import Hash; tests += Hash.get_tests(config=config)
from Crypto.SelfTest import Protocol; tests += Protocol.get_tests(config=config)
from Crypto.SelfTest import PublicKey; tests += PublicKey.get_tests(config=config)
from Crypto.SelfTest import Random; tests += Random.get_tests(config=config)
from Crypto.SelfTest import Util; tests += Util.get_tests(config=config)
from Crypto.SelfTest import Signature; tests += Signature.get_tests(config=config)
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
#
# SelfTest/st_common.py: Common functions for SelfTest modules
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Common functions for SelfTest modules"""
__revision__ = "$Id$"
import unittest
import binascii
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
from Crypto.Util.py3compat import *
class _list_testloader(unittest.TestLoader):
suiteClass = list
def list_test_cases(class_):
"""Return a list of TestCase instances given a TestCase class
This is useful when you have defined test* methods on your TestCase class.
"""
return _list_testloader().loadTestsFromTestCase(class_)
def strip_whitespace(s):
"""Remove whitespace from a text or byte string"""
if isinstance(s,str):
return b("".join(s.split()))
else:
return b("").join(s.split())
def a2b_hex(s):
"""Convert hexadecimal to binary, ignoring whitespace"""
return binascii.a2b_hex(strip_whitespace(s))
def b2a_hex(s):
"""Convert binary to hexadecimal"""
# For completeness
return binascii.b2a_hex(s)
# vim:set ts=4 sw=4 sts=4 expandtab: