kpqc 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 (191) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +21 -0
  4. data/README.md +174 -0
  5. data/Rakefile +57 -0
  6. data/THIRD_PARTY_NOTICES.md +53 -0
  7. data/ext/kpqc/aimer128f/extconf.rb +4 -0
  8. data/ext/kpqc/aimer128s/extconf.rb +4 -0
  9. data/ext/kpqc/aimer192f/extconf.rb +4 -0
  10. data/ext/kpqc/aimer192s/extconf.rb +4 -0
  11. data/ext/kpqc/aimer256f/extconf.rb +4 -0
  12. data/ext/kpqc/aimer256s/extconf.rb +4 -0
  13. data/ext/kpqc/extconf_helper.rb +93 -0
  14. data/ext/kpqc/haetae2/extconf.rb +4 -0
  15. data/ext/kpqc/haetae3/extconf.rb +4 -0
  16. data/ext/kpqc/haetae5/extconf.rb +4 -0
  17. data/ext/kpqc/module.c +195 -0
  18. data/ext/kpqc/ntruplus1152/extconf.rb +4 -0
  19. data/ext/kpqc/ntruplus768/extconf.rb +4 -0
  20. data/ext/kpqc/ntruplus864/extconf.rb +4 -0
  21. data/ext/kpqc/randombytes.c +107 -0
  22. data/ext/kpqc/smaugt128/extconf.rb +4 -0
  23. data/ext/kpqc/smaugt192/extconf.rb +4 -0
  24. data/ext/kpqc/smaugt256/extconf.rb +4 -0
  25. data/ext/kpqc/timer/extconf.rb +4 -0
  26. data/kpqc.gemspec +41 -0
  27. data/lib/kpqc/aimer.rb +38 -0
  28. data/lib/kpqc/api.rb +129 -0
  29. data/lib/kpqc/haetae.rb +25 -0
  30. data/lib/kpqc/ntruplus.rb +25 -0
  31. data/lib/kpqc/smaugt.rb +29 -0
  32. data/lib/kpqc/types.rb +103 -0
  33. data/lib/kpqc/version.rb +6 -0
  34. data/lib/kpqc.rb +33 -0
  35. data/test/algorithm_test.rb +111 -0
  36. data/test/api_test.rb +52 -0
  37. data/test/interop.mjs +34 -0
  38. data/test/interop_test.rb +82 -0
  39. data/test/kat/aimer128f.rsp +10 -0
  40. data/test/kat/aimer128s.rsp +10 -0
  41. data/test/kat/aimer192f.rsp +10 -0
  42. data/test/kat/aimer192s.rsp +10 -0
  43. data/test/kat/aimer256f.rsp +10 -0
  44. data/test/kat/aimer256s.rsp +10 -0
  45. data/test/kat/haetae2.rsp +10 -0
  46. data/test/kat/haetae3.rsp +10 -0
  47. data/test/kat/haetae5.rsp +10 -0
  48. data/test/kat/ntruplus1152.rsp +8 -0
  49. data/test/kat/ntruplus768.rsp +8 -0
  50. data/test/kat/ntruplus864.rsp +8 -0
  51. data/test/kat/smaugt128.rsp +8 -0
  52. data/test/kat/smaugt192.rsp +8 -0
  53. data/test/kat/smaugt256.rsp +8 -0
  54. data/test/kat/timer.rsp +8 -0
  55. data/test/kat_drbg.rb +155 -0
  56. data/test/kat_test.rb +99 -0
  57. data/test/test_helper.rb +21 -0
  58. data/vendor/AIMer/LICENSE +21 -0
  59. data/vendor/AIMer/aim2.c +163 -0
  60. data/vendor/AIMer/aim2.h +36 -0
  61. data/vendor/AIMer/aim2_constant.h +74 -0
  62. data/vendor/AIMer/api.h +42 -0
  63. data/vendor/AIMer/common/crypto_declassify.h +7 -0
  64. data/vendor/AIMer/common/fips202.c +878 -0
  65. data/vendor/AIMer/common/fips202.h +166 -0
  66. data/vendor/AIMer/common/rng.h +56 -0
  67. data/vendor/AIMer/field.h +43 -0
  68. data/vendor/AIMer/field128.c +454 -0
  69. data/vendor/AIMer/field192.c +485 -0
  70. data/vendor/AIMer/field256.c +564 -0
  71. data/vendor/AIMer/hash.c +50 -0
  72. data/vendor/AIMer/hash.h +37 -0
  73. data/vendor/AIMer/params/params-aimer-128f.h +34 -0
  74. data/vendor/AIMer/params/params-aimer-128s.h +34 -0
  75. data/vendor/AIMer/params/params-aimer-192f.h +34 -0
  76. data/vendor/AIMer/params/params-aimer-192s.h +34 -0
  77. data/vendor/AIMer/params/params-aimer-256f.h +34 -0
  78. data/vendor/AIMer/params/params-aimer-256s.h +34 -0
  79. data/vendor/AIMer/params.h +5 -0
  80. data/vendor/AIMer/sign.c +631 -0
  81. data/vendor/AIMer/sign.h +40 -0
  82. data/vendor/AIMer/tree.c +75 -0
  83. data/vendor/AIMer/tree.h +26 -0
  84. data/vendor/HAETAE/LICENSE +22 -0
  85. data/vendor/HAETAE/include/api.h +54 -0
  86. data/vendor/HAETAE/include/common.h +12 -0
  87. data/vendor/HAETAE/include/config.h +42 -0
  88. data/vendor/HAETAE/include/decompose.h +19 -0
  89. data/vendor/HAETAE/include/encoding.h +20 -0
  90. data/vendor/HAETAE/include/fft.h +26 -0
  91. data/vendor/HAETAE/include/fips202.h +40 -0
  92. data/vendor/HAETAE/include/fixpoint.h +125 -0
  93. data/vendor/HAETAE/include/ntt.h +16 -0
  94. data/vendor/HAETAE/include/packing.h +58 -0
  95. data/vendor/HAETAE/include/params.h +117 -0
  96. data/vendor/HAETAE/include/poly.h +65 -0
  97. data/vendor/HAETAE/include/polyfix.h +65 -0
  98. data/vendor/HAETAE/include/polymat.h +32 -0
  99. data/vendor/HAETAE/include/polyvec.h +131 -0
  100. data/vendor/HAETAE/include/randombytes.h +39 -0
  101. data/vendor/HAETAE/include/rans_byte.h +335 -0
  102. data/vendor/HAETAE/include/reduce.h +31 -0
  103. data/vendor/HAETAE/include/sampler.h +23 -0
  104. data/vendor/HAETAE/include/symmetric.h +52 -0
  105. data/vendor/HAETAE/src/decompose.c +73 -0
  106. data/vendor/HAETAE/src/encoding.c +700 -0
  107. data/vendor/HAETAE/src/fft.c +235 -0
  108. data/vendor/HAETAE/src/fips202.c +745 -0
  109. data/vendor/HAETAE/src/fixpoint.c +143 -0
  110. data/vendor/HAETAE/src/ntt.c +98 -0
  111. data/vendor/HAETAE/src/packing.c +595 -0
  112. data/vendor/HAETAE/src/poly.c +371 -0
  113. data/vendor/HAETAE/src/polyfix.c +298 -0
  114. data/vendor/HAETAE/src/polymat.c +82 -0
  115. data/vendor/HAETAE/src/polyvec.c +534 -0
  116. data/vendor/HAETAE/src/reduce.c +96 -0
  117. data/vendor/HAETAE/src/sampler.c +310 -0
  118. data/vendor/HAETAE/src/sign.c +558 -0
  119. data/vendor/HAETAE/src/symmetric-shake.c +50 -0
  120. data/vendor/NTRUplus/LICENSE +21 -0
  121. data/vendor/NTRUplus/NTRU+1152/api.h +24 -0
  122. data/vendor/NTRUplus/NTRU+1152/fips202/fips202.c +878 -0
  123. data/vendor/NTRUplus/NTRU+1152/fips202/fips202.h +166 -0
  124. data/vendor/NTRUplus/NTRU+1152/kem.c +286 -0
  125. data/vendor/NTRUplus/NTRU+1152/ntt.c +394 -0
  126. data/vendor/NTRUplus/NTRU+1152/ntt.h +16 -0
  127. data/vendor/NTRUplus/NTRU+1152/params.h +18 -0
  128. data/vendor/NTRUplus/NTRU+1152/poly.c +318 -0
  129. data/vendor/NTRUplus/NTRU+1152/poly.h +31 -0
  130. data/vendor/NTRUplus/NTRU+1152/randombytes.h +9 -0
  131. data/vendor/NTRUplus/NTRU+1152/symmetric.c +39 -0
  132. data/vendor/NTRUplus/NTRU+1152/symmetric.h +12 -0
  133. data/vendor/NTRUplus/NTRU+768/api.h +24 -0
  134. data/vendor/NTRUplus/NTRU+768/fips202/fips202.c +878 -0
  135. data/vendor/NTRUplus/NTRU+768/fips202/fips202.h +166 -0
  136. data/vendor/NTRUplus/NTRU+768/kem.c +286 -0
  137. data/vendor/NTRUplus/NTRU+768/ntt.c +379 -0
  138. data/vendor/NTRUplus/NTRU+768/ntt.h +16 -0
  139. data/vendor/NTRUplus/NTRU+768/params.h +18 -0
  140. data/vendor/NTRUplus/NTRU+768/poly.c +320 -0
  141. data/vendor/NTRUplus/NTRU+768/poly.h +31 -0
  142. data/vendor/NTRUplus/NTRU+768/randombytes.h +9 -0
  143. data/vendor/NTRUplus/NTRU+768/symmetric.c +39 -0
  144. data/vendor/NTRUplus/NTRU+768/symmetric.h +12 -0
  145. data/vendor/NTRUplus/NTRU+864/api.h +24 -0
  146. data/vendor/NTRUplus/NTRU+864/fips202/fips202.c +878 -0
  147. data/vendor/NTRUplus/NTRU+864/fips202/fips202.h +166 -0
  148. data/vendor/NTRUplus/NTRU+864/kem.c +286 -0
  149. data/vendor/NTRUplus/NTRU+864/ntt.c +383 -0
  150. data/vendor/NTRUplus/NTRU+864/ntt.h +16 -0
  151. data/vendor/NTRUplus/NTRU+864/params.h +18 -0
  152. data/vendor/NTRUplus/NTRU+864/poly.c +314 -0
  153. data/vendor/NTRUplus/NTRU+864/poly.h +31 -0
  154. data/vendor/NTRUplus/NTRU+864/randombytes.h +9 -0
  155. data/vendor/NTRUplus/NTRU+864/symmetric.c +39 -0
  156. data/vendor/NTRUplus/NTRU+864/symmetric.h +12 -0
  157. data/vendor/SMAUG-T/LICENSE +22 -0
  158. data/vendor/SMAUG-T/include/api.h +37 -0
  159. data/vendor/SMAUG-T/include/cbd.h +15 -0
  160. data/vendor/SMAUG-T/include/ciphertext.h +45 -0
  161. data/vendor/SMAUG-T/include/common.h +12 -0
  162. data/vendor/SMAUG-T/include/config.h +48 -0
  163. data/vendor/SMAUG-T/include/dg.h +28 -0
  164. data/vendor/SMAUG-T/include/fips202.h +41 -0
  165. data/vendor/SMAUG-T/include/hash.h +21 -0
  166. data/vendor/SMAUG-T/include/hwt.h +28 -0
  167. data/vendor/SMAUG-T/include/indcpa.h +33 -0
  168. data/vendor/SMAUG-T/include/key.h +34 -0
  169. data/vendor/SMAUG-T/include/pack.h +78 -0
  170. data/vendor/SMAUG-T/include/packring.h +50 -0
  171. data/vendor/SMAUG-T/include/params.h +84 -0
  172. data/vendor/SMAUG-T/include/poly.h +41 -0
  173. data/vendor/SMAUG-T/include/randombytes.h +11 -0
  174. data/vendor/SMAUG-T/include/toomcook.h +14 -0
  175. data/vendor/SMAUG-T/include/verify.h +16 -0
  176. data/vendor/SMAUG-T/src/cbd.c +159 -0
  177. data/vendor/SMAUG-T/src/ciphertext.c +95 -0
  178. data/vendor/SMAUG-T/src/dg.c +112 -0
  179. data/vendor/SMAUG-T/src/fips202.c +745 -0
  180. data/vendor/SMAUG-T/src/hash.c +15 -0
  181. data/vendor/SMAUG-T/src/hwt.c +121 -0
  182. data/vendor/SMAUG-T/src/indcpa.c +187 -0
  183. data/vendor/SMAUG-T/src/kem.c +194 -0
  184. data/vendor/SMAUG-T/src/key.c +102 -0
  185. data/vendor/SMAUG-T/src/pack.c +349 -0
  186. data/vendor/SMAUG-T/src/packring.c +503 -0
  187. data/vendor/SMAUG-T/src/poly.c +200 -0
  188. data/vendor/SMAUG-T/src/toomcook.c +256 -0
  189. data/vendor/SMAUG-T/src/verify.c +48 -0
  190. data/vendor/SOURCES.json +130 -0
  191. metadata +280 -0
@@ -0,0 +1,745 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ #include "fips202.h"
4
+
5
+ #include <stddef.h>
6
+ #include <stdint.h>
7
+
8
+ #define NROUNDS 24
9
+ #define ROL(a, offset) ((a << offset) ^ (a >> (64 - offset)))
10
+
11
+ /*************************************************
12
+ * Name: load64
13
+ *
14
+ * Description: Load 8 bytes into uint64_t in little-endian order
15
+ *
16
+ * Arguments: - const uint8_t x[8]: pointer to input byte array
17
+ *
18
+ * Return: loaded 64-bit unsigned integer
19
+ **************************************************/
20
+ static uint64_t load64(const uint8_t x[8]) {
21
+ unsigned int i;
22
+ uint64_t r = 0;
23
+
24
+ for (i = 0; i < 8; i++)
25
+ r |= (uint64_t)x[i] << 8 * i;
26
+
27
+ return r;
28
+ }
29
+
30
+ /*************************************************
31
+ * Name: store64
32
+ *
33
+ * Description: Store a 64-bit integer to array of 8 bytes in little-endian
34
+ *order
35
+ *
36
+ * Arguments: - uint8_t x[8]: pointer to output byte array (allocated)
37
+ * - uint64_t u: input 64-bit unsigned integer
38
+ **************************************************/
39
+ static void store64(uint8_t x[8], uint64_t u) {
40
+ unsigned int i;
41
+
42
+ for (i = 0; i < 8; i++)
43
+ x[i] = u >> 8 * i;
44
+ }
45
+
46
+ /* Keccak round constants */
47
+ const uint64_t KeccakF_RoundConstants[NROUNDS] = {
48
+ (uint64_t)0x0000000000000001ULL, (uint64_t)0x0000000000008082ULL,
49
+ (uint64_t)0x800000000000808aULL, (uint64_t)0x8000000080008000ULL,
50
+ (uint64_t)0x000000000000808bULL, (uint64_t)0x0000000080000001ULL,
51
+ (uint64_t)0x8000000080008081ULL, (uint64_t)0x8000000000008009ULL,
52
+ (uint64_t)0x000000000000008aULL, (uint64_t)0x0000000000000088ULL,
53
+ (uint64_t)0x0000000080008009ULL, (uint64_t)0x000000008000000aULL,
54
+ (uint64_t)0x000000008000808bULL, (uint64_t)0x800000000000008bULL,
55
+ (uint64_t)0x8000000000008089ULL, (uint64_t)0x8000000000008003ULL,
56
+ (uint64_t)0x8000000000008002ULL, (uint64_t)0x8000000000000080ULL,
57
+ (uint64_t)0x000000000000800aULL, (uint64_t)0x800000008000000aULL,
58
+ (uint64_t)0x8000000080008081ULL, (uint64_t)0x8000000000008080ULL,
59
+ (uint64_t)0x0000000080000001ULL, (uint64_t)0x8000000080008008ULL};
60
+
61
+ /*************************************************
62
+ * Name: KeccakF1600_StatePermute
63
+ *
64
+ * Description: The Keccak F1600 Permutation
65
+ *
66
+ * Arguments: - uint64_t state[25]: pointer to input/output Keccak state
67
+ **************************************************/
68
+ static void KeccakF1600_StatePermute(uint64_t state[25]) {
69
+ int round;
70
+
71
+ uint64_t Aba, Abe, Abi, Abo, Abu;
72
+ uint64_t Aga, Age, Agi, Ago, Agu;
73
+ uint64_t Aka, Ake, Aki, Ako, Aku;
74
+ uint64_t Ama, Ame, Ami, Amo, Amu;
75
+ uint64_t Asa, Ase, Asi, Aso, Asu;
76
+ uint64_t BCa, BCe, BCi, BCo, BCu;
77
+ uint64_t Da, De, Di, Do, Du;
78
+ uint64_t Eba, Ebe, Ebi, Ebo, Ebu;
79
+ uint64_t Ega, Ege, Egi, Ego, Egu;
80
+ uint64_t Eka, Eke, Eki, Eko, Eku;
81
+ uint64_t Ema, Eme, Emi, Emo, Emu;
82
+ uint64_t Esa, Ese, Esi, Eso, Esu;
83
+
84
+ // copyFromState(A, state)
85
+ Aba = state[0];
86
+ Abe = state[1];
87
+ Abi = state[2];
88
+ Abo = state[3];
89
+ Abu = state[4];
90
+ Aga = state[5];
91
+ Age = state[6];
92
+ Agi = state[7];
93
+ Ago = state[8];
94
+ Agu = state[9];
95
+ Aka = state[10];
96
+ Ake = state[11];
97
+ Aki = state[12];
98
+ Ako = state[13];
99
+ Aku = state[14];
100
+ Ama = state[15];
101
+ Ame = state[16];
102
+ Ami = state[17];
103
+ Amo = state[18];
104
+ Amu = state[19];
105
+ Asa = state[20];
106
+ Ase = state[21];
107
+ Asi = state[22];
108
+ Aso = state[23];
109
+ Asu = state[24];
110
+
111
+ for (round = 0; round < NROUNDS; round += 2) {
112
+ // prepareTheta
113
+ BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
114
+ BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase;
115
+ BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
116
+ BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
117
+ BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
118
+
119
+ // thetaRhoPiChiIotaPrepareTheta(round, A, E)
120
+ Da = BCu ^ ROL(BCe, 1);
121
+ De = BCa ^ ROL(BCi, 1);
122
+ Di = BCe ^ ROL(BCo, 1);
123
+ Do = BCi ^ ROL(BCu, 1);
124
+ Du = BCo ^ ROL(BCa, 1);
125
+
126
+ Aba ^= Da;
127
+ BCa = Aba;
128
+ Age ^= De;
129
+ BCe = ROL(Age, 44);
130
+ Aki ^= Di;
131
+ BCi = ROL(Aki, 43);
132
+ Amo ^= Do;
133
+ BCo = ROL(Amo, 21);
134
+ Asu ^= Du;
135
+ BCu = ROL(Asu, 14);
136
+ Eba = BCa ^ ((~BCe) & BCi);
137
+ Eba ^= (uint64_t)KeccakF_RoundConstants[round];
138
+ Ebe = BCe ^ ((~BCi) & BCo);
139
+ Ebi = BCi ^ ((~BCo) & BCu);
140
+ Ebo = BCo ^ ((~BCu) & BCa);
141
+ Ebu = BCu ^ ((~BCa) & BCe);
142
+
143
+ Abo ^= Do;
144
+ BCa = ROL(Abo, 28);
145
+ Agu ^= Du;
146
+ BCe = ROL(Agu, 20);
147
+ Aka ^= Da;
148
+ BCi = ROL(Aka, 3);
149
+ Ame ^= De;
150
+ BCo = ROL(Ame, 45);
151
+ Asi ^= Di;
152
+ BCu = ROL(Asi, 61);
153
+ Ega = BCa ^ ((~BCe) & BCi);
154
+ Ege = BCe ^ ((~BCi) & BCo);
155
+ Egi = BCi ^ ((~BCo) & BCu);
156
+ Ego = BCo ^ ((~BCu) & BCa);
157
+ Egu = BCu ^ ((~BCa) & BCe);
158
+
159
+ Abe ^= De;
160
+ BCa = ROL(Abe, 1);
161
+ Agi ^= Di;
162
+ BCe = ROL(Agi, 6);
163
+ Ako ^= Do;
164
+ BCi = ROL(Ako, 25);
165
+ Amu ^= Du;
166
+ BCo = ROL(Amu, 8);
167
+ Asa ^= Da;
168
+ BCu = ROL(Asa, 18);
169
+ Eka = BCa ^ ((~BCe) & BCi);
170
+ Eke = BCe ^ ((~BCi) & BCo);
171
+ Eki = BCi ^ ((~BCo) & BCu);
172
+ Eko = BCo ^ ((~BCu) & BCa);
173
+ Eku = BCu ^ ((~BCa) & BCe);
174
+
175
+ Abu ^= Du;
176
+ BCa = ROL(Abu, 27);
177
+ Aga ^= Da;
178
+ BCe = ROL(Aga, 36);
179
+ Ake ^= De;
180
+ BCi = ROL(Ake, 10);
181
+ Ami ^= Di;
182
+ BCo = ROL(Ami, 15);
183
+ Aso ^= Do;
184
+ BCu = ROL(Aso, 56);
185
+ Ema = BCa ^ ((~BCe) & BCi);
186
+ Eme = BCe ^ ((~BCi) & BCo);
187
+ Emi = BCi ^ ((~BCo) & BCu);
188
+ Emo = BCo ^ ((~BCu) & BCa);
189
+ Emu = BCu ^ ((~BCa) & BCe);
190
+
191
+ Abi ^= Di;
192
+ BCa = ROL(Abi, 62);
193
+ Ago ^= Do;
194
+ BCe = ROL(Ago, 55);
195
+ Aku ^= Du;
196
+ BCi = ROL(Aku, 39);
197
+ Ama ^= Da;
198
+ BCo = ROL(Ama, 41);
199
+ Ase ^= De;
200
+ BCu = ROL(Ase, 2);
201
+ Esa = BCa ^ ((~BCe) & BCi);
202
+ Ese = BCe ^ ((~BCi) & BCo);
203
+ Esi = BCi ^ ((~BCo) & BCu);
204
+ Eso = BCo ^ ((~BCu) & BCa);
205
+ Esu = BCu ^ ((~BCa) & BCe);
206
+
207
+ // prepareTheta
208
+ BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
209
+ BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
210
+ BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
211
+ BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
212
+ BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
213
+
214
+ // thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
215
+ Da = BCu ^ ROL(BCe, 1);
216
+ De = BCa ^ ROL(BCi, 1);
217
+ Di = BCe ^ ROL(BCo, 1);
218
+ Do = BCi ^ ROL(BCu, 1);
219
+ Du = BCo ^ ROL(BCa, 1);
220
+
221
+ Eba ^= Da;
222
+ BCa = Eba;
223
+ Ege ^= De;
224
+ BCe = ROL(Ege, 44);
225
+ Eki ^= Di;
226
+ BCi = ROL(Eki, 43);
227
+ Emo ^= Do;
228
+ BCo = ROL(Emo, 21);
229
+ Esu ^= Du;
230
+ BCu = ROL(Esu, 14);
231
+ Aba = BCa ^ ((~BCe) & BCi);
232
+ Aba ^= (uint64_t)KeccakF_RoundConstants[round + 1];
233
+ Abe = BCe ^ ((~BCi) & BCo);
234
+ Abi = BCi ^ ((~BCo) & BCu);
235
+ Abo = BCo ^ ((~BCu) & BCa);
236
+ Abu = BCu ^ ((~BCa) & BCe);
237
+
238
+ Ebo ^= Do;
239
+ BCa = ROL(Ebo, 28);
240
+ Egu ^= Du;
241
+ BCe = ROL(Egu, 20);
242
+ Eka ^= Da;
243
+ BCi = ROL(Eka, 3);
244
+ Eme ^= De;
245
+ BCo = ROL(Eme, 45);
246
+ Esi ^= Di;
247
+ BCu = ROL(Esi, 61);
248
+ Aga = BCa ^ ((~BCe) & BCi);
249
+ Age = BCe ^ ((~BCi) & BCo);
250
+ Agi = BCi ^ ((~BCo) & BCu);
251
+ Ago = BCo ^ ((~BCu) & BCa);
252
+ Agu = BCu ^ ((~BCa) & BCe);
253
+
254
+ Ebe ^= De;
255
+ BCa = ROL(Ebe, 1);
256
+ Egi ^= Di;
257
+ BCe = ROL(Egi, 6);
258
+ Eko ^= Do;
259
+ BCi = ROL(Eko, 25);
260
+ Emu ^= Du;
261
+ BCo = ROL(Emu, 8);
262
+ Esa ^= Da;
263
+ BCu = ROL(Esa, 18);
264
+ Aka = BCa ^ ((~BCe) & BCi);
265
+ Ake = BCe ^ ((~BCi) & BCo);
266
+ Aki = BCi ^ ((~BCo) & BCu);
267
+ Ako = BCo ^ ((~BCu) & BCa);
268
+ Aku = BCu ^ ((~BCa) & BCe);
269
+
270
+ Ebu ^= Du;
271
+ BCa = ROL(Ebu, 27);
272
+ Ega ^= Da;
273
+ BCe = ROL(Ega, 36);
274
+ Eke ^= De;
275
+ BCi = ROL(Eke, 10);
276
+ Emi ^= Di;
277
+ BCo = ROL(Emi, 15);
278
+ Eso ^= Do;
279
+ BCu = ROL(Eso, 56);
280
+ Ama = BCa ^ ((~BCe) & BCi);
281
+ Ame = BCe ^ ((~BCi) & BCo);
282
+ Ami = BCi ^ ((~BCo) & BCu);
283
+ Amo = BCo ^ ((~BCu) & BCa);
284
+ Amu = BCu ^ ((~BCa) & BCe);
285
+
286
+ Ebi ^= Di;
287
+ BCa = ROL(Ebi, 62);
288
+ Ego ^= Do;
289
+ BCe = ROL(Ego, 55);
290
+ Eku ^= Du;
291
+ BCi = ROL(Eku, 39);
292
+ Ema ^= Da;
293
+ BCo = ROL(Ema, 41);
294
+ Ese ^= De;
295
+ BCu = ROL(Ese, 2);
296
+ Asa = BCa ^ ((~BCe) & BCi);
297
+ Ase = BCe ^ ((~BCi) & BCo);
298
+ Asi = BCi ^ ((~BCo) & BCu);
299
+ Aso = BCo ^ ((~BCu) & BCa);
300
+ Asu = BCu ^ ((~BCa) & BCe);
301
+ }
302
+
303
+ // copyToState(state, A)
304
+ state[0] = Aba;
305
+ state[1] = Abe;
306
+ state[2] = Abi;
307
+ state[3] = Abo;
308
+ state[4] = Abu;
309
+ state[5] = Aga;
310
+ state[6] = Age;
311
+ state[7] = Agi;
312
+ state[8] = Ago;
313
+ state[9] = Agu;
314
+ state[10] = Aka;
315
+ state[11] = Ake;
316
+ state[12] = Aki;
317
+ state[13] = Ako;
318
+ state[14] = Aku;
319
+ state[15] = Ama;
320
+ state[16] = Ame;
321
+ state[17] = Ami;
322
+ state[18] = Amo;
323
+ state[19] = Amu;
324
+ state[20] = Asa;
325
+ state[21] = Ase;
326
+ state[22] = Asi;
327
+ state[23] = Aso;
328
+ state[24] = Asu;
329
+ }
330
+
331
+ /*************************************************
332
+ * Name: keccak_init
333
+ *
334
+ * Description: Initializes the Keccak state.
335
+ *
336
+ * Arguments: - uint64_t s[25]: pointer to output Keccak state
337
+ **************************************************/
338
+ static void keccak_init(uint64_t s[25]) {
339
+ unsigned int i;
340
+ for (i = 0; i < 25; i++)
341
+ s[i] = 0;
342
+ }
343
+
344
+ /*************************************************
345
+ * Name: keccak_absorb
346
+ *
347
+ * Description: Absorb step of Keccak; incremental.
348
+ *
349
+ * Arguments: - uint64_t s[25]: pointer to input/output Keccak state
350
+ * - unsigned int pos: position in current block to be absorbed
351
+ * - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
352
+ * - const uint8_t *in: pointer to input to be absorbed into s
353
+ * - size_t inlen: length of input in bytes
354
+ *
355
+ * Returns new position pos in current block
356
+ **************************************************/
357
+ static unsigned int keccak_absorb(uint64_t s[25], unsigned int pos,
358
+ unsigned int r, const uint8_t *in,
359
+ size_t inlen) {
360
+ unsigned int i;
361
+
362
+ while (pos + inlen >= r) {
363
+ for (i = pos; i < r; i++)
364
+ s[i / 8] ^= (uint64_t)*in++ << 8 * (i % 8);
365
+ inlen -= r - pos;
366
+ KeccakF1600_StatePermute(s);
367
+ pos = 0;
368
+ }
369
+
370
+ for (i = pos; i < pos + inlen; i++)
371
+ s[i / 8] ^= (uint64_t)*in++ << 8 * (i % 8);
372
+
373
+ return i;
374
+ }
375
+
376
+ /*************************************************
377
+ * Name: keccak_finalize
378
+ *
379
+ * Description: Finalize absorb step.
380
+ *
381
+ * Arguments: - uint64_t s[25]: pointer to input/output Keccak state
382
+ * - unsigned int pos: position in current block to be absorbed
383
+ * - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
384
+ * - uint8_t p: domain separation byte
385
+ **************************************************/
386
+ static void keccak_finalize(uint64_t s[25], unsigned int pos, unsigned int r,
387
+ uint8_t p) {
388
+ s[pos / 8] ^= (uint64_t)p << 8 * (pos % 8);
389
+ s[r / 8 - 1] ^= 1ULL << 63;
390
+ }
391
+
392
+ /*************************************************
393
+ * Name: keccak_squeeze
394
+ *
395
+ * Description: Squeeze step of Keccak. Squeezes arbitratrily many bytes.
396
+ * Modifies the state. Can be called multiple times to keep
397
+ * squeezing, i.e., is incremental.
398
+ *
399
+ * Arguments: - uint8_t *out: pointer to output
400
+ * - size_t outlen: number of bytes to be squeezed (written to out)
401
+ * - uint64_t s[25]: pointer to input/output Keccak state
402
+ * - unsigned int pos: number of bytes in current block already
403
+ * squeezed
404
+ * - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
405
+ *
406
+ * Returns new position pos in current block
407
+ **************************************************/
408
+ static unsigned int keccak_squeeze(uint8_t *out, size_t outlen, uint64_t s[25],
409
+ unsigned int pos, unsigned int r) {
410
+ unsigned int i;
411
+
412
+ while (outlen) {
413
+ if (pos == r) {
414
+ KeccakF1600_StatePermute(s);
415
+ pos = 0;
416
+ }
417
+ for (i = pos; i < r && i < pos + outlen; i++)
418
+ *out++ = s[i / 8] >> 8 * (i % 8);
419
+ outlen -= i - pos;
420
+ pos = i;
421
+ }
422
+
423
+ return pos;
424
+ }
425
+
426
+ /*************************************************
427
+ * Name: keccak_absorb_once
428
+ *
429
+ * Description: Absorb step of Keccak;
430
+ * non-incremental, starts by zeroeing the state.
431
+ *
432
+ * Arguments: - uint64_t s[25]: pointer to (uninitialized) output Keccak state
433
+ * - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
434
+ * - const uint8_t *in: pointer to input to be absorbed into s
435
+ * - size_t inlen: length of input in bytes
436
+ * - uint8_t p: domain-separation byte for different Keccak-derived
437
+ *functions
438
+ **************************************************/
439
+ static void keccak_absorb_once(uint64_t s[25], unsigned int r,
440
+ const uint8_t *in, size_t inlen, uint8_t p) {
441
+ unsigned int i;
442
+
443
+ for (i = 0; i < 25; i++)
444
+ s[i] = 0;
445
+
446
+ while (inlen >= r) {
447
+ for (i = 0; i < r / 8; i++)
448
+ s[i] ^= load64(in + 8 * i);
449
+ in += r;
450
+ inlen -= r;
451
+ KeccakF1600_StatePermute(s);
452
+ }
453
+
454
+ for (i = 0; i < inlen; i++)
455
+ s[i / 8] ^= (uint64_t)in[i] << 8 * (i % 8);
456
+
457
+ s[i / 8] ^= (uint64_t)p << 8 * (i % 8);
458
+ s[(r - 1) / 8] ^= 1ULL << 63;
459
+ }
460
+
461
+ /*************************************************
462
+ * Name: keccak_squeezeblocks
463
+ *
464
+ * Description: Squeeze step of Keccak. Squeezes full blocks of r bytes each.
465
+ * Modifies the state. Can be called multiple times to keep
466
+ * squeezing, i.e., is incremental. Assumes zero bytes of current
467
+ * block have already been squeezed.
468
+ *
469
+ * Arguments: - uint8_t *out: pointer to output blocks
470
+ * - size_t nblocks: number of blocks to be squeezed (written to
471
+ * out)
472
+ * - uint64_t s[25]: pointer to input/output Keccak state
473
+ * - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
474
+ **************************************************/
475
+ static void keccak_squeezeblocks(uint8_t *out, size_t nblocks, uint64_t s[25],
476
+ unsigned int r) {
477
+ unsigned int i;
478
+
479
+ while (nblocks) {
480
+ KeccakF1600_StatePermute(s);
481
+ for (i = 0; i < r / 8; i++)
482
+ store64(out + 8 * i, s[i]);
483
+ out += r;
484
+ nblocks -= 1;
485
+ }
486
+ }
487
+
488
+ /*************************************************
489
+ * Name: shake128_init
490
+ *
491
+ * Description: Initilizes Keccak state for use as SHAKE128 XOF
492
+ *
493
+ * Arguments: - keccak_state *state: pointer to (uninitialized) Keccak state
494
+ **************************************************/
495
+ void shake128_init(keccak_state *state) {
496
+ keccak_init(state->s);
497
+ state->pos = 0;
498
+ }
499
+
500
+ /*************************************************
501
+ * Name: shake128_absorb
502
+ *
503
+ * Description: Absorb step of the SHAKE128 XOF; incremental.
504
+ *
505
+ * Arguments: - keccak_state *state: pointer to (initialized) input/output
506
+ * Keccak state
507
+ * - const uint8_t *in: pointer to input to be absorbed into s
508
+ * - size_t inlen: length of input in bytes
509
+ **************************************************/
510
+ void shake128_absorb(keccak_state *state, const uint8_t *in, size_t inlen) {
511
+ state->pos = keccak_absorb(state->s, state->pos, SHAKE128_RATE, in, inlen);
512
+ }
513
+
514
+ /*************************************************
515
+ * Name: shake128_finalize
516
+ *
517
+ * Description: Finalize absorb step of the SHAKE128 XOF.
518
+ *
519
+ * Arguments: - keccak_state *state: pointer to input/output Keccak state
520
+ **************************************************/
521
+ void shake128_finalize(keccak_state *state) {
522
+ keccak_finalize(state->s, state->pos, SHAKE128_RATE, 0x1F);
523
+ state->pos = SHAKE128_RATE;
524
+ }
525
+
526
+ /*************************************************
527
+ * Name: shake128_squeeze
528
+ *
529
+ * Description: Squeeze step of SHAKE128 XOF. Squeezes arbitraily many
530
+ * bytes. Can be called multiple times to keep squeezing.
531
+ *
532
+ * Arguments: - uint8_t *out: pointer to output blocks
533
+ * - size_t outlen : number of bytes to be squeezed (written to
534
+ * output)
535
+ * - keccak_state *state: pointer to input/output Keccak state
536
+ **************************************************/
537
+ void shake128_squeeze(uint8_t *out, size_t outlen, keccak_state *state) {
538
+ state->pos =
539
+ keccak_squeeze(out, outlen, state->s, state->pos, SHAKE128_RATE);
540
+ }
541
+
542
+ /*************************************************
543
+ * Name: shake128_absorb_once
544
+ *
545
+ * Description: Initialize, absorb into and finalize SHAKE128 XOF;
546
+ *non-incremental.
547
+ *
548
+ * Arguments: - keccak_state *state: pointer to (uninitialized) input/output
549
+ * Keccak state
550
+ * - const uint8_t *in: pointer to input to be absorbed into s
551
+ * - size_t inlen: length of input in bytes
552
+ **************************************************/
553
+ void shake128_absorb_once(keccak_state *state, const uint8_t *in,
554
+ size_t inlen) {
555
+ keccak_absorb_once(state->s, SHAKE128_RATE, in, inlen, 0x1F);
556
+ state->pos = SHAKE128_RATE;
557
+ }
558
+
559
+ /*************************************************
560
+ * Name: shake128_squeezeblocks
561
+ *
562
+ * Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of
563
+ * SHAKE128_RATE bytes each. Can be called multiple times
564
+ * to keep squeezing. Assumes new block has not yet been
565
+ * started (state->pos = SHAKE128_RATE).
566
+ *
567
+ * Arguments: - uint8_t *out: pointer to output blocks
568
+ * - size_t nblocks: number of blocks to be squeezed (written to
569
+ * output)
570
+ * - keccak_state *state: pointer to input/output Keccak state
571
+ **************************************************/
572
+ void shake128_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state) {
573
+ keccak_squeezeblocks(out, nblocks, state->s, SHAKE128_RATE);
574
+ }
575
+
576
+ /*************************************************
577
+ * Name: shake256_init
578
+ *
579
+ * Description: Initilizes Keccak state for use as SHAKE256 XOF
580
+ *
581
+ * Arguments: - keccak_state *state: pointer to (uninitialized) output Keccak
582
+ * state
583
+ **************************************************/
584
+ void shake256_init(keccak_state *state) {
585
+ keccak_init(state->s);
586
+ state->pos = 0;
587
+ }
588
+
589
+ /*************************************************
590
+ * Name: shake256_absorb
591
+ *
592
+ * Description: Absorb step of the SHAKE256 XOF; incremental.
593
+ *
594
+ * Arguments: - keccak_state *state: pointer to (initialized) input/output
595
+ * Keccak state
596
+ * - const uint8_t *in: pointer to input to be absorbed into s
597
+ * - size_t inlen: length of input in bytes
598
+ **************************************************/
599
+ void shake256_absorb(keccak_state *state, const uint8_t *in, size_t inlen) {
600
+ state->pos = keccak_absorb(state->s, state->pos, SHAKE256_RATE, in, inlen);
601
+ }
602
+
603
+ /*************************************************
604
+ * Name: shake256_finalize
605
+ *
606
+ * Description: Finalize absorb step of the SHAKE256 XOF.
607
+ *
608
+ * Arguments: - keccak_state *state: pointer to input/output Keccak state
609
+ **************************************************/
610
+ void shake256_finalize(keccak_state *state) {
611
+ keccak_finalize(state->s, state->pos, SHAKE256_RATE, 0x1F);
612
+ state->pos = SHAKE256_RATE;
613
+ }
614
+
615
+ /*************************************************
616
+ * Name: shake256_squeeze
617
+ *
618
+ * Description: Squeeze step of SHAKE256 XOF. Squeezes arbitraily many
619
+ * bytes. Can be called multiple times to keep squeezing.
620
+ *
621
+ * Arguments: - uint8_t *out: pointer to output blocks
622
+ * - size_t outlen : number of bytes to be squeezed (written to
623
+ * output)
624
+ * - keccak_state *state: pointer to input/output Keccak state
625
+ **************************************************/
626
+ void shake256_squeeze(uint8_t *out, size_t outlen, keccak_state *state) {
627
+ state->pos =
628
+ keccak_squeeze(out, outlen, state->s, state->pos, SHAKE256_RATE);
629
+ }
630
+
631
+ /*************************************************
632
+ * Name: shake256_absorb_once
633
+ *
634
+ * Description: Initialize, absorb into and finalize SHAKE256 XOF;
635
+ * non-incremental.
636
+ *
637
+ * Arguments: - keccak_state *state: pointer to (uninitialized) input/output
638
+ * Keccak state
639
+ * - const uint8_t *in: pointer to input to be absorbed into s
640
+ * - size_t inlen: length of input in bytes
641
+ **************************************************/
642
+ void shake256_absorb_once(keccak_state *state, const uint8_t *in,
643
+ size_t inlen) {
644
+ keccak_absorb_once(state->s, SHAKE256_RATE, in, inlen, 0x1F);
645
+ state->pos = SHAKE256_RATE;
646
+ }
647
+
648
+ /*************************************************
649
+ * Name: shake256_squeezeblocks
650
+ *
651
+ * Description: Squeeze step of SHAKE256 XOF. Squeezes full blocks of
652
+ * SHAKE256_RATE bytes each. Can be called multiple times
653
+ * to keep squeezing. Assumes next block has not yet been
654
+ * started (state->pos = SHAKE256_RATE).
655
+ *
656
+ * Arguments: - uint8_t *out: pointer to output blocks
657
+ * - size_t nblocks: number of blocks to be squeezed (written to
658
+ * output)
659
+ * - keccak_state *s: pointer to input/output Keccak state
660
+ **************************************************/
661
+ void shake256_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state) {
662
+ keccak_squeezeblocks(out, nblocks, state->s, SHAKE256_RATE);
663
+ }
664
+
665
+ /*************************************************
666
+ * Name: shake128
667
+ *
668
+ * Description: SHAKE128 XOF with non-incremental API
669
+ *
670
+ * Arguments: - uint8_t *out: pointer to output
671
+ * - size_t outlen: requested output length in bytes
672
+ * - const uint8_t *in: pointer to input
673
+ * - size_t inlen: length of input in bytes
674
+ **************************************************/
675
+ void shake128(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) {
676
+ size_t nblocks;
677
+ keccak_state state;
678
+
679
+ shake128_absorb_once(&state, in, inlen);
680
+ nblocks = outlen / SHAKE128_RATE;
681
+ shake128_squeezeblocks(out, nblocks, &state);
682
+ outlen -= nblocks * SHAKE128_RATE;
683
+ out += nblocks * SHAKE128_RATE;
684
+ shake128_squeeze(out, outlen, &state);
685
+ }
686
+
687
+ /*************************************************
688
+ * Name: shake256
689
+ *
690
+ * Description: SHAKE256 XOF with non-incremental API
691
+ *
692
+ * Arguments: - uint8_t *out: pointer to output
693
+ * - size_t outlen: requested output length in bytes
694
+ * - const uint8_t *in: pointer to input
695
+ * - size_t inlen: length of input in bytes
696
+ **************************************************/
697
+ void shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) {
698
+ size_t nblocks;
699
+ keccak_state state;
700
+
701
+ shake256_absorb_once(&state, in, inlen);
702
+ nblocks = outlen / SHAKE256_RATE;
703
+ shake256_squeezeblocks(out, nblocks, &state);
704
+ outlen -= nblocks * SHAKE256_RATE;
705
+ out += nblocks * SHAKE256_RATE;
706
+ shake256_squeeze(out, outlen, &state);
707
+ }
708
+
709
+ /*************************************************
710
+ * Name: sha3_256
711
+ *
712
+ * Description: SHA3-256 with non-incremental API
713
+ *
714
+ * Arguments: - uint8_t h[32]: pointer to output
715
+ * - const uint8_t *in: pointer to input
716
+ * - size_t inlen: length of input in bytes
717
+ **************************************************/
718
+ void sha3_256(uint8_t h[32], const uint8_t *in, size_t inlen) {
719
+ unsigned int i;
720
+ uint64_t s[25];
721
+
722
+ keccak_absorb_once(s, SHA3_256_RATE, in, inlen, 0x06);
723
+ KeccakF1600_StatePermute(s);
724
+ for (i = 0; i < 4; i++)
725
+ store64(h + 8 * i, s[i]);
726
+ }
727
+
728
+ /*************************************************
729
+ * Name: sha3_512
730
+ *
731
+ * Description: SHA3-512 with non-incremental API
732
+ *
733
+ * Arguments: - uint8_t h[64]: pointer to output
734
+ * - const uint8_t *in: pointer to input
735
+ * - size_t inlen: length of input in bytes
736
+ **************************************************/
737
+ void sha3_512(uint8_t h[64], const uint8_t *in, size_t inlen) {
738
+ unsigned int i;
739
+ uint64_t s[25];
740
+
741
+ keccak_absorb_once(s, SHA3_512_RATE, in, inlen, 0x06);
742
+ KeccakF1600_StatePermute(s);
743
+ for (i = 0; i < 8; i++)
744
+ store64(h + 8 * i, s[i]);
745
+ }