Why is there no overflow check in the Jenkins one-at-a-time hash function?

The one-at-a-time hash is designed to take as input a string of bytes and then output a (roughly) uniformly-distributed 32-bit value. Importantly, this means that if you want to use the hash function to distribute keys into a hash table, you’ll need to perform some secondary math to convert the 32-bit hash to a table index because the hash function itself isn’t designed to restrict its output to a smaller number of slots. So, for example, you could mod the result by the number of table slots if you wanted to use it to distribute keys.

The reasoning in the above paragraph essentially boils down to “as initially written, the hash function doesn’t make any attempt to fit into a small number of slots.” But there’s a deeper question here too: why doesn’t the hash function make any provisions for dealing with integer overflow, and why doesn’t it mod its internal values by a prime at each step? That has to do with the design principles guiding the hash function. The one-at-a-time hash is described in an article about building families of hash functions with certain desirable properties using invertible transformations. The idea is to build a hash of a long byte stream by incrementally applying invertible transforms that combine together the existing hash value and new bytes. Doing so has the useful property that if you’ve hashed byte streams X and Y and didn’t get a collision, then there’s a no chance of getting a collision if you append the same byte sequence to both X and Y. The specific operations used in the hash are indeed invertible , but the justifications as to why are subtle and rely on the fact that adding in shifts and allowing the computation to overflow correspond to multiplication modulo 232 by invertible values. In that sense, there are intentionally no mods here because the implicit modulo computed by an overflow performs the “correct” modulo to make all the steps invertible.

This contrasts with polynomial hashing modulo some prime. You’re correct that when using the polynomial hashing strategy you need to be mindful of integer overflow because you specifically don’t want these implicit mods to kick in - after all, you’re modding by a different number! But that’s particular to that specific hashing strategy. There are lots of different ways to build hash functions, each of which uses a different approach.