D. J. Bernstein
Authenticators and signatures
hash127

The hash127 library interface

Hashing strings of 32-bit integers

#include <hash127.h>

void hash127_expand(&bigr,r);

void hash127(out,m,l,&bigr,kn);

int32 r[4];
struct hash127 bigr;
int32 kn[4];
int32 *m;
unsigned int l;

int32 out[4];
hash127 reads three arrays of signed 32-bit integers:
• r[0], r[1], r[2], r[3],
• kn[0], kn[1], kn[2], kn[3], and
• m[0], m[1], ..., m[l-1].

hash127 computes

• r = r[0] + 2^32 r[1] + 2^64 r[2] + 2^96 r[3],
• k = kn[0] + 2^32 kn[1] + 2^64 kn[2] + 2^96 kn[3], and
• u = (r^(l+1) + m[0]r^l + m[1]r^(l-1) + ... + m[l-1]r + k) mod p
where p = 2^127-1.

hash127 stores u in an array of four signed 32-bit integers, out[0], out[1], out[2], out[3], such that u = (2^31+out[0]) + 2^32(2^31+out[1]) + 2^64(2^31+out[2]) + 2^96(2^31+out[3]).

Note that there are only 127 bits of information in the output: out[3] is always negative.

Before you call hash127 you must call hash127_expand to convert r into bigr. You may reuse bigr for any number of calls to hash127. You may call hash127_expand with a new r to change the contents of bigr.

hash127 is not guaranteed to be reentrant; it may modify bigr.

hash127 may use floating-point arithmetic. On some architectures it is not safe to use floating-point arithmetic in signal handlers.

On the x86 architecture, the current implementation of hash127_expand sets the precision control to 64 bits; hash127 will then assume that the precision control is still 64 bits.

Hashing strings of bytes

#include <hash127.h>

void hash127_little(out,(int32 *) b,l,&bigr,kn);

struct hash127 bigr;
int32 kn[4];
unsigned char *b;
unsigned int l;

int32 out[4];
hash127_little is just like hash127 except that it reads bytes b[0], b[1], ..., b[4*l-1], interpreted as signed 32-bit integers, little-endian, twos-complement.

WARNING: b must be aligned as an int32 pointer.

Performance

On the x86 architecture, the performance of hash127 and hash127_little depends on the alignment of bigr. Make sure to use gcc -malign-double so that floating-point variables are properly aligned in memory.

The time taken by these functions is independent of the contents of r, x, and m on processors with constant-time floating-point arithmetic, specifically the Pentium, Pentium MMX, Pentium Pro, and Pentium II.