# @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")