# @file message_to_indices.py (2023-03-16T14:29Z)
# @author David Ireland <www.di-mgt.com.au/contact>
# @copyright 2023 DI Management Services Pty Ltd
# @license Apache-2.0
"""Interpret 25-byte mhash as 33 * 6-bit unsigned integers."""
SPX_FORS_TREES = 33
SPX_FORS_HEIGHT = 6
DEBUG = False
DPRINT = print if DEBUG else lambda *a, **k: None
indices = [0] * SPX_FORS_TREES
m = bytes.fromhex('5b7eb772aecf04c74af07d9d9c1c1f8d3a90dcda00d5bab1dc')
print(f"mhash={m.hex()}")
offset = 0
for i in range(SPX_FORS_TREES):
DPRINT("i =", i)
indices[i] = 0
for j in range(SPX_FORS_HEIGHT):
DPRINT(
f" j={j}, offset={offset:2d}, offset>>3={offset>>3}, \
m[offset >> 3]={m[offset >> 3]:#02x}, \
shift={offset & 0x7} \
bit={((m[offset >> 3] >> (offset & 0x7)) & 0x1)}"
)
indices[i] ^= ((m[offset >> 3] >> (offset & 0x7)) & 0x1) << j
offset += 1
DPRINT(f"indices[{i}]={indices[i]}")
print("message_to_indices:\n", [m for m in indices])
# EXPLANATION:
# Each byte value in mhash is interpreted in little-endian order
# > `0x5b7eb7 -> [27,57,55,45]
# Each byte as bits in big-endian order
# 0x5b 0x7e 0xb7
# 01011011 01111110 10110111
# Rewrite in little-endian order
# 11011010 01111110 11101101
# Then split left-to-right into blocks of 6
# 110110 100111 111011 101101
# And interpret these in big-endian order
# 011011 111001 110111 101101
# 27=011011 57=111001 55=110111 45=101101