# SHA-384 Accelerator Test on ESP32
from struct import pack, unpack
from binascii import hexlify
import machine
SHA_DATA = 0x3ff03000
SHA_SHA1_START_REG = 0x3ff03080
SHA_SHA1_CONTINUE_REG = 0x3ff03084
SHA_SHA1_LOAD_REG = 0x3ff03088
SHA_SHA1_BUSY_REG = 0x3ff0308c
SHA_SHA256_START_REG = 0x3ff03090
SHA_SHA256_CONTINUE_REG = 0x3ff03094
SHA_SHA256_LOAD_REG = 0x3ff03098
SHA_SHA256_BUSY_REG = 0x3ff0309c
SHA_SHA384_START_REG = 0x3ff030a0
SHA_SHA384_CONTINUE_REG = 0x3ff030a4
SHA_SHA384_LOAD_REG = 0x3ff030a8
SHA_SHA384_BUSY_REG = 0x3ff030ac
SHA_SHA512_START_REG = 0x3ff030b0
SHA_SHA512_CONTINUE_REG = 0x3ff030b4
SHA_SHA512_LOAD_REG = 0x3ff030b8
SHA_SHA512_BUSY_REG = 0x3ff030bc
DPORT_PERI_CLK_EN_REG = 0x3ff0001C
DPORT_PERI_RST_EN_REG = 0x3ff00020
data = b"hello"
# Enable the SHA peripheral, reset it to clear the state
machine.mem32[DPORT_PERI_CLK_EN_REG] = 1 << 1
machine.mem32[DPORT_PERI_RST_EN_REG] = 1 << 1
machine.mem32[DPORT_PERI_RST_EN_REG] = 0
# Add SHA padding
block = bytearray(128)
block[:len(data)] = data
block[len(data)] = 0x80
block[127] = len(data) * 8 # Length in bits
# Load block data
for offset, value in enumerate(unpack('>32L', block)):
machine.mem32[SHA_DATA + offset * 4] = value
# Perform hash
machine.mem32[SHA_SHA384_START_REG] = 1
while machine.mem32[SHA_SHA384_BUSY_REG]:
pass
machine.mem32[SHA_SHA512_LOAD_REG] = 1
while machine.mem32[SHA_SHA512_BUSY_REG]:
pass
# Read result
result_words = [machine.mem32[SHA_DATA + offset * 4] & 0xffffffff for offset in range(12)]
result = pack('>12L', *result_words)
print("sha384({:s}) = {:s}".format(data, hexlify(result)))