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,441 @@
1
+ #define hydro_kx_AEAD_KEYBYTES hydro_hash_KEYBYTES
2
+ #define hydro_kx_AEAD_MACBYTES 16
3
+ #define hydro_kx_AEAD_HEADERBYTES hydro_kx_AEAD_MACBYTES
4
+
5
+ #define hydro_kx_CONTEXT "hydro_kx"
6
+ #define hydro_kx_CONTEXT_CK_K "kdf_ck_k"
7
+
8
+ void
9
+ hydro_kx_keygen(hydro_kx_keypair *static_kp)
10
+ {
11
+ hydro_random_buf(static_kp->sk, hydro_kx_SECRETKEYBYTES);
12
+ if (hydro_x25519_scalarmult_base(static_kp->pk, static_kp->sk) != 0) {
13
+ abort();
14
+ }
15
+ }
16
+
17
+ void
18
+ hydro_kx_keygen_deterministic(hydro_kx_keypair *static_kp, const uint8_t seed[hydro_kx_SEEDBYTES])
19
+ {
20
+ COMPILER_ASSERT(hydro_kx_SEEDBYTES >= hydro_random_SEEDBYTES);
21
+ hydro_random_buf_deterministic(static_kp->sk, hydro_kx_SECRETKEYBYTES, seed);
22
+ if (hydro_x25519_scalarmult_base(static_kp->pk, static_kp->sk) != 0) {
23
+ abort();
24
+ }
25
+ }
26
+
27
+ static void
28
+ hydro_kx_aead_setup(uint8_t buf[gimli_BLOCKBYTES], const hydro_kx_state *state,
29
+ const uint8_t psk[hydro_kx_PSKBYTES])
30
+ {
31
+ static const uint8_t prefix[] = { 6, 'k', 'x', 'x', '2', '5', '6', 0 };
32
+
33
+ mem_zero(buf + sizeof prefix, gimli_BLOCKBYTES - sizeof prefix);
34
+ memcpy(buf, prefix, sizeof prefix);
35
+ gimli_core_u8(buf, gimli_TAG_HEADER);
36
+
37
+ COMPILER_ASSERT(hydro_kx_AEAD_KEYBYTES == 2 * gimli_RATE);
38
+ mem_xor(buf, state->k, gimli_RATE);
39
+ gimli_core_u8(buf, gimli_TAG_KEY);
40
+ mem_xor(buf, state->k + gimli_RATE, gimli_RATE);
41
+ gimli_core_u8(buf, gimli_TAG_KEY);
42
+
43
+ COMPILER_ASSERT(sizeof state->h == 2 * gimli_RATE);
44
+ mem_xor(buf, state->h, gimli_RATE);
45
+ gimli_core_u8(buf, gimli_TAG_HEADER);
46
+ mem_xor(buf, state->h + gimli_RATE, gimli_RATE);
47
+ gimli_core_u8(buf, gimli_TAG_HEADER);
48
+
49
+ if (psk != NULL) {
50
+ COMPILER_ASSERT(hydro_kx_PSKBYTES == 2 * gimli_RATE);
51
+ mem_xor(buf, psk, gimli_RATE);
52
+ gimli_core_u8(buf, gimli_TAG_HEADER);
53
+ mem_xor(buf, psk + gimli_RATE, gimli_RATE);
54
+ gimli_core_u8(buf, gimli_TAG_HEADER);
55
+ }
56
+ }
57
+
58
+ static void
59
+ hydro_kx_finalize(uint8_t *buf, const uint8_t key[hydro_kx_AEAD_KEYBYTES])
60
+ {
61
+ COMPILER_ASSERT(hydro_kx_AEAD_KEYBYTES == gimli_CAPACITY);
62
+ mem_xor(buf + gimli_RATE, key, hydro_kx_AEAD_KEYBYTES);
63
+ gimli_core_u8(buf, gimli_TAG_FINAL);
64
+ mem_xor(buf + gimli_RATE, key, hydro_kx_AEAD_KEYBYTES);
65
+ gimli_core_u8(buf, gimli_TAG_FINAL);
66
+ }
67
+
68
+ static void
69
+ hydro_kx_aead_xor_enc(uint8_t buf[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in, size_t inlen)
70
+ {
71
+ size_t i;
72
+ size_t leftover;
73
+
74
+ for (i = 0; i < inlen / gimli_RATE; i++) {
75
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, gimli_RATE);
76
+ memcpy(buf, &out[i * gimli_RATE], gimli_RATE);
77
+ gimli_core_u8(buf, gimli_TAG_PAYLOAD);
78
+ }
79
+ leftover = inlen % gimli_RATE;
80
+ if (leftover != 0) {
81
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, leftover);
82
+ mem_cpy(buf, &out[i * gimli_RATE], leftover);
83
+ }
84
+ gimli_pad_u8(buf, leftover, gimli_DOMAIN_AEAD);
85
+ gimli_core_u8(buf, gimli_TAG_PAYLOAD);
86
+ }
87
+
88
+ static void
89
+ hydro_kx_aead_xor_dec(uint8_t buf[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in, size_t inlen)
90
+ {
91
+ size_t i;
92
+ size_t leftover;
93
+
94
+ for (i = 0; i < inlen / gimli_RATE; i++) {
95
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, gimli_RATE);
96
+ memcpy(buf, &in[i * gimli_RATE], gimli_RATE);
97
+ gimli_core_u8(buf, gimli_TAG_PAYLOAD);
98
+ }
99
+ leftover = inlen % gimli_RATE;
100
+ if (leftover != 0) {
101
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, leftover);
102
+ mem_cpy(buf, &in[i * gimli_RATE], leftover);
103
+ }
104
+ gimli_pad_u8(buf, leftover, gimli_DOMAIN_AEAD);
105
+ gimli_core_u8(buf, gimli_TAG_PAYLOAD);
106
+ }
107
+
108
+ static void
109
+ hydro_kx_encrypt(const hydro_kx_state *state, uint8_t *c, const uint8_t *m, size_t mlen,
110
+ const uint8_t psk[hydro_kx_PSKBYTES])
111
+ {
112
+ _hydro_attr_aligned_(16) uint8_t buf[gimli_BLOCKBYTES];
113
+ uint8_t * mac = &c[0];
114
+ uint8_t * ct = &c[hydro_kx_AEAD_MACBYTES];
115
+
116
+ hydro_kx_aead_setup(buf, state, psk);
117
+ hydro_kx_aead_xor_enc(buf, ct, m, mlen);
118
+
119
+ hydro_kx_finalize(buf, state->k);
120
+ COMPILER_ASSERT(hydro_kx_AEAD_MACBYTES <= gimli_CAPACITY);
121
+ memcpy(mac, buf + gimli_RATE, hydro_kx_AEAD_MACBYTES);
122
+ }
123
+
124
+ static int hydro_kx_decrypt(hydro_kx_state *state, uint8_t *m, const uint8_t *c, size_t clen,
125
+ const uint8_t psk[hydro_kx_PSKBYTES]) _hydro_attr_warn_unused_result_;
126
+
127
+ static int
128
+ hydro_kx_decrypt(hydro_kx_state *state, uint8_t *m, const uint8_t *c, size_t clen,
129
+ const uint8_t psk[hydro_kx_PSKBYTES])
130
+ {
131
+ _hydro_attr_aligned_(16) uint32_t int_state[gimli_BLOCKBYTES / 4];
132
+ uint32_t pub_mac[hydro_kx_AEAD_MACBYTES / 4];
133
+ uint8_t * buf = (uint8_t *) (void *) int_state;
134
+ const uint8_t * mac;
135
+ const uint8_t * ct;
136
+ size_t mlen;
137
+ uint32_t cv;
138
+
139
+ if (clen < hydro_kx_AEAD_HEADERBYTES) {
140
+ return -1;
141
+ }
142
+ mac = &c[0];
143
+ ct = &c[hydro_kx_AEAD_MACBYTES];
144
+ mlen = clen - hydro_kx_AEAD_HEADERBYTES;
145
+ memcpy(pub_mac, mac, sizeof pub_mac);
146
+ hydro_kx_aead_setup(buf, state, psk);
147
+ hydro_kx_aead_xor_dec(buf, m, ct, mlen);
148
+
149
+ hydro_kx_finalize(buf, state->k);
150
+ COMPILER_ASSERT(hydro_kx_AEAD_MACBYTES <= gimli_CAPACITY);
151
+ COMPILER_ASSERT(gimli_RATE % 4 == 0);
152
+ cv = hydro_mem_ct_cmp_u32(int_state + gimli_RATE / 4, pub_mac, hydro_kx_AEAD_MACBYTES / 4);
153
+ hydro_mem_ct_zero_u32(int_state, gimli_BLOCKBYTES / 4);
154
+ if (cv != 0) {
155
+ mem_zero(m, mlen);
156
+ return -1;
157
+ }
158
+ return 0;
159
+ }
160
+
161
+ static int
162
+ hydro_kx_scalarmult(hydro_kx_state *state, uint8_t dh_res[hydro_x25519_BYTES],
163
+ const uint8_t scalar[hydro_x25519_BYTES], const uint8_t x1[hydro_x25519_BYTES])
164
+ {
165
+ uint8_t ck_k[hydro_hash_BYTES + hydro_hash_KEYBYTES];
166
+
167
+ if (hydro_x25519_scalarmult(dh_res, scalar, x1, 1) != 0) {
168
+ return -1;
169
+ }
170
+ COMPILER_ASSERT(sizeof state->ck >= hydro_hash_KEYBYTES);
171
+ hydro_hash_hash(ck_k, sizeof ck_k, dh_res, hydro_x25519_BYTES, hydro_kx_CONTEXT_CK_K,
172
+ state->ck);
173
+ memcpy(state->ck, ck_k, sizeof state->ck);
174
+ memcpy(state->k, ck_k + sizeof state->ck, sizeof state->k);
175
+
176
+ return 0;
177
+ }
178
+
179
+ static void
180
+ hydro_kx_final(hydro_kx_state *state, uint8_t rx[hydro_kx_SESSIONKEYBYTES],
181
+ uint8_t tx[hydro_kx_SESSIONKEYBYTES])
182
+ {
183
+ COMPILER_ASSERT(hydro_kx_SESSIONKEYBYTES == hydro_kx_AEAD_KEYBYTES);
184
+ COMPILER_ASSERT(hydro_kx_PUBLICKEYBYTES == hydro_x25519_BYTES);
185
+ COMPILER_ASSERT(hydro_kx_SECRETKEYBYTES == hydro_x25519_BYTES);
186
+ COMPILER_ASSERT(hydro_kx_PSKBYTES == hydro_hash_KEYBYTES);
187
+ COMPILER_ASSERT(sizeof(state->h) == hydro_hash_BYTES);
188
+ COMPILER_ASSERT(sizeof(state->ck) == hydro_hash_KEYBYTES);
189
+ COMPILER_ASSERT(sizeof(state->k) == hydro_kx_AEAD_KEYBYTES);
190
+ COMPILER_ASSERT(hydro_kx_XX_PACKET1BYTES == hydro_kx_PUBLICKEYBYTES);
191
+ COMPILER_ASSERT(hydro_kx_XX_PACKET2BYTES ==
192
+ hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_HEADERBYTES + hydro_kx_PUBLICKEYBYTES);
193
+ COMPILER_ASSERT(hydro_kx_XX_PACKET3BYTES ==
194
+ hydro_kx_AEAD_HEADERBYTES + hydro_kx_PUBLICKEYBYTES);
195
+
196
+ COMPILER_ASSERT(hydro_kdf_KEYBYTES == hydro_hash_BYTES);
197
+ hydro_kdf_derive_from_key(rx, hydro_kx_SESSIONKEYBYTES, 0, hydro_kx_CONTEXT, state->ck);
198
+ hydro_kdf_derive_from_key(tx, hydro_kx_SESSIONKEYBYTES, 1, hydro_kx_CONTEXT, state->ck);
199
+ hydro_memzero(state, sizeof *state);
200
+ }
201
+
202
+ /* NOISE_N */
203
+
204
+ int
205
+ hydro_kx_n_1(hydro_kx_session_keypair *kp, uint8_t packet1[hydro_kx_N_PACKET1BYTES],
206
+ const uint8_t psk[hydro_kx_PSKBYTES],
207
+ const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES])
208
+ {
209
+ hydro_kx_state state;
210
+ uint8_t dh_res[hydro_x25519_BYTES];
211
+
212
+ mem_zero(&state, sizeof state);
213
+
214
+ hydro_kx_keygen(&state.eph_kp);
215
+ COMPILER_ASSERT(hydro_kx_PSKBYTES >= hydro_hash_KEYBYTES);
216
+ hydro_hash_hash(state.h, sizeof state.h, peer_static_pk, hydro_kx_PUBLICKEYBYTES,
217
+ hydro_kx_CONTEXT, psk);
218
+ memcpy(packet1, state.eph_kp.pk, hydro_kx_PUBLICKEYBYTES);
219
+
220
+ COMPILER_ASSERT(sizeof state.h >= hydro_hash_KEYBYTES);
221
+ hydro_hash_hash(state.h, sizeof state.h, state.eph_kp.pk, sizeof state.eph_kp.pk,
222
+ hydro_kx_CONTEXT, state.h);
223
+
224
+ if (hydro_kx_scalarmult(&state, dh_res, state.eph_kp.sk, peer_static_pk) != 0) {
225
+ return -1;
226
+ }
227
+ hydro_kx_final(&state, kp->rx, kp->tx);
228
+
229
+ return 0;
230
+ }
231
+
232
+ int
233
+ hydro_kx_n_2(hydro_kx_session_keypair *kp, const uint8_t packet1[hydro_kx_N_PACKET1BYTES],
234
+ const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp)
235
+ {
236
+ hydro_kx_state state;
237
+ uint8_t dh_res[hydro_x25519_BYTES];
238
+ const uint8_t *peer_eph_pk = packet1;
239
+
240
+ mem_zero(&state, sizeof state);
241
+
242
+ COMPILER_ASSERT(hydro_kx_PSKBYTES >= hydro_hash_KEYBYTES);
243
+ hydro_hash_hash(state.h, sizeof state.h, static_kp->pk, sizeof static_kp->pk, hydro_kx_CONTEXT,
244
+ psk);
245
+
246
+ COMPILER_ASSERT(sizeof state.h >= hydro_hash_KEYBYTES);
247
+ hydro_hash_hash(state.h, sizeof state.h, peer_eph_pk, hydro_kx_PUBLICKEYBYTES, hydro_kx_CONTEXT,
248
+ state.h);
249
+
250
+ if (hydro_kx_scalarmult(&state, dh_res, static_kp->sk, peer_eph_pk) != 0) {
251
+ return -1;
252
+ }
253
+ hydro_kx_final(&state, kp->tx, kp->rx);
254
+
255
+ return 0;
256
+ }
257
+
258
+ /* NOISE_KK */
259
+
260
+ int
261
+ hydro_kx_kk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_KK_PACKET1BYTES],
262
+ const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
263
+ const hydro_kx_keypair *static_kp)
264
+ {
265
+ uint8_t dh_res[hydro_x25519_BYTES];
266
+ mem_zero(state, sizeof *state);
267
+
268
+ hydro_kx_keygen(&state->eph_kp);
269
+ hydro_hash_hash(state->h, sizeof state->h, state->eph_kp.pk, sizeof state->eph_kp.pk,
270
+ hydro_kx_CONTEXT, NULL);
271
+ memcpy(packet1, state->eph_kp.pk, sizeof state->eph_kp.pk);
272
+
273
+ if (hydro_kx_scalarmult(state, dh_res, state->eph_kp.sk, peer_static_pk) != 0) {
274
+ return -1;
275
+ }
276
+ if (hydro_kx_scalarmult(state, dh_res, static_kp->sk, peer_static_pk) != 0) {
277
+ return -1;
278
+ }
279
+ return 0;
280
+ }
281
+
282
+ int
283
+ hydro_kx_kk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_KK_PACKET2BYTES],
284
+ const uint8_t packet1[hydro_kx_KK_PACKET1BYTES],
285
+ const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
286
+ const hydro_kx_keypair *static_kp)
287
+ {
288
+ hydro_kx_state state;
289
+ uint8_t dh_res[hydro_x25519_BYTES];
290
+ const uint8_t *peer_eph_pk = packet1;
291
+
292
+ mem_zero(&state, sizeof state);
293
+
294
+ hydro_kx_keygen(&state.eph_kp);
295
+ hydro_hash_hash(state.h, sizeof state.h, state.eph_kp.pk, sizeof state.eph_kp.pk,
296
+ hydro_kx_CONTEXT, NULL);
297
+ memcpy(packet2, state.eph_kp.pk, sizeof state.eph_kp.pk);
298
+
299
+ if (hydro_kx_scalarmult(&state, dh_res, static_kp->sk, peer_eph_pk) != 0) {
300
+ return -1;
301
+ }
302
+ if (hydro_kx_scalarmult(&state, dh_res, static_kp->sk, peer_static_pk) != 0) {
303
+ return -1;
304
+ }
305
+
306
+ if (hydro_kx_scalarmult(&state, dh_res, state.eph_kp.sk, peer_eph_pk) != 0) {
307
+ return -1;
308
+ }
309
+ if (hydro_kx_scalarmult(&state, dh_res, static_kp->sk, peer_eph_pk) != 0) {
310
+ return -1;
311
+ }
312
+ hydro_kx_final(&state, kp->rx, kp->tx);
313
+
314
+ return 0;
315
+ }
316
+
317
+ int
318
+ hydro_kx_kk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
319
+ const uint8_t packet2[hydro_kx_KK_PACKET2BYTES],
320
+ const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES])
321
+ {
322
+ uint8_t dh_res[hydro_x25519_BYTES];
323
+ const uint8_t *peer_eph_pk = packet2;
324
+
325
+ if (hydro_kx_scalarmult(state, dh_res, state->eph_kp.sk, peer_eph_pk) != 0) {
326
+ return -1;
327
+ }
328
+ if (hydro_kx_scalarmult(state, dh_res, state->eph_kp.sk, peer_static_pk) != 0) {
329
+ return -1;
330
+ }
331
+ hydro_kx_final(state, kp->tx, kp->rx);
332
+
333
+ return 0;
334
+ }
335
+
336
+ /* NOISE_XX */
337
+
338
+ int
339
+ hydro_kx_xx_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_XX_PACKET1BYTES],
340
+ const uint8_t psk[hydro_kx_PSKBYTES])
341
+ {
342
+ mem_zero(state, sizeof *state);
343
+
344
+ hydro_kx_keygen(&state->eph_kp);
345
+ COMPILER_ASSERT(hydro_kx_PSKBYTES >= hydro_hash_KEYBYTES);
346
+ hydro_hash_hash(state->h, sizeof state->h, state->eph_kp.pk, sizeof state->eph_kp.pk,
347
+ hydro_kx_CONTEXT, psk);
348
+ memcpy(packet1, state->eph_kp.pk, hydro_kx_PUBLICKEYBYTES);
349
+
350
+ return 0;
351
+ }
352
+
353
+ int
354
+ hydro_kx_xx_2(hydro_kx_state *state, uint8_t packet2[hydro_kx_XX_PACKET2BYTES],
355
+ const uint8_t packet1[hydro_kx_XX_PACKET1BYTES], const uint8_t psk[hydro_kx_PSKBYTES],
356
+ const hydro_kx_keypair *static_kp)
357
+ {
358
+ uint8_t dh_res[hydro_x25519_BYTES];
359
+ const uint8_t *peer_eph_pk = packet1;
360
+
361
+ mem_zero(state, sizeof *state);
362
+
363
+ hydro_hash_hash(state->h, sizeof state->h, peer_eph_pk, hydro_kx_PUBLICKEYBYTES,
364
+ hydro_kx_CONTEXT, psk);
365
+ hydro_kx_keygen(&state->eph_kp);
366
+ memcpy(packet2, state->eph_kp.pk, sizeof state->eph_kp.pk);
367
+ COMPILER_ASSERT(sizeof state->h >= hydro_hash_KEYBYTES);
368
+ hydro_hash_hash(state->h, sizeof state->h, state->eph_kp.pk, sizeof state->eph_kp.pk,
369
+ hydro_kx_CONTEXT, state->h);
370
+
371
+ if (hydro_kx_scalarmult(state, dh_res, state->eph_kp.sk, peer_eph_pk) != 0) {
372
+ return -1;
373
+ }
374
+ hydro_kx_encrypt(state, packet2 + sizeof state->eph_kp.pk, static_kp->pk, sizeof static_kp->pk,
375
+ psk);
376
+ if (hydro_kx_scalarmult(state, dh_res, static_kp->sk, peer_eph_pk) != 0) {
377
+ return -1;
378
+ }
379
+ return 0;
380
+ }
381
+
382
+ int
383
+ hydro_kx_xx_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
384
+ uint8_t packet3[hydro_kx_XX_PACKET3BYTES],
385
+ uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
386
+ const uint8_t packet2[hydro_kx_XX_PACKET2BYTES], const uint8_t psk[hydro_kx_PSKBYTES],
387
+ const hydro_kx_keypair *static_kp)
388
+ {
389
+ uint8_t dh_res[hydro_x25519_BYTES];
390
+ uint8_t peer_static_pk_[hydro_kx_PUBLICKEYBYTES];
391
+ const uint8_t *peer_eph_pk = packet2;
392
+ const uint8_t *peer_encrypted_static_pk = packet2 + hydro_kx_PUBLICKEYBYTES;
393
+
394
+ hydro_hash_hash(state->h, sizeof state->h, peer_eph_pk, hydro_kx_PUBLICKEYBYTES,
395
+ hydro_kx_CONTEXT, state->h);
396
+
397
+ if (hydro_kx_scalarmult(state, dh_res, state->eph_kp.sk, peer_eph_pk) != 0) {
398
+ return -1;
399
+ }
400
+ if (peer_static_pk == NULL) {
401
+ peer_static_pk = peer_static_pk_;
402
+ }
403
+ if (hydro_kx_decrypt(state, peer_static_pk, peer_encrypted_static_pk,
404
+ hydro_kx_AEAD_HEADERBYTES + hydro_kx_PUBLICKEYBYTES, psk) != 0) {
405
+ return -1;
406
+ }
407
+ if (hydro_kx_scalarmult(state, dh_res, state->eph_kp.sk, peer_static_pk) != 0) {
408
+ return -1;
409
+ }
410
+ hydro_kx_encrypt(state, packet3, static_kp->pk, sizeof static_kp->pk, psk);
411
+ if (hydro_kx_scalarmult(state, dh_res, static_kp->sk, peer_eph_pk) != 0) {
412
+ return -1;
413
+ }
414
+ hydro_kx_final(state, kp->rx, kp->tx);
415
+
416
+ return 0;
417
+ }
418
+
419
+ int
420
+ hydro_kx_xx_4(hydro_kx_state *state, hydro_kx_session_keypair *kp,
421
+ uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
422
+ const uint8_t packet3[hydro_kx_XX_PACKET3BYTES], const uint8_t psk[hydro_kx_PSKBYTES])
423
+ {
424
+ uint8_t dh_res[hydro_x25519_BYTES];
425
+ uint8_t peer_static_pk_[hydro_kx_PUBLICKEYBYTES];
426
+ const uint8_t *peer_encrypted_static_pk = packet3;
427
+
428
+ if (peer_static_pk == NULL) {
429
+ peer_static_pk = peer_static_pk_;
430
+ }
431
+ if (hydro_kx_decrypt(state, peer_static_pk, peer_encrypted_static_pk,
432
+ hydro_kx_AEAD_HEADERBYTES + hydro_kx_PUBLICKEYBYTES, psk) != 0) {
433
+ return -1;
434
+ }
435
+ if (hydro_kx_scalarmult(state, dh_res, state->eph_kp.sk, peer_static_pk) != 0) {
436
+ return -1;
437
+ }
438
+ hydro_kx_final(state, kp->tx, kp->rx);
439
+
440
+ return 0;
441
+ }