# @file hashlib_pki.py
# @version 1.1.0 (2026-02-15T08:23Z)
# @author David Ireland <https://di-mgt.com.au/contact>
# @copyright 2023-26 DI Management Services Pty Ltd
# @license Apache-2.0
"""SHA-2/SHAKE functions using cryptosyspki.
An alternative to hashlib_pure.py.
"""
# All values passed are hex-encoded
import cryptosyspki as pki
""" ``pip install cryptosyspki``
Requires CryptoSysPKI to be installed on your system.
Available from <https://cryptosys.net/pki/>
"""
def SHA256(hexval):
return pki.Hash.hex_from_hex(hexval, pki.Hash.Alg.SHA256)
def SHA512(hexval):
return pki.Hash.hex_from_hex(hexval, pki.Hash.Alg.SHA512)
def HMAC_SHA256(keyhex, msghex):
return pki.Hmac.hex_from_hex(msghex, keyhex, pki.Hmac.Alg.SHA256)
def MGF1_SHA256(msghex, mlen):
return pki.Cnv.tohex(pki.Xof.bytes(mlen, pki.Cnv.fromhex(msghex),
pki.Xof.Alg.MGF1_SHA256)).lower()
def HMAC_SHA512(keyhex, msghex):
return pki.Hmac.hex_from_hex(msghex, keyhex, pki.Hmac.Alg.SHA512)
def MGF1_SHA512(msghex, mlen):
return pki.Cnv.tohex(pki.Xof.bytes(mlen, pki.Cnv.fromhex(msghex),
pki.Xof.Alg.MGF1_SHA512)).lower()
def SHAKE256(msghex, mlen):
return pki.Cnv.tohex(pki.Xof.bytes(mlen, pki.Cnv.fromhex(msghex),
pki.Xof.Alg.SHAKE256)).lower()
def SHAKE128_256(msghex):
"""SHAKE128-256 fixed output 32 bytes."""
return pki.Cnv.tohex(pki.Xof.bytes(32, pki.Cnv.fromhex(msghex),
pki.Xof.Alg.SHAKE128)).lower()
if __name__ == '__main__':
# Basic SHA256 with hex-encoded input
h = SHA256('616263') # 'abc' in hex
print(h)
# ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
assert (h == "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")
h = SHA256('') # hash of empty string
print(h)
# e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
assert (h == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
# SHA512
h = SHA512('616263') # 'abc' in hex
print(h)
# ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
assert (h == "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f")
h = SHA512('') # hash of empty string
print(h)
# cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
assert (h == "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
# HMAC with hex-encoded input RFC 4231
h = HMAC_SHA256("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "4869205468657265")
print(h)
# b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7
assert (h == "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7")
h = HMAC_SHA512("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "4869205468657265")
print(h)
# 87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854
assert (h == "87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854")
# MGF1_SHA256
h = MGF1_SHA256('3b5c056af3ebba70d4c805380420585562b32410a778f558ff951252407647e3', 34)
print(h)
# 5b7eb772aecf04c74af07d9d9c1c1f8d3a90dcda00d5bab1dc28daecdc86eb87611e
assert (h == "5b7eb772aecf04c74af07d9d9c1c1f8d3a90dcda00d5bab1dc28daecdc86eb87611e")
h = MGF1_SHA256('', 16) # empty string
print(h)
# df3f619804a92fdb4057192dc43dd748
assert (h == "df3f619804a92fdb4057192dc43dd748")
# MGF1_SHA512
h = MGF1_SHA512('', 32)
print(h)
# ec2d57691d9b2d40182ac565032054b7d784ba96b18bcb5be0bb4e70e3fb041e
assert (h == "ec2d57691d9b2d40182ac565032054b7d784ba96b18bcb5be0bb4e70e3fb041e")