AWS SigV4 is built entirely out of these two primitives, and nothing in the
Mojo ecosystem provides either: hashes.mojo covers the non-cryptographic
hashes Iceberg needs for partition transforms (murmur3, xxhash, CRC32), and no
conda-resolvable package offers SHA-2. Rather than pull OpenSSL in through a
second FFI shim — libcurl already links it, but its EVP surface is a moving
target across conda builds — this module implements FIPS 180-4 and RFC 2104
directly.
SigV4 hashes the whole payload of every signed PUT, so this is not a
negligible cost: a purely scalar compression function caps a multipart upload
at the speed of the hash. The block loop therefore has three backends, chosen
at compile time by _BACKEND:
armv8-crypto — the ARMv8 SHA-2 extension (sha256h/sha256h2/sha256su0
/sha256su1), which every Apple Silicon and every server aarch64 part has.
x86-sha-ni — Intel SHA extensions (sha256rnds2/sha256msg1
/sha256msg2), present on AMD Zen and on Intel from Goldmont/Ice Lake
client onwards, but not on Ice Lake / Sapphire Rapids Xeons.
scalar — portable FIPS 180-4, fully unrolled with a 16-word rolling
schedule so the whole working set stays in registers.
The choice is a comptime query of the target's CPU features, and mojo
compiles for the host CPU unless told otherwise, so on a normal build (pixi
source dependency, pixi run, CI) the compile-time answer is the run-time
truth. A binary deliberately cross-built with --target-cpu for a CPU it will
not run on is the one case that would fault, and that is the same contract as
every other -march=native build.
If a general-purpose home ever appears, this belongs in hashes.mojo.