• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

HashSip.cc

Go to the documentation of this file.
00001 /**
00002 
00003 Algorithm Info:
00004 https://131002.net/siphash/
00005 
00006 Based off of implementation:
00007 https://github.com/floodyberry/siphash
00008 
00009  */
00010 
00011 #include "HashSip.h"
00012 #include <cstring>
00013 
00014 #define SIP_BLOCK_SIZE 8
00015 
00016 #define ROTL64(a,b) (((a)<<(b))|((a)>>(64-b)))
00017 
00018 #define U8TO64_LE(p) *(const uint64_t *)(p)
00019 
00020 #define SIPCOMPRESS(x0,x1,x2,x3) \
00021     x0 += x1; \
00022     x2 += x3; \
00023     x1 = ROTL64(x1,13); \
00024     x3 = ROTL64(x3,16); \
00025     x1 ^= x0; \
00026     x3 ^= x2; \
00027     x0 = ROTL64(x0,32); \
00028     x2 += x1; \
00029     x0 += x3; \
00030     x1 = ROTL64(x1,17); \
00031     x3 = ROTL64(x3,21); \
00032     x1 ^= x2; \
00033     x3 ^= x0; \
00034     x2 = ROTL64(x2,32);
00035 
00036 ATSHash64Sip24::ATSHash64Sip24(void)
00037 {
00038   k0 = 0;
00039   k1 = 0;
00040   this->clear();
00041 }
00042 
00043 ATSHash64Sip24::ATSHash64Sip24(const unsigned char key[16])
00044 {
00045   k0 = U8TO64_LE(key);
00046   k1 = U8TO64_LE(key + sizeof(k0));
00047   this->clear();
00048 }
00049 
00050 ATSHash64Sip24::ATSHash64Sip24(uint64_t key0, uint64_t key1)
00051 {
00052   k0 = key0;
00053   k1 = key1;
00054   this->clear();
00055 }
00056 
00057 void
00058 ATSHash64Sip24::update(const void *data, size_t len)
00059 {
00060   size_t i, blocks;
00061   unsigned char *m;
00062   uint64_t mi;
00063   uint8_t block_off = 0;
00064 
00065   if (!finalized) {
00066     m = (unsigned char *) data;
00067     total_len += len;
00068 
00069     if (len + block_buffer_len < SIP_BLOCK_SIZE) {
00070       memcpy(block_buffer + block_buffer_len, m, len);
00071       block_buffer_len += len;
00072     } else {
00073       if (block_buffer_len > 0) {
00074         block_off = SIP_BLOCK_SIZE - block_buffer_len;
00075         memcpy(block_buffer + block_buffer_len, m, block_off);
00076 
00077         mi = U8TO64_LE(block_buffer);
00078         v3 ^= mi;
00079         SIPCOMPRESS(v0, v1, v2, v3);
00080         SIPCOMPRESS(v0, v1, v2, v3);
00081         v0 ^= mi;
00082       }
00083 
00084       for (i = block_off, blocks = ((len - block_off) & ~(SIP_BLOCK_SIZE - 1)); i < blocks; i += SIP_BLOCK_SIZE) {
00085         mi = U8TO64_LE(m + i);
00086         v3 ^= mi;
00087         SIPCOMPRESS(v0, v1, v2, v3);
00088         SIPCOMPRESS(v0, v1, v2, v3);
00089         v0 ^= mi;
00090       }
00091 
00092       block_buffer_len = (len - block_off) & (SIP_BLOCK_SIZE - 1);
00093       memcpy(block_buffer, m + block_off + blocks, block_buffer_len);
00094     }
00095   }
00096 }
00097 
00098 void
00099 ATSHash64Sip24::final(void)
00100 {
00101   uint64_t last7;
00102   int i;
00103 
00104   if (!finalized) {
00105     last7 = (uint64_t) (total_len & 0xff) << 56;
00106 
00107     for (i = block_buffer_len - 1; i >= 0; i--) {
00108       last7 |= (uint64_t) block_buffer[i] << (i * 8);
00109     }
00110 
00111     v3 ^= last7;
00112     SIPCOMPRESS(v0, v1, v2, v3);
00113     SIPCOMPRESS(v0, v1, v2, v3);
00114     v0 ^= last7;
00115     v2 ^= 0xff;
00116     SIPCOMPRESS(v0, v1, v2, v3);
00117     SIPCOMPRESS(v0, v1, v2, v3);
00118     SIPCOMPRESS(v0, v1, v2, v3);
00119     SIPCOMPRESS(v0, v1, v2, v3);
00120     hfinal = v0 ^ v1 ^ v2 ^ v3;
00121     finalized = true;
00122   }
00123 }
00124 
00125 uint64_t
00126 ATSHash64Sip24::get(void) const
00127 {
00128   if (finalized) {
00129     return hfinal;
00130   } else {
00131     return 0;
00132   }
00133 }
00134 
00135 void
00136 ATSHash64Sip24::clear(void)
00137 {
00138   v0 = k0 ^ 0x736f6d6570736575ull;
00139   v1 = k1 ^ 0x646f72616e646f6dull;
00140   v2 = k0 ^ 0x6c7967656e657261ull;
00141   v3 = k1 ^ 0x7465646279746573ull;
00142   finalized = false;
00143   total_len = 0;
00144   block_buffer_len = 0;
00145 }

Generated by  doxygen 1.7.1