Apple M5 Pro, CLI benchmark: 24.0 -> 43.2 MH/s. Kernel output is
unchanged and bit-exact against the CPU reference.
Field arithmetic:
- Deferred-carry additions (Acc): the external layer and the internal
row sum accumulate unreduced with a carry counter and fold once per
output instead of two epsilon corrections per add.
- gf64_mul_add folds the row sum into the 128-bit product before a
single plain reduction.
- mul_wide / gf64_sqr assemble the 128-bit product from 32-bit-valued
partial sums with no carry compares.
Kernel structure (code size dominates on Apple's compiler; every
unrolled variant measured slower):
- One loop drives all 30 rounds so each layer is emitted once, with
round constants added by the linear layer preceding each S-box
(RC_EXT table, RC_INTERNAL padded with a trailing zero).
- One S-box site with a runtime lane count (12 external, 1 internal).
- mining_main runs pad / first squeeze / second squeeze through a
single inlined permute64 call in a phase loop.
Measured and rejected: uniform buffers and unhoisted loads, workgroup
sizes 64/128/512, 8-add MDS, one-compare reduce, fully unrolled
layers, two nonces per thread.