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,236 @@
1
+ #define hydro_secretbox_IVBYTES 20
2
+ #define hydro_secretbox_SIVBYTES 20
3
+ #define hydro_secretbox_MACBYTES 16
4
+
5
+ void
6
+ hydro_secretbox_keygen(uint8_t key[hydro_secretbox_KEYBYTES])
7
+ {
8
+ hydro_random_buf(key, hydro_secretbox_KEYBYTES);
9
+ }
10
+
11
+ static void
12
+ hydro_secretbox_xor_enc(uint8_t buf[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in,
13
+ size_t inlen)
14
+ {
15
+ size_t i;
16
+ size_t leftover;
17
+
18
+ for (i = 0; i < inlen / gimli_RATE; i++) {
19
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, gimli_RATE);
20
+ memcpy(buf, &out[i * gimli_RATE], gimli_RATE);
21
+ gimli_core_u8(buf, gimli_TAG_PAYLOAD);
22
+ }
23
+ leftover = inlen % gimli_RATE;
24
+ if (leftover != 0) {
25
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, leftover);
26
+ mem_cpy(buf, &out[i * gimli_RATE], leftover);
27
+ }
28
+ gimli_pad_u8(buf, leftover, gimli_DOMAIN_AEAD);
29
+ gimli_core_u8(buf, gimli_TAG_PAYLOAD);
30
+ }
31
+
32
+ static void
33
+ hydro_secretbox_xor_dec(uint8_t buf[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in,
34
+ size_t inlen)
35
+ {
36
+ size_t i;
37
+ size_t leftover;
38
+
39
+ for (i = 0; i < inlen / gimli_RATE; i++) {
40
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, gimli_RATE);
41
+ memcpy(buf, &in[i * gimli_RATE], gimli_RATE);
42
+ gimli_core_u8(buf, gimli_TAG_PAYLOAD);
43
+ }
44
+ leftover = inlen % gimli_RATE;
45
+ if (leftover != 0) {
46
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, leftover);
47
+ mem_cpy(buf, &in[i * gimli_RATE], leftover);
48
+ }
49
+ gimli_pad_u8(buf, leftover, gimli_DOMAIN_AEAD);
50
+ gimli_core_u8(buf, gimli_TAG_PAYLOAD);
51
+ }
52
+
53
+ static void
54
+ hydro_secretbox_setup(uint8_t buf[gimli_BLOCKBYTES], uint64_t msg_id,
55
+ const char ctx[hydro_secretbox_CONTEXTBYTES],
56
+ const uint8_t key[hydro_secretbox_KEYBYTES],
57
+ const uint8_t iv[hydro_secretbox_IVBYTES], uint8_t key_tag)
58
+ {
59
+ static const uint8_t prefix[] = { 6, 's', 'b', 'x', '2', '5', '6', 8 };
60
+ uint8_t msg_id_le[8];
61
+
62
+ mem_zero(buf, gimli_BLOCKBYTES);
63
+ COMPILER_ASSERT(hydro_secretbox_CONTEXTBYTES == 8);
64
+ COMPILER_ASSERT(sizeof prefix + hydro_secretbox_CONTEXTBYTES <= gimli_RATE);
65
+ memcpy(buf, prefix, sizeof prefix);
66
+ memcpy(buf + sizeof prefix, ctx, hydro_secretbox_CONTEXTBYTES);
67
+ COMPILER_ASSERT(sizeof prefix + hydro_secretbox_CONTEXTBYTES == gimli_RATE);
68
+ gimli_core_u8(buf, gimli_TAG_HEADER);
69
+
70
+ COMPILER_ASSERT(hydro_secretbox_KEYBYTES == 2 * gimli_RATE);
71
+ mem_xor(buf, key, gimli_RATE);
72
+ gimli_core_u8(buf, key_tag);
73
+ mem_xor(buf, key + gimli_RATE, gimli_RATE);
74
+ gimli_core_u8(buf, key_tag);
75
+
76
+ COMPILER_ASSERT(hydro_secretbox_IVBYTES < gimli_RATE * 2);
77
+ buf[0] ^= hydro_secretbox_IVBYTES;
78
+ mem_xor(&buf[1], iv, gimli_RATE - 1);
79
+ gimli_core_u8(buf, gimli_TAG_HEADER);
80
+ mem_xor(buf, iv + gimli_RATE - 1, hydro_secretbox_IVBYTES - (gimli_RATE - 1));
81
+ STORE64_LE(msg_id_le, msg_id);
82
+ COMPILER_ASSERT(hydro_secretbox_IVBYTES - gimli_RATE + 8 <= gimli_RATE);
83
+ mem_xor(buf + hydro_secretbox_IVBYTES - gimli_RATE, msg_id_le, 8);
84
+ gimli_core_u8(buf, gimli_TAG_HEADER);
85
+ }
86
+
87
+ static void
88
+ hydro_secretbox_finalize(uint8_t *buf, const uint8_t key[hydro_secretbox_KEYBYTES], uint8_t tag)
89
+ {
90
+ COMPILER_ASSERT(hydro_secretbox_KEYBYTES == gimli_CAPACITY);
91
+ mem_xor(buf + gimli_RATE, key, hydro_secretbox_KEYBYTES);
92
+ gimli_core_u8(buf, tag);
93
+ mem_xor(buf + gimli_RATE, key, hydro_secretbox_KEYBYTES);
94
+ gimli_core_u8(buf, tag);
95
+ }
96
+
97
+ static int
98
+ hydro_secretbox_encrypt_iv(uint8_t *c, const void *m_, size_t mlen, uint64_t msg_id,
99
+ const char ctx[hydro_secretbox_CONTEXTBYTES],
100
+ const uint8_t key[hydro_secretbox_KEYBYTES],
101
+ const uint8_t iv[hydro_secretbox_IVBYTES])
102
+ {
103
+ _hydro_attr_aligned_(16) uint32_t state[gimli_BLOCKBYTES / 4];
104
+ uint8_t * buf = (uint8_t *) (void *) state;
105
+ const uint8_t * m = (const uint8_t *) m_;
106
+ uint8_t * siv = &c[0];
107
+ uint8_t * mac = &c[hydro_secretbox_SIVBYTES];
108
+ uint8_t * ct = &c[hydro_secretbox_SIVBYTES + hydro_secretbox_MACBYTES];
109
+ size_t i;
110
+ size_t leftover;
111
+
112
+ if (c == m) {
113
+ memmove(c + hydro_secretbox_HEADERBYTES, m, mlen);
114
+ m = c + hydro_secretbox_HEADERBYTES;
115
+ }
116
+
117
+ /* first pass: compute the SIV */
118
+
119
+ hydro_secretbox_setup(buf, msg_id, ctx, key, iv, gimli_TAG_KEY0);
120
+ for (i = 0; i < mlen / gimli_RATE; i++) {
121
+ mem_xor(buf, &m[i * gimli_RATE], gimli_RATE);
122
+ gimli_core_u8(buf, gimli_TAG_PAYLOAD);
123
+ }
124
+ leftover = mlen % gimli_RATE;
125
+ if (leftover != 0) {
126
+ mem_xor(buf, &m[i * gimli_RATE], leftover);
127
+ }
128
+ gimli_pad_u8(buf, leftover, gimli_DOMAIN_XOF);
129
+ gimli_core_u8(buf, gimli_TAG_PAYLOAD);
130
+
131
+ hydro_secretbox_finalize(buf, key, gimli_TAG_FINAL0);
132
+ COMPILER_ASSERT(hydro_secretbox_SIVBYTES <= gimli_CAPACITY);
133
+ memcpy(siv, buf + gimli_RATE, hydro_secretbox_SIVBYTES);
134
+
135
+ /* second pass: encrypt the message, mix the key, squeeze an extra block for
136
+ * the MAC */
137
+
138
+ COMPILER_ASSERT(hydro_secretbox_SIVBYTES == hydro_secretbox_IVBYTES);
139
+ hydro_secretbox_setup(buf, msg_id, ctx, key, siv, gimli_TAG_KEY);
140
+ hydro_secretbox_xor_enc(buf, ct, m, mlen);
141
+
142
+ hydro_secretbox_finalize(buf, key, gimli_TAG_FINAL);
143
+ COMPILER_ASSERT(hydro_secretbox_MACBYTES <= gimli_CAPACITY);
144
+ memcpy(mac, buf + gimli_RATE, hydro_secretbox_MACBYTES);
145
+
146
+ return 0;
147
+ }
148
+
149
+ void
150
+ hydro_secretbox_probe_create(uint8_t probe[hydro_secretbox_PROBEBYTES], const uint8_t *c,
151
+ size_t c_len, const char ctx[hydro_secretbox_CONTEXTBYTES],
152
+ const uint8_t key[hydro_secretbox_KEYBYTES])
153
+ {
154
+ const uint8_t *mac;
155
+
156
+ if (c_len < hydro_secretbox_HEADERBYTES) {
157
+ abort();
158
+ }
159
+ mac = &c[hydro_secretbox_SIVBYTES];
160
+ COMPILER_ASSERT(hydro_secretbox_CONTEXTBYTES >= hydro_hash_CONTEXTBYTES);
161
+ COMPILER_ASSERT(hydro_secretbox_KEYBYTES >= hydro_hash_KEYBYTES);
162
+ hydro_hash_hash(probe, hydro_secretbox_PROBEBYTES, mac, hydro_secretbox_MACBYTES, ctx, key);
163
+ }
164
+
165
+ int
166
+ hydro_secretbox_probe_verify(const uint8_t probe[hydro_secretbox_PROBEBYTES], const uint8_t *c,
167
+ size_t c_len, const char ctx[hydro_secretbox_CONTEXTBYTES],
168
+ const uint8_t key[hydro_secretbox_KEYBYTES])
169
+ {
170
+ uint8_t computed_probe[hydro_secretbox_PROBEBYTES];
171
+ const uint8_t *mac;
172
+
173
+ if (c_len < hydro_secretbox_HEADERBYTES) {
174
+ return -1;
175
+ }
176
+ mac = &c[hydro_secretbox_SIVBYTES];
177
+ hydro_hash_hash(computed_probe, hydro_secretbox_PROBEBYTES, mac, hydro_secretbox_MACBYTES, ctx,
178
+ key);
179
+ if (hydro_equal(computed_probe, probe, hydro_secretbox_PROBEBYTES) == 1) {
180
+ return 0;
181
+ }
182
+ hydro_memzero(computed_probe, hydro_secretbox_PROBEBYTES);
183
+ return -1;
184
+ }
185
+
186
+ int
187
+ hydro_secretbox_encrypt(uint8_t *c, const void *m_, size_t mlen, uint64_t msg_id,
188
+ const char ctx[hydro_secretbox_CONTEXTBYTES],
189
+ const uint8_t key[hydro_secretbox_KEYBYTES])
190
+ {
191
+ uint8_t iv[hydro_secretbox_IVBYTES];
192
+
193
+ hydro_random_buf(iv, sizeof iv);
194
+
195
+ return hydro_secretbox_encrypt_iv(c, m_, mlen, msg_id, ctx, key, iv);
196
+ }
197
+
198
+ int
199
+ hydro_secretbox_decrypt(void *m_, const uint8_t *c, size_t clen, uint64_t msg_id,
200
+ const char ctx[hydro_secretbox_CONTEXTBYTES],
201
+ const uint8_t key[hydro_secretbox_KEYBYTES])
202
+ {
203
+ _hydro_attr_aligned_(16) uint32_t state[gimli_BLOCKBYTES / 4];
204
+ uint32_t pub_mac[hydro_secretbox_MACBYTES / 4];
205
+ uint8_t * buf = (uint8_t *) (void *) state;
206
+ const uint8_t * siv;
207
+ const uint8_t * mac;
208
+ const uint8_t * ct;
209
+ uint8_t * m = (uint8_t *) m_;
210
+ size_t mlen;
211
+ uint32_t cv;
212
+
213
+ if (clen < hydro_secretbox_HEADERBYTES) {
214
+ return -1;
215
+ }
216
+ siv = &c[0];
217
+ mac = &c[hydro_secretbox_SIVBYTES];
218
+ ct = &c[hydro_secretbox_SIVBYTES + hydro_secretbox_MACBYTES];
219
+
220
+ mlen = clen - hydro_secretbox_HEADERBYTES;
221
+ memcpy(pub_mac, mac, sizeof pub_mac);
222
+ COMPILER_ASSERT(hydro_secretbox_SIVBYTES == hydro_secretbox_IVBYTES);
223
+ hydro_secretbox_setup(buf, msg_id, ctx, key, siv, gimli_TAG_KEY);
224
+ hydro_secretbox_xor_dec(buf, m, ct, mlen);
225
+
226
+ hydro_secretbox_finalize(buf, key, gimli_TAG_FINAL);
227
+ COMPILER_ASSERT(hydro_secretbox_MACBYTES <= gimli_CAPACITY);
228
+ COMPILER_ASSERT(gimli_RATE % 4 == 0);
229
+ cv = hydro_mem_ct_cmp_u32(state + gimli_RATE / 4, pub_mac, hydro_secretbox_MACBYTES / 4);
230
+ hydro_mem_ct_zero_u32(state, gimli_BLOCKBYTES / 4);
231
+ if (cv != 0) {
232
+ mem_zero(m, mlen);
233
+ return -1;
234
+ }
235
+ return 0;
236
+ }
@@ -0,0 +1,207 @@
1
+ #define hydro_sign_CHALLENGEBYTES 32
2
+ #define hydro_sign_NONCEBYTES 32
3
+ #define hydro_sign_PREHASHBYTES 64
4
+
5
+ static void
6
+ hydro_sign_p2(uint8_t sig[hydro_x25519_BYTES], const uint8_t challenge[hydro_sign_CHALLENGEBYTES],
7
+ const uint8_t eph_sk[hydro_x25519_BYTES], const uint8_t sk[hydro_x25519_BYTES])
8
+ {
9
+ hydro_x25519_scalar_t scalar1, scalar2, scalar3;
10
+
11
+ COMPILER_ASSERT(hydro_sign_CHALLENGEBYTES == hydro_x25519_BYTES);
12
+ hydro_x25519_swapin(scalar1, eph_sk);
13
+ hydro_x25519_swapin(scalar2, sk);
14
+ hydro_x25519_swapin(scalar3, challenge);
15
+ hydro_x25519_sc_montmul(scalar1, scalar2, scalar3);
16
+ mem_zero(scalar2, sizeof scalar2);
17
+ hydro_x25519_sc_montmul(scalar2, scalar1, hydro_x25519_sc_r2);
18
+ hydro_x25519_swapout(sig, scalar2);
19
+ }
20
+
21
+ static void
22
+ hydro_sign_challenge(uint8_t challenge[hydro_sign_CHALLENGEBYTES],
23
+ const uint8_t nonce[hydro_sign_NONCEBYTES],
24
+ const uint8_t pk[hydro_sign_PUBLICKEYBYTES],
25
+ const uint8_t prehash[hydro_sign_PREHASHBYTES])
26
+ {
27
+ hydro_hash_state st;
28
+
29
+ hydro_hash_init(&st, (const char *) zero, NULL);
30
+ hydro_hash_update(&st, nonce, hydro_sign_NONCEBYTES);
31
+ hydro_hash_update(&st, pk, hydro_sign_PUBLICKEYBYTES);
32
+ hydro_hash_update(&st, prehash, hydro_sign_PREHASHBYTES);
33
+ hydro_hash_final(&st, challenge, hydro_sign_CHALLENGEBYTES);
34
+ }
35
+
36
+ static int
37
+ hydro_sign_prehash(uint8_t csig[hydro_sign_BYTES], const uint8_t prehash[hydro_sign_PREHASHBYTES],
38
+ const uint8_t sk[hydro_sign_SECRETKEYBYTES])
39
+ {
40
+ hydro_hash_state st;
41
+ uint8_t challenge[hydro_sign_CHALLENGEBYTES];
42
+ const uint8_t * pk = &sk[hydro_x25519_SECRETKEYBYTES];
43
+ uint8_t * nonce = &csig[0];
44
+ uint8_t * sig = &csig[hydro_sign_NONCEBYTES];
45
+ uint8_t * eph_sk = sig;
46
+
47
+ hydro_random_buf(eph_sk, hydro_x25519_SECRETKEYBYTES);
48
+ COMPILER_ASSERT(hydro_x25519_SECRETKEYBYTES == hydro_hash_KEYBYTES);
49
+ hydro_hash_init(&st, (const char *) zero, sk);
50
+ hydro_hash_update(&st, eph_sk, hydro_x25519_SECRETKEYBYTES);
51
+ hydro_hash_update(&st, prehash, hydro_sign_CHALLENGEBYTES);
52
+ hydro_hash_final(&st, eph_sk, hydro_x25519_SECRETKEYBYTES);
53
+
54
+ hydro_x25519_scalarmult_base_uniform(nonce, eph_sk);
55
+ hydro_sign_challenge(challenge, nonce, pk, prehash);
56
+
57
+ COMPILER_ASSERT(hydro_sign_BYTES == hydro_sign_NONCEBYTES + hydro_x25519_SECRETKEYBYTES);
58
+ COMPILER_ASSERT(hydro_x25519_SECRETKEYBYTES <= hydro_sign_CHALLENGEBYTES);
59
+ hydro_sign_p2(sig, challenge, eph_sk, sk);
60
+
61
+ return 0;
62
+ }
63
+
64
+ static int
65
+ hydro_sign_verify_core(hydro_x25519_fe xs[5], const hydro_x25519_limb_t *other1,
66
+ const uint8_t other2[hydro_x25519_BYTES])
67
+ {
68
+ hydro_x25519_limb_t * z2 = xs[1], *x3 = xs[2], *z3 = xs[3];
69
+ hydro_x25519_fe xo2;
70
+ const hydro_x25519_limb_t sixteen = 16;
71
+
72
+ hydro_x25519_swapin(xo2, other2);
73
+ memcpy(x3, other1, 2 * sizeof(hydro_x25519_fe));
74
+ hydro_x25519_ladder_part1(xs);
75
+
76
+ /* Here z2 = t2^2 */
77
+ hydro_x25519_mul1(z2, other1);
78
+ hydro_x25519_mul1(z2, other1 + hydro_x25519_NLIMBS);
79
+ hydro_x25519_mul1(z2, xo2);
80
+
81
+ hydro_x25519_mul(z2, z2, &sixteen, 1);
82
+
83
+ hydro_x25519_mul1(z3, xo2);
84
+ hydro_x25519_sub(z3, z3, x3);
85
+ hydro_x25519_sqr1(z3);
86
+
87
+ /* check equality */
88
+ hydro_x25519_sub(z3, z3, z2);
89
+
90
+ /* canon(z2): both sides are zero. canon(z3): the two sides are equal. */
91
+ /* Reject sigs where both sides are zero. */
92
+ return hydro_x25519_canon(z2) | ~hydro_x25519_canon(z3);
93
+ }
94
+
95
+ static int
96
+ hydro_sign_verify_p2(const uint8_t sig[hydro_x25519_BYTES],
97
+ const uint8_t challenge[hydro_sign_CHALLENGEBYTES],
98
+ const uint8_t nonce[hydro_sign_NONCEBYTES],
99
+ const uint8_t pk[hydro_x25519_BYTES])
100
+ {
101
+ hydro_x25519_fe xs[7];
102
+
103
+ hydro_x25519_core(&xs[0], challenge, pk, 0);
104
+ hydro_x25519_core(&xs[2], sig, hydro_x25519_BASE_POINT, 0);
105
+
106
+ return hydro_sign_verify_core(&xs[2], xs[0], nonce);
107
+ }
108
+
109
+ static int
110
+ hydro_sign_verify_challenge(const uint8_t csig[hydro_sign_BYTES],
111
+ const uint8_t challenge[hydro_sign_CHALLENGEBYTES],
112
+ const uint8_t pk[hydro_sign_PUBLICKEYBYTES])
113
+ {
114
+ const uint8_t *nonce = &csig[0];
115
+ const uint8_t *sig = &csig[hydro_sign_NONCEBYTES];
116
+
117
+ return hydro_sign_verify_p2(sig, challenge, nonce, pk);
118
+ }
119
+
120
+ void
121
+ hydro_sign_keygen(hydro_sign_keypair *kp)
122
+ {
123
+ uint8_t *pk_copy = &kp->sk[hydro_x25519_SECRETKEYBYTES];
124
+
125
+ COMPILER_ASSERT(hydro_sign_SECRETKEYBYTES ==
126
+ hydro_x25519_SECRETKEYBYTES + hydro_x25519_PUBLICKEYBYTES);
127
+ COMPILER_ASSERT(hydro_sign_PUBLICKEYBYTES == hydro_x25519_PUBLICKEYBYTES);
128
+ hydro_random_buf(kp->sk, hydro_x25519_SECRETKEYBYTES);
129
+ hydro_x25519_scalarmult_base_uniform(kp->pk, kp->sk);
130
+ memcpy(pk_copy, kp->pk, hydro_x25519_PUBLICKEYBYTES);
131
+ }
132
+
133
+ void
134
+ hydro_sign_keygen_deterministic(hydro_sign_keypair *kp, const uint8_t seed[hydro_sign_SEEDBYTES])
135
+ {
136
+ uint8_t *pk_copy = &kp->sk[hydro_x25519_SECRETKEYBYTES];
137
+
138
+ COMPILER_ASSERT(hydro_sign_SEEDBYTES >= hydro_random_SEEDBYTES);
139
+ hydro_random_buf_deterministic(kp->sk, hydro_x25519_SECRETKEYBYTES, seed);
140
+ hydro_x25519_scalarmult_base_uniform(kp->pk, kp->sk);
141
+ memcpy(pk_copy, kp->pk, hydro_x25519_PUBLICKEYBYTES);
142
+ }
143
+
144
+ int
145
+ hydro_sign_init(hydro_sign_state *state, const char ctx[hydro_sign_CONTEXTBYTES])
146
+ {
147
+ return hydro_hash_init(&state->hash_st, ctx, NULL);
148
+ }
149
+
150
+ int
151
+ hydro_sign_update(hydro_sign_state *state, const void *m_, size_t mlen)
152
+ {
153
+ return hydro_hash_update(&state->hash_st, m_, mlen);
154
+ }
155
+
156
+ int
157
+ hydro_sign_final_create(hydro_sign_state *state, uint8_t csig[hydro_sign_BYTES],
158
+ const uint8_t sk[hydro_sign_SECRETKEYBYTES])
159
+ {
160
+ uint8_t prehash[hydro_sign_PREHASHBYTES];
161
+
162
+ hydro_hash_final(&state->hash_st, prehash, sizeof prehash);
163
+
164
+ return hydro_sign_prehash(csig, prehash, sk);
165
+ }
166
+
167
+ int
168
+ hydro_sign_final_verify(hydro_sign_state *state, const uint8_t csig[hydro_sign_BYTES],
169
+ const uint8_t pk[hydro_sign_PUBLICKEYBYTES])
170
+ {
171
+ uint8_t challenge[hydro_sign_CHALLENGEBYTES];
172
+ uint8_t prehash[hydro_sign_PREHASHBYTES];
173
+ const uint8_t *nonce = &csig[0];
174
+
175
+ hydro_hash_final(&state->hash_st, prehash, sizeof prehash);
176
+ hydro_sign_challenge(challenge, nonce, pk, prehash);
177
+
178
+ return hydro_sign_verify_challenge(csig, challenge, pk);
179
+ }
180
+
181
+ int
182
+ hydro_sign_create(uint8_t csig[hydro_sign_BYTES], const void *m_, size_t mlen,
183
+ const char ctx[hydro_sign_CONTEXTBYTES],
184
+ const uint8_t sk[hydro_sign_SECRETKEYBYTES])
185
+ {
186
+ hydro_sign_state st;
187
+
188
+ if (hydro_sign_init(&st, ctx) != 0 || hydro_sign_update(&st, m_, mlen) != 0 ||
189
+ hydro_sign_final_create(&st, csig, sk) != 0) {
190
+ return -1;
191
+ }
192
+ return 0;
193
+ }
194
+
195
+ int
196
+ hydro_sign_verify(const uint8_t csig[hydro_sign_BYTES], const void *m_, size_t mlen,
197
+ const char ctx[hydro_sign_CONTEXTBYTES],
198
+ const uint8_t pk[hydro_sign_PUBLICKEYBYTES])
199
+ {
200
+ hydro_sign_state st;
201
+
202
+ if (hydro_sign_init(&st, ctx) != 0 || hydro_sign_update(&st, m_, mlen) != 0 ||
203
+ hydro_sign_final_verify(&st, csig, pk) != 0) {
204
+ return -1;
205
+ }
206
+ return 0;
207
+ }