ffi-hydrogen 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +30 -0
  5. data/.travis.yml +10 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +72 -0
  9. data/Rakefile +46 -0
  10. data/bench/both.rb +86 -0
  11. data/bench/encode.rb +57 -0
  12. data/bench/encrypt.rb +80 -0
  13. data/bench/init.rb +5 -0
  14. data/bin/console +14 -0
  15. data/bin/setup +8 -0
  16. data/ffi-hydrogen.gemspec +31 -0
  17. data/lib/ffi/hydrogen.rb +216 -0
  18. data/vendor/.clang-format +2 -0
  19. data/vendor/.gitignore +3 -0
  20. data/vendor/README.md +2 -0
  21. data/vendor/libhydrogen/.clang-format +95 -0
  22. data/vendor/libhydrogen/.gitignore +32 -0
  23. data/vendor/libhydrogen/.travis.yml +22 -0
  24. data/vendor/libhydrogen/LICENSE +18 -0
  25. data/vendor/libhydrogen/Makefile +61 -0
  26. data/vendor/libhydrogen/Makefile.arduino +51 -0
  27. data/vendor/libhydrogen/README.md +29 -0
  28. data/vendor/libhydrogen/hydrogen.c +18 -0
  29. data/vendor/libhydrogen/hydrogen.h +317 -0
  30. data/vendor/libhydrogen/impl/common.h +316 -0
  31. data/vendor/libhydrogen/impl/core.h +220 -0
  32. data/vendor/libhydrogen/impl/gimli-core/portable.h +39 -0
  33. data/vendor/libhydrogen/impl/gimli-core/sse2.h +97 -0
  34. data/vendor/libhydrogen/impl/gimli-core.h +25 -0
  35. data/vendor/libhydrogen/impl/hash.h +138 -0
  36. data/vendor/libhydrogen/impl/hydrogen_p.h +83 -0
  37. data/vendor/libhydrogen/impl/kdf.h +20 -0
  38. data/vendor/libhydrogen/impl/kx.h +441 -0
  39. data/vendor/libhydrogen/impl/pwhash.h +281 -0
  40. data/vendor/libhydrogen/impl/random.h +376 -0
  41. data/vendor/libhydrogen/impl/secretbox.h +236 -0
  42. data/vendor/libhydrogen/impl/sign.h +207 -0
  43. data/vendor/libhydrogen/impl/x25519.h +383 -0
  44. data/vendor/libhydrogen/library.properties +10 -0
  45. data/vendor/libhydrogen/logo.png +0 -0
  46. data/vendor/libhydrogen/tests/tests.c +431 -0
  47. data/vendor/main.c +140 -0
  48. data/vendor/stringencoders/.gitignore +25 -0
  49. data/vendor/stringencoders/.travis.yml +13 -0
  50. data/vendor/stringencoders/AUTHORS +1 -0
  51. data/vendor/stringencoders/COPYING +2 -0
  52. data/vendor/stringencoders/ChangeLog +170 -0
  53. data/vendor/stringencoders/Doxyfile +276 -0
  54. data/vendor/stringencoders/INSTALL +119 -0
  55. data/vendor/stringencoders/LICENSE +22 -0
  56. data/vendor/stringencoders/Makefile.am +3 -0
  57. data/vendor/stringencoders/NEWS +3 -0
  58. data/vendor/stringencoders/README +2 -0
  59. data/vendor/stringencoders/README.md +32 -0
  60. data/vendor/stringencoders/bootstrap.sh +3 -0
  61. data/vendor/stringencoders/configure-gcc-hardened.sh +16 -0
  62. data/vendor/stringencoders/configure.ac +44 -0
  63. data/vendor/stringencoders/doxy/footer.html +34 -0
  64. data/vendor/stringencoders/doxy/header.html +85 -0
  65. data/vendor/stringencoders/indent.sh +9 -0
  66. data/vendor/stringencoders/javascript/base64-speed.html +43 -0
  67. data/vendor/stringencoders/javascript/base64-test.html +209 -0
  68. data/vendor/stringencoders/javascript/base64.html +18 -0
  69. data/vendor/stringencoders/javascript/base64.js +176 -0
  70. data/vendor/stringencoders/javascript/qunit.css +119 -0
  71. data/vendor/stringencoders/javascript/qunit.js +1062 -0
  72. data/vendor/stringencoders/javascript/urlparse-test.html +367 -0
  73. data/vendor/stringencoders/javascript/urlparse.js +328 -0
  74. data/vendor/stringencoders/make-ci.sh +13 -0
  75. data/vendor/stringencoders/makerelease.sh +16 -0
  76. data/vendor/stringencoders/python/b85.py +176 -0
  77. data/vendor/stringencoders/src/Makefile.am +134 -0
  78. data/vendor/stringencoders/src/arraytoc.c +85 -0
  79. data/vendor/stringencoders/src/arraytoc.h +43 -0
  80. data/vendor/stringencoders/src/extern_c_begin.h +3 -0
  81. data/vendor/stringencoders/src/extern_c_end.h +3 -0
  82. data/vendor/stringencoders/src/html_named_entities_generator.py +203 -0
  83. data/vendor/stringencoders/src/modp_ascii.c +159 -0
  84. data/vendor/stringencoders/src/modp_ascii.h +162 -0
  85. data/vendor/stringencoders/src/modp_ascii_data.h +84 -0
  86. data/vendor/stringencoders/src/modp_ascii_gen.c +55 -0
  87. data/vendor/stringencoders/src/modp_b16.c +125 -0
  88. data/vendor/stringencoders/src/modp_b16.h +148 -0
  89. data/vendor/stringencoders/src/modp_b16_data.h +104 -0
  90. data/vendor/stringencoders/src/modp_b16_gen.c +65 -0
  91. data/vendor/stringencoders/src/modp_b2.c +69 -0
  92. data/vendor/stringencoders/src/modp_b2.h +130 -0
  93. data/vendor/stringencoders/src/modp_b2_data.h +44 -0
  94. data/vendor/stringencoders/src/modp_b2_gen.c +36 -0
  95. data/vendor/stringencoders/src/modp_b36.c +108 -0
  96. data/vendor/stringencoders/src/modp_b36.h +170 -0
  97. data/vendor/stringencoders/src/modp_b64.c +254 -0
  98. data/vendor/stringencoders/src/modp_b64.h +236 -0
  99. data/vendor/stringencoders/src/modp_b64_data.h +477 -0
  100. data/vendor/stringencoders/src/modp_b64_gen.c +168 -0
  101. data/vendor/stringencoders/src/modp_b64r.c +254 -0
  102. data/vendor/stringencoders/src/modp_b64r.h +242 -0
  103. data/vendor/stringencoders/src/modp_b64r_data.h +477 -0
  104. data/vendor/stringencoders/src/modp_b64w.c +254 -0
  105. data/vendor/stringencoders/src/modp_b64w.h +231 -0
  106. data/vendor/stringencoders/src/modp_b64w_data.h +477 -0
  107. data/vendor/stringencoders/src/modp_b85.c +109 -0
  108. data/vendor/stringencoders/src/modp_b85.h +171 -0
  109. data/vendor/stringencoders/src/modp_b85_data.h +36 -0
  110. data/vendor/stringencoders/src/modp_b85_gen.c +65 -0
  111. data/vendor/stringencoders/src/modp_bjavascript.c +65 -0
  112. data/vendor/stringencoders/src/modp_bjavascript.h +105 -0
  113. data/vendor/stringencoders/src/modp_bjavascript_data.h +84 -0
  114. data/vendor/stringencoders/src/modp_bjavascript_gen.c +58 -0
  115. data/vendor/stringencoders/src/modp_burl.c +228 -0
  116. data/vendor/stringencoders/src/modp_burl.h +259 -0
  117. data/vendor/stringencoders/src/modp_burl_data.h +136 -0
  118. data/vendor/stringencoders/src/modp_burl_gen.c +121 -0
  119. data/vendor/stringencoders/src/modp_html.c +128 -0
  120. data/vendor/stringencoders/src/modp_html.h +53 -0
  121. data/vendor/stringencoders/src/modp_html_named_entities.h +9910 -0
  122. data/vendor/stringencoders/src/modp_json.c +315 -0
  123. data/vendor/stringencoders/src/modp_json.h +103 -0
  124. data/vendor/stringencoders/src/modp_json_data.h +57 -0
  125. data/vendor/stringencoders/src/modp_json_gen.py +60 -0
  126. data/vendor/stringencoders/src/modp_mainpage.h +120 -0
  127. data/vendor/stringencoders/src/modp_numtoa.c +350 -0
  128. data/vendor/stringencoders/src/modp_numtoa.h +100 -0
  129. data/vendor/stringencoders/src/modp_qsiter.c +76 -0
  130. data/vendor/stringencoders/src/modp_qsiter.h +71 -0
  131. data/vendor/stringencoders/src/modp_stdint.h +43 -0
  132. data/vendor/stringencoders/src/modp_utf8.c +88 -0
  133. data/vendor/stringencoders/src/modp_utf8.h +38 -0
  134. data/vendor/stringencoders/src/modp_xml.c +311 -0
  135. data/vendor/stringencoders/src/modp_xml.h +166 -0
  136. data/vendor/stringencoders/src/stringencoders.pc +10 -0
  137. data/vendor/stringencoders/src/stringencoders.pc.in +10 -0
  138. data/vendor/stringencoders/test/Makefile.am +113 -0
  139. data/vendor/stringencoders/test/apr_base64.c +262 -0
  140. data/vendor/stringencoders/test/apr_base64.h +120 -0
  141. data/vendor/stringencoders/test/cxx_test.cc +482 -0
  142. data/vendor/stringencoders/test/minunit.h +82 -0
  143. data/vendor/stringencoders/test/modp_ascii_test.c +281 -0
  144. data/vendor/stringencoders/test/modp_b16_test.c +288 -0
  145. data/vendor/stringencoders/test/modp_b2_test.c +250 -0
  146. data/vendor/stringencoders/test/modp_b64_test.c +266 -0
  147. data/vendor/stringencoders/test/modp_b85_test.c +130 -0
  148. data/vendor/stringencoders/test/modp_bjavascript_test.c +137 -0
  149. data/vendor/stringencoders/test/modp_burl_test.c +423 -0
  150. data/vendor/stringencoders/test/modp_html_test.c +296 -0
  151. data/vendor/stringencoders/test/modp_json_test.c +336 -0
  152. data/vendor/stringencoders/test/modp_numtoa_test.c +545 -0
  153. data/vendor/stringencoders/test/modp_qsiter_test.c +280 -0
  154. data/vendor/stringencoders/test/modp_utf8_test.c +188 -0
  155. data/vendor/stringencoders/test/modp_xml_test.c +339 -0
  156. data/vendor/stringencoders/test/speedtest.c +241 -0
  157. data/vendor/stringencoders/test/speedtest_ascii.c +345 -0
  158. data/vendor/stringencoders/test/speedtest_msg.c +78 -0
  159. data/vendor/stringencoders/test/speedtest_numtoa.c +276 -0
  160. metadata +314 -0
@@ -0,0 +1,220 @@
1
+ int
2
+ hydro_init(void)
3
+ {
4
+ if (hydro_random_init() != 0) {
5
+ abort();
6
+ }
7
+ return 0;
8
+ }
9
+
10
+ void
11
+ hydro_memzero(void *pnt, size_t len)
12
+ {
13
+ volatile unsigned char *volatile pnt_ = (volatile unsigned char *volatile) pnt;
14
+ size_t i = (size_t) 0U;
15
+
16
+ while (i < len) {
17
+ pnt_[i++] = 0U;
18
+ }
19
+ }
20
+
21
+ void
22
+ hydro_increment(uint8_t *n, size_t len)
23
+ {
24
+ size_t i;
25
+ uint_fast16_t c = 1U;
26
+
27
+ for (i = 0; i < len; i++) {
28
+ c += (uint_fast16_t) n[i];
29
+ n[i] = (uint8_t) c;
30
+ c >>= 8;
31
+ }
32
+ }
33
+
34
+ char *
35
+ hydro_bin2hex(char *hex, size_t hex_maxlen, const uint8_t *bin, size_t bin_len)
36
+ {
37
+ size_t i = (size_t) 0U;
38
+ unsigned int x;
39
+ int b;
40
+ int c;
41
+
42
+ if (bin_len >= SIZE_MAX / 2 || hex_maxlen <= bin_len * 2U) {
43
+ abort();
44
+ }
45
+ while (i < bin_len) {
46
+ c = bin[i] & 0xf;
47
+ b = bin[i] >> 4;
48
+ x = (unsigned char) (87U + c + (((c - 10U) >> 8) & ~38U)) << 8 |
49
+ (unsigned char) (87U + b + (((b - 10U) >> 8) & ~38U));
50
+ hex[i * 2U] = (char) x;
51
+ x >>= 8;
52
+ hex[i * 2U + 1U] = (char) x;
53
+ i++;
54
+ }
55
+ hex[i * 2U] = 0U;
56
+
57
+ return hex;
58
+ }
59
+
60
+ int
61
+ hydro_hex2bin(uint8_t *bin, size_t bin_maxlen, const char *hex, size_t hex_len, const char *ignore,
62
+ const char **hex_end_p)
63
+ {
64
+ size_t bin_pos = (size_t) 0U;
65
+ size_t hex_pos = (size_t) 0U;
66
+ int ret = 0;
67
+ unsigned char c;
68
+ unsigned char c_alpha0, c_alpha;
69
+ unsigned char c_num0, c_num;
70
+ uint8_t c_acc = 0U;
71
+ uint8_t c_val;
72
+ unsigned char state = 0U;
73
+
74
+ while (hex_pos < hex_len) {
75
+ c = (unsigned char) hex[hex_pos];
76
+ c_num = c ^ 48U;
77
+ c_num0 = (c_num - 10U) >> 8;
78
+ c_alpha = (c & ~32U) - 55U;
79
+ c_alpha0 = ((c_alpha - 10U) ^ (c_alpha - 16U)) >> 8;
80
+ if ((c_num0 | c_alpha0) == 0U) {
81
+ if (ignore != NULL && state == 0U && strchr(ignore, c) != NULL) {
82
+ hex_pos++;
83
+ continue;
84
+ }
85
+ break;
86
+ }
87
+ c_val = (uint8_t)((c_num0 & c_num) | (c_alpha0 & c_alpha));
88
+ if (bin_pos >= bin_maxlen) {
89
+ ret = -1;
90
+ errno = ERANGE;
91
+ break;
92
+ }
93
+ if (state == 0U) {
94
+ c_acc = c_val * 16U;
95
+ } else {
96
+ bin[bin_pos++] = c_acc | c_val;
97
+ }
98
+ state = ~state;
99
+ hex_pos++;
100
+ }
101
+ if (state != 0U) {
102
+ hex_pos--;
103
+ errno = EINVAL;
104
+ ret = -1;
105
+ }
106
+ if (ret != 0) {
107
+ bin_pos = (size_t) 0U;
108
+ }
109
+ if (hex_end_p != NULL) {
110
+ *hex_end_p = &hex[hex_pos];
111
+ } else if (hex_pos != hex_len) {
112
+ errno = EINVAL;
113
+ ret = -1;
114
+ }
115
+ if (ret != 0) {
116
+ return ret;
117
+ }
118
+ return (int) bin_pos;
119
+ }
120
+
121
+ bool
122
+ hydro_equal(const void *b1_, const void *b2_, size_t len)
123
+ {
124
+ const volatile uint8_t *volatile b1 = (const volatile uint8_t *volatile) b1_;
125
+ const uint8_t *b2 = (const uint8_t *) b2_;
126
+ size_t i;
127
+ uint8_t d = (uint8_t) 0U;
128
+
129
+ if (b1 == b2) {
130
+ d = ~d;
131
+ }
132
+ for (i = 0U; i < len; i++) {
133
+ d |= b1[i] ^ b2[i];
134
+ }
135
+ return (bool) (1 & ((d - 1) >> 8));
136
+ }
137
+
138
+ int
139
+ hydro_compare(const uint8_t *b1_, const uint8_t *b2_, size_t len)
140
+ {
141
+ const volatile uint8_t *volatile b1 = (const volatile uint8_t *volatile) b1_;
142
+ const uint8_t *b2 = (const uint8_t *) b2_;
143
+ uint8_t gt = 0U;
144
+ uint8_t eq = 1U;
145
+ size_t i;
146
+
147
+ i = len;
148
+ while (i != 0U) {
149
+ i--;
150
+ gt |= ((b2[i] - b1[i]) >> 8) & eq;
151
+ eq &= ((b2[i] ^ b1[i]) - 1) >> 8;
152
+ }
153
+ return (int) (gt + gt + eq) - 1;
154
+ }
155
+
156
+ int
157
+ hydro_pad(unsigned char *buf, size_t unpadded_buflen, size_t blocksize, size_t max_buflen)
158
+ {
159
+ unsigned char * tail;
160
+ size_t i;
161
+ size_t xpadlen;
162
+ size_t xpadded_len;
163
+ volatile unsigned char mask;
164
+ unsigned char barrier_mask;
165
+
166
+ if (blocksize <= 0U || max_buflen > INT_MAX) {
167
+ return -1;
168
+ }
169
+ xpadlen = blocksize - 1U;
170
+ if ((blocksize & (blocksize - 1U)) == 0U) {
171
+ xpadlen -= unpadded_buflen & (blocksize - 1U);
172
+ } else {
173
+ xpadlen -= unpadded_buflen % blocksize;
174
+ }
175
+ if (SIZE_MAX - unpadded_buflen <= xpadlen) {
176
+ return -1;
177
+ }
178
+ xpadded_len = unpadded_buflen + xpadlen;
179
+ if (xpadded_len >= max_buflen) {
180
+ return -1;
181
+ }
182
+ tail = &buf[xpadded_len];
183
+ mask = 0U;
184
+ for (i = 0; i < blocksize; i++) {
185
+ barrier_mask = (unsigned char)
186
+ (((i ^ xpadlen) - 1U) >> ((sizeof(size_t) - 1U) * CHAR_BIT));
187
+ tail[-i] = (tail[-i] & mask) | (0x80 & barrier_mask);
188
+ mask |= barrier_mask;
189
+ }
190
+ return (int) (xpadded_len + 1);
191
+ }
192
+
193
+ int
194
+ hydro_unpad(const unsigned char *buf, size_t padded_buflen, size_t blocksize)
195
+ {
196
+ const unsigned char *tail;
197
+ unsigned char acc = 0U;
198
+ unsigned char c;
199
+ unsigned char valid = 0U;
200
+ volatile size_t pad_len = 0U;
201
+ size_t i;
202
+ size_t is_barrier;
203
+
204
+ if (padded_buflen < blocksize || blocksize <= 0U) {
205
+ return -1;
206
+ }
207
+ tail = &buf[padded_buflen - 1U];
208
+
209
+ for (i = 0U; i < blocksize; i++) {
210
+ c = tail[-i];
211
+ is_barrier = (((acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U)) >> 8) & 1U;
212
+ acc |= c;
213
+ pad_len |= (i & -is_barrier);
214
+ valid |= (unsigned char) is_barrier;
215
+ }
216
+ if (valid == 0) {
217
+ return -1;
218
+ }
219
+ return (int) (padded_buflen - 1 - pad_len);
220
+ }
@@ -0,0 +1,39 @@
1
+ static void
2
+ gimli_core(uint32_t state[gimli_BLOCKBYTES / 4])
3
+ {
4
+ unsigned int round;
5
+ unsigned int column;
6
+ uint32_t x;
7
+ uint32_t y;
8
+ uint32_t z;
9
+
10
+ for (round = 24; round > 0; round--) {
11
+ for (column = 0; column < 4; column++) {
12
+ x = ROTL32(state[column], 24);
13
+ y = ROTL32(state[4 + column], 9);
14
+ z = state[8 + column];
15
+
16
+ state[8 + column] = x ^ (z << 1) ^ ((y & z) << 2);
17
+ state[4 + column] = y ^ x ^ ((x | z) << 1);
18
+ state[column] = z ^ y ^ ((x & y) << 3);
19
+ }
20
+ switch (round & 3) {
21
+ case 0:
22
+ x = state[0];
23
+ state[0] = state[1];
24
+ state[1] = x;
25
+ x = state[2];
26
+ state[2] = state[3];
27
+ state[3] = x;
28
+ state[0] ^= ((uint32_t) 0x9e377900 | round);
29
+ break;
30
+ case 2:
31
+ x = state[0];
32
+ state[0] = state[2];
33
+ state[2] = x;
34
+ x = state[1];
35
+ state[1] = state[3];
36
+ state[3] = x;
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,97 @@
1
+ #include <tmmintrin.h>
2
+
3
+ #define S 9
4
+
5
+ static inline __m128i
6
+ shift(__m128i x, int bits)
7
+ {
8
+ return _mm_slli_epi32(x, bits);
9
+ }
10
+
11
+ static inline __m128i
12
+ rotate(__m128i x, int bits)
13
+ {
14
+ return _mm_slli_epi32(x, bits) | _mm_srli_epi32(x, 32 - bits);
15
+ }
16
+
17
+ #ifdef __SSSE3__
18
+ static inline __m128i
19
+ rotate24(__m128i x)
20
+ {
21
+ return _mm_shuffle_epi8(x, _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1));
22
+ }
23
+ #else
24
+ static inline __m128i
25
+ rotate24(__m128i x)
26
+ {
27
+ uint8_t _hydro_attr_aligned_(16) x8[16], y8[16];
28
+
29
+ _mm_storeu_si128((__m128i *) (void *) x8, x);
30
+
31
+ y8[ 0] = x8[ 1]; y8[ 1] = x8[ 2]; y8[ 2] = x8[ 3]; y8[ 3] = x8[ 0];
32
+ y8[ 4] = x8[ 5]; y8[ 5] = x8[ 6]; y8[ 6] = x8[ 7]; y8[ 7] = x8[ 4];
33
+ y8[ 8] = x8[ 9]; y8[ 9] = x8[10]; y8[10] = x8[11]; y8[11] = x8[ 8];
34
+ y8[12] = x8[13]; y8[13] = x8[14]; y8[14] = x8[15]; y8[15] = x8[12];
35
+
36
+ return _mm_loadu_si128((const __m128i *) (const void *) y8);
37
+ }
38
+ #endif
39
+
40
+ static const uint32_t coeffs[24] _hydro_attr_aligned_(16) = {
41
+ 0x9e377904, 0, 0, 0, 0x9e377908, 0, 0, 0, 0x9e37790c, 0, 0, 0,
42
+ 0x9e377910, 0, 0, 0, 0x9e377914, 0, 0, 0, 0x9e377918, 0, 0, 0,
43
+ };
44
+
45
+ static void
46
+ gimli_core(uint32_t state[gimli_BLOCKBYTES / 4])
47
+ {
48
+ __m128i x = _mm_loadu_si128((const __m128i *) (const void *) &state[0]);
49
+ __m128i y = _mm_loadu_si128((const __m128i *) (const void *) &state[4]);
50
+ __m128i z = _mm_loadu_si128((const __m128i *) (const void *) &state[8]);
51
+ __m128i newy;
52
+ __m128i newz;
53
+ int round;
54
+
55
+ for (round = 5; round >= 0; round--) {
56
+ x = rotate24(x);
57
+ y = rotate(y, S);
58
+ newz = x ^ shift(z, 1) ^ shift(y & z, 2);
59
+ newy = y ^ x ^ shift(x | z, 1);
60
+ x = z ^ y ^ shift(x & y, 3);
61
+ y = newy;
62
+ z = newz;
63
+
64
+ x = _mm_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1));
65
+ x ^= ((const __m128i *) (const void *) coeffs)[round];
66
+
67
+ x = rotate24(x);
68
+ y = rotate(y, S);
69
+ newz = x ^ shift(z, 1) ^ shift(y & z, 2);
70
+ newy = y ^ x ^ shift(x | z, 1);
71
+ x = z ^ y ^ shift(x & y, 3);
72
+ y = newy;
73
+ z = newz;
74
+
75
+ x = rotate24(x);
76
+ y = rotate(y, S);
77
+ newz = x ^ shift(z, 1) ^ shift(y & z, 2);
78
+ newy = y ^ x ^ shift(x | z, 1);
79
+ x = z ^ y ^ shift(x & y, 3);
80
+ y = newy;
81
+ z = newz;
82
+
83
+ x = _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2));
84
+
85
+ x = rotate24(x);
86
+ y = rotate(y, S);
87
+ newz = x ^ shift(z, 1) ^ shift(y & z, 2);
88
+ newy = y ^ x ^ shift(x | z, 1);
89
+ x = z ^ y ^ shift(x & y, 3);
90
+ y = newy;
91
+ z = newz;
92
+ }
93
+
94
+ _mm_storeu_si128((__m128i *) (void *) &state[0], x);
95
+ _mm_storeu_si128((__m128i *) (void *) &state[4], y);
96
+ _mm_storeu_si128((__m128i *) (void *) &state[8], z);
97
+ }
@@ -0,0 +1,25 @@
1
+ #ifdef __SSE2__
2
+ # include "gimli-core/sse2.h"
3
+ #else
4
+ # include "gimli-core/portable.h"
5
+ #endif
6
+
7
+ static void
8
+ gimli_core_u8(uint8_t state_u8[gimli_BLOCKBYTES], uint8_t tag)
9
+ {
10
+ state_u8[gimli_BLOCKBYTES - 1] ^= tag;
11
+ #ifndef NATIVE_LITTLE_ENDIAN
12
+ uint32_t state_u32[12];
13
+ int i;
14
+
15
+ for (i = 0; i < 12; i++) {
16
+ state_u32[i] = LOAD32_LE(&state_u8[i * 4]);
17
+ }
18
+ gimli_core(state_u32);
19
+ for (i = 0; i < 12; i++) {
20
+ STORE32_LE(&state_u8[i * 4], state_u32[i]);
21
+ }
22
+ #else
23
+ gimli_core((uint32_t *) (void *) state_u8); /* state_u8 must be properly aligned */
24
+ #endif
25
+ }
@@ -0,0 +1,138 @@
1
+ int
2
+ hydro_hash_update(hydro_hash_state *state, const void *in_, size_t in_len)
3
+ {
4
+ const uint8_t *in = (const uint8_t *) in_;
5
+ uint8_t * buf = (uint8_t *) (void *) state->state;
6
+ size_t left;
7
+ size_t ps;
8
+ size_t i;
9
+
10
+ while (in_len > 0) {
11
+ if ((left = gimli_RATE - state->buf_off) == 0) {
12
+ gimli_core_u8(buf, 0);
13
+ state->buf_off = 0;
14
+ left = gimli_RATE;
15
+ }
16
+ if ((ps = in_len) > left) {
17
+ ps = left;
18
+ }
19
+ for (i = 0; i < ps; i++) {
20
+ buf[state->buf_off + i] ^= in[i];
21
+ }
22
+ state->buf_off += (uint8_t) ps;
23
+ in += ps;
24
+ in_len -= ps;
25
+ }
26
+ return 0;
27
+ }
28
+
29
+ /* pad(str_enc("kmac") || str_enc(context)) || pad(str_enc(k)) ||
30
+ msg || right_enc(msg_len) || 0x00 */
31
+
32
+ int
33
+ hydro_hash_init(hydro_hash_state *state, const char ctx[hydro_hash_CONTEXTBYTES],
34
+ const uint8_t key[hydro_hash_KEYBYTES])
35
+ {
36
+ uint8_t block[64] = { 4, 'k', 'm', 'a', 'c', 8 };
37
+ size_t p;
38
+
39
+ COMPILER_ASSERT(hydro_hash_KEYBYTES <= sizeof block - gimli_RATE - 1);
40
+ COMPILER_ASSERT(hydro_hash_CONTEXTBYTES == 8);
41
+ mem_zero(block + 14, sizeof block - 14);
42
+ memcpy(block + 6, ctx, 8);
43
+ if (key != NULL) {
44
+ block[gimli_RATE] = (uint8_t) hydro_hash_KEYBYTES;
45
+ memcpy(block + gimli_RATE + 1, key, hydro_hash_KEYBYTES);
46
+ p = (gimli_RATE + 1 + hydro_hash_KEYBYTES + (gimli_RATE - 1)) & ~(size_t)(gimli_RATE - 1);
47
+ } else {
48
+ block[gimli_RATE] = (uint8_t) 0;
49
+ p = (gimli_RATE + 1 + 0 + (gimli_RATE - 1)) & ~(size_t)(gimli_RATE - 1);
50
+ }
51
+ mem_zero(state, sizeof *state);
52
+ hydro_hash_update(state, block, p);
53
+
54
+ return 0;
55
+ }
56
+
57
+ /* pad(str_enc("tmac") || str_enc(context)) || pad(str_enc(k)) ||
58
+ pad(right_enc(tweak)) || msg || right_enc(msg_len) || 0x00 */
59
+
60
+ static int
61
+ hydro_hash_init_with_tweak(hydro_hash_state *state, const char ctx[hydro_hash_CONTEXTBYTES],
62
+ uint64_t tweak, const uint8_t key[hydro_hash_KEYBYTES])
63
+ {
64
+ uint8_t block[80] = { 4, 't', 'm', 'a', 'c', 8 };
65
+ size_t p;
66
+
67
+ COMPILER_ASSERT(hydro_hash_KEYBYTES <= sizeof block - 2 * gimli_RATE - 1);
68
+ COMPILER_ASSERT(hydro_hash_CONTEXTBYTES == 8);
69
+ mem_zero(block + 14, sizeof block - 14);
70
+ memcpy(block + 6, ctx, 8);
71
+ if (key != NULL) {
72
+ block[gimli_RATE] = (uint8_t) hydro_hash_KEYBYTES;
73
+ memcpy(block + gimli_RATE + 1, key, hydro_hash_KEYBYTES);
74
+ p = (gimli_RATE + 1 + hydro_hash_KEYBYTES + (gimli_RATE - 1)) & ~(size_t)(gimli_RATE - 1);
75
+ } else {
76
+ block[gimli_RATE] = (uint8_t) 0;
77
+ p = (gimli_RATE + 1 + 0 + (gimli_RATE - 1)) & ~(size_t)(gimli_RATE - 1);
78
+ }
79
+ block[p] = (uint8_t) sizeof tweak;
80
+ STORE64_LE(&block[p + 1], tweak);
81
+ p += gimli_RATE;
82
+ mem_zero(state, sizeof *state);
83
+ hydro_hash_update(state, block, p);
84
+
85
+ return 0;
86
+ }
87
+
88
+ int
89
+ hydro_hash_final(hydro_hash_state *state, uint8_t *out, size_t out_len)
90
+ {
91
+ uint8_t lc[4];
92
+ uint8_t *buf = (uint8_t *) (void *) state->state;
93
+ size_t i;
94
+ size_t lc_len;
95
+ size_t leftover;
96
+
97
+ if (out_len < hydro_hash_BYTES_MIN || out_len > hydro_hash_BYTES_MAX) {
98
+ return -1;
99
+ }
100
+ COMPILER_ASSERT(hydro_hash_BYTES_MAX <= 0xffff);
101
+ lc[1] = (uint8_t) out_len;
102
+ lc[2] = (uint8_t)(out_len >> 8);
103
+ lc[3] = 0;
104
+ lc_len = (size_t)(1 + (lc[2] != 0));
105
+ lc[0] = (uint8_t) lc_len;
106
+ hydro_hash_update(state, lc, 1 + lc_len + 1);
107
+ gimli_pad_u8(buf, state->buf_off, gimli_DOMAIN_XOF);
108
+ for (i = 0; i < out_len / gimli_RATE; i++) {
109
+ gimli_core_u8(buf, 0);
110
+ memcpy(out + i * gimli_RATE, buf, gimli_RATE);
111
+ }
112
+ leftover = out_len % gimli_RATE;
113
+ if (leftover != 0) {
114
+ gimli_core_u8(buf, 0);
115
+ mem_cpy(out + i * gimli_RATE, buf, leftover);
116
+ }
117
+ return 0;
118
+ }
119
+
120
+ int
121
+ hydro_hash_hash(uint8_t *out, size_t out_len, const void *in_, size_t in_len,
122
+ const char ctx[hydro_hash_CONTEXTBYTES], const uint8_t key[hydro_hash_KEYBYTES])
123
+ {
124
+ hydro_hash_state st;
125
+ const uint8_t * in = (const uint8_t *) in_;
126
+
127
+ if (hydro_hash_init(&st, ctx, key) != 0 || hydro_hash_update(&st, in, in_len) != 0 ||
128
+ hydro_hash_final(&st, out, out_len) != 0) {
129
+ return -1;
130
+ }
131
+ return 0;
132
+ }
133
+
134
+ void
135
+ hydro_hash_keygen(uint8_t key[hydro_hash_KEYBYTES])
136
+ {
137
+ hydro_random_buf(key, hydro_hash_KEYBYTES);
138
+ }
@@ -0,0 +1,83 @@
1
+ static int hydro_random_init(void);
2
+
3
+ /* ---------------- */
4
+
5
+ #define gimli_BLOCKBYTES 48
6
+ #define gimli_CAPACITY 32
7
+ #define gimli_RATE 16
8
+
9
+ #define gimli_TAG_HEADER 0x01
10
+ #define gimli_TAG_PAYLOAD 0x02
11
+ #define gimli_TAG_FINAL 0x08
12
+ #define gimli_TAG_FINAL0 0xf8
13
+ #define gimli_TAG_KEY0 0xfe
14
+ #define gimli_TAG_KEY 0xff
15
+
16
+ #define gimli_DOMAIN_AEAD 0x0
17
+ #define gimli_DOMAIN_XOF 0xf
18
+
19
+ static void gimli_core_u8(uint8_t state_u8[gimli_BLOCKBYTES], uint8_t tag);
20
+
21
+ static inline void
22
+ gimli_pad_u8(uint8_t buf[gimli_BLOCKBYTES], size_t pos, uint8_t domain)
23
+ {
24
+ buf[pos] ^= (domain << 1) | 1;
25
+ buf[gimli_RATE - 1] ^= 0x80;
26
+ }
27
+
28
+ static inline void
29
+ hydro_mem_ct_zero_u32(uint32_t *dst_, size_t n)
30
+ {
31
+ volatile uint32_t *volatile dst = (volatile uint32_t * volatile)(void *) dst_;
32
+ size_t i;
33
+
34
+ for (i = 0; i < n; i++) {
35
+ dst[i] = 0;
36
+ }
37
+ }
38
+
39
+ static inline uint32_t hydro_mem_ct_cmp_u32(const uint32_t *b1_, const uint32_t *b2,
40
+ size_t n) _hydro_attr_warn_unused_result_;
41
+
42
+ static inline uint32_t
43
+ hydro_mem_ct_cmp_u32(const uint32_t *b1_, const uint32_t *b2, size_t n)
44
+ {
45
+ const volatile uint32_t *volatile b1 = (const volatile uint32_t *volatile)(const void *) b1_;
46
+ size_t i;
47
+ uint32_t cv = 0;
48
+
49
+ for (i = 0; i < n; i++) {
50
+ cv |= b1[i] ^ b2[i];
51
+ }
52
+ return cv;
53
+ }
54
+
55
+ /* ---------------- */
56
+
57
+ static int hydro_hash_init_with_tweak(hydro_hash_state *state,
58
+ const char ctx[hydro_hash_CONTEXTBYTES], uint64_t tweak,
59
+ const uint8_t key[hydro_hash_KEYBYTES]);
60
+
61
+ /* ---------------- */
62
+
63
+ #define hydro_secretbox_NONCEBYTES 20
64
+ #define hydro_secretbox_MACBYTES 16
65
+
66
+ /* ---------------- */
67
+
68
+ #define hydro_x25519_BYTES 32
69
+ #define hydro_x25519_PUBLICKEYBYTES 32
70
+ #define hydro_x25519_SECRETKEYBYTES 32
71
+
72
+ static int hydro_x25519_scalarmult(uint8_t out[hydro_x25519_BYTES],
73
+ const uint8_t scalar[hydro_x25519_BYTES],
74
+ const uint8_t x1[hydro_x25519_BYTES],
75
+ bool clamp) _hydro_attr_warn_unused_result_;
76
+
77
+ static inline int hydro_x25519_scalarmult_base(uint8_t pk[hydro_x25519_PUBLICKEYBYTES],
78
+ const uint8_t sk[hydro_x25519_SECRETKEYBYTES])
79
+ _hydro_attr_warn_unused_result_;
80
+
81
+ static inline void
82
+ hydro_x25519_scalarmult_base_uniform(uint8_t pk[hydro_x25519_PUBLICKEYBYTES],
83
+ const uint8_t sk[hydro_x25519_SECRETKEYBYTES]);
@@ -0,0 +1,20 @@
1
+ int
2
+ hydro_kdf_derive_from_key(uint8_t *subkey, size_t subkey_len, uint64_t subkey_id,
3
+ const char ctx[hydro_kdf_CONTEXTBYTES],
4
+ const uint8_t key[hydro_kdf_KEYBYTES])
5
+ {
6
+ hydro_hash_state st;
7
+
8
+ COMPILER_ASSERT(hydro_kdf_CONTEXTBYTES >= hydro_hash_CONTEXTBYTES);
9
+ COMPILER_ASSERT(hydro_kdf_KEYBYTES >= hydro_hash_KEYBYTES);
10
+ if (hydro_hash_init_with_tweak(&st, ctx, subkey_id, key) != 0) {
11
+ return -1;
12
+ }
13
+ return hydro_hash_final(&st, subkey, subkey_len);
14
+ }
15
+
16
+ void
17
+ hydro_kdf_keygen(uint8_t key[hydro_kdf_KEYBYTES])
18
+ {
19
+ hydro_random_buf(key, hydro_kdf_KEYBYTES);
20
+ }