From 6b6f80850cf8532c06bd0b4d19fcacdc73c279e0 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 18 Jun 2024 00:59:22 +0000 Subject: [PATCH] Drop excess siphash round (see comment for more details) --- siphash.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/siphash.h b/siphash.h index f6d5fb3..cfcaad9 100644 --- a/siphash.h +++ b/siphash.h @@ -104,11 +104,23 @@ static inline uint64_t siphash(const uint64_t *in, const size_t inwords, const u v0 ^= m; } - v3 ^= b; + // Generally, here siphash writes any extra bytes that weren't an even + // multiple of eight as well as the length (in the form of `b`). Then, + // because we've written fresh attacker-controlled data into our state, we + // do an extra `cROUNDS` `SIPROUND`s. This ensures we have + // `cROUNDS` + `dROUNDS` `SIPROUND`s between any attacker-controlled data + // and the output, which for SipHash 1-3 means the four rounds required for + // good mixing. + // + // However, in our use-case the input is always a multiple of eight bytes + // and the attacker doesn't control the length. Thus, we skip the extra + // round here, giving us a very slightly tweaked SipHash 1-2 which is + // equivalent to SipHash 1-3 with a fixed input of N*8+7 bytes. + /*v3 ^= b; TRACE; for (i = 0; i < cROUNDS; ++i) - SIPROUND; + SIPROUND;*/ v0 ^= b; v2 ^= 0xff; -- 2.30.2