wip

clean up SipHash code

autumn 79eeeb29 82cc8256

+61 -65
+59 -65
crone/core/hash.h
··· 14 14 const uint64_t init_v2 = key_0 ^ magic_number_2; 15 15 const uint64_t init_v3 = key_1 ^ magic_number_3; 16 16 17 - const uint32_t compress_rounds = 2; 18 - const uint32_t finalize_rounds = 4; 17 + #define ROTL(x, r) ((x << r) | (x >> (64 - r))) 18 + 19 + #define SIPROUND \ 20 + v0 += v1; \ 21 + v2 += v3; \ 22 + v1 = ROTL(v1, 13); \ 23 + v3 = ROTL(v3, 16); \ 24 + v1 ^= v0; \ 25 + v3 ^= v2; \ 26 + v0 = ROTL(v0, 32); \ 27 + v2 += v1; \ 28 + v0 += v3; \ 29 + v1 = ROTL(v1, 17); \ 30 + v3 = ROTL(v3, 21); \ 31 + v1 ^= v2; \ 32 + v3 ^= v0; \ 33 + v2 = ROTL(v2, 32); 19 34 20 - #define ROTL(x, r) ((x << r) | (x >> (64 - r))) 21 - #define ROTR(x, r) ((x >> r) | (x << (64 - r))) 35 + #define COMPRESS_ROUNDS SIPROUND SIPROUND 36 + 37 + #define FINALIZE_ROUNDS SIPROUND SIPROUND SIPROUND SIPROUND 38 + 39 + typedef struct partial_hash { 40 + size_t length, position; 41 + uint64_t v0, v1, v2, v3; 42 + uint64_t chunk; // "m_n" in the SipHash paper 43 + } partial_hash; 44 + 45 + partial_hash start_hash() { 46 + #ifdef BIG_ENDIAN 47 + fprintf(stderr, "[core/hash.h] Warning: SipHash implementation expects a little endian system, but the BIG_ENDIAN flag was set for this target."); 48 + #endif 49 + partial_hash h = { 50 + .length = 0, 51 + .position = 0, 52 + .v0 = init_v0, 53 + .v1 = init_v1, 54 + .v2 = init_v2, 55 + .v3 = init_v3, 56 + .chunk = 0 57 + }; 58 + return h; 59 + } 60 + 61 + partial_hash continue_hash(partial_hash partial, string s) { 62 + return start_hash();// todo 63 + } 64 + 65 + hash resolve_hash(partial_hash partial) { 66 + return partial.v0 ^ partial.v1 ^ partial.v2 ^ partial.v3; 67 + } 22 68 23 69 hash calculate_hash(string s) { 70 + #ifdef BIG_ENDIAN 71 + fprintf(stderr, "[core/hash.h] Warning: SipHash implementation expects a little endian system, but the BIG_ENDIAN flag was set for this target."); 72 + #endif 73 + 24 74 uint8_t b = s.length % 256; 25 75 uint64_t v0 = init_v0; 26 76 uint64_t v1 = init_v1; 27 77 uint64_t v2 = init_v2; 28 78 uint64_t v3 = init_v3; 29 79 30 - fprintf(stderr, " %lx %lx %lx %lx \n", v0, v1, v2, v3); 31 - 32 80 size_t position = 0; 33 81 while (s.length - position > 7) { 34 - uint64_t m = 35 - ((uint64_t)s.data[position]) | 36 - ((uint64_t)s.data[position+1] << 8) | 37 - ((uint64_t)s.data[position+2] << 16) | 38 - ((uint64_t)s.data[position+3] << 24) | 39 - ((uint64_t)s.data[position+4] << 32) | 40 - ((uint64_t)s.data[position+5] << 40) | 41 - ((uint64_t)s.data[position+6] << 48) | 42 - ((uint64_t)s.data[position+7] << 56); 82 + uint64_t m = *(uint64_t*)&(s.data[position]); 43 83 44 84 v3 ^= m; 45 - fprintf(stderr, " %lx %lx %lx %lx \n", v0, v1, v2, v3); 46 85 47 - for (int round = 0; round < compress_rounds; ++round) { 48 - // SipRound, matching formatting of specification 49 - v0 += v1; v2 += v3; 50 - v1 = ROTL(v1, 13); v3 = ROTL(v3, 16); 51 - v1 ^= v0; v3 ^= v2; 52 - v0 = ROTL(v0, 32); 53 - v2 += v1; v0 += v3; 54 - v1 = ROTL(v1, 17); v3 = ROTL(v3, 21); 55 - v1 ^= v2; v3 ^= v0; 56 - v2 = ROTL(v2, 32); 57 - } 58 - fprintf(stderr, " %lx %lx %lx %lx \n", v0, v1, v2, v3); 86 + COMPRESS_ROUNDS 59 87 60 88 v0 ^= m; 61 - 62 - fprintf(stderr, " %lx %lx %lx %lx \n", v0, v1, v2, v3); 63 89 64 90 position += 8; 65 91 } 66 92 67 93 uint64_t m = ((uint64_t)b << 56); 68 - size_t byte = 0; 69 - while (s.length - position > byte) { 70 - m |= ((uint64_t)s.data[position+byte] << (8*byte)); 71 - ++byte; 72 - } 94 + memcpy(&m, &(s.data[position]), s.length - position); 73 95 74 96 v3 ^= m; 75 97 76 - for (int round = 0; round < compress_rounds; ++round) { 77 - // SipRound, matching formatting of specification 78 - v0 += v1; v2 += v3; 79 - v1 = ROTL(v1, 13); v3 = ROTL(v3, 16); 80 - v1 ^= v0; v3 ^= v2; 81 - v0 = ROTL(v0, 32); 82 - v2 += v1; v0 += v3; 83 - v1 = ROTL(v1, 17); v3 = ROTL(v3, 21); 84 - v1 ^= v2; v3 ^= v0; 85 - v2 = ROTL(v2, 32); 86 - } 98 + COMPRESS_ROUNDS 87 99 88 100 v0 ^= m; 89 101 90 102 v2 ^= (uint64_t)0xff; 91 103 92 - fprintf(stderr, " %lx %lx %lx %lx \n", v0, v1, v2, v3); 93 - 94 - for (int round = 0; round < finalize_rounds; ++round) { 95 - // SipRound, matching formatting of specification 96 - v0 += v1; v2 += v3; 97 - v1 = ROTL(v1, 13); v3 = ROTL(v3, 16); 98 - v1 ^= v0; v3 ^= v2; 99 - v0 = ROTL(v0, 32); 100 - v2 += v1; v0 += v3; 101 - v1 = ROTL(v1, 17); v3 = ROTL(v3, 21); 102 - v1 ^= v2; v3 ^= v0; 103 - v2 = ROTL(v2, 32); 104 - } 105 - 106 - fprintf(stderr, " %lx %lx %lx %lx \n", v0, v1, v2, v3); 107 - 108 - fprintf(stderr, " %lx \n", v0 ^ v1 ^ v2 ^ v3); 104 + FINALIZE_ROUNDS 109 105 110 106 return v0 ^ v1 ^ v2 ^ v3; 111 107 } 112 108 113 - // TODO maybe-more-performant version ingesting one u8 at a time 114 -
+2
program.c
··· 24 24 25 25 hash h = calculate_hash(s); 26 26 27 + fprintf(stderr, " hash: %lx \n", h); 28 + 27 29 /* parser 28 30 //int fileDesc = open("./crone/core/core.cr", O_RDONLY, 0); 29 31 int fileDesc = open("./crone/lang/parseme.cr", O_RDONLY, 0);