ffi-hydrogen 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }