Implementation notes

Design

hayahash64 is structured to keep instruction-level parallelism high without giving up defined, reproducible behavior on ordinary C99 targets.

01

Short bulk dependency chain

ChibiHash v2 carries an approximately five-cycle add → multiply → xor chain per 8-byte stripe across four lanes. hayahash uses eight independent lanes over 64-byte blocks.

The loop-carried path contains nothing longer than add → multiply. Cross-lane work is deferred until the upper lanes are folded into the lower four.

t  = w + rotl(w_prev, 27)
h0 = (h0 + t) * K

K = 0x9E3779B97F4A7C15

02

Chained, injective absorb

Every lane absorbs the current 64-bit word plus a rotated copy of the previous word.

First difference
At the first stripe where two inputs differ, the previous stripes are equal. The absorb values must therefore differ. Repeating the argument makes the absorb sequence injective by induction.
Low-position copy
Odd multiplication spreads bit differences upward. Rotation puts a copy of every stripe bit at another, lower-reaching position in the next lane.
Final wall
After the loops, the last stripe’s dangling rotated copy is absorbed into h0. A difference ladder cannot simply leave the end of the input.
Rotation choice
The absorb, fold, and injection rotations were selected against difference-ladder and resonance failures found in earlier variants.

03

Derived lane state

The seed and length are premixed into one value: s = seed ^ (len * K). Each lane starts from a different rotation of s plus a shifted copy of K.

This feeds seed and length into every path, avoids large per-lane literals, and keeps overlapping tail reads distinct across input lengths.

Portability effect

Deriving constants matters on targets where materializing a full 64-bit literal costs several instructions. The implementation does not require a target-specific fast path.

04

Overlapping tail reads

Whole words are read from the end of the input, with overlap where needed. There is no byte-at-a-time loop for any length.

0–3 bytes

Sample three positions

The first, middle, and final bytes populate two input words.

4–16 bytes

Overlapping words

Head and tail reads are independently spread with different bijective three-rotation injections.

>16 bytes

Whole-word tail

Up to 31 remaining bytes are handled with full 64-bit reads and length already mixed into every lane.

Earlier failures informed the design

SMHasher3 found five structural collision classes during development. The implementation documents each failure and its corresponding change.

The authoritative rationale is maintained as comments in hayahash.h.