update windows build to Python 3.7
This commit is contained in:
parent
73105fa71e
commit
ddc59ab92d
5761 changed files with 750298 additions and 213405 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,399 +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:
|
||||
# -*- 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
|
|
@ -1,124 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,81 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,113 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,57 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,339 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,333 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,72 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,174 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,372 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,197 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,223 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,64 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,64 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,64 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,73 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,64 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,65 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,96 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,63 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,60 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,98 +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
|
||||
# -*- 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
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,210 +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')
|
||||
|
||||
# -*- 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')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,415 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,345 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,189 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,171 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,171 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,40 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,219 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,446 +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
|
||||
# -*- 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
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,165 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,293 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,295 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
|
|
@ -1,92 +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:
|
||||
# -*- 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:
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue