dualcone 0.0.1

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.
@@ -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,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,100 @@
1
+ #include <emmintrin.h>
2
+ #ifdef __SSSE3__
3
+ # include <tmmintrin.h>
4
+ #endif
5
+
6
+ #define S 9
7
+
8
+ static inline __m128i
9
+ shift(__m128i x, int bits)
10
+ {
11
+ return _mm_slli_epi32(x, bits);
12
+ }
13
+
14
+ static inline __m128i
15
+ rotate(__m128i x, int bits)
16
+ {
17
+ return _mm_slli_epi32(x, bits) | _mm_srli_epi32(x, 32 - bits);
18
+ }
19
+
20
+ #ifdef __SSSE3__
21
+ static inline __m128i
22
+ rotate24(__m128i x)
23
+ {
24
+ return _mm_shuffle_epi8(x, _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1));
25
+ }
26
+ #else
27
+ static inline __m128i
28
+ rotate24(__m128i x)
29
+ {
30
+ uint8_t _hydro_attr_aligned_(16) x8[16], y8[16];
31
+
32
+ _mm_storeu_si128((__m128i *) (void *) x8, x);
33
+
34
+ y8[ 0] = x8[ 1]; y8[ 1] = x8[ 2]; y8[ 2] = x8[ 3]; y8[ 3] = x8[ 0];
35
+ y8[ 4] = x8[ 5]; y8[ 5] = x8[ 6]; y8[ 6] = x8[ 7]; y8[ 7] = x8[ 4];
36
+ y8[ 8] = x8[ 9]; y8[ 9] = x8[10]; y8[10] = x8[11]; y8[11] = x8[ 8];
37
+ y8[12] = x8[13]; y8[13] = x8[14]; y8[14] = x8[15]; y8[15] = x8[12];
38
+
39
+ return _mm_loadu_si128((const __m128i *) (const void *) y8);
40
+ }
41
+ #endif
42
+
43
+ static const uint32_t coeffs[24] _hydro_attr_aligned_(16) = {
44
+ 0x9e377904, 0, 0, 0, 0x9e377908, 0, 0, 0, 0x9e37790c, 0, 0, 0,
45
+ 0x9e377910, 0, 0, 0, 0x9e377914, 0, 0, 0, 0x9e377918, 0, 0, 0,
46
+ };
47
+
48
+ static void
49
+ gimli_core(uint32_t state[gimli_BLOCKBYTES / 4])
50
+ {
51
+ __m128i x = _mm_loadu_si128((const __m128i *) (const void *) &state[0]);
52
+ __m128i y = _mm_loadu_si128((const __m128i *) (const void *) &state[4]);
53
+ __m128i z = _mm_loadu_si128((const __m128i *) (const void *) &state[8]);
54
+ __m128i newy;
55
+ __m128i newz;
56
+ int round;
57
+
58
+ for (round = 5; round >= 0; round--) {
59
+ x = rotate24(x);
60
+ y = rotate(y, S);
61
+ newz = x ^ shift(z, 1) ^ shift(y & z, 2);
62
+ newy = y ^ x ^ shift(x | z, 1);
63
+ x = z ^ y ^ shift(x & y, 3);
64
+ y = newy;
65
+ z = newz;
66
+
67
+ x = _mm_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1));
68
+ x ^= ((const __m128i *) (const void *) coeffs)[round];
69
+
70
+ x = rotate24(x);
71
+ y = rotate(y, S);
72
+ newz = x ^ shift(z, 1) ^ shift(y & z, 2);
73
+ newy = y ^ x ^ shift(x | z, 1);
74
+ x = z ^ y ^ shift(x & y, 3);
75
+ y = newy;
76
+ z = newz;
77
+
78
+ x = rotate24(x);
79
+ y = rotate(y, S);
80
+ newz = x ^ shift(z, 1) ^ shift(y & z, 2);
81
+ newy = y ^ x ^ shift(x | z, 1);
82
+ x = z ^ y ^ shift(x & y, 3);
83
+ y = newy;
84
+ z = newz;
85
+
86
+ x = _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2));
87
+
88
+ x = rotate24(x);
89
+ y = rotate(y, S);
90
+ newz = x ^ shift(z, 1) ^ shift(y & z, 2);
91
+ newy = y ^ x ^ shift(x | z, 1);
92
+ x = z ^ y ^ shift(x & y, 3);
93
+ y = newy;
94
+ z = newz;
95
+ }
96
+
97
+ _mm_storeu_si128((__m128i *) (void *) &state[0], x);
98
+ _mm_storeu_si128((__m128i *) (void *) &state[4], y);
99
+ _mm_storeu_si128((__m128i *) (void *) &state[8], z);
100
+ }
@@ -0,0 +1,140 @@
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
+ left = gimli_RATE - state->buf_off;
12
+ if ((ps = in_len) > left) {
13
+ ps = left;
14
+ }
15
+ for (i = 0; i < ps; i++) {
16
+ buf[state->buf_off + i] ^= in[i];
17
+ }
18
+ in += ps;
19
+ in_len -= ps;
20
+ state->buf_off += (uint8_t) ps;
21
+ if (state->buf_off == gimli_RATE) {
22
+ gimli_core_u8(buf, 0);
23
+ state->buf_off = 0;
24
+ }
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
+ state->buf_off = gimli_RATE;
118
+
119
+ return 0;
120
+ }
121
+
122
+ int
123
+ hydro_hash_hash(uint8_t *out, size_t out_len, const void *in_, size_t in_len,
124
+ const char ctx[hydro_hash_CONTEXTBYTES], const uint8_t key[hydro_hash_KEYBYTES])
125
+ {
126
+ hydro_hash_state st;
127
+ const uint8_t * in = (const uint8_t *) in_;
128
+
129
+ if (hydro_hash_init(&st, ctx, key) != 0 || hydro_hash_update(&st, in, in_len) != 0 ||
130
+ hydro_hash_final(&st, out, out_len) != 0) {
131
+ return -1;
132
+ }
133
+ return 0;
134
+ }
135
+
136
+ void
137
+ hydro_hash_keygen(uint8_t key[hydro_hash_KEYBYTES])
138
+ {
139
+ hydro_random_buf(key, hydro_hash_KEYBYTES);
140
+ }
@@ -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_SECRETKEYBYTES],
74
+ const uint8_t x1[hydro_x25519_PUBLICKEYBYTES],
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
+ }
@@ -0,0 +1,535 @@
1
+ #define hydro_kx_AEAD_KEYBYTES hydro_hash_KEYBYTES
2
+ #define hydro_kx_AEAD_MACBYTES 16
3
+
4
+ #define hydro_kx_CONTEXT "hydro_kx"
5
+
6
+ static void
7
+ hydro_kx_aead_init(uint8_t aead_state[gimli_BLOCKBYTES], uint8_t k[hydro_kx_AEAD_KEYBYTES],
8
+ hydro_kx_state *state)
9
+ {
10
+ static const uint8_t prefix[] = { 6, 'k', 'x', 'x', '2', '5', '6', 0 };
11
+
12
+ hydro_hash_final(&state->h_st, k, hydro_kx_AEAD_KEYBYTES);
13
+
14
+ mem_zero(aead_state + sizeof prefix, gimli_BLOCKBYTES - sizeof prefix);
15
+ memcpy(aead_state, prefix, sizeof prefix);
16
+ gimli_core_u8(aead_state, gimli_TAG_HEADER);
17
+
18
+ COMPILER_ASSERT(hydro_kx_AEAD_KEYBYTES == 2 * gimli_RATE);
19
+ mem_xor(aead_state, k, gimli_RATE);
20
+ gimli_core_u8(aead_state, gimli_TAG_KEY);
21
+ mem_xor(aead_state, k + gimli_RATE, gimli_RATE);
22
+ gimli_core_u8(aead_state, gimli_TAG_KEY);
23
+ }
24
+
25
+ static void
26
+ hydro_kx_aead_final(uint8_t *aead_state, const uint8_t key[hydro_kx_AEAD_KEYBYTES])
27
+ {
28
+ COMPILER_ASSERT(hydro_kx_AEAD_KEYBYTES == gimli_CAPACITY);
29
+ mem_xor(aead_state + gimli_RATE, key, hydro_kx_AEAD_KEYBYTES);
30
+ gimli_core_u8(aead_state, gimli_TAG_FINAL);
31
+ mem_xor(aead_state + gimli_RATE, key, hydro_kx_AEAD_KEYBYTES);
32
+ gimli_core_u8(aead_state, gimli_TAG_FINAL);
33
+ }
34
+
35
+ static void
36
+ hydro_kx_aead_xor_enc(uint8_t aead_state[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in,
37
+ size_t inlen)
38
+ {
39
+ size_t i;
40
+ size_t leftover;
41
+
42
+ for (i = 0; i < inlen / gimli_RATE; i++) {
43
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, gimli_RATE);
44
+ memcpy(aead_state, &out[i * gimli_RATE], gimli_RATE);
45
+ gimli_core_u8(aead_state, gimli_TAG_PAYLOAD);
46
+ }
47
+ leftover = inlen % gimli_RATE;
48
+ if (leftover != 0) {
49
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, leftover);
50
+ mem_cpy(aead_state, &out[i * gimli_RATE], leftover);
51
+ }
52
+ gimli_pad_u8(aead_state, leftover, gimli_DOMAIN_AEAD);
53
+ gimli_core_u8(aead_state, gimli_TAG_PAYLOAD);
54
+ }
55
+
56
+ static void
57
+ hydro_kx_aead_xor_dec(uint8_t aead_state[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in,
58
+ size_t inlen)
59
+ {
60
+ size_t i;
61
+ size_t leftover;
62
+
63
+ for (i = 0; i < inlen / gimli_RATE; i++) {
64
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, gimli_RATE);
65
+ memcpy(aead_state, &in[i * gimli_RATE], gimli_RATE);
66
+ gimli_core_u8(aead_state, gimli_TAG_PAYLOAD);
67
+ }
68
+ leftover = inlen % gimli_RATE;
69
+ if (leftover != 0) {
70
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, leftover);
71
+ mem_cpy(aead_state, &in[i * gimli_RATE], leftover);
72
+ }
73
+ gimli_pad_u8(aead_state, leftover, gimli_DOMAIN_AEAD);
74
+ gimli_core_u8(aead_state, gimli_TAG_PAYLOAD);
75
+ }
76
+
77
+ static void
78
+ hydro_kx_aead_encrypt(hydro_kx_state *state, uint8_t *c, const uint8_t *m, size_t mlen)
79
+ {
80
+ _hydro_attr_aligned_(16) uint8_t aead_state[gimli_BLOCKBYTES];
81
+ uint8_t k[hydro_kx_AEAD_KEYBYTES];
82
+ uint8_t * mac = &c[0];
83
+ uint8_t * ct = &c[hydro_kx_AEAD_MACBYTES];
84
+
85
+ hydro_kx_aead_init(aead_state, k, state);
86
+ hydro_kx_aead_xor_enc(aead_state, ct, m, mlen);
87
+ hydro_kx_aead_final(aead_state, k);
88
+ COMPILER_ASSERT(hydro_kx_AEAD_MACBYTES <= gimli_CAPACITY);
89
+ memcpy(mac, aead_state + gimli_RATE, hydro_kx_AEAD_MACBYTES);
90
+ hydro_hash_update(&state->h_st, c, mlen + hydro_kx_AEAD_MACBYTES);
91
+ }
92
+
93
+ static int hydro_kx_aead_decrypt(hydro_kx_state *state, uint8_t *m, const uint8_t *c,
94
+ size_t clen) _hydro_attr_warn_unused_result_;
95
+
96
+ static int
97
+ hydro_kx_aead_decrypt(hydro_kx_state *state, uint8_t *m, const uint8_t *c, size_t clen)
98
+ {
99
+ _hydro_attr_aligned_(16) uint32_t int_state[gimli_BLOCKBYTES / 4];
100
+ uint32_t pub_mac[hydro_kx_AEAD_MACBYTES / 4];
101
+ uint8_t k[hydro_kx_AEAD_KEYBYTES];
102
+ uint8_t * aead_state = (uint8_t *) (void *) int_state;
103
+ const uint8_t * mac;
104
+ const uint8_t * ct;
105
+ size_t mlen;
106
+ uint32_t cv;
107
+
108
+ if (clen < hydro_kx_AEAD_MACBYTES) {
109
+ return -1;
110
+ }
111
+ mac = &c[0];
112
+ ct = &c[hydro_kx_AEAD_MACBYTES];
113
+ mlen = clen - hydro_kx_AEAD_MACBYTES;
114
+ memcpy(pub_mac, mac, sizeof pub_mac);
115
+ hydro_kx_aead_init(aead_state, k, state);
116
+ hydro_hash_update(&state->h_st, c, clen);
117
+ hydro_kx_aead_xor_dec(aead_state, m, ct, mlen);
118
+ hydro_kx_aead_final(aead_state, k);
119
+ COMPILER_ASSERT(hydro_kx_AEAD_MACBYTES <= gimli_CAPACITY);
120
+ COMPILER_ASSERT(gimli_RATE % 4 == 0);
121
+ cv = hydro_mem_ct_cmp_u32(int_state + gimli_RATE / 4, pub_mac, hydro_kx_AEAD_MACBYTES / 4);
122
+ hydro_mem_ct_zero_u32(int_state, gimli_BLOCKBYTES / 4);
123
+ if (cv != 0) {
124
+ mem_zero(m, mlen);
125
+ return -1;
126
+ }
127
+ return 0;
128
+ }
129
+
130
+ /* -- */
131
+
132
+ void
133
+ hydro_kx_keygen(hydro_kx_keypair *static_kp)
134
+ {
135
+ hydro_random_buf(static_kp->sk, hydro_kx_SECRETKEYBYTES);
136
+ if (hydro_x25519_scalarmult_base(static_kp->pk, static_kp->sk) != 0) {
137
+ abort();
138
+ }
139
+ }
140
+
141
+ void
142
+ hydro_kx_keygen_deterministic(hydro_kx_keypair *static_kp, const uint8_t seed[hydro_kx_SEEDBYTES])
143
+ {
144
+ COMPILER_ASSERT(hydro_kx_SEEDBYTES >= hydro_random_SEEDBYTES);
145
+ hydro_random_buf_deterministic(static_kp->sk, hydro_kx_SECRETKEYBYTES, seed);
146
+ if (hydro_x25519_scalarmult_base(static_kp->pk, static_kp->sk) != 0) {
147
+ abort();
148
+ }
149
+ }
150
+
151
+ static void
152
+ hydro_kx_init_state(hydro_kx_state *state, const char *name)
153
+ {
154
+ mem_zero(state, sizeof *state);
155
+ hydro_hash_init(&state->h_st, hydro_kx_CONTEXT, NULL);
156
+ hydro_hash_update(&state->h_st, name, strlen(name));
157
+ hydro_hash_final(&state->h_st, NULL, 0);
158
+ }
159
+
160
+ static void
161
+ hydro_kx_final(hydro_kx_state *state, uint8_t session_k1[hydro_kx_SESSIONKEYBYTES],
162
+ uint8_t session_k2[hydro_kx_SESSIONKEYBYTES])
163
+ {
164
+ uint8_t kdf_key[hydro_kdf_KEYBYTES];
165
+
166
+ hydro_hash_final(&state->h_st, kdf_key, sizeof kdf_key);
167
+ hydro_kdf_derive_from_key(session_k1, hydro_kx_SESSIONKEYBYTES, 0, hydro_kx_CONTEXT, kdf_key);
168
+ hydro_kdf_derive_from_key(session_k2, hydro_kx_SESSIONKEYBYTES, 1, hydro_kx_CONTEXT, kdf_key);
169
+ }
170
+
171
+ static int
172
+ hydro_kx_dh(hydro_kx_state *state, const uint8_t sk[hydro_x25519_SECRETKEYBYTES],
173
+ const uint8_t pk[hydro_x25519_PUBLICKEYBYTES])
174
+ {
175
+ uint8_t dh_result[hydro_x25519_BYTES];
176
+
177
+ if (hydro_x25519_scalarmult(dh_result, sk, pk, 1) != 0) {
178
+ return -1;
179
+ }
180
+ hydro_hash_update(&state->h_st, dh_result, hydro_x25519_BYTES);
181
+
182
+ return 0;
183
+ }
184
+
185
+ static void
186
+ hydro_kx_eph_keygen(hydro_kx_state *state, hydro_kx_keypair *kp)
187
+ {
188
+ hydro_kx_keygen(kp);
189
+ hydro_hash_update(&state->h_st, kp->pk, sizeof kp->pk);
190
+ }
191
+
192
+ /* NOISE_N */
193
+
194
+ int
195
+ hydro_kx_n_1(hydro_kx_session_keypair *kp, uint8_t packet1[hydro_kx_N_PACKET1BYTES],
196
+ const uint8_t psk[hydro_kx_PSKBYTES],
197
+ const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES])
198
+ {
199
+ hydro_kx_state state;
200
+ uint8_t * packet1_eph_pk = &packet1[0];
201
+ uint8_t * packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
202
+
203
+ if (psk == NULL) {
204
+ psk = zero;
205
+ }
206
+ hydro_kx_init_state(&state, "Noise_Npsk0_hydro1");
207
+ hydro_hash_update(&state.h_st, peer_static_pk, hydro_x25519_PUBLICKEYBYTES);
208
+
209
+ hydro_hash_update(&state.h_st, psk, hydro_kx_PSKBYTES);
210
+ hydro_kx_eph_keygen(&state, &state.eph_kp);
211
+ if (hydro_kx_dh(&state, state.eph_kp.sk, peer_static_pk) != 0) {
212
+ return -1;
213
+ }
214
+ hydro_kx_aead_encrypt(&state, packet1_mac, NULL, 0);
215
+ memcpy(packet1_eph_pk, state.eph_kp.pk, sizeof state.eph_kp.pk);
216
+
217
+ hydro_kx_final(&state, kp->rx, kp->tx);
218
+
219
+ return 0;
220
+ }
221
+
222
+ int
223
+ hydro_kx_n_2(hydro_kx_session_keypair *kp, const uint8_t packet1[hydro_kx_N_PACKET1BYTES],
224
+ const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp)
225
+ {
226
+ hydro_kx_state state;
227
+ const uint8_t *peer_eph_pk = &packet1[0];
228
+ const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
229
+
230
+ if (psk == NULL) {
231
+ psk = zero;
232
+ }
233
+ hydro_kx_init_state(&state, "Noise_Npsk0_hydro1");
234
+ hydro_hash_update(&state.h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES);
235
+
236
+ hydro_hash_update(&state.h_st, psk, hydro_kx_PSKBYTES);
237
+ hydro_hash_update(&state.h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES);
238
+ if (hydro_kx_dh(&state, static_kp->sk, peer_eph_pk) != 0 ||
239
+ hydro_kx_aead_decrypt(&state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) {
240
+ return -1;
241
+ }
242
+ hydro_kx_final(&state, kp->tx, kp->rx);
243
+
244
+ return 0;
245
+ }
246
+
247
+ /* NOISE_KK */
248
+
249
+ int
250
+ hydro_kx_kk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_KK_PACKET1BYTES],
251
+ const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
252
+ const hydro_kx_keypair *static_kp)
253
+ {
254
+ uint8_t *packet1_eph_pk = &packet1[0];
255
+ uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
256
+
257
+ hydro_kx_init_state(state, "Noise_KK_hydro1");
258
+ hydro_hash_update(&state->h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES);
259
+ hydro_hash_update(&state->h_st, peer_static_pk, hydro_kx_PUBLICKEYBYTES);
260
+
261
+ hydro_kx_eph_keygen(state, &state->eph_kp);
262
+ if (hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0 ||
263
+ hydro_kx_dh(state, static_kp->sk, peer_static_pk) != 0) {
264
+ return -1;
265
+ }
266
+ hydro_kx_aead_encrypt(state, packet1_mac, NULL, 0);
267
+ memcpy(packet1_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk);
268
+
269
+ return 0;
270
+ }
271
+
272
+ int
273
+ hydro_kx_kk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_KK_PACKET2BYTES],
274
+ const uint8_t packet1[hydro_kx_KK_PACKET1BYTES],
275
+ const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
276
+ const hydro_kx_keypair *static_kp)
277
+ {
278
+ hydro_kx_state state;
279
+ const uint8_t *peer_eph_pk = &packet1[0];
280
+ const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
281
+ uint8_t * packet2_eph_pk = &packet2[0];
282
+ uint8_t * packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];
283
+
284
+ hydro_kx_init_state(&state, "Noise_KK_hydro1");
285
+ hydro_hash_update(&state.h_st, peer_static_pk, hydro_kx_PUBLICKEYBYTES);
286
+ hydro_hash_update(&state.h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES);
287
+
288
+ hydro_hash_update(&state.h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES);
289
+ if (hydro_kx_dh(&state, static_kp->sk, peer_eph_pk) != 0 ||
290
+ hydro_kx_dh(&state, static_kp->sk, peer_static_pk) != 0 ||
291
+ hydro_kx_aead_decrypt(&state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) {
292
+ return -1;
293
+ }
294
+
295
+ hydro_kx_eph_keygen(&state, &state.eph_kp);
296
+ if (hydro_kx_dh(&state, state.eph_kp.sk, peer_eph_pk) != 0 ||
297
+ hydro_kx_dh(&state, state.eph_kp.sk, peer_static_pk) != 0) {
298
+ return -1;
299
+ }
300
+ hydro_kx_aead_encrypt(&state, packet2_mac, NULL, 0);
301
+ hydro_kx_final(&state, kp->tx, kp->rx);
302
+ memcpy(packet2_eph_pk, state.eph_kp.pk, sizeof state.eph_kp.pk);
303
+
304
+ return 0;
305
+ }
306
+
307
+ int
308
+ hydro_kx_kk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
309
+ const uint8_t packet2[hydro_kx_KK_PACKET2BYTES], const hydro_kx_keypair *static_kp)
310
+ {
311
+ const uint8_t *peer_eph_pk = packet2;
312
+ const uint8_t *packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];
313
+
314
+ hydro_hash_update(&state->h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES);
315
+ if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0 ||
316
+ hydro_kx_dh(state, static_kp->sk, peer_eph_pk) != 0) {
317
+ return -1;
318
+ }
319
+
320
+ if (hydro_kx_aead_decrypt(state, NULL, packet2_mac, hydro_kx_AEAD_MACBYTES) != 0) {
321
+ return -1;
322
+ }
323
+ hydro_kx_final(state, kp->rx, kp->tx);
324
+
325
+ return 0;
326
+ }
327
+
328
+ /* NOISE_XX */
329
+
330
+ int
331
+ hydro_kx_xx_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_XX_PACKET1BYTES],
332
+ const uint8_t psk[hydro_kx_PSKBYTES])
333
+ {
334
+ uint8_t *packet1_eph_pk = &packet1[0];
335
+ uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
336
+
337
+ if (psk == NULL) {
338
+ psk = zero;
339
+ }
340
+ hydro_kx_init_state(state, "Noise_XXpsk0+psk3_hydro1");
341
+
342
+ hydro_kx_eph_keygen(state, &state->eph_kp);
343
+ hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
344
+ memcpy(packet1_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk);
345
+ hydro_kx_aead_encrypt(state, packet1_mac, NULL, 0);
346
+
347
+ return 0;
348
+ }
349
+
350
+ int
351
+ hydro_kx_xx_2(hydro_kx_state *state, uint8_t packet2[hydro_kx_XX_PACKET2BYTES],
352
+ const uint8_t packet1[hydro_kx_XX_PACKET1BYTES], const uint8_t psk[hydro_kx_PSKBYTES],
353
+ const hydro_kx_keypair *static_kp)
354
+ {
355
+ const uint8_t *peer_eph_pk = &packet1[0];
356
+ const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
357
+ uint8_t * packet2_eph_pk = &packet2[0];
358
+ uint8_t * packet2_enc_static_pk = &packet2[hydro_kx_PUBLICKEYBYTES];
359
+ uint8_t * packet2_mac =
360
+ &packet2[hydro_kx_PUBLICKEYBYTES + hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES];
361
+
362
+ if (psk == NULL) {
363
+ psk = zero;
364
+ }
365
+ hydro_kx_init_state(state, "Noise_XXpsk0+psk3_hydro1");
366
+
367
+ hydro_hash_update(&state->h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES);
368
+ hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
369
+ if (hydro_kx_aead_decrypt(state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) {
370
+ return -1;
371
+ }
372
+
373
+ hydro_kx_eph_keygen(state, &state->eph_kp);
374
+ if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0) {
375
+ return -1;
376
+ }
377
+ hydro_kx_aead_encrypt(state, packet2_enc_static_pk, static_kp->pk, sizeof static_kp->pk);
378
+ if (hydro_kx_dh(state, static_kp->sk, peer_eph_pk) != 0) {
379
+ return -1;
380
+ }
381
+ hydro_kx_aead_encrypt(state, packet2_mac, NULL, 0);
382
+
383
+ memcpy(packet2_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk);
384
+
385
+ return 0;
386
+ }
387
+
388
+ int
389
+ hydro_kx_xx_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
390
+ uint8_t packet3[hydro_kx_XX_PACKET3BYTES],
391
+ uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
392
+ const uint8_t packet2[hydro_kx_XX_PACKET2BYTES], const uint8_t psk[hydro_kx_PSKBYTES],
393
+ const hydro_kx_keypair *static_kp)
394
+ {
395
+ uint8_t peer_static_pk_[hydro_kx_PUBLICKEYBYTES];
396
+ const uint8_t *peer_eph_pk = &packet2[0];
397
+ const uint8_t *peer_enc_static_pk = &packet2[hydro_kx_PUBLICKEYBYTES];
398
+ const uint8_t *packet2_mac =
399
+ &packet2[hydro_kx_PUBLICKEYBYTES + hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES];
400
+ uint8_t *packet3_enc_static_pk = &packet3[0];
401
+ uint8_t *packet3_mac = &packet3[hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES];
402
+
403
+ if (psk == NULL) {
404
+ psk = zero;
405
+ }
406
+ if (peer_static_pk == NULL) {
407
+ peer_static_pk = peer_static_pk_;
408
+ }
409
+ hydro_hash_update(&state->h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES);
410
+ if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0 ||
411
+ hydro_kx_aead_decrypt(state, peer_static_pk, peer_enc_static_pk,
412
+ hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES) != 0 ||
413
+ hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0 ||
414
+ hydro_kx_aead_decrypt(state, NULL, packet2_mac, hydro_kx_AEAD_MACBYTES) != 0) {
415
+ return -1;
416
+ }
417
+
418
+ hydro_kx_aead_encrypt(state, packet3_enc_static_pk, static_kp->pk, sizeof static_kp->pk);
419
+ if (hydro_kx_dh(state, static_kp->sk, peer_eph_pk) != 0) {
420
+ return -1;
421
+ }
422
+ hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
423
+ hydro_kx_aead_encrypt(state, packet3_mac, NULL, 0);
424
+ hydro_kx_final(state, kp->rx, kp->tx);
425
+
426
+ return 0;
427
+ }
428
+
429
+ int
430
+ hydro_kx_xx_4(hydro_kx_state *state, hydro_kx_session_keypair *kp,
431
+ uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
432
+ const uint8_t packet3[hydro_kx_XX_PACKET3BYTES], const uint8_t psk[hydro_kx_PSKBYTES])
433
+ {
434
+ uint8_t peer_static_pk_[hydro_kx_PUBLICKEYBYTES];
435
+ const uint8_t *peer_enc_static_pk = &packet3[0];
436
+ const uint8_t *packet3_mac = &packet3[hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES];
437
+
438
+ if (psk == NULL) {
439
+ psk = zero;
440
+ }
441
+ if (peer_static_pk == NULL) {
442
+ peer_static_pk = peer_static_pk_;
443
+ }
444
+ if (hydro_kx_aead_decrypt(state, peer_static_pk, peer_enc_static_pk,
445
+ hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES) != 0 ||
446
+ hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0) {
447
+ return -1;
448
+ }
449
+ hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
450
+ if (hydro_kx_aead_decrypt(state, NULL, packet3_mac, hydro_kx_AEAD_MACBYTES) != 0) {
451
+ return -1;
452
+ }
453
+ hydro_kx_final(state, kp->tx, kp->rx);
454
+
455
+ return 0;
456
+ }
457
+
458
+ /* NOISE_NK */
459
+
460
+ int
461
+ hydro_kx_nk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_NK_PACKET1BYTES],
462
+ const uint8_t psk[hydro_kx_PSKBYTES],
463
+ const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES])
464
+ {
465
+ uint8_t *packet1_eph_pk = &packet1[0];
466
+ uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
467
+
468
+ if (psk == NULL) {
469
+ psk = zero;
470
+ }
471
+ hydro_kx_init_state(state, "Noise_NKpsk0_hydro1");
472
+ hydro_hash_update(&state->h_st, peer_static_pk, hydro_x25519_PUBLICKEYBYTES);
473
+
474
+ hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
475
+ hydro_kx_eph_keygen(state, &state->eph_kp);
476
+ if (hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0) {
477
+ return -1;
478
+ }
479
+ hydro_kx_aead_encrypt(state, packet1_mac, NULL, 0);
480
+ memcpy(packet1_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk);
481
+
482
+ return 0;
483
+ }
484
+
485
+ int
486
+ hydro_kx_nk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_NK_PACKET2BYTES],
487
+ const uint8_t packet1[hydro_kx_NK_PACKET1BYTES], const uint8_t psk[hydro_kx_PSKBYTES],
488
+ const hydro_kx_keypair *static_kp)
489
+ {
490
+ hydro_kx_state state;
491
+ const uint8_t *peer_eph_pk = &packet1[0];
492
+ const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
493
+ uint8_t * packet2_eph_pk = &packet2[0];
494
+ uint8_t * packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];
495
+
496
+ if (psk == NULL) {
497
+ psk = zero;
498
+ }
499
+ hydro_kx_init_state(&state, "Noise_NKpsk0_hydro1");
500
+ hydro_hash_update(&state.h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES);
501
+
502
+ hydro_hash_update(&state.h_st, psk, hydro_kx_PSKBYTES);
503
+ hydro_hash_update(&state.h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES);
504
+ if (hydro_kx_dh(&state, static_kp->sk, peer_eph_pk) != 0 ||
505
+ hydro_kx_aead_decrypt(&state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) {
506
+ return -1;
507
+ }
508
+
509
+ hydro_kx_eph_keygen(&state, &state.eph_kp);
510
+ if (hydro_kx_dh(&state, state.eph_kp.sk, peer_eph_pk) != 0) {
511
+ return -1;
512
+ }
513
+ hydro_kx_aead_encrypt(&state, packet2_mac, NULL, 0);
514
+ hydro_kx_final(&state, kp->tx, kp->rx);
515
+ memcpy(packet2_eph_pk, state.eph_kp.pk, sizeof state.eph_kp.pk);
516
+
517
+ return 0;
518
+ }
519
+
520
+ int
521
+ hydro_kx_nk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
522
+ const uint8_t packet2[hydro_kx_NK_PACKET2BYTES])
523
+ {
524
+ const uint8_t *peer_eph_pk = &packet2[0];
525
+ const uint8_t *packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];
526
+
527
+ hydro_hash_update(&state->h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES);
528
+ if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0 ||
529
+ hydro_kx_aead_decrypt(state, NULL, packet2_mac, hydro_kx_AEAD_MACBYTES) != 0) {
530
+ return -1;
531
+ }
532
+ hydro_kx_final(state, kp->rx, kp->tx);
533
+
534
+ return 0;
535
+ }