tangled
alpha
login
or
join now
ponder.ooo
/
crone
0
fork
atom
wip
0
fork
atom
overview
issues
pulls
pipelines
clean up SipHash code
autumn
1 year ago
79eeeb29
82cc8256
+61
-65
2 changed files
expand all
collapse all
unified
split
crone
core
hash.h
program.c
+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
17
-
const uint32_t compress_rounds = 2;
18
18
-
const uint32_t finalize_rounds = 4;
17
17
+
#define ROTL(x, r) ((x << r) | (x >> (64 - r)))
18
18
+
19
19
+
#define SIPROUND \
20
20
+
v0 += v1; \
21
21
+
v2 += v3; \
22
22
+
v1 = ROTL(v1, 13); \
23
23
+
v3 = ROTL(v3, 16); \
24
24
+
v1 ^= v0; \
25
25
+
v3 ^= v2; \
26
26
+
v0 = ROTL(v0, 32); \
27
27
+
v2 += v1; \
28
28
+
v0 += v3; \
29
29
+
v1 = ROTL(v1, 17); \
30
30
+
v3 = ROTL(v3, 21); \
31
31
+
v1 ^= v2; \
32
32
+
v3 ^= v0; \
33
33
+
v2 = ROTL(v2, 32);
19
34
20
20
-
#define ROTL(x, r) ((x << r) | (x >> (64 - r)))
21
21
-
#define ROTR(x, r) ((x >> r) | (x << (64 - r)))
35
35
+
#define COMPRESS_ROUNDS SIPROUND SIPROUND
36
36
+
37
37
+
#define FINALIZE_ROUNDS SIPROUND SIPROUND SIPROUND SIPROUND
38
38
+
39
39
+
typedef struct partial_hash {
40
40
+
size_t length, position;
41
41
+
uint64_t v0, v1, v2, v3;
42
42
+
uint64_t chunk; // "m_n" in the SipHash paper
43
43
+
} partial_hash;
44
44
+
45
45
+
partial_hash start_hash() {
46
46
+
#ifdef BIG_ENDIAN
47
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
48
+
#endif
49
49
+
partial_hash h = {
50
50
+
.length = 0,
51
51
+
.position = 0,
52
52
+
.v0 = init_v0,
53
53
+
.v1 = init_v1,
54
54
+
.v2 = init_v2,
55
55
+
.v3 = init_v3,
56
56
+
.chunk = 0
57
57
+
};
58
58
+
return h;
59
59
+
}
60
60
+
61
61
+
partial_hash continue_hash(partial_hash partial, string s) {
62
62
+
return start_hash();// todo
63
63
+
}
64
64
+
65
65
+
hash resolve_hash(partial_hash partial) {
66
66
+
return partial.v0 ^ partial.v1 ^ partial.v2 ^ partial.v3;
67
67
+
}
22
68
23
69
hash calculate_hash(string s) {
70
70
+
#ifdef BIG_ENDIAN
71
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
72
+
#endif
73
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
30
-
fprintf(stderr, " %lx %lx %lx %lx \n", v0, v1, v2, v3);
31
31
-
32
80
size_t position = 0;
33
81
while (s.length - position > 7) {
34
34
-
uint64_t m =
35
35
-
((uint64_t)s.data[position]) |
36
36
-
((uint64_t)s.data[position+1] << 8) |
37
37
-
((uint64_t)s.data[position+2] << 16) |
38
38
-
((uint64_t)s.data[position+3] << 24) |
39
39
-
((uint64_t)s.data[position+4] << 32) |
40
40
-
((uint64_t)s.data[position+5] << 40) |
41
41
-
((uint64_t)s.data[position+6] << 48) |
42
42
-
((uint64_t)s.data[position+7] << 56);
82
82
+
uint64_t m = *(uint64_t*)&(s.data[position]);
43
83
44
84
v3 ^= m;
45
45
-
fprintf(stderr, " %lx %lx %lx %lx \n", v0, v1, v2, v3);
46
85
47
47
-
for (int round = 0; round < compress_rounds; ++round) {
48
48
-
// SipRound, matching formatting of specification
49
49
-
v0 += v1; v2 += v3;
50
50
-
v1 = ROTL(v1, 13); v3 = ROTL(v3, 16);
51
51
-
v1 ^= v0; v3 ^= v2;
52
52
-
v0 = ROTL(v0, 32);
53
53
-
v2 += v1; v0 += v3;
54
54
-
v1 = ROTL(v1, 17); v3 = ROTL(v3, 21);
55
55
-
v1 ^= v2; v3 ^= v0;
56
56
-
v2 = ROTL(v2, 32);
57
57
-
}
58
58
-
fprintf(stderr, " %lx %lx %lx %lx \n", v0, v1, v2, v3);
86
86
+
COMPRESS_ROUNDS
59
87
60
88
v0 ^= m;
61
61
-
62
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
68
-
size_t byte = 0;
69
69
-
while (s.length - position > byte) {
70
70
-
m |= ((uint64_t)s.data[position+byte] << (8*byte));
71
71
-
++byte;
72
72
-
}
94
94
+
memcpy(&m, &(s.data[position]), s.length - position);
73
95
74
96
v3 ^= m;
75
97
76
76
-
for (int round = 0; round < compress_rounds; ++round) {
77
77
-
// SipRound, matching formatting of specification
78
78
-
v0 += v1; v2 += v3;
79
79
-
v1 = ROTL(v1, 13); v3 = ROTL(v3, 16);
80
80
-
v1 ^= v0; v3 ^= v2;
81
81
-
v0 = ROTL(v0, 32);
82
82
-
v2 += v1; v0 += v3;
83
83
-
v1 = ROTL(v1, 17); v3 = ROTL(v3, 21);
84
84
-
v1 ^= v2; v3 ^= v0;
85
85
-
v2 = ROTL(v2, 32);
86
86
-
}
98
98
+
COMPRESS_ROUNDS
87
99
88
100
v0 ^= m;
89
101
90
102
v2 ^= (uint64_t)0xff;
91
103
92
92
-
fprintf(stderr, " %lx %lx %lx %lx \n", v0, v1, v2, v3);
93
93
-
94
94
-
for (int round = 0; round < finalize_rounds; ++round) {
95
95
-
// SipRound, matching formatting of specification
96
96
-
v0 += v1; v2 += v3;
97
97
-
v1 = ROTL(v1, 13); v3 = ROTL(v3, 16);
98
98
-
v1 ^= v0; v3 ^= v2;
99
99
-
v0 = ROTL(v0, 32);
100
100
-
v2 += v1; v0 += v3;
101
101
-
v1 = ROTL(v1, 17); v3 = ROTL(v3, 21);
102
102
-
v1 ^= v2; v3 ^= v0;
103
103
-
v2 = ROTL(v2, 32);
104
104
-
}
105
105
-
106
106
-
fprintf(stderr, " %lx %lx %lx %lx \n", v0, v1, v2, v3);
107
107
-
108
108
-
fprintf(stderr, " %lx \n", v0 ^ v1 ^ v2 ^ v3);
104
104
+
FINALIZE_ROUNDS
109
105
110
106
return v0 ^ v1 ^ v2 ^ v3;
111
107
}
112
108
113
113
-
// TODO maybe-more-performant version ingesting one u8 at a time
114
114
-
+2
program.c
···
24
24
25
25
hash h = calculate_hash(s);
26
26
27
27
+
fprintf(stderr, " hash: %lx \n", h);
28
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);