1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
#!/usr/bin/env python3
#
# sha3.py: Access libsha3.so functions via Python ctypes module and
# compare libsha3.so output against hashlib output.
#
import csv, ctypes, hashlib, sys
# common function argument types
XOF_ARGS = [ctypes.c_char_p, ctypes.c_size_t, ctypes.c_char_p, ctypes.c_size_t]
HASH_ARGS = [ctypes.c_char_p, ctypes.c_size_t, ctypes.c_char_p]
# load sha3 module
sha3 = ctypes.CDLL('../../libsha3.so')
# set function argument and return types
# (note: this is not required, but it helps to prevent argument and type
# oopsies)
sha3.shake128_xof_once.argtypes = XOF_ARGS
sha3.shake128_xof_once.rettype = None
sha3.shake256_xof_once.argtypes = XOF_ARGS
sha3.shake256_xof_once.rettype = None
sha3.sha3_224.argtypes = HASH_ARGS
sha3.sha3_224.rettype = None
sha3.sha3_256.argtypes = HASH_ARGS
sha3.sha3_256.rettype = None
sha3.sha3_384.argtypes = HASH_ARGS
sha3.sha3_384.rettype = None
sha3.sha3_512.argtypes = HASH_ARGS
sha3.sha3_512.rettype = None
class Result:
"""Individual digest result"""
algo : str
source : str
digest : bytes
def __init__(self: object, algo: str, source: str, digest: bytes) -> None:
"""Create hash test result."""
self.algo = algo
self.source = source
self.digest = digest
def to_row(self: object) -> [str]:
"""Convert result to CSV row."""
return [self.algo, self.source, self.digest.hex()]
class Results:
"""Collection of digest results."""
rs : [Result]
def __init__(self: object) -> None:
self.rs = []
def append(self: object, algo: str, source: str, digest: bytes) -> None:
"""append result to self"""
self.rs.append(Result(algo, source, digest))
def write(self, io) -> None:
"""write results as CSV to given IO."""
cw = csv.writer(io) # create csv writer
cw.writerow(['algo', 'source', 'digest']) # write headers
# write rows
for r in self.rs:
cw.writerow(r.to_row())
def test_shake128_xof(rs: Results, data: bytes) -> None:
"""append SHAKE128-XOF digest of data from hashlib and libsha3 to results"""
algo = 'shake128-xof' # algorithm name
size = 32 # output size, in bytes
# append hashlib digest
rs.append(algo, 'hashlib', hashlib.shake_128(data).digest(size))
# append libsha3 digest
buf = ctypes.create_string_buffer(size)
sha3.shake128_xof_once(data, len(data), buf, size)
rs.append(algo, 'libsha3', buf.raw)
def test_shake256_xof(rs: Results, data: bytes) -> None:
"""append SHAKE256-XOF digest of data from hashlib and libsha3 to results"""
algo = 'shake256-xof' # algorithm name
size = 32 # output size, in bytes
# append hashlib digest
rs.append(algo, 'hashlib', hashlib.shake_256(data).digest(size))
# append libsha3 digest
buf = ctypes.create_string_buffer(size)
sha3.shake256_xof_once(data, len(data), buf, size)
rs.append(algo, 'libsha3', buf.raw)
def test_sha3_224(rs: Results, data: bytes) -> None:
"""append SHA3-224 digest of data from hashlib and libsha3 to results"""
algo = 'sha3-224' # algorithm name
# append hashlib digest
rs.append(algo, 'hashlib', hashlib.sha3_224(data).digest())
# append libsha3 digest
buf = ctypes.create_string_buffer(28)
sha3.sha3_224(data, len(data), buf)
rs.append(algo, 'libsha3', buf.raw)
def test_sha3_256(rs: Results, data: bytes) -> None:
"""append SHA3-256 digest of data from hashlib and libsha3 to results"""
algo = 'sha3-256' # algorithm name
# append hashlib digest
rs.append(algo, 'hashlib', hashlib.sha3_256(data).digest())
# append libsha3 digest
buf = ctypes.create_string_buffer(32)
sha3.sha3_256(data, len(data), buf)
rs.append(algo, 'libsha3', buf.raw)
def test_sha3_384(rs: Results, data: bytes) -> None:
"""append SHA3-384 digest of data from hashlib and libsha3 to results"""
algo = 'sha3-384' # algorithm name
# append hashlib digest
rs.append(algo, 'hashlib', hashlib.sha3_384(data).digest())
# append libsha3 digest
buf = ctypes.create_string_buffer(48)
sha3.sha3_384(data, len(data), buf)
rs.append(algo, 'libsha3', buf.raw)
def test_sha3_512(rs: Results, data: bytes) -> None:
"""append SHA3-512 digest of data from hashlib and libsha3 to results"""
algo = 'sha3-512' # algorithm name
# append hashlib digest
rs.append(algo, 'hashlib', hashlib.sha3_512(data).digest())
# append libsha3 digest
buf = ctypes.create_string_buffer(64)
sha3.sha3_512(data, len(data), buf)
rs.append(algo, 'libsha3', buf.raw)
# declare test data and results
DATA = b'foo bar'
rs = Results()
# run tests, add to results
test_shake128_xof(rs, DATA)
test_shake256_xof(rs, DATA)
test_sha3_224(rs, DATA)
test_sha3_256(rs, DATA)
test_sha3_384(rs, DATA)
test_sha3_512(rs, DATA)
# print results to stdout as csv
rs.write(sys.stdout)
|