| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- import unittest
- from binascii import unhexlify, hexlify
- from Crypto.Util.py3compat import tobytes
- from Crypto.SelfTest.st_common import list_test_cases
- from Crypto.Hash import TupleHash128, TupleHash256
- class TupleHashTest(unittest.TestCase):
- def new(self, *args, **kwargs):
- return self.TupleHash.new(*args, **kwargs)
- def test_new_positive(self):
- h = self.new()
- for new_func in self.TupleHash.new, h.new:
- for dbits in range(64, 1024 + 1, 8):
- hobj = new_func(digest_bits=dbits)
- self.assertEqual(hobj.digest_size * 8, dbits)
- for dbytes in range(8, 128 + 1):
- hobj = new_func(digest_bytes=dbytes)
- self.assertEqual(hobj.digest_size, dbytes)
- hobj = h.new()
- self.assertEqual(hobj.digest_size, self.default_bytes)
- def test_new_negative(self):
- h = self.new()
- for new_func in self.TupleHash.new, h.new:
- self.assertRaises(TypeError, new_func,
- digest_bytes=self.minimum_bytes,
- digest_bits=self.minimum_bits)
- self.assertRaises(ValueError, new_func, digest_bytes=0)
- self.assertRaises(ValueError, new_func,
- digest_bits=self.minimum_bits + 7)
- self.assertRaises(ValueError, new_func,
- digest_bits=self.minimum_bits - 8)
- self.assertRaises(ValueError, new_func,
- digest_bits=self.minimum_bytes - 1)
- def test_default_digest_size(self):
- digest = self.new().digest()
- self.assertEqual(len(digest), self.default_bytes)
- def test_update(self):
- h = self.new()
- h.update(b'')
- h.digest()
- h = self.new()
- h.update(b'')
- h.update(b'STRING1')
- h.update(b'STRING2')
- mac1 = h.digest()
- h = self.new()
- h.update(b'STRING1')
- h.update(b'STRING2')
- mac2 = h.digest()
- self.assertNotEqual(mac1, mac2)
- h = self.new()
- h.update(b'STRING1', b'STRING2')
- self.assertEqual(mac2, h.digest())
- h = self.new()
- t = b'STRING1', b'STRING2'
- h.update(*t)
- self.assertEqual(mac2, h.digest())
- def test_update_negative(self):
- h = self.new()
- self.assertRaises(TypeError, h.update, u"string")
- self.assertRaises(TypeError, h.update, None)
- self.assertRaises(TypeError, h.update, (b'STRING1', b'STRING2'))
- def test_digest(self):
- h = self.new()
- digest = h.digest()
- # hexdigest does not change the state
- self.assertEqual(h.digest(), digest)
- # digest returns a byte string
- self.assertTrue(isinstance(digest, type(b"digest")))
- def test_update_after_digest(self):
- msg = b"rrrrttt"
- # Normally, update() cannot be done after digest()
- h = self.new()
- h.update(msg)
- dig1 = h.digest()
- self.assertRaises(TypeError, h.update, dig1)
- def test_hex_digest(self):
- mac = self.new()
- digest = mac.digest()
- hexdigest = mac.hexdigest()
- # hexdigest is equivalent to digest
- self.assertEqual(hexlify(digest), tobytes(hexdigest))
- # hexdigest does not change the state
- self.assertEqual(mac.hexdigest(), hexdigest)
- # hexdigest returns a string
- self.assertTrue(isinstance(hexdigest, type("digest")))
- def test_bytearray(self):
- data = b"\x00\x01\x02"
- # Data can be a bytearray (during operation)
- data_ba = bytearray(data)
- h1 = self.new()
- h2 = self.new()
- h1.update(data)
- h2.update(data_ba)
- data_ba[:1] = b'\xFF'
- self.assertEqual(h1.digest(), h2.digest())
- def test_memoryview(self):
- data = b"\x00\x01\x02"
- def get_mv_ro(data):
- return memoryview(data)
- def get_mv_rw(data):
- return memoryview(bytearray(data))
- for get_mv in (get_mv_ro, get_mv_rw):
- # Data can be a memoryview (during operation)
- data_mv = get_mv(data)
- h1 = self.new()
- h2 = self.new()
- h1.update(data)
- h2.update(data_mv)
- if not data_mv.readonly:
- data_mv[:1] = b'\xFF'
- self.assertEqual(h1.digest(), h2.digest())
- class TupleHash128Test(TupleHashTest):
- TupleHash = TupleHash128
- minimum_bytes = 8
- default_bytes = 64
- minimum_bits = 64
- default_bits = 512
- class TupleHash256Test(TupleHashTest):
- TupleHash = TupleHash256
- minimum_bytes = 8
- default_bytes = 64
- minimum_bits = 64
- default_bits = 512
- class NISTExampleTestVectors(unittest.TestCase):
- # http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TupleHash_samples.pdf
- test_data = [
- (
- (
- "00 01 02",
- "10 11 12 13 14 15",
- ),
- "",
- "C5 D8 78 6C 1A FB 9B 82 11 1A B3 4B 65 B2 C0 04"
- "8F A6 4E 6D 48 E2 63 26 4C E1 70 7D 3F FC 8E D1",
- "KMAC128 Sample #1 NIST",
- TupleHash128
- ),
- (
- (
- "00 01 02",
- "10 11 12 13 14 15",
- ),
- "My Tuple App",
- "75 CD B2 0F F4 DB 11 54 E8 41 D7 58 E2 41 60 C5"
- "4B AE 86 EB 8C 13 E7 F5 F4 0E B3 55 88 E9 6D FB",
- "KMAC128 Sample #2 NIST",
- TupleHash128
- ),
- (
- (
- "00 01 02",
- "10 11 12 13 14 15",
- "20 21 22 23 24 25 26 27 28",
- ),
- "My Tuple App",
- "E6 0F 20 2C 89 A2 63 1E DA 8D 4C 58 8C A5 FD 07"
- "F3 9E 51 51 99 8D EC CF 97 3A DB 38 04 BB 6E 84",
- "KMAC128 Sample #3 NIST",
- TupleHash128
- ),
- (
- (
- "00 01 02",
- "10 11 12 13 14 15",
- ),
- "",
- "CF B7 05 8C AC A5 E6 68 F8 1A 12 A2 0A 21 95 CE"
- "97 A9 25 F1 DB A3 E7 44 9A 56 F8 22 01 EC 60 73"
- "11 AC 26 96 B1 AB 5E A2 35 2D F1 42 3B DE 7B D4"
- "BB 78 C9 AE D1 A8 53 C7 86 72 F9 EB 23 BB E1 94",
- "KMAC256 Sample #4 NIST",
- TupleHash256
- ),
- (
- (
- "00 01 02",
- "10 11 12 13 14 15",
- ),
- "My Tuple App",
- "14 7C 21 91 D5 ED 7E FD 98 DB D9 6D 7A B5 A1 16"
- "92 57 6F 5F E2 A5 06 5F 3E 33 DE 6B BA 9F 3A A1"
- "C4 E9 A0 68 A2 89 C6 1C 95 AA B3 0A EE 1E 41 0B"
- "0B 60 7D E3 62 0E 24 A4 E3 BF 98 52 A1 D4 36 7E",
- "KMAC256 Sample #5 NIST",
- TupleHash256
- ),
- (
- (
- "00 01 02",
- "10 11 12 13 14 15",
- "20 21 22 23 24 25 26 27 28",
- ),
- "My Tuple App",
- "45 00 0B E6 3F 9B 6B FD 89 F5 47 17 67 0F 69 A9"
- "BC 76 35 91 A4 F0 5C 50 D6 88 91 A7 44 BC C6 E7"
- "D6 D5 B5 E8 2C 01 8D A9 99 ED 35 B0 BB 49 C9 67"
- "8E 52 6A BD 8E 85 C1 3E D2 54 02 1D B9 E7 90 CE",
- "KMAC256 Sample #6 NIST",
- TupleHash256
- ),
- ]
- def setUp(self):
- td = []
- for tv_in in self.test_data:
- tv_out = [None] * len(tv_in)
- tv_out[0] = []
- for string in tv_in[0]:
- tv_out[0].append(unhexlify(string.replace(" ", "")))
- tv_out[1] = tobytes(tv_in[1]) # Custom
- tv_out[2] = unhexlify(tv_in[2].replace(" ", ""))
- tv_out[3] = tv_in[3]
- tv_out[4] = tv_in[4]
- td.append(tv_out)
- self.test_data = td
- def runTest(self):
- for data, custom, digest, text, module in self.test_data:
- hd1 = module.new(custom=custom, digest_bytes=len(digest))
- hd2 = module.new(custom=custom, digest_bytes=len(digest))
- # Call update() for each element
- for string in data:
- hd1.update(string)
- # One single update for all elements
- hd2.update(*data)
- self.assertEqual(hd1.digest(), digest, msg=text)
- self.assertEqual(hd2.digest(), digest, msg=text)
- def get_tests(config={}):
- tests = []
- tests += list_test_cases(TupleHash128Test)
- tests += list_test_cases(TupleHash256Test)
- tests.append(NISTExampleTestVectors())
- return tests
- if __name__ == '__main__':
- def suite():
- return unittest.TestSuite(get_tests())
- unittest.main(defaultTest='suite')
|