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