aboutsummaryrefslogtreecommitdiff
path: root/examples/05-python
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2023-09-17 11:21:47 -0400
committerPaul Duncan <pabs@pablotron.org>2023-09-17 11:21:47 -0400
commitc6cbe4eb859162e527998ded07db959feb13584c (patch)
tree9fecf59353b3cb59a8fa6cdb83bf18bf09d176b1 /examples/05-python
parent75b6d96e139c65ba457120d04767a3fc1b948372 (diff)
downloadsha3-c6cbe4eb859162e527998ded07db959feb13584c.tar.bz2
sha3-c6cbe4eb859162e527998ded07db959feb13584c.zip
add examples/05-python
Diffstat (limited to 'examples/05-python')
-rw-r--r--examples/05-python/README.md4
-rw-r--r--examples/05-python/sha3.py156
2 files changed, 160 insertions, 0 deletions
diff --git a/examples/05-python/README.md b/examples/05-python/README.md
new file mode 100644
index 0000000..1da638c
--- /dev/null
+++ b/examples/05-python/README.md
@@ -0,0 +1,4 @@
+# sha3.py
+
+Access `libsha3.so` functions via Python ctypes module and compare
+libsha3.so output against hashlib output.
diff --git a/examples/05-python/sha3.py b/examples/05-python/sha3.py
new file mode 100644
index 0000000..bd0e11b
--- /dev/null
+++ b/examples/05-python/sha3.py
@@ -0,0 +1,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)