Subversion Repositories pub

Compare Revisions

Ignore whitespace Rev 167 → Rev 168

/relevation/branches/1.1-PyCryptoPlus/python-cryptoplus/src/CryptoPlus/SelfTest/Cipher/common.py
0,0 → 1,189
# -*- coding: utf-8 -*-
#
# SelfTest/Hash/common.py: Common code for CryptoPlus.SelfTest.Hash
#
# =======================================================================
# Copyright (C) 2008 Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# =======================================================================
#
 
"""Self-testing for PyCryptoPlus hash modules"""
 
__revision__ = "$Id$"
 
import sys
import unittest
from binascii import a2b_hex, b2a_hex
 
# 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 = __builtins__['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 = _extract(params, 'key')
self.plaintext = _extract(params, 'plaintext')
self.ciphertext = _extract(params, 'ciphertext')
 
mode = _extract(params, 'mode', None)
if mode is not None:
# Block cipher
self.mode = getattr(self.module, "MODE_" + mode)
self.iv = _extract(params, 'iv', None)
else:
# Stream cipher
self.mode = None
self.iv = None
 
self.extra_params = params
 
def shortDescription(self):
return self.description
 
def _new(self):
if self.mode is None:
# Stream cipher
return self.module.new(a2b_hex(self.key), **self.extra_params)
elif self.iv is None:
# Block cipher without iv
return self.module.new(a2b_hex(self.key), self.mode, **self.extra_params)
else:
# Block cipher with iv
return self.module.new(a2b_hex(self.key), self.mode, a2b_hex(self.iv), **self.extra_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().decrypt(ciphertext))
ct2 = b2a_hex(self._new().encrypt(plaintext))
pt2 = b2a_hex(self._new().decrypt(ciphertext))
 
self.assertEqual(self.ciphertext, ct1)
self.assertEqual(self.ciphertext, ct2)
self.assertEqual(self.plaintext, pt1)
self.assertEqual(self.plaintext, pt2)
 
def make_block_tests(module, module_name, test_data):
tests = []
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
 
# Add the test to the test suite
tests.append(CipherSelfTest(module, params))
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
 
# Add the test to the test suite
tests.append(CipherSelfTest(module, params))
return tests
 
# vim:set ts=4 sw=4 sts=4 expandtab: