aHash 0.8.12 (AES path): lane-tied echoes, few-way multicollisions
The post's 424-byte pair E is a two-S-box "lane echo" in one AES lane: a one-byte difference from the tail is cancelled by an InvMixColumns column in the first loop block (difference-table entry 4/256), and a second injection four blocks later is cancelled the same way. This package places the same echo in all four AES lanes of a 448-byte message and lets each lane independently take the M or M' bytes of the pattern: 2^4 = 16 messages.
Generator (build_tie in ahash_mc.c, and
build_tie in native-crate-check/src/main.rs):
448 zero bytes; for lane j = 0..3 with choice bit c_j, at offset o = 16j
+ 8:
m[384 + o] = {0x03, 0x08}[c_j] (tail injection)
m[o .. o+3] = {7c067e7b, 81088180}[c_j] (block 0 column)
m[256 + o] = {0x08, 0x03}[c_j] (block 4 injection)
m[320 + o .. o+3] = {80088280, 7d067d7b}[c_j] (block 5 column)
Key model: four independent uniform RandomState words
(with_seeds(a, b, c, d)), byte slices hashed with
hash_one(&[u8]) (length, then bytes).
Results
| event | this transcription, 2^31 keys (x86 AES-NI) | native crate 0.8.12, 2^30 keys (x86, target-feature aes) |
|---|---|---|
| one echo (slot 0 pair) | 484,058 = 2^-12.115 | 242,644 = 2^-12.112 |
| echoes in lanes 0 and 2 together (4-way set {0,1,4,5}) | 446,660 = 2^-12.231 | 224,041 = 2^-12.227 |
| echoes in lanes 1 and 3 together (4-way set {0,2,8,10}) | 446,245 = 2^-12.233 | 222,952 = 2^-12.234 |
| echoes in lanes 0 and 1 together | 120 = 2^-24.09 | - |
| all 16 messages equal | 104 = 2^-24.30 [2^-24.59, 2^-24.02] | 47 = 2^-24.45 |
Lanes 0 and 2 succeed under one key condition (joint rate 2^-12.23, almost the single-echo rate), and so do lanes 1 and 3; the two groups are independent. So 4 messages collide for about 2^-12.2 of keys and 16 for about 2^-24.3. Longer messages would allow more independent groups (4^r messages at about 2^-12.3 r); only r <= 2 is measured here.
Witness (16-way): internal key words
9644eff90e6144b3 7c41347a2bb5039f 3c026049b1eee2d8 38f6b49792da5af9,
i.e.
RandomState::with_seeds(0xd36cce1f36b157c4, 0xc21552b51f5c0ff3, 0xfcae49fe7892b205, 0x07726122279d53ee):
all 16 messages hash to 0x5593e3264efc6b5b (transcription and native
crate agree). Members 0 and 15 in memory order are printed in
logs/native_crate_2p26.txt.
Build and run
cc -O2 -std=c11 -maes -pthread ahash_mc.c -o ahash_mc -lm # arm64: -march=armv8-a+crypto
./ahash_mc tie 31 8 0x77ad # checks 0x3BF4383B and pair E, then the 16-message family
./ahash_mc pairE 32 8 0x77ac # pair E: 970,320 / 2^32 = 2^-12.112
cd native-crate-check
RUSTFLAGS="-C target-feature=+aes,+sse2,+ssse3" cargo build --release
./target/release/ahcheck 30 # x86-64 only: aHash 0.8.12 uses AES on ARM only with nightly-arm-aes
Expected output is in logs/.