36763820049411358964d052ad122db23f402200
[trex.git] /
1 #include "api.h"
2 #include "crypto_uint64.h"
3 #include "crypto_uint32.h"
4 #include "crypto_uint8.h"
5
6 typedef crypto_uint64 u64;
7 typedef crypto_uint32 u32;
8 typedef crypto_uint8   u8;
9
10 #define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
11
12 #define U32TO8_LE(p, v)         \
13     (p)[0] = (u8)((v)      ); (p)[1] = (u8)((v) >>  8); \
14     (p)[2] = (u8)((v) >> 16); (p)[3] = (u8)((v) >> 24);
15
16 #define U64TO8_LE(p, v)         \
17   U32TO8_LE((p),     (u32)((v)      ));   \
18   U32TO8_LE((p) + 4, (u32)((v) >> 32));
19
20 #define U8TO64_LE(p) \
21   (((u64)((p)[0])      ) | \
22    ((u64)((p)[1]) <<  8) | \
23    ((u64)((p)[2]) << 16) | \
24    ((u64)((p)[3]) << 24) | \
25    ((u64)((p)[4]) << 32) | \
26    ((u64)((p)[5]) << 40) | \
27    ((u64)((p)[6]) << 48) | \
28    ((u64)((p)[7]) << 56))
29
30 #define SIPROUND            \
31   do {              \
32     v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
33     v2 += v3; v3=ROTL(v3,16); v3 ^= v2;     \
34     v0 += v3; v3=ROTL(v3,21); v3 ^= v0;     \
35     v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
36   } while(0)
37
38 int crypto_shorthash(unsigned char *out,const unsigned char *in,unsigned long long inlen,const unsigned char *k)
39 {
40   /* "somepseudorandomlygeneratedbytes" */
41   u64 v0 = 0x736f6d6570736575ULL;
42   u64 v1 = 0x646f72616e646f6dULL;
43   u64 v2 = 0x6c7967656e657261ULL;
44   u64 v3 = 0x7465646279746573ULL;
45   u64 b;
46   u64 k0 = U8TO64_LE( k );
47   u64 k1 = U8TO64_LE( k + 8 );
48   u64 m;
49   const u8 *end = in + inlen - ( inlen % sizeof( u64 ) );
50   const int left = inlen & 7;
51   b = ( ( u64 )inlen ) << 56;
52   v3 ^= k1;
53   v2 ^= k0;
54   v1 ^= k1;
55   v0 ^= k0;
56
57   for ( ; in != end; in += 8 )
58   {
59     m = U8TO64_LE( in );
60     v3 ^= m;
61     SIPROUND;
62     SIPROUND;
63     v0 ^= m;
64   }
65
66   switch( left )
67   {
68   case 7: b |= ( ( u64 )in[ 6] )  << 48;
69   case 6: b |= ( ( u64 )in[ 5] )  << 40;
70   case 5: b |= ( ( u64 )in[ 4] )  << 32;
71   case 4: b |= ( ( u64 )in[ 3] )  << 24;
72   case 3: b |= ( ( u64 )in[ 2] )  << 16;
73   case 2: b |= ( ( u64 )in[ 1] )  <<  8;
74   case 1: b |= ( ( u64 )in[ 0] ); break;
75   case 0: break;
76   }
77
78   v3 ^= b;
79   SIPROUND;
80   SIPROUND;
81   v0 ^= b;
82   v2 ^= 0xff;
83   SIPROUND;
84   SIPROUND;
85   SIPROUND;
86   SIPROUND;
87   b = v0 ^ v1 ^ v2  ^ v3;
88   U64TO8_LE( out, b );
89   return 0;
90 }
91