uint64_t siphash(const unsigned char key[16], const unsigned char *m, size_t len) { uint64_t v0, v1, v2, v3; uint64_t mi, k0, k1; uint64_t last7; size_t i, blocks; k0 = U8TO64_LE(key + 0); k1 = U8TO64_LE(key + 8); v0 = k0 ^ 0x736f6d6570736575ull; v1 = k1 ^ 0x646f72616e646f6dull; v2 = k0 ^ 0x6c7967656e657261ull; v3 = k1 ^ 0x7465646279746573ull; last7 = (uint64_t)(len & 0xff) << 56; #define sipcompress() \ v0 += v1; v2 += v3; \ v1 = ROTL64(v1,13); v3 = ROTL64(v3,16); \ v1 ^= v0; v3 ^= v2; \ v0 = ROTL64(v0,32); \ v2 += v1; v0 += v3; \ v1 = ROTL64(v1,17); v3 = ROTL64(v3,21); \ v1 ^= v2; v3 ^= v0; \ v2 = ROTL64(v2,32); for (i = 0, blocks = (len & ~7); i < blocks; i += 8) { mi = U8TO64_LE(m + i); v3 ^= mi; sipcompress() sipcompress() v0 ^= mi; } switch (len - blocks) { case 7: last7 |= (uint64_t)m[i + 6] << 48; case 6: last7 |= (uint64_t)m[i + 5] << 40; case 5: last7 |= (uint64_t)m[i + 4] << 32; case 4: last7 |= (uint64_t)m[i + 3] << 24; case 3: last7 |= (uint64_t)m[i + 2] << 16; case 2: last7 |= (uint64_t)m[i + 1] << 8; case 1: last7 |= (uint64_t)m[i + 0] ; case 0: default:; }; v3 ^= last7; sipcompress() sipcompress() v0 ^= last7; v2 ^= 0xff; sipcompress() sipcompress() sipcompress() sipcompress() return v0 ^ v1 ^ v2 ^ v3; }
int crypto_shorthash(unsigned char *out,const unsigned char *in,uint64_t inlen,const unsigned char *k) { /* "somepseudorandomlygeneratedbytes" */ u64 v0 = 0x736f6d6570736575ULL; u64 v1 = 0x646f72616e646f6dULL; u64 v2 = 0x6c7967656e657261ULL; u64 v3 = 0x7465646279746573ULL; u64 b; u64 k0 = U8TO64_LE( k ); u64 k1 = U8TO64_LE( k + 8 ); u64 m; const u8 *end = in + inlen - ( inlen % sizeof( u64 ) ); const int left = inlen & 7; b = ( ( u64 )inlen ) << 56; v3 ^= k1; v2 ^= k0; v1 ^= k1; v0 ^= k0; for ( ; in != end; in += 8 ) { m = U8TO64_LE( in ); v3 ^= m; SIPROUND; SIPROUND; v0 ^= m; } switch( left ) { case 7: b |= ( ( u64 )in[ 6] ) << 48; case 6: b |= ( ( u64 )in[ 5] ) << 40; case 5: b |= ( ( u64 )in[ 4] ) << 32; case 4: b |= ( ( u64 )in[ 3] ) << 24; case 3: b |= ( ( u64 )in[ 2] ) << 16; case 2: b |= ( ( u64 )in[ 1] ) << 8; case 1: b |= ( ( u64 )in[ 0] ); break; case 0: break; } v3 ^= b; SIPROUND; SIPROUND; v0 ^= b; v2 ^= 0xff; SIPROUND; SIPROUND; SIPROUND; SIPROUND; b = v0 ^ v1 ^ v2 ^ v3; U64TO8_LE( out, b ); return 0; }
/* The 64bit 2-4 variant */ uint64_t siphash(const unsigned char key[16], const unsigned char *m, size_t len) { uint64_t v0, v1, v2, v3; uint64_t mi, k0, k1; uint64_t last7; size_t i, blocks; k0 = U8TO64_LE(key + 0); k1 = U8TO64_LE(key + 8); v0 = k0 ^ 0x736f6d6570736575ull; v1 = k1 ^ 0x646f72616e646f6dull; v2 = k0 ^ 0x6c7967656e657261ull; v3 = k1 ^ 0x7465646279746573ull; last7 = (uint64_t)(len & 0xff) << 56; for (i = 0, blocks = (len & ~7); i < blocks; i += 8) { mi = U8TO64_LE(m + i); v3 ^= mi; sipcompress() /* 2 c rounds */ sipcompress() v0 ^= mi; } switch (len - blocks) { case 7: last7 |= (uint64_t)m[i + 6] << 48; case 6: last7 |= (uint64_t)m[i + 5] << 40; case 5: last7 |= (uint64_t)m[i + 4] << 32; case 4: last7 |= (uint64_t)m[i + 3] << 24; case 3: last7 |= (uint64_t)m[i + 2] << 16; case 2: last7 |= (uint64_t)m[i + 1] << 8; case 1: last7 |= (uint64_t)m[i + 0] ; case 0: default:; }; v3 ^= last7; sipcompress() /* 2 more c rounds */ sipcompress() v0 ^= last7; v2 ^= 0xff; sipcompress() /* and 4 final d rounds */ sipcompress() sipcompress() sipcompress() return v0 ^ v1 ^ v2 ^ v3; #undef sipcompress }
SipHash::SipHash(char key[16], int c, int d) { this->c = c; this->d = d; uint64_t k0 = U8TO64_LE(key); uint64_t k1 = U8TO64_LE(key + 8); this->v0 = (0x736f6d6570736575 ^ k0); this->v1 = (0x646f72616e646f6d ^ k1); this->v2 = (0x6c7967656e657261 ^ k0); this->v3 = (0x7465646279746573 ^ k1); this->m_idx = 0; this->input_len = 0; this->m = 0; }
uint64 siphash24( const void* bytes, const size_t size, const uint64 k0, const uint64 k1) { /* "somepseudorandomlygeneratedbytes" */ uint64 v0 = 0x736f6d6570736575ULL; uint64 v1 = 0x646f72616e646f6dULL; uint64 v2 = 0x6c7967656e657261ULL; uint64 v3 = 0x7465646279746573ULL; uint64 b; uint64 m; int i; const uint8* in = reinterpret_cast<const uint8*>(bytes); const uint8* end = in + size - ( size % sizeof( uint64 ) ); const int left = size & 7; b = ( ( uint64 )size ) << 56; v3 ^= k1; v2 ^= k0; v1 ^= k1; v0 ^= k0; for ( ; in != end; in += 8 ) { m = U8TO64_LE( in ); v3 ^= m; for( i=0; i<cROUNDS; ++i ) SIPROUND; v0 ^= m; } switch( left ) { case 7: b |= ( ( uint64 )in[ 6] ) << 48; case 6: b |= ( ( uint64 )in[ 5] ) << 40; case 5: b |= ( ( uint64 )in[ 4] ) << 32; case 4: b |= ( ( uint64 )in[ 3] ) << 24; case 3: b |= ( ( uint64 )in[ 2] ) << 16; case 2: b |= ( ( uint64 )in[ 1] ) << 8; case 1: b |= ( ( uint64 )in[ 0] ); break; case 0: break; } v3 ^= b; for( i=0; i<cROUNDS; ++i ) SIPROUND; v0 ^= b; v2 ^= 0xff; for( i=0; i<dROUNDS; ++i ) SIPROUND; b = v0 ^ v1 ^ v2 ^ v3; return b; }
uint64_t siphash(char key[16], char data[], int c, int d){ uint64_t k0 = U8TO64_LE(key); uint64_t k1 = U8TO64_LE(key + 8); uint64_t v0 = 0x736f6d6570736575 ^ k0; uint64_t v1 = 0x646f72616e646f6d ^ k1; uint64_t v2 = 0x6c7967656e657261 ^ k0; uint64_t v3 = 0x7465646279746573 ^ k1; uint64_t m = 0; int i, iter = 0, index = 0, len = strlen(data); for (; index < len; index++) { m |= ((uint64_t) data[index]) << (iter++ * 8); if (iter >= 8) { DIGEST_BLOCK iter = 0; m = 0; } } while (iter < 7) { m |= 0 << (iter++ * 8); } m |= ((uint64_t) len) << (iter * 8); DIGEST_BLOCK v2 ^= 0xff; for(i = 0; i < d; i++){ COMPRESS } return ((uint64_t)(v0 ^ v1 ^ v2 ^ v3)); }
} static const uint8_t hash_key[BUFFER_LENGTH] = { 210, 40, 228, 187, 182, 248, 110, 170, 199, 138, 64, 14, 234, 233, 23, 133 }; static uint8_t out[BUFFER_LENGTH] = { 0 }; // hash hashes key using siphash and places both halves of the // 128-bit return value inside a and b. static void hash(const char* key, const size_t key_len, uint64_t *restrict a, uint64_t *restrict b) { // Need to be uint8_t* for siphash's API... siphash(out, (const uint8_t *)(key), (const uint64_t)(key_len), hash_key); *a = U8TO64_LE(out); *b = U8TO64_LE(out + 8); } // add adds a key to the Filter. void add(Filter *f, const char* key, const size_t key_len) { uint64_t a = 0; uint64_t b = 0; hash(key, key_len, &a, &b); uint64_t m = f->nbits - 1; for (int64_t i = 0; i < f->hashes; ++i) { set(f, (a + b*i) & m); } ++f->items;
static int siphash(const uint8_t *in, const size_t inlen, const uint8_t *k, uint8_t *out, const size_t outlen) { assert((outlen == 8) || (outlen == 16)); uint64_t v0 = 0x736f6d6570736575ULL; uint64_t v1 = 0x646f72616e646f6dULL; uint64_t v2 = 0x6c7967656e657261ULL; uint64_t v3 = 0x7465646279746573ULL; uint64_t k0 = U8TO64_LE(k); uint64_t k1 = U8TO64_LE(k + 8); uint64_t m; int i; const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t)); const int left = inlen & 7; uint64_t b = ((uint64_t)inlen) << 56; v3 ^= k1; v2 ^= k0; v1 ^= k1; v0 ^= k0; if (outlen == 16) v1 ^= 0xee; for (; in != end; in += 8) { m = U8TO64_LE(in); v3 ^= m; TRACE; for (i = 0; i < cROUNDS; ++i) SIPROUND; v0 ^= m; } switch (left) { case 7: b |= ((uint64_t)in[6]) << 48; case 6: b |= ((uint64_t)in[5]) << 40; case 5: b |= ((uint64_t)in[4]) << 32; case 4: b |= ((uint64_t)in[3]) << 24; case 3: b |= ((uint64_t)in[2]) << 16; case 2: b |= ((uint64_t)in[1]) << 8; case 1: b |= ((uint64_t)in[0]); break; case 0: break; } v3 ^= b; TRACE; for (i = 0; i < cROUNDS; ++i) SIPROUND; v0 ^= b; if (outlen == 16) v2 ^= 0xee; else v2 ^= 0xff; TRACE; for (i = 0; i < dROUNDS; ++i) SIPROUND; b = v0 ^ v1 ^ v2 ^ v3; U64TO8_LE(out, b); if (outlen == 8) return 0; v1 ^= 0xdd; TRACE; for (i = 0; i < dROUNDS; ++i) SIPROUND; b = v0 ^ v1 ^ v2 ^ v3; U64TO8_LE(out + 8, b); return 0; }
PMOD_EXPORT UINT64 low_hashmem_siphash24( const void *s, size_t len, size_t nbytes, UINT64 key ) { const unsigned char * in = (const unsigned char*)s; unsigned long long inlen = MINIMUM(len, nbytes); /* "somepseudorandomlygeneratedbytes" */ UINT64 v0 = 0x736f6d6570736575ULL; UINT64 v1 = 0x646f72616e646f6dULL; UINT64 v2 = 0x6c7967656e657261ULL; UINT64 v3 = 0x7465646279746573ULL; UINT64 b; UINT64 k0 = key; UINT64 k1 = key; UINT64 m; const unsigned char *end = in + inlen - ( inlen % sizeof( UINT64 ) ); const int left = inlen & 7; b = ( ( UINT64 )inlen ) << 56; v3 ^= k1; v2 ^= k0; v1 ^= k1; v0 ^= k0; for ( ; in != end; in += 8 ) { m = U8TO64_LE( in ); v3 ^= m; SIPROUND; SIPROUND; v0 ^= m; } switch( left ) { case 7: b |= ( ( UINT64 )in[ 6] ) << 48; /* FALLTHRU */ case 6: b |= ( ( UINT64 )in[ 5] ) << 40; /* FALLTHRU */ case 5: b |= ( ( UINT64 )in[ 4] ) << 32; /* FALLTHRU */ case 4: b |= ( ( UINT64 )in[ 3] ) << 24; /* FALLTHRU */ case 3: b |= ( ( UINT64 )in[ 2] ) << 16; /* FALLTHRU */ case 2: b |= ( ( UINT64 )in[ 1] ) << 8; /* FALLTHRU */ case 1: b |= ( ( UINT64 )in[ 0] ); break; case 0: break; } v3 ^= b; SIPROUND; SIPROUND; v0 ^= b; v2 ^= 0xff; SIPROUND; SIPROUND; SIPROUND; SIPROUND; b = v0 ^ v1 ^ v2 ^ v3; return b; }
int siphash( uint8_t *out, const uint8_t *in, uint64_t inlen, const uint8_t *k ) { /* "somepseudorandomlygeneratedbytes" */ uint64_t v0 = 0x736f6d6570736575ULL; uint64_t v1 = 0x646f72616e646f6dULL; uint64_t v2 = 0x6c7967656e657261ULL; uint64_t v3 = 0x7465646279746573ULL; uint64_t b; uint64_t k0 = U8TO64_LE( k ); uint64_t k1 = U8TO64_LE( k + 8 ); uint64_t m; int i; const uint8_t *end = in + inlen - ( inlen % sizeof( uint64_t ) ); const int left = inlen & 7; b = ( ( uint64_t )inlen ) << 56; v3 ^= k1; v2 ^= k0; v1 ^= k1; v0 ^= k0; #ifdef DOUBLE v1 ^= 0xee; #endif for ( ; in != end; in += 8 ) { m = U8TO64_LE( in ); v3 ^= m; TRACE; for( i=0; i<cROUNDS; ++i ) SIPROUND; v0 ^= m; } switch( left ) { case 7: b |= ( ( uint64_t )in[ 6] ) << 48; case 6: b |= ( ( uint64_t )in[ 5] ) << 40; case 5: b |= ( ( uint64_t )in[ 4] ) << 32; case 4: b |= ( ( uint64_t )in[ 3] ) << 24; case 3: b |= ( ( uint64_t )in[ 2] ) << 16; case 2: b |= ( ( uint64_t )in[ 1] ) << 8; case 1: b |= ( ( uint64_t )in[ 0] ); break; case 0: break; } v3 ^= b; TRACE; for( i=0; i<cROUNDS; ++i ) SIPROUND; v0 ^= b; #ifndef DOUBLE v2 ^= 0xff; #else v2 ^= 0xee; #endif TRACE; for( i=0; i<dROUNDS; ++i ) SIPROUND; b = v0 ^ v1 ^ v2 ^ v3; U64TO8_LE( out, b ); #ifdef DOUBLE v1 ^= 0xdd; TRACE; for( i=0; i<dROUNDS; ++i ) SIPROUND; b = v0 ^ v1 ^ v2 ^ v3; U64TO8_LE( out+8, b ); #endif return 0; }
static void keccak_block(scrypt_hash_state *S, const uint8_t *in) { size_t i; uint64_t *s = S->state, t[5], u[5], v, w; /* absorb input */ for (i = 0; i < SCRYPT_HASH_BLOCK_SIZE / 8; i++, in += 8) s[i] ^= U8TO64_LE(in); for (i = 0; i < 24; i++) { /* theta: c = a[0,i] ^ a[1,i] ^ .. a[4,i] */ t[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20]; t[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21]; t[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22]; t[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23]; t[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24]; /* theta: d[i] = c[i+4] ^ rotl(c[i+1],1) */ u[0] = t[4] ^ ROTL64(t[1], 1); u[1] = t[0] ^ ROTL64(t[2], 1); u[2] = t[1] ^ ROTL64(t[3], 1); u[3] = t[2] ^ ROTL64(t[4], 1); u[4] = t[3] ^ ROTL64(t[0], 1); /* theta: a[0,i], a[1,i], .. a[4,i] ^= d[i] */ s[0] ^= u[0]; s[5] ^= u[0]; s[10] ^= u[0]; s[15] ^= u[0]; s[20] ^= u[0]; s[1] ^= u[1]; s[6] ^= u[1]; s[11] ^= u[1]; s[16] ^= u[1]; s[21] ^= u[1]; s[2] ^= u[2]; s[7] ^= u[2]; s[12] ^= u[2]; s[17] ^= u[2]; s[22] ^= u[2]; s[3] ^= u[3]; s[8] ^= u[3]; s[13] ^= u[3]; s[18] ^= u[3]; s[23] ^= u[3]; s[4] ^= u[4]; s[9] ^= u[4]; s[14] ^= u[4]; s[19] ^= u[4]; s[24] ^= u[4]; /* rho pi: b[..] = rotl(a[..], ..) */ v = s[ 1]; s[ 1] = ROTL64(s[ 6], 44); s[ 6] = ROTL64(s[ 9], 20); s[ 9] = ROTL64(s[22], 61); s[22] = ROTL64(s[14], 39); s[14] = ROTL64(s[20], 18); s[20] = ROTL64(s[ 2], 62); s[ 2] = ROTL64(s[12], 43); s[12] = ROTL64(s[13], 25); s[13] = ROTL64(s[19], 8); s[19] = ROTL64(s[23], 56); s[23] = ROTL64(s[15], 41); s[15] = ROTL64(s[ 4], 27); s[ 4] = ROTL64(s[24], 14); s[24] = ROTL64(s[21], 2); s[21] = ROTL64(s[ 8], 55); s[ 8] = ROTL64(s[16], 45); s[16] = ROTL64(s[ 5], 36); s[ 5] = ROTL64(s[ 3], 28); s[ 3] = ROTL64(s[18], 21); s[18] = ROTL64(s[17], 15); s[17] = ROTL64(s[11], 10); s[11] = ROTL64(s[ 7], 6); s[ 7] = ROTL64(s[10], 3); s[10] = ROTL64( v, 1); /* chi: a[i,j] ^= ~b[i,j+1] & b[i,j+2] */ v = s[ 0]; w = s[ 1]; s[ 0] ^= (~w) & s[ 2]; s[ 1] ^= (~s[ 2]) & s[ 3]; s[ 2] ^= (~s[ 3]) & s[ 4]; s[ 3] ^= (~s[ 4]) & v; s[ 4] ^= (~v) & w; v = s[ 5]; w = s[ 6]; s[ 5] ^= (~w) & s[ 7]; s[ 6] ^= (~s[ 7]) & s[ 8]; s[ 7] ^= (~s[ 8]) & s[ 9]; s[ 8] ^= (~s[ 9]) & v; s[ 9] ^= (~v) & w; v = s[10]; w = s[11]; s[10] ^= (~w) & s[12]; s[11] ^= (~s[12]) & s[13]; s[12] ^= (~s[13]) & s[14]; s[13] ^= (~s[14]) & v; s[14] ^= (~v) & w; v = s[15]; w = s[16]; s[15] ^= (~w) & s[17]; s[16] ^= (~s[17]) & s[18]; s[17] ^= (~s[18]) & s[19]; s[18] ^= (~s[19]) & v; s[19] ^= (~v) & w; v = s[20]; w = s[21]; s[20] ^= (~w) & s[22]; s[21] ^= (~s[22]) & s[23]; s[22] ^= (~s[23]) & s[24]; s[23] ^= (~s[24]) & v; s[24] ^= (~v) & w; /* iota: a[0,0] ^= round constant */ s[0] ^= keccak_round_constants[i]; } }