|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"""Self-test suite for Crypto.Hash.keccak""" |
|
|
|
|
|
import unittest |
|
|
from binascii import hexlify, unhexlify |
|
|
|
|
|
from Crypto.SelfTest.loader import load_test_vectors |
|
|
from Crypto.SelfTest.st_common import list_test_cases |
|
|
|
|
|
from Crypto.Hash import keccak |
|
|
from Crypto.Util.py3compat import b, tobytes, bchr |
|
|
|
|
|
class KeccakTest(unittest.TestCase): |
|
|
|
|
|
def test_new_positive(self): |
|
|
|
|
|
for digest_bits in (224, 256, 384, 512): |
|
|
hobj = keccak.new(digest_bits=digest_bits) |
|
|
self.assertEqual(hobj.digest_size, digest_bits // 8) |
|
|
|
|
|
hobj2 = hobj.new() |
|
|
self.assertEqual(hobj2.digest_size, digest_bits // 8) |
|
|
|
|
|
for digest_bytes in (28, 32, 48, 64): |
|
|
hobj = keccak.new(digest_bytes=digest_bytes) |
|
|
self.assertEqual(hobj.digest_size, digest_bytes) |
|
|
|
|
|
hobj2 = hobj.new() |
|
|
self.assertEqual(hobj2.digest_size, digest_bytes) |
|
|
|
|
|
def test_new_positive2(self): |
|
|
|
|
|
digest1 = keccak.new(data=b("\x90"), digest_bytes=64).digest() |
|
|
digest2 = keccak.new(digest_bytes=64).update(b("\x90")).digest() |
|
|
self.assertEqual(digest1, digest2) |
|
|
|
|
|
def test_new_negative(self): |
|
|
|
|
|
|
|
|
self.assertRaises(TypeError, keccak.new) |
|
|
|
|
|
h = keccak.new(digest_bits=512) |
|
|
|
|
|
|
|
|
self.assertRaises(TypeError, keccak.new, |
|
|
digest_bytes=64, |
|
|
digest_bits=512) |
|
|
|
|
|
|
|
|
self.assertRaises(ValueError, keccak.new, digest_bytes=0) |
|
|
self.assertRaises(ValueError, keccak.new, digest_bytes=1) |
|
|
self.assertRaises(ValueError, keccak.new, digest_bytes=65) |
|
|
self.assertRaises(ValueError, keccak.new, digest_bits=0) |
|
|
self.assertRaises(ValueError, keccak.new, digest_bits=1) |
|
|
self.assertRaises(ValueError, keccak.new, digest_bits=513) |
|
|
|
|
|
def test_update(self): |
|
|
pieces = [bchr(10) * 200, bchr(20) * 300] |
|
|
h = keccak.new(digest_bytes=64) |
|
|
h.update(pieces[0]).update(pieces[1]) |
|
|
digest = h.digest() |
|
|
h = keccak.new(digest_bytes=64) |
|
|
h.update(pieces[0] + pieces[1]) |
|
|
self.assertEqual(h.digest(), digest) |
|
|
|
|
|
def test_update_negative(self): |
|
|
h = keccak.new(digest_bytes=64) |
|
|
self.assertRaises(TypeError, h.update, u"string") |
|
|
|
|
|
def test_digest(self): |
|
|
h = keccak.new(digest_bytes=64) |
|
|
digest = h.digest() |
|
|
|
|
|
|
|
|
self.assertEqual(h.digest(), digest) |
|
|
|
|
|
self.assertTrue(isinstance(digest, type(b("digest")))) |
|
|
|
|
|
def test_hex_digest(self): |
|
|
mac = keccak.new(digest_bits=512) |
|
|
digest = mac.digest() |
|
|
hexdigest = mac.hexdigest() |
|
|
|
|
|
|
|
|
self.assertEqual(hexlify(digest), tobytes(hexdigest)) |
|
|
|
|
|
self.assertEqual(mac.hexdigest(), hexdigest) |
|
|
|
|
|
self.assertTrue(isinstance(hexdigest, type("digest"))) |
|
|
|
|
|
def test_update_after_digest(self): |
|
|
msg=b("rrrrttt") |
|
|
|
|
|
|
|
|
h = keccak.new(digest_bits=512, data=msg[:4]) |
|
|
dig1 = h.digest() |
|
|
self.assertRaises(TypeError, h.update, msg[4:]) |
|
|
dig2 = keccak.new(digest_bits=512, data=msg).digest() |
|
|
|
|
|
|
|
|
h = keccak.new(digest_bits=512, data=msg[:4], update_after_digest=True) |
|
|
self.assertEqual(h.digest(), dig1) |
|
|
|
|
|
|
|
|
h.update(msg[4:]) |
|
|
self.assertEqual(h.digest(), dig2) |
|
|
|
|
|
|
|
|
class KeccakVectors(unittest.TestCase): |
|
|
pass |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test_vectors_224 = load_test_vectors(("Hash", "keccak"), |
|
|
"ShortMsgKAT_224.txt", |
|
|
"Short Messages KAT 224", |
|
|
{"len": lambda x: int(x)}) or [] |
|
|
|
|
|
test_vectors_224 += load_test_vectors(("Hash", "keccak"), |
|
|
"LongMsgKAT_224.txt", |
|
|
"Long Messages KAT 224", |
|
|
{"len": lambda x: int(x)}) or [] |
|
|
|
|
|
for idx, tv in enumerate(test_vectors_224): |
|
|
if tv.len == 0: |
|
|
data = b("") |
|
|
else: |
|
|
data = tobytes(tv.msg) |
|
|
|
|
|
def new_test(self, data=data, result=tv.md): |
|
|
hobj = keccak.new(digest_bits=224, data=data) |
|
|
self.assertEqual(hobj.digest(), result) |
|
|
|
|
|
setattr(KeccakVectors, "test_224_%d" % idx, new_test) |
|
|
|
|
|
|
|
|
|
|
|
test_vectors_256 = load_test_vectors(("Hash", "keccak"), |
|
|
"ShortMsgKAT_256.txt", |
|
|
"Short Messages KAT 256", |
|
|
{ "len" : lambda x: int(x) } ) or [] |
|
|
|
|
|
test_vectors_256 += load_test_vectors(("Hash", "keccak"), |
|
|
"LongMsgKAT_256.txt", |
|
|
"Long Messages KAT 256", |
|
|
{ "len" : lambda x: int(x) } ) or [] |
|
|
|
|
|
for idx, tv in enumerate(test_vectors_256): |
|
|
if tv.len == 0: |
|
|
data = b("") |
|
|
else: |
|
|
data = tobytes(tv.msg) |
|
|
|
|
|
def new_test(self, data=data, result=tv.md): |
|
|
hobj = keccak.new(digest_bits=256, data=data) |
|
|
self.assertEqual(hobj.digest(), result) |
|
|
|
|
|
setattr(KeccakVectors, "test_256_%d" % idx, new_test) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test_vectors_384 = load_test_vectors(("Hash", "keccak"), |
|
|
"ShortMsgKAT_384.txt", |
|
|
"Short Messages KAT 384", |
|
|
{"len": lambda x: int(x)}) or [] |
|
|
|
|
|
test_vectors_384 += load_test_vectors(("Hash", "keccak"), |
|
|
"LongMsgKAT_384.txt", |
|
|
"Long Messages KAT 384", |
|
|
{"len": lambda x: int(x)}) or [] |
|
|
|
|
|
for idx, tv in enumerate(test_vectors_384): |
|
|
if tv.len == 0: |
|
|
data = b("") |
|
|
else: |
|
|
data = tobytes(tv.msg) |
|
|
|
|
|
def new_test(self, data=data, result=tv.md): |
|
|
hobj = keccak.new(digest_bits=384, data=data) |
|
|
self.assertEqual(hobj.digest(), result) |
|
|
|
|
|
setattr(KeccakVectors, "test_384_%d" % idx, new_test) |
|
|
|
|
|
|
|
|
|
|
|
test_vectors_512 = load_test_vectors(("Hash", "keccak"), |
|
|
"ShortMsgKAT_512.txt", |
|
|
"Short Messages KAT 512", |
|
|
{"len": lambda x: int(x)}) or [] |
|
|
|
|
|
test_vectors_512 += load_test_vectors(("Hash", "keccak"), |
|
|
"LongMsgKAT_512.txt", |
|
|
"Long Messages KAT 512", |
|
|
{"len": lambda x: int(x)}) or [] |
|
|
|
|
|
for idx, tv in enumerate(test_vectors_512): |
|
|
if tv.len == 0: |
|
|
data = b("") |
|
|
else: |
|
|
data = tobytes(tv.msg) |
|
|
|
|
|
def new_test(self, data=data, result=tv.md): |
|
|
hobj = keccak.new(digest_bits=512, data=data) |
|
|
self.assertEqual(hobj.digest(), result) |
|
|
|
|
|
setattr(KeccakVectors, "test_512_%d" % idx, new_test) |
|
|
|
|
|
|
|
|
def get_tests(config={}): |
|
|
tests = [] |
|
|
tests += list_test_cases(KeccakTest) |
|
|
tests += list_test_cases(KeccakVectors) |
|
|
return tests |
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
import unittest |
|
|
suite = lambda: unittest.TestSuite(get_tests()) |
|
|
unittest.main(defaultTest='suite') |
|
|
|