pq_crypto 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 (93) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +37 -0
  3. data/CHANGELOG.md +29 -0
  4. data/GET_STARTED.md +65 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +135 -0
  7. data/SECURITY.md +57 -0
  8. data/ext/pqcrypto/extconf.rb +157 -0
  9. data/ext/pqcrypto/mldsa_api.h +51 -0
  10. data/ext/pqcrypto/mlkem_api.h +21 -0
  11. data/ext/pqcrypto/pqcrypto_ruby_secure.c +889 -0
  12. data/ext/pqcrypto/pqcrypto_secure.c +1178 -0
  13. data/ext/pqcrypto/pqcrypto_secure.h +135 -0
  14. data/ext/pqcrypto/vendor/.vendored +5 -0
  15. data/ext/pqcrypto/vendor/pqclean/common/aes.c +639 -0
  16. data/ext/pqcrypto/vendor/pqclean/common/aes.h +64 -0
  17. data/ext/pqcrypto/vendor/pqclean/common/compat.h +73 -0
  18. data/ext/pqcrypto/vendor/pqclean/common/crypto_declassify.h +7 -0
  19. data/ext/pqcrypto/vendor/pqclean/common/fips202.c +928 -0
  20. data/ext/pqcrypto/vendor/pqclean/common/fips202.h +166 -0
  21. data/ext/pqcrypto/vendor/pqclean/common/keccak2x/feat.S +168 -0
  22. data/ext/pqcrypto/vendor/pqclean/common/keccak2x/fips202x2.c +684 -0
  23. data/ext/pqcrypto/vendor/pqclean/common/keccak2x/fips202x2.h +60 -0
  24. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-times4-SIMD256.c +1028 -0
  25. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-times4-SnP.h +50 -0
  26. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-unrolling.macros +198 -0
  27. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/Makefile +8 -0
  28. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/Makefile.Microsoft_nmake +8 -0
  29. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/SIMD256-config.h +3 -0
  30. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/align.h +34 -0
  31. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/brg_endian.h +142 -0
  32. data/ext/pqcrypto/vendor/pqclean/common/nistseedexpander.c +101 -0
  33. data/ext/pqcrypto/vendor/pqclean/common/nistseedexpander.h +39 -0
  34. data/ext/pqcrypto/vendor/pqclean/common/randombytes.c +355 -0
  35. data/ext/pqcrypto/vendor/pqclean/common/randombytes.h +27 -0
  36. data/ext/pqcrypto/vendor/pqclean/common/sha2.c +769 -0
  37. data/ext/pqcrypto/vendor/pqclean/common/sha2.h +173 -0
  38. data/ext/pqcrypto/vendor/pqclean/common/sp800-185.c +156 -0
  39. data/ext/pqcrypto/vendor/pqclean/common/sp800-185.h +27 -0
  40. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/LICENSE +5 -0
  41. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/Makefile +19 -0
  42. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/Makefile.Microsoft_nmake +23 -0
  43. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/api.h +18 -0
  44. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/cbd.c +83 -0
  45. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/cbd.h +11 -0
  46. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/indcpa.c +327 -0
  47. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/indcpa.h +22 -0
  48. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/kem.c +164 -0
  49. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/kem.h +23 -0
  50. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/ntt.c +146 -0
  51. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/ntt.h +14 -0
  52. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/params.h +36 -0
  53. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/poly.c +299 -0
  54. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/poly.h +37 -0
  55. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/polyvec.c +188 -0
  56. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/polyvec.h +26 -0
  57. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/reduce.c +41 -0
  58. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/reduce.h +13 -0
  59. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/symmetric-shake.c +71 -0
  60. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/symmetric.h +30 -0
  61. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/verify.c +67 -0
  62. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/verify.h +13 -0
  63. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/LICENSE +5 -0
  64. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/Makefile +19 -0
  65. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/Makefile.Microsoft_nmake +23 -0
  66. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/api.h +50 -0
  67. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/ntt.c +98 -0
  68. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/ntt.h +10 -0
  69. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/packing.c +261 -0
  70. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/packing.h +31 -0
  71. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/params.h +44 -0
  72. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/poly.c +799 -0
  73. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/poly.h +52 -0
  74. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/polyvec.c +415 -0
  75. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/polyvec.h +65 -0
  76. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/reduce.c +69 -0
  77. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/reduce.h +17 -0
  78. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/rounding.c +92 -0
  79. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/rounding.h +14 -0
  80. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/sign.c +407 -0
  81. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/sign.h +47 -0
  82. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/symmetric-shake.c +26 -0
  83. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/symmetric.h +34 -0
  84. data/lib/pq_crypto/errors.rb +10 -0
  85. data/lib/pq_crypto/hybrid_kem.rb +106 -0
  86. data/lib/pq_crypto/kem.rb +199 -0
  87. data/lib/pq_crypto/serialization.rb +102 -0
  88. data/lib/pq_crypto/signature.rb +198 -0
  89. data/lib/pq_crypto/version.rb +5 -0
  90. data/lib/pq_crypto.rb +177 -0
  91. data/lib/pqcrypto.rb +3 -0
  92. data/script/vendor_libs.rb +199 -0
  93. metadata +195 -0
@@ -0,0 +1,928 @@
1
+ /* Based on the public domain implementation in
2
+ * crypto_hash/keccakc512/simple/ from http://bench.cr.yp.to/supercop.html
3
+ * by Ronny Van Keer
4
+ * and the public domain "TweetFips202" implementation
5
+ * from https://twitter.com/tweetfips202
6
+ * by Gilles Van Assche, Daniel J. Bernstein, and Peter Schwabe */
7
+
8
+ #include <stddef.h>
9
+ #include <stdint.h>
10
+ #include <stdlib.h>
11
+ #include <string.h>
12
+
13
+ #include "fips202.h"
14
+
15
+ #define NROUNDS 24
16
+ #define ROL(a, offset) (((a) << (offset)) ^ ((a) >> (64 - (offset))))
17
+
18
+ /*************************************************
19
+ * Name: load64
20
+ *
21
+ * Description: Load 8 bytes into uint64_t in little-endian order
22
+ *
23
+ * Arguments: - const uint8_t *x: pointer to input byte array
24
+ *
25
+ * Returns the loaded 64-bit unsigned integer
26
+ **************************************************/
27
+ static uint64_t load64(const uint8_t *x) {
28
+ uint64_t r = 0;
29
+ for (size_t i = 0; i < 8; ++i) {
30
+ r |= (uint64_t)x[i] << 8 * i;
31
+ }
32
+
33
+ return r;
34
+ }
35
+
36
+ /*************************************************
37
+ * Name: store64
38
+ *
39
+ * Description: Store a 64-bit integer to a byte array in little-endian order
40
+ *
41
+ * Arguments: - uint8_t *x: pointer to the output byte array
42
+ * - uint64_t u: input 64-bit unsigned integer
43
+ **************************************************/
44
+ static void store64(uint8_t *x, uint64_t u) {
45
+ for (size_t i = 0; i < 8; ++i) {
46
+ x[i] = (uint8_t) (u >> 8 * i);
47
+ }
48
+ }
49
+
50
+ /* Keccak round constants */
51
+ static const uint64_t KeccakF_RoundConstants[NROUNDS] = {
52
+ 0x0000000000000001ULL, 0x0000000000008082ULL,
53
+ 0x800000000000808aULL, 0x8000000080008000ULL,
54
+ 0x000000000000808bULL, 0x0000000080000001ULL,
55
+ 0x8000000080008081ULL, 0x8000000000008009ULL,
56
+ 0x000000000000008aULL, 0x0000000000000088ULL,
57
+ 0x0000000080008009ULL, 0x000000008000000aULL,
58
+ 0x000000008000808bULL, 0x800000000000008bULL,
59
+ 0x8000000000008089ULL, 0x8000000000008003ULL,
60
+ 0x8000000000008002ULL, 0x8000000000000080ULL,
61
+ 0x000000000000800aULL, 0x800000008000000aULL,
62
+ 0x8000000080008081ULL, 0x8000000000008080ULL,
63
+ 0x0000000080000001ULL, 0x8000000080008008ULL
64
+ };
65
+
66
+ /*************************************************
67
+ * Name: KeccakF1600_StatePermute
68
+ *
69
+ * Description: The Keccak F1600 Permutation
70
+ *
71
+ * Arguments: - uint64_t *state: pointer to input/output Keccak state
72
+ **************************************************/
73
+ static void KeccakF1600_StatePermute(uint64_t *state) {
74
+ int round;
75
+
76
+ uint64_t Aba, Abe, Abi, Abo, Abu;
77
+ uint64_t Aga, Age, Agi, Ago, Agu;
78
+ uint64_t Aka, Ake, Aki, Ako, Aku;
79
+ uint64_t Ama, Ame, Ami, Amo, Amu;
80
+ uint64_t Asa, Ase, Asi, Aso, Asu;
81
+ uint64_t BCa, BCe, BCi, BCo, BCu;
82
+ uint64_t Da, De, Di, Do, Du;
83
+ uint64_t Eba, Ebe, Ebi, Ebo, Ebu;
84
+ uint64_t Ega, Ege, Egi, Ego, Egu;
85
+ uint64_t Eka, Eke, Eki, Eko, Eku;
86
+ uint64_t Ema, Eme, Emi, Emo, Emu;
87
+ uint64_t Esa, Ese, Esi, Eso, Esu;
88
+
89
+ // copyFromState(A, state)
90
+ Aba = state[0];
91
+ Abe = state[1];
92
+ Abi = state[2];
93
+ Abo = state[3];
94
+ Abu = state[4];
95
+ Aga = state[5];
96
+ Age = state[6];
97
+ Agi = state[7];
98
+ Ago = state[8];
99
+ Agu = state[9];
100
+ Aka = state[10];
101
+ Ake = state[11];
102
+ Aki = state[12];
103
+ Ako = state[13];
104
+ Aku = state[14];
105
+ Ama = state[15];
106
+ Ame = state[16];
107
+ Ami = state[17];
108
+ Amo = state[18];
109
+ Amu = state[19];
110
+ Asa = state[20];
111
+ Ase = state[21];
112
+ Asi = state[22];
113
+ Aso = state[23];
114
+ Asu = state[24];
115
+
116
+ for (round = 0; round < NROUNDS; round += 2) {
117
+ // prepareTheta
118
+ BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
119
+ BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase;
120
+ BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
121
+ BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
122
+ BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
123
+
124
+ // thetaRhoPiChiIotaPrepareTheta(round , A, E)
125
+ Da = BCu ^ ROL(BCe, 1);
126
+ De = BCa ^ ROL(BCi, 1);
127
+ Di = BCe ^ ROL(BCo, 1);
128
+ Do = BCi ^ ROL(BCu, 1);
129
+ Du = BCo ^ ROL(BCa, 1);
130
+
131
+ Aba ^= Da;
132
+ BCa = Aba;
133
+ Age ^= De;
134
+ BCe = ROL(Age, 44);
135
+ Aki ^= Di;
136
+ BCi = ROL(Aki, 43);
137
+ Amo ^= Do;
138
+ BCo = ROL(Amo, 21);
139
+ Asu ^= Du;
140
+ BCu = ROL(Asu, 14);
141
+ Eba = BCa ^ ((~BCe) & BCi);
142
+ Eba ^= KeccakF_RoundConstants[round];
143
+ Ebe = BCe ^ ((~BCi) & BCo);
144
+ Ebi = BCi ^ ((~BCo) & BCu);
145
+ Ebo = BCo ^ ((~BCu) & BCa);
146
+ Ebu = BCu ^ ((~BCa) & BCe);
147
+
148
+ Abo ^= Do;
149
+ BCa = ROL(Abo, 28);
150
+ Agu ^= Du;
151
+ BCe = ROL(Agu, 20);
152
+ Aka ^= Da;
153
+ BCi = ROL(Aka, 3);
154
+ Ame ^= De;
155
+ BCo = ROL(Ame, 45);
156
+ Asi ^= Di;
157
+ BCu = ROL(Asi, 61);
158
+ Ega = BCa ^ ((~BCe) & BCi);
159
+ Ege = BCe ^ ((~BCi) & BCo);
160
+ Egi = BCi ^ ((~BCo) & BCu);
161
+ Ego = BCo ^ ((~BCu) & BCa);
162
+ Egu = BCu ^ ((~BCa) & BCe);
163
+
164
+ Abe ^= De;
165
+ BCa = ROL(Abe, 1);
166
+ Agi ^= Di;
167
+ BCe = ROL(Agi, 6);
168
+ Ako ^= Do;
169
+ BCi = ROL(Ako, 25);
170
+ Amu ^= Du;
171
+ BCo = ROL(Amu, 8);
172
+ Asa ^= Da;
173
+ BCu = ROL(Asa, 18);
174
+ Eka = BCa ^ ((~BCe) & BCi);
175
+ Eke = BCe ^ ((~BCi) & BCo);
176
+ Eki = BCi ^ ((~BCo) & BCu);
177
+ Eko = BCo ^ ((~BCu) & BCa);
178
+ Eku = BCu ^ ((~BCa) & BCe);
179
+
180
+ Abu ^= Du;
181
+ BCa = ROL(Abu, 27);
182
+ Aga ^= Da;
183
+ BCe = ROL(Aga, 36);
184
+ Ake ^= De;
185
+ BCi = ROL(Ake, 10);
186
+ Ami ^= Di;
187
+ BCo = ROL(Ami, 15);
188
+ Aso ^= Do;
189
+ BCu = ROL(Aso, 56);
190
+ Ema = BCa ^ ((~BCe) & BCi);
191
+ Eme = BCe ^ ((~BCi) & BCo);
192
+ Emi = BCi ^ ((~BCo) & BCu);
193
+ Emo = BCo ^ ((~BCu) & BCa);
194
+ Emu = BCu ^ ((~BCa) & BCe);
195
+
196
+ Abi ^= Di;
197
+ BCa = ROL(Abi, 62);
198
+ Ago ^= Do;
199
+ BCe = ROL(Ago, 55);
200
+ Aku ^= Du;
201
+ BCi = ROL(Aku, 39);
202
+ Ama ^= Da;
203
+ BCo = ROL(Ama, 41);
204
+ Ase ^= De;
205
+ BCu = ROL(Ase, 2);
206
+ Esa = BCa ^ ((~BCe) & BCi);
207
+ Ese = BCe ^ ((~BCi) & BCo);
208
+ Esi = BCi ^ ((~BCo) & BCu);
209
+ Eso = BCo ^ ((~BCu) & BCa);
210
+ Esu = BCu ^ ((~BCa) & BCe);
211
+
212
+ // prepareTheta
213
+ BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
214
+ BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
215
+ BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
216
+ BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
217
+ BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
218
+
219
+ // thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
220
+ Da = BCu ^ ROL(BCe, 1);
221
+ De = BCa ^ ROL(BCi, 1);
222
+ Di = BCe ^ ROL(BCo, 1);
223
+ Do = BCi ^ ROL(BCu, 1);
224
+ Du = BCo ^ ROL(BCa, 1);
225
+
226
+ Eba ^= Da;
227
+ BCa = Eba;
228
+ Ege ^= De;
229
+ BCe = ROL(Ege, 44);
230
+ Eki ^= Di;
231
+ BCi = ROL(Eki, 43);
232
+ Emo ^= Do;
233
+ BCo = ROL(Emo, 21);
234
+ Esu ^= Du;
235
+ BCu = ROL(Esu, 14);
236
+ Aba = BCa ^ ((~BCe) & BCi);
237
+ Aba ^= KeccakF_RoundConstants[round + 1];
238
+ Abe = BCe ^ ((~BCi) & BCo);
239
+ Abi = BCi ^ ((~BCo) & BCu);
240
+ Abo = BCo ^ ((~BCu) & BCa);
241
+ Abu = BCu ^ ((~BCa) & BCe);
242
+
243
+ Ebo ^= Do;
244
+ BCa = ROL(Ebo, 28);
245
+ Egu ^= Du;
246
+ BCe = ROL(Egu, 20);
247
+ Eka ^= Da;
248
+ BCi = ROL(Eka, 3);
249
+ Eme ^= De;
250
+ BCo = ROL(Eme, 45);
251
+ Esi ^= Di;
252
+ BCu = ROL(Esi, 61);
253
+ Aga = BCa ^ ((~BCe) & BCi);
254
+ Age = BCe ^ ((~BCi) & BCo);
255
+ Agi = BCi ^ ((~BCo) & BCu);
256
+ Ago = BCo ^ ((~BCu) & BCa);
257
+ Agu = BCu ^ ((~BCa) & BCe);
258
+
259
+ Ebe ^= De;
260
+ BCa = ROL(Ebe, 1);
261
+ Egi ^= Di;
262
+ BCe = ROL(Egi, 6);
263
+ Eko ^= Do;
264
+ BCi = ROL(Eko, 25);
265
+ Emu ^= Du;
266
+ BCo = ROL(Emu, 8);
267
+ Esa ^= Da;
268
+ BCu = ROL(Esa, 18);
269
+ Aka = BCa ^ ((~BCe) & BCi);
270
+ Ake = BCe ^ ((~BCi) & BCo);
271
+ Aki = BCi ^ ((~BCo) & BCu);
272
+ Ako = BCo ^ ((~BCu) & BCa);
273
+ Aku = BCu ^ ((~BCa) & BCe);
274
+
275
+ Ebu ^= Du;
276
+ BCa = ROL(Ebu, 27);
277
+ Ega ^= Da;
278
+ BCe = ROL(Ega, 36);
279
+ Eke ^= De;
280
+ BCi = ROL(Eke, 10);
281
+ Emi ^= Di;
282
+ BCo = ROL(Emi, 15);
283
+ Eso ^= Do;
284
+ BCu = ROL(Eso, 56);
285
+ Ama = BCa ^ ((~BCe) & BCi);
286
+ Ame = BCe ^ ((~BCi) & BCo);
287
+ Ami = BCi ^ ((~BCo) & BCu);
288
+ Amo = BCo ^ ((~BCu) & BCa);
289
+ Amu = BCu ^ ((~BCa) & BCe);
290
+
291
+ Ebi ^= Di;
292
+ BCa = ROL(Ebi, 62);
293
+ Ego ^= Do;
294
+ BCe = ROL(Ego, 55);
295
+ Eku ^= Du;
296
+ BCi = ROL(Eku, 39);
297
+ Ema ^= Da;
298
+ BCo = ROL(Ema, 41);
299
+ Ese ^= De;
300
+ BCu = ROL(Ese, 2);
301
+ Asa = BCa ^ ((~BCe) & BCi);
302
+ Ase = BCe ^ ((~BCi) & BCo);
303
+ Asi = BCi ^ ((~BCo) & BCu);
304
+ Aso = BCo ^ ((~BCu) & BCa);
305
+ Asu = BCu ^ ((~BCa) & BCe);
306
+ }
307
+
308
+ // copyToState(state, A)
309
+ state[0] = Aba;
310
+ state[1] = Abe;
311
+ state[2] = Abi;
312
+ state[3] = Abo;
313
+ state[4] = Abu;
314
+ state[5] = Aga;
315
+ state[6] = Age;
316
+ state[7] = Agi;
317
+ state[8] = Ago;
318
+ state[9] = Agu;
319
+ state[10] = Aka;
320
+ state[11] = Ake;
321
+ state[12] = Aki;
322
+ state[13] = Ako;
323
+ state[14] = Aku;
324
+ state[15] = Ama;
325
+ state[16] = Ame;
326
+ state[17] = Ami;
327
+ state[18] = Amo;
328
+ state[19] = Amu;
329
+ state[20] = Asa;
330
+ state[21] = Ase;
331
+ state[22] = Asi;
332
+ state[23] = Aso;
333
+ state[24] = Asu;
334
+ }
335
+
336
+ /*************************************************
337
+ * Name: keccak_absorb
338
+ *
339
+ * Description: Absorb step of Keccak;
340
+ * non-incremental, starts by zeroeing the state.
341
+ *
342
+ * Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
343
+ * - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
344
+ * - const uint8_t *m: pointer to input to be absorbed into s
345
+ * - size_t mlen: length of input in bytes
346
+ * - uint8_t p: domain-separation byte for different
347
+ * Keccak-derived functions
348
+ **************************************************/
349
+ static void keccak_absorb(uint64_t *s, uint32_t r, const uint8_t *m,
350
+ size_t mlen, uint8_t p) {
351
+ size_t i;
352
+ uint8_t t[200];
353
+
354
+ /* Zero state */
355
+ for (i = 0; i < 25; ++i) {
356
+ s[i] = 0;
357
+ }
358
+
359
+ while (mlen >= r) {
360
+ for (i = 0; i < r / 8; ++i) {
361
+ s[i] ^= load64(m + 8 * i);
362
+ }
363
+
364
+ KeccakF1600_StatePermute(s);
365
+ mlen -= r;
366
+ m += r;
367
+ }
368
+
369
+ for (i = 0; i < r; ++i) {
370
+ t[i] = 0;
371
+ }
372
+ for (i = 0; i < mlen; ++i) {
373
+ t[i] = m[i];
374
+ }
375
+ t[i] = p;
376
+ t[r - 1] |= 128;
377
+ for (i = 0; i < r / 8; ++i) {
378
+ s[i] ^= load64(t + 8 * i);
379
+ }
380
+ }
381
+
382
+ /*************************************************
383
+ * Name: keccak_squeezeblocks
384
+ *
385
+ * Description: Squeeze step of Keccak. Squeezes full blocks of r bytes each.
386
+ * Modifies the state. Can be called multiple times to keep
387
+ * squeezing, i.e., is incremental.
388
+ *
389
+ * Arguments: - uint8_t *h: pointer to output blocks
390
+ * - size_t nblocks: number of blocks to be
391
+ * squeezed (written to h)
392
+ * - uint64_t *s: pointer to input/output Keccak state
393
+ * - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
394
+ **************************************************/
395
+ static void keccak_squeezeblocks(uint8_t *h, size_t nblocks,
396
+ uint64_t *s, uint32_t r) {
397
+ while (nblocks > 0) {
398
+ KeccakF1600_StatePermute(s);
399
+ for (size_t i = 0; i < (r >> 3); i++) {
400
+ store64(h + 8 * i, s[i]);
401
+ }
402
+ h += r;
403
+ nblocks--;
404
+ }
405
+ }
406
+
407
+ /*************************************************
408
+ * Name: keccak_inc_init
409
+ *
410
+ * Description: Initializes the incremental Keccak state to zero.
411
+ *
412
+ * Arguments: - uint64_t *s_inc: pointer to input/output incremental state
413
+ * First 25 values represent Keccak state.
414
+ * 26th value represents either the number of absorbed bytes
415
+ * that have not been permuted, or not-yet-squeezed bytes.
416
+ **************************************************/
417
+ static void keccak_inc_init(uint64_t *s_inc) {
418
+ size_t i;
419
+
420
+ for (i = 0; i < 25; ++i) {
421
+ s_inc[i] = 0;
422
+ }
423
+ s_inc[25] = 0;
424
+ }
425
+
426
+ /*************************************************
427
+ * Name: keccak_inc_absorb
428
+ *
429
+ * Description: Incremental keccak absorb
430
+ * Preceded by keccak_inc_init, succeeded by keccak_inc_finalize
431
+ *
432
+ * Arguments: - uint64_t *s_inc: pointer to input/output incremental state
433
+ * First 25 values represent Keccak state.
434
+ * 26th value represents either the number of absorbed bytes
435
+ * that have not been permuted, or not-yet-squeezed bytes.
436
+ * - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
437
+ * - const uint8_t *m: pointer to input to be absorbed into s
438
+ * - size_t mlen: length of input in bytes
439
+ **************************************************/
440
+ static void keccak_inc_absorb(uint64_t *s_inc, uint32_t r, const uint8_t *m,
441
+ size_t mlen) {
442
+ size_t i;
443
+
444
+ /* Recall that s_inc[25] is the non-absorbed bytes xored into the state */
445
+ while (mlen + s_inc[25] >= r) {
446
+ for (i = 0; i < r - (uint32_t)s_inc[25]; i++) {
447
+ /* Take the i'th byte from message
448
+ xor with the s_inc[25] + i'th byte of the state; little-endian */
449
+ s_inc[(s_inc[25] + i) >> 3] ^= (uint64_t)m[i] << (8 * ((s_inc[25] + i) & 0x07));
450
+ }
451
+ mlen -= (size_t)(r - s_inc[25]);
452
+ m += r - s_inc[25];
453
+ s_inc[25] = 0;
454
+
455
+ KeccakF1600_StatePermute(s_inc);
456
+ }
457
+
458
+ for (i = 0; i < mlen; i++) {
459
+ s_inc[(s_inc[25] + i) >> 3] ^= (uint64_t)m[i] << (8 * ((s_inc[25] + i) & 0x07));
460
+ }
461
+ s_inc[25] += mlen;
462
+ }
463
+
464
+ /*************************************************
465
+ * Name: keccak_inc_finalize
466
+ *
467
+ * Description: Finalizes Keccak absorb phase, prepares for squeezing
468
+ *
469
+ * Arguments: - uint64_t *s_inc: pointer to input/output incremental state
470
+ * First 25 values represent Keccak state.
471
+ * 26th value represents either the number of absorbed bytes
472
+ * that have not been permuted, or not-yet-squeezed bytes.
473
+ * - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
474
+ * - uint8_t p: domain-separation byte for different
475
+ * Keccak-derived functions
476
+ **************************************************/
477
+ static void keccak_inc_finalize(uint64_t *s_inc, uint32_t r, uint8_t p) {
478
+ /* After keccak_inc_absorb, we are guaranteed that s_inc[25] < r,
479
+ so we can always use one more byte for p in the current state. */
480
+ s_inc[s_inc[25] >> 3] ^= (uint64_t)p << (8 * (s_inc[25] & 0x07));
481
+ s_inc[(r - 1) >> 3] ^= (uint64_t)128 << (8 * ((r - 1) & 0x07));
482
+ s_inc[25] = 0;
483
+ }
484
+
485
+ /*************************************************
486
+ * Name: keccak_inc_squeeze
487
+ *
488
+ * Description: Incremental Keccak squeeze; can be called on byte-level
489
+ *
490
+ * Arguments: - uint8_t *h: pointer to output bytes
491
+ * - size_t outlen: number of bytes to be squeezed
492
+ * - uint64_t *s_inc: pointer to input/output incremental state
493
+ * First 25 values represent Keccak state.
494
+ * 26th value represents either the number of absorbed bytes
495
+ * that have not been permuted, or not-yet-squeezed bytes.
496
+ * - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
497
+ **************************************************/
498
+ static void keccak_inc_squeeze(uint8_t *h, size_t outlen,
499
+ uint64_t *s_inc, uint32_t r) {
500
+ size_t i;
501
+
502
+ /* First consume any bytes we still have sitting around */
503
+ for (i = 0; i < outlen && i < s_inc[25]; i++) {
504
+ /* There are s_inc[25] bytes left, so r - s_inc[25] is the first
505
+ available byte. We consume from there, i.e., up to r. */
506
+ h[i] = (uint8_t)(s_inc[(r - s_inc[25] + i) >> 3] >> (8 * ((r - s_inc[25] + i) & 0x07)));
507
+ }
508
+ h += i;
509
+ outlen -= i;
510
+ s_inc[25] -= i;
511
+
512
+ /* Then squeeze the remaining necessary blocks */
513
+ while (outlen > 0) {
514
+ KeccakF1600_StatePermute(s_inc);
515
+
516
+ for (i = 0; i < outlen && i < r; i++) {
517
+ h[i] = (uint8_t)(s_inc[i >> 3] >> (8 * (i & 0x07)));
518
+ }
519
+ h += i;
520
+ outlen -= i;
521
+ s_inc[25] = r - i;
522
+ }
523
+ }
524
+
525
+ void shake128_inc_init(shake128incctx *state) {
526
+ state->ctx = malloc(PQC_SHAKEINCCTX_BYTES);
527
+ if (state->ctx == NULL) {
528
+ exit(111);
529
+ }
530
+ keccak_inc_init(state->ctx);
531
+ }
532
+
533
+ void shake128_inc_absorb(shake128incctx *state, const uint8_t *input, size_t inlen) {
534
+ keccak_inc_absorb(state->ctx, SHAKE128_RATE, input, inlen);
535
+ }
536
+
537
+ void shake128_inc_finalize(shake128incctx *state) {
538
+ keccak_inc_finalize(state->ctx, SHAKE128_RATE, 0x1F);
539
+ }
540
+
541
+ void shake128_inc_squeeze(uint8_t *output, size_t outlen, shake128incctx *state) {
542
+ keccak_inc_squeeze(output, outlen, state->ctx, SHAKE128_RATE);
543
+ }
544
+
545
+ void shake128_inc_ctx_clone(shake128incctx *dest, const shake128incctx *src) {
546
+ dest->ctx = malloc(PQC_SHAKEINCCTX_BYTES);
547
+ if (dest->ctx == NULL) {
548
+ exit(111);
549
+ }
550
+ memcpy(dest->ctx, src->ctx, PQC_SHAKEINCCTX_BYTES);
551
+ }
552
+
553
+ void shake128_inc_ctx_release(shake128incctx *state) {
554
+ free(state->ctx);
555
+ }
556
+
557
+ void shake256_inc_init(shake256incctx *state) {
558
+ state->ctx = malloc(PQC_SHAKEINCCTX_BYTES);
559
+ if (state->ctx == NULL) {
560
+ exit(111);
561
+ }
562
+ keccak_inc_init(state->ctx);
563
+ }
564
+
565
+ void shake256_inc_absorb(shake256incctx *state, const uint8_t *input, size_t inlen) {
566
+ keccak_inc_absorb(state->ctx, SHAKE256_RATE, input, inlen);
567
+ }
568
+
569
+ void shake256_inc_finalize(shake256incctx *state) {
570
+ keccak_inc_finalize(state->ctx, SHAKE256_RATE, 0x1F);
571
+ }
572
+
573
+ void shake256_inc_squeeze(uint8_t *output, size_t outlen, shake256incctx *state) {
574
+ keccak_inc_squeeze(output, outlen, state->ctx, SHAKE256_RATE);
575
+ }
576
+
577
+ void shake256_inc_ctx_clone(shake256incctx *dest, const shake256incctx *src) {
578
+ dest->ctx = malloc(PQC_SHAKEINCCTX_BYTES);
579
+ if (dest->ctx == NULL) {
580
+ exit(111);
581
+ }
582
+ memcpy(dest->ctx, src->ctx, PQC_SHAKEINCCTX_BYTES);
583
+ }
584
+
585
+ void shake256_inc_ctx_release(shake256incctx *state) {
586
+ free(state->ctx);
587
+ }
588
+
589
+ /*************************************************
590
+ * Name: shake128_absorb
591
+ *
592
+ * Description: Absorb step of the SHAKE128 XOF.
593
+ * non-incremental, starts by zeroeing the state.
594
+ *
595
+ * Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
596
+ * - const uint8_t *input: pointer to input to be absorbed
597
+ * into s
598
+ * - size_t inlen: length of input in bytes
599
+ **************************************************/
600
+ void shake128_absorb(shake128ctx *state, const uint8_t *input, size_t inlen) {
601
+ state->ctx = malloc(PQC_SHAKECTX_BYTES);
602
+ if (state->ctx == NULL) {
603
+ exit(111);
604
+ }
605
+ keccak_absorb(state->ctx, SHAKE128_RATE, input, inlen, 0x1F);
606
+ }
607
+
608
+ /*************************************************
609
+ * Name: shake128_squeezeblocks
610
+ *
611
+ * Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of
612
+ * SHAKE128_RATE bytes each. Modifies the state. Can be called
613
+ * multiple times to keep squeezing, i.e., is incremental.
614
+ *
615
+ * Arguments: - uint8_t *output: pointer to output blocks
616
+ * - size_t nblocks: number of blocks to be squeezed
617
+ * (written to output)
618
+ * - shake128ctx *state: pointer to input/output Keccak state
619
+ **************************************************/
620
+ void shake128_squeezeblocks(uint8_t *output, size_t nblocks, shake128ctx *state) {
621
+ keccak_squeezeblocks(output, nblocks, state->ctx, SHAKE128_RATE);
622
+ }
623
+
624
+ void shake128_ctx_clone(shake128ctx *dest, const shake128ctx *src) {
625
+ dest->ctx = malloc(PQC_SHAKECTX_BYTES);
626
+ if (dest->ctx == NULL) {
627
+ exit(111);
628
+ }
629
+ memcpy(dest->ctx, src->ctx, PQC_SHAKECTX_BYTES);
630
+ }
631
+
632
+ /** Release the allocated state. Call only once. */
633
+ void shake128_ctx_release(shake128ctx *state) {
634
+ free(state->ctx);
635
+ }
636
+
637
+ /*************************************************
638
+ * Name: shake256_absorb
639
+ *
640
+ * Description: Absorb step of the SHAKE256 XOF.
641
+ * non-incremental, starts by zeroeing the state.
642
+ *
643
+ * Arguments: - shake256ctx *state: pointer to (uninitialized) output Keccak state
644
+ * - const uint8_t *input: pointer to input to be absorbed
645
+ * into s
646
+ * - size_t inlen: length of input in bytes
647
+ **************************************************/
648
+ void shake256_absorb(shake256ctx *state, const uint8_t *input, size_t inlen) {
649
+ state->ctx = malloc(PQC_SHAKECTX_BYTES);
650
+ if (state->ctx == NULL) {
651
+ exit(111);
652
+ }
653
+ keccak_absorb(state->ctx, SHAKE256_RATE, input, inlen, 0x1F);
654
+ }
655
+
656
+ /*************************************************
657
+ * Name: shake256_squeezeblocks
658
+ *
659
+ * Description: Squeeze step of SHAKE256 XOF. Squeezes full blocks of
660
+ * SHAKE256_RATE bytes each. Modifies the state. Can be called
661
+ * multiple times to keep squeezing, i.e., is incremental.
662
+ *
663
+ * Arguments: - uint8_t *output: pointer to output blocks
664
+ * - size_t nblocks: number of blocks to be squeezed
665
+ * (written to output)
666
+ * - shake256ctx *state: pointer to input/output Keccak state
667
+ **************************************************/
668
+ void shake256_squeezeblocks(uint8_t *output, size_t nblocks, shake256ctx *state) {
669
+ keccak_squeezeblocks(output, nblocks, state->ctx, SHAKE256_RATE);
670
+ }
671
+
672
+ void shake256_ctx_clone(shake256ctx *dest, const shake256ctx *src) {
673
+ dest->ctx = malloc(PQC_SHAKECTX_BYTES);
674
+ if (dest->ctx == NULL) {
675
+ exit(111);
676
+ }
677
+ memcpy(dest->ctx, src->ctx, PQC_SHAKECTX_BYTES);
678
+ }
679
+
680
+ /** Release the allocated state. Call only once. */
681
+ void shake256_ctx_release(shake256ctx *state) {
682
+ free(state->ctx);
683
+ }
684
+
685
+ /*************************************************
686
+ * Name: shake128
687
+ *
688
+ * Description: SHAKE128 XOF with non-incremental API
689
+ *
690
+ * Arguments: - uint8_t *output: pointer to output
691
+ * - size_t outlen: requested output length in bytes
692
+ * - const uint8_t *input: pointer to input
693
+ * - size_t inlen: length of input in bytes
694
+ **************************************************/
695
+ void shake128(uint8_t *output, size_t outlen,
696
+ const uint8_t *input, size_t inlen) {
697
+ size_t nblocks = outlen / SHAKE128_RATE;
698
+ uint8_t t[SHAKE128_RATE];
699
+ shake128ctx s;
700
+
701
+ shake128_absorb(&s, input, inlen);
702
+ shake128_squeezeblocks(output, nblocks, &s);
703
+
704
+ output += nblocks * SHAKE128_RATE;
705
+ outlen -= nblocks * SHAKE128_RATE;
706
+
707
+ if (outlen) {
708
+ shake128_squeezeblocks(t, 1, &s);
709
+ for (size_t i = 0; i < outlen; ++i) {
710
+ output[i] = t[i];
711
+ }
712
+ }
713
+ shake128_ctx_release(&s);
714
+ }
715
+
716
+ /*************************************************
717
+ * Name: shake256
718
+ *
719
+ * Description: SHAKE256 XOF with non-incremental API
720
+ *
721
+ * Arguments: - uint8_t *output: pointer to output
722
+ * - size_t outlen: requested output length in bytes
723
+ * - const uint8_t *input: pointer to input
724
+ * - size_t inlen: length of input in bytes
725
+ **************************************************/
726
+ void shake256(uint8_t *output, size_t outlen,
727
+ const uint8_t *input, size_t inlen) {
728
+ size_t nblocks = outlen / SHAKE256_RATE;
729
+ uint8_t t[SHAKE256_RATE];
730
+ shake256ctx s;
731
+
732
+ shake256_absorb(&s, input, inlen);
733
+ shake256_squeezeblocks(output, nblocks, &s);
734
+
735
+ output += nblocks * SHAKE256_RATE;
736
+ outlen -= nblocks * SHAKE256_RATE;
737
+
738
+ if (outlen) {
739
+ shake256_squeezeblocks(t, 1, &s);
740
+ for (size_t i = 0; i < outlen; ++i) {
741
+ output[i] = t[i];
742
+ }
743
+ }
744
+ shake256_ctx_release(&s);
745
+ }
746
+
747
+ void sha3_256_inc_init(sha3_256incctx *state) {
748
+ state->ctx = malloc(PQC_SHAKEINCCTX_BYTES);
749
+ if (state->ctx == NULL) {
750
+ exit(111);
751
+ }
752
+ keccak_inc_init(state->ctx);
753
+ }
754
+
755
+ void sha3_256_inc_ctx_clone(sha3_256incctx *dest, const sha3_256incctx *src) {
756
+ dest->ctx = malloc(PQC_SHAKEINCCTX_BYTES);
757
+ if (dest->ctx == NULL) {
758
+ exit(111);
759
+ }
760
+ memcpy(dest->ctx, src->ctx, PQC_SHAKEINCCTX_BYTES);
761
+ }
762
+
763
+ void sha3_256_inc_ctx_release(sha3_256incctx *state) {
764
+ free(state->ctx);
765
+ }
766
+
767
+ void sha3_256_inc_absorb(sha3_256incctx *state, const uint8_t *input, size_t inlen) {
768
+ keccak_inc_absorb(state->ctx, SHA3_256_RATE, input, inlen);
769
+ }
770
+
771
+ void sha3_256_inc_finalize(uint8_t *output, sha3_256incctx *state) {
772
+ uint8_t t[SHA3_256_RATE];
773
+ keccak_inc_finalize(state->ctx, SHA3_256_RATE, 0x06);
774
+
775
+ keccak_squeezeblocks(t, 1, state->ctx, SHA3_256_RATE);
776
+
777
+ sha3_256_inc_ctx_release(state);
778
+
779
+ for (size_t i = 0; i < 32; i++) {
780
+ output[i] = t[i];
781
+ }
782
+ }
783
+
784
+ /*************************************************
785
+ * Name: sha3_256
786
+ *
787
+ * Description: SHA3-256 with non-incremental API
788
+ *
789
+ * Arguments: - uint8_t *output: pointer to output
790
+ * - const uint8_t *input: pointer to input
791
+ * - size_t inlen: length of input in bytes
792
+ **************************************************/
793
+ void sha3_256(uint8_t *output, const uint8_t *input, size_t inlen) {
794
+ uint64_t s[25];
795
+ uint8_t t[SHA3_256_RATE];
796
+
797
+ /* Absorb input */
798
+ keccak_absorb(s, SHA3_256_RATE, input, inlen, 0x06);
799
+
800
+ /* Squeeze output */
801
+ keccak_squeezeblocks(t, 1, s, SHA3_256_RATE);
802
+
803
+ for (size_t i = 0; i < 32; i++) {
804
+ output[i] = t[i];
805
+ }
806
+ }
807
+
808
+ void sha3_384_inc_init(sha3_384incctx *state) {
809
+ state->ctx = malloc(PQC_SHAKEINCCTX_BYTES);
810
+ if (state->ctx == NULL) {
811
+ exit(111);
812
+ }
813
+ keccak_inc_init(state->ctx);
814
+ }
815
+
816
+ void sha3_384_inc_ctx_clone(sha3_384incctx *dest, const sha3_384incctx *src) {
817
+ dest->ctx = malloc(PQC_SHAKEINCCTX_BYTES);
818
+ if (dest->ctx == NULL) {
819
+ exit(111);
820
+ }
821
+ memcpy(dest->ctx, src->ctx, PQC_SHAKEINCCTX_BYTES);
822
+ }
823
+
824
+ void sha3_384_inc_absorb(sha3_384incctx *state, const uint8_t *input, size_t inlen) {
825
+ keccak_inc_absorb(state->ctx, SHA3_384_RATE, input, inlen);
826
+ }
827
+
828
+ void sha3_384_inc_ctx_release(sha3_384incctx *state) {
829
+ free(state->ctx);
830
+ }
831
+
832
+ void sha3_384_inc_finalize(uint8_t *output, sha3_384incctx *state) {
833
+ uint8_t t[SHA3_384_RATE];
834
+ keccak_inc_finalize(state->ctx, SHA3_384_RATE, 0x06);
835
+
836
+ keccak_squeezeblocks(t, 1, state->ctx, SHA3_384_RATE);
837
+
838
+ sha3_384_inc_ctx_release(state);
839
+
840
+ for (size_t i = 0; i < 48; i++) {
841
+ output[i] = t[i];
842
+ }
843
+ }
844
+
845
+ /*************************************************
846
+ * Name: sha3_384
847
+ *
848
+ * Description: SHA3-256 with non-incremental API
849
+ *
850
+ * Arguments: - uint8_t *output: pointer to output
851
+ * - const uint8_t *input: pointer to input
852
+ * - size_t inlen: length of input in bytes
853
+ **************************************************/
854
+ void sha3_384(uint8_t *output, const uint8_t *input, size_t inlen) {
855
+ uint64_t s[25];
856
+ uint8_t t[SHA3_384_RATE];
857
+
858
+ /* Absorb input */
859
+ keccak_absorb(s, SHA3_384_RATE, input, inlen, 0x06);
860
+
861
+ /* Squeeze output */
862
+ keccak_squeezeblocks(t, 1, s, SHA3_384_RATE);
863
+
864
+ for (size_t i = 0; i < 48; i++) {
865
+ output[i] = t[i];
866
+ }
867
+ }
868
+
869
+ void sha3_512_inc_init(sha3_512incctx *state) {
870
+ state->ctx = malloc(PQC_SHAKEINCCTX_BYTES);
871
+ if (state->ctx == NULL) {
872
+ exit(111);
873
+ }
874
+ keccak_inc_init(state->ctx);
875
+ }
876
+
877
+ void sha3_512_inc_ctx_clone(sha3_512incctx *dest, const sha3_512incctx *src) {
878
+ dest->ctx = malloc(PQC_SHAKEINCCTX_BYTES);
879
+ if (dest->ctx == NULL) {
880
+ exit(111);
881
+ }
882
+ memcpy(dest->ctx, src->ctx, PQC_SHAKEINCCTX_BYTES);
883
+ }
884
+
885
+ void sha3_512_inc_absorb(sha3_512incctx *state, const uint8_t *input, size_t inlen) {
886
+ keccak_inc_absorb(state->ctx, SHA3_512_RATE, input, inlen);
887
+ }
888
+
889
+ void sha3_512_inc_ctx_release(sha3_512incctx *state) {
890
+ free(state->ctx);
891
+ }
892
+
893
+ void sha3_512_inc_finalize(uint8_t *output, sha3_512incctx *state) {
894
+ uint8_t t[SHA3_512_RATE];
895
+ keccak_inc_finalize(state->ctx, SHA3_512_RATE, 0x06);
896
+
897
+ keccak_squeezeblocks(t, 1, state->ctx, SHA3_512_RATE);
898
+
899
+ sha3_512_inc_ctx_release(state);
900
+
901
+ for (size_t i = 0; i < 64; i++) {
902
+ output[i] = t[i];
903
+ }
904
+ }
905
+
906
+ /*************************************************
907
+ * Name: sha3_512
908
+ *
909
+ * Description: SHA3-512 with non-incremental API
910
+ *
911
+ * Arguments: - uint8_t *output: pointer to output
912
+ * - const uint8_t *input: pointer to input
913
+ * - size_t inlen: length of input in bytes
914
+ **************************************************/
915
+ void sha3_512(uint8_t *output, const uint8_t *input, size_t inlen) {
916
+ uint64_t s[25];
917
+ uint8_t t[SHA3_512_RATE];
918
+
919
+ /* Absorb input */
920
+ keccak_absorb(s, SHA3_512_RATE, input, inlen, 0x06);
921
+
922
+ /* Squeeze output */
923
+ keccak_squeezeblocks(t, 1, s, SHA3_512_RATE);
924
+
925
+ for (size_t i = 0; i < 64; i++) {
926
+ output[i] = t[i];
927
+ }
928
+ }