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
+ /* Based on the public domain implementation in crypto_hash/keccakc512/simple/
2
+ * from http://bench.cr.yp.to/supercop.html by Ronny Van Keer and the public
3
+ * domain "TweetFips202" implementation from https://twitter.com/tweetfips202 by
4
+ * Gilles Van Assche, Daniel J. Bernstein, and Peter Schwabe */
5
+
6
+ #include "fips202.h"
7
+
8
+ #include <stddef.h>
9
+ #include <stdint.h>
10
+
11
+ #define NROUNDS 24
12
+ #define ROL(a, offset) ((a << offset) ^ (a >> (64 - offset)))
13
+
14
+ /*************************************************
15
+ * Name: load64
16
+ *
17
+ * Description: Load 8 bytes into uint64_t in little-endian order
18
+ *
19
+ * Arguments: - const uint8_t *x: pointer to input byte array
20
+ *
21
+ * Returns the loaded 64-bit unsigned integer
22
+ **************************************************/
23
+ static uint64_t load64(const uint8_t x[8]) {
24
+ unsigned int i;
25
+ uint64_t r = 0;
26
+
27
+ for (i = 0; i < 8; ++i)
28
+ r |= (uint64_t)x[i] << 8 * i;
29
+
30
+ return r;
31
+ }
32
+
33
+ /*************************************************
34
+ * Name: store64
35
+ *
36
+ * Description: Store a 64-bit integer to array of 8 bytes in little-endian
37
+ * order
38
+ *
39
+ * Arguments: - uint8_t *x: pointer to the output byte array (allocated)
40
+ * - uint64_t u: input 64-bit unsigned integer
41
+ **************************************************/
42
+ static void store64(uint8_t x[8], uint64_t u) {
43
+ unsigned int i;
44
+
45
+ for (i = 0; i < 8; ++i)
46
+ x[i] = u >> 8 * i;
47
+ }
48
+
49
+ /* Keccak round constants */
50
+ const uint64_t KeccakF_RoundConstants[NROUNDS] = {
51
+ (uint64_t)0x0000000000000001ULL, (uint64_t)0x0000000000008082ULL,
52
+ (uint64_t)0x800000000000808aULL, (uint64_t)0x8000000080008000ULL,
53
+ (uint64_t)0x000000000000808bULL, (uint64_t)0x0000000080000001ULL,
54
+ (uint64_t)0x8000000080008081ULL, (uint64_t)0x8000000000008009ULL,
55
+ (uint64_t)0x000000000000008aULL, (uint64_t)0x0000000000000088ULL,
56
+ (uint64_t)0x0000000080008009ULL, (uint64_t)0x000000008000000aULL,
57
+ (uint64_t)0x000000008000808bULL, (uint64_t)0x800000000000008bULL,
58
+ (uint64_t)0x8000000000008089ULL, (uint64_t)0x8000000000008003ULL,
59
+ (uint64_t)0x8000000000008002ULL, (uint64_t)0x8000000000000080ULL,
60
+ (uint64_t)0x000000000000800aULL, (uint64_t)0x800000008000000aULL,
61
+ (uint64_t)0x8000000080008081ULL, (uint64_t)0x8000000000008080ULL,
62
+ (uint64_t)0x0000000080000001ULL, (uint64_t)0x8000000080008008ULL};
63
+
64
+ /*************************************************
65
+ * Name: KeccakF1600_StatePermute
66
+ *
67
+ * Description: The Keccak F1600 Permutation
68
+ *
69
+ * Arguments: - uint64_t *state: pointer to input/output Keccak state
70
+ **************************************************/
71
+ static void KeccakF1600_StatePermute(uint64_t state[25]) {
72
+ int round;
73
+
74
+ uint64_t Aba, Abe, Abi, Abo, Abu;
75
+ uint64_t Aga, Age, Agi, Ago, Agu;
76
+ uint64_t Aka, Ake, Aki, Ako, Aku;
77
+ uint64_t Ama, Ame, Ami, Amo, Amu;
78
+ uint64_t Asa, Ase, Asi, Aso, Asu;
79
+ uint64_t BCa, BCe, BCi, BCo, BCu;
80
+ uint64_t Da, De, Di, Do, Du;
81
+ uint64_t Eba, Ebe, Ebi, Ebo, Ebu;
82
+ uint64_t Ega, Ege, Egi, Ego, Egu;
83
+ uint64_t Eka, Eke, Eki, Eko, Eku;
84
+ uint64_t Ema, Eme, Emi, Emo, Emu;
85
+ uint64_t Esa, Ese, Esi, Eso, Esu;
86
+
87
+ // copyFromState(A, state)
88
+ Aba = state[0];
89
+ Abe = state[1];
90
+ Abi = state[2];
91
+ Abo = state[3];
92
+ Abu = state[4];
93
+ Aga = state[5];
94
+ Age = state[6];
95
+ Agi = state[7];
96
+ Ago = state[8];
97
+ Agu = state[9];
98
+ Aka = state[10];
99
+ Ake = state[11];
100
+ Aki = state[12];
101
+ Ako = state[13];
102
+ Aku = state[14];
103
+ Ama = state[15];
104
+ Ame = state[16];
105
+ Ami = state[17];
106
+ Amo = state[18];
107
+ Amu = state[19];
108
+ Asa = state[20];
109
+ Ase = state[21];
110
+ Asi = state[22];
111
+ Aso = state[23];
112
+ Asu = state[24];
113
+
114
+ for (round = 0; round < NROUNDS; round += 2) {
115
+ // prepareTheta
116
+ BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
117
+ BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase;
118
+ BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
119
+ BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
120
+ BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
121
+
122
+ // thetaRhoPiChiIotaPrepareTheta(round, A, E)
123
+ Da = BCu ^ ROL(BCe, 1);
124
+ De = BCa ^ ROL(BCi, 1);
125
+ Di = BCe ^ ROL(BCo, 1);
126
+ Do = BCi ^ ROL(BCu, 1);
127
+ Du = BCo ^ ROL(BCa, 1);
128
+
129
+ Aba ^= Da;
130
+ BCa = Aba;
131
+ Age ^= De;
132
+ BCe = ROL(Age, 44);
133
+ Aki ^= Di;
134
+ BCi = ROL(Aki, 43);
135
+ Amo ^= Do;
136
+ BCo = ROL(Amo, 21);
137
+ Asu ^= Du;
138
+ BCu = ROL(Asu, 14);
139
+ Eba = BCa ^ ((~BCe) & BCi);
140
+ Eba ^= (uint64_t)KeccakF_RoundConstants[round];
141
+ Ebe = BCe ^ ((~BCi) & BCo);
142
+ Ebi = BCi ^ ((~BCo) & BCu);
143
+ Ebo = BCo ^ ((~BCu) & BCa);
144
+ Ebu = BCu ^ ((~BCa) & BCe);
145
+
146
+ Abo ^= Do;
147
+ BCa = ROL(Abo, 28);
148
+ Agu ^= Du;
149
+ BCe = ROL(Agu, 20);
150
+ Aka ^= Da;
151
+ BCi = ROL(Aka, 3);
152
+ Ame ^= De;
153
+ BCo = ROL(Ame, 45);
154
+ Asi ^= Di;
155
+ BCu = ROL(Asi, 61);
156
+ Ega = BCa ^ ((~BCe) & BCi);
157
+ Ege = BCe ^ ((~BCi) & BCo);
158
+ Egi = BCi ^ ((~BCo) & BCu);
159
+ Ego = BCo ^ ((~BCu) & BCa);
160
+ Egu = BCu ^ ((~BCa) & BCe);
161
+
162
+ Abe ^= De;
163
+ BCa = ROL(Abe, 1);
164
+ Agi ^= Di;
165
+ BCe = ROL(Agi, 6);
166
+ Ako ^= Do;
167
+ BCi = ROL(Ako, 25);
168
+ Amu ^= Du;
169
+ BCo = ROL(Amu, 8);
170
+ Asa ^= Da;
171
+ BCu = ROL(Asa, 18);
172
+ Eka = BCa ^ ((~BCe) & BCi);
173
+ Eke = BCe ^ ((~BCi) & BCo);
174
+ Eki = BCi ^ ((~BCo) & BCu);
175
+ Eko = BCo ^ ((~BCu) & BCa);
176
+ Eku = BCu ^ ((~BCa) & BCe);
177
+
178
+ Abu ^= Du;
179
+ BCa = ROL(Abu, 27);
180
+ Aga ^= Da;
181
+ BCe = ROL(Aga, 36);
182
+ Ake ^= De;
183
+ BCi = ROL(Ake, 10);
184
+ Ami ^= Di;
185
+ BCo = ROL(Ami, 15);
186
+ Aso ^= Do;
187
+ BCu = ROL(Aso, 56);
188
+ Ema = BCa ^ ((~BCe) & BCi);
189
+ Eme = BCe ^ ((~BCi) & BCo);
190
+ Emi = BCi ^ ((~BCo) & BCu);
191
+ Emo = BCo ^ ((~BCu) & BCa);
192
+ Emu = BCu ^ ((~BCa) & BCe);
193
+
194
+ Abi ^= Di;
195
+ BCa = ROL(Abi, 62);
196
+ Ago ^= Do;
197
+ BCe = ROL(Ago, 55);
198
+ Aku ^= Du;
199
+ BCi = ROL(Aku, 39);
200
+ Ama ^= Da;
201
+ BCo = ROL(Ama, 41);
202
+ Ase ^= De;
203
+ BCu = ROL(Ase, 2);
204
+ Esa = BCa ^ ((~BCe) & BCi);
205
+ Ese = BCe ^ ((~BCi) & BCo);
206
+ Esi = BCi ^ ((~BCo) & BCu);
207
+ Eso = BCo ^ ((~BCu) & BCa);
208
+ Esu = BCu ^ ((~BCa) & BCe);
209
+
210
+ // prepareTheta
211
+ BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
212
+ BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
213
+ BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
214
+ BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
215
+ BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
216
+
217
+ // thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
218
+ Da = BCu ^ ROL(BCe, 1);
219
+ De = BCa ^ ROL(BCi, 1);
220
+ Di = BCe ^ ROL(BCo, 1);
221
+ Do = BCi ^ ROL(BCu, 1);
222
+ Du = BCo ^ ROL(BCa, 1);
223
+
224
+ Eba ^= Da;
225
+ BCa = Eba;
226
+ Ege ^= De;
227
+ BCe = ROL(Ege, 44);
228
+ Eki ^= Di;
229
+ BCi = ROL(Eki, 43);
230
+ Emo ^= Do;
231
+ BCo = ROL(Emo, 21);
232
+ Esu ^= Du;
233
+ BCu = ROL(Esu, 14);
234
+ Aba = BCa ^ ((~BCe) & BCi);
235
+ Aba ^= (uint64_t)KeccakF_RoundConstants[round + 1];
236
+ Abe = BCe ^ ((~BCi) & BCo);
237
+ Abi = BCi ^ ((~BCo) & BCu);
238
+ Abo = BCo ^ ((~BCu) & BCa);
239
+ Abu = BCu ^ ((~BCa) & BCe);
240
+
241
+ Ebo ^= Do;
242
+ BCa = ROL(Ebo, 28);
243
+ Egu ^= Du;
244
+ BCe = ROL(Egu, 20);
245
+ Eka ^= Da;
246
+ BCi = ROL(Eka, 3);
247
+ Eme ^= De;
248
+ BCo = ROL(Eme, 45);
249
+ Esi ^= Di;
250
+ BCu = ROL(Esi, 61);
251
+ Aga = BCa ^ ((~BCe) & BCi);
252
+ Age = BCe ^ ((~BCi) & BCo);
253
+ Agi = BCi ^ ((~BCo) & BCu);
254
+ Ago = BCo ^ ((~BCu) & BCa);
255
+ Agu = BCu ^ ((~BCa) & BCe);
256
+
257
+ Ebe ^= De;
258
+ BCa = ROL(Ebe, 1);
259
+ Egi ^= Di;
260
+ BCe = ROL(Egi, 6);
261
+ Eko ^= Do;
262
+ BCi = ROL(Eko, 25);
263
+ Emu ^= Du;
264
+ BCo = ROL(Emu, 8);
265
+ Esa ^= Da;
266
+ BCu = ROL(Esa, 18);
267
+ Aka = BCa ^ ((~BCe) & BCi);
268
+ Ake = BCe ^ ((~BCi) & BCo);
269
+ Aki = BCi ^ ((~BCo) & BCu);
270
+ Ako = BCo ^ ((~BCu) & BCa);
271
+ Aku = BCu ^ ((~BCa) & BCe);
272
+
273
+ Ebu ^= Du;
274
+ BCa = ROL(Ebu, 27);
275
+ Ega ^= Da;
276
+ BCe = ROL(Ega, 36);
277
+ Eke ^= De;
278
+ BCi = ROL(Eke, 10);
279
+ Emi ^= Di;
280
+ BCo = ROL(Emi, 15);
281
+ Eso ^= Do;
282
+ BCu = ROL(Eso, 56);
283
+ Ama = BCa ^ ((~BCe) & BCi);
284
+ Ame = BCe ^ ((~BCi) & BCo);
285
+ Ami = BCi ^ ((~BCo) & BCu);
286
+ Amo = BCo ^ ((~BCu) & BCa);
287
+ Amu = BCu ^ ((~BCa) & BCe);
288
+
289
+ Ebi ^= Di;
290
+ BCa = ROL(Ebi, 62);
291
+ Ego ^= Do;
292
+ BCe = ROL(Ego, 55);
293
+ Eku ^= Du;
294
+ BCi = ROL(Eku, 39);
295
+ Ema ^= Da;
296
+ BCo = ROL(Ema, 41);
297
+ Ese ^= De;
298
+ BCu = ROL(Ese, 2);
299
+ Asa = BCa ^ ((~BCe) & BCi);
300
+ Ase = BCe ^ ((~BCi) & BCo);
301
+ Asi = BCi ^ ((~BCo) & BCu);
302
+ Aso = BCo ^ ((~BCu) & BCa);
303
+ Asu = BCu ^ ((~BCa) & BCe);
304
+ }
305
+
306
+ // copyToState(state, A)
307
+ state[0] = Aba;
308
+ state[1] = Abe;
309
+ state[2] = Abi;
310
+ state[3] = Abo;
311
+ state[4] = Abu;
312
+ state[5] = Aga;
313
+ state[6] = Age;
314
+ state[7] = Agi;
315
+ state[8] = Ago;
316
+ state[9] = Agu;
317
+ state[10] = Aka;
318
+ state[11] = Ake;
319
+ state[12] = Aki;
320
+ state[13] = Ako;
321
+ state[14] = Aku;
322
+ state[15] = Ama;
323
+ state[16] = Ame;
324
+ state[17] = Ami;
325
+ state[18] = Amo;
326
+ state[19] = Amu;
327
+ state[20] = Asa;
328
+ state[21] = Ase;
329
+ state[22] = Asi;
330
+ state[23] = Aso;
331
+ state[24] = Asu;
332
+ }
333
+
334
+ /*************************************************
335
+ * Name: keccak_init
336
+ *
337
+ * Description: Initializes the Keccak state.
338
+ *
339
+ * Arguments: - uint64_t *s: pointer to Keccak state
340
+ **************************************************/
341
+ static void keccak_init(uint64_t s[25]) {
342
+ unsigned int i;
343
+ for (i = 0; i < 25; ++i)
344
+ s[i] = 0;
345
+ }
346
+
347
+ /*************************************************
348
+ * Name: keccak_absorb
349
+ *
350
+ * Description: Absorb step of Keccak; incremental.
351
+ *
352
+ * Arguments: - uint64_t *s: pointer to Keccak state
353
+ * - unsigned int pos: position in current block to be absorbed
354
+ * - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
355
+ * - const uint8_t *in: pointer to input to be absorbed into s
356
+ * - size_t inlen: length of input in bytes
357
+ *
358
+ * Returns new position pos in current block
359
+ **************************************************/
360
+ static unsigned int keccak_absorb(uint64_t s[25], unsigned int pos,
361
+ unsigned int r, const uint8_t *in,
362
+ size_t inlen) {
363
+ unsigned int i;
364
+
365
+ while (pos + inlen >= r) {
366
+ for (i = pos; i < r; ++i)
367
+ s[i / 8] ^= (uint64_t)*in++ << 8 * (i % 8);
368
+ inlen -= r - pos;
369
+ KeccakF1600_StatePermute(s);
370
+ pos = 0;
371
+ }
372
+
373
+ for (i = pos; i < pos + inlen; ++i)
374
+ s[i / 8] ^= (uint64_t)*in++ << 8 * (i % 8);
375
+
376
+ return i;
377
+ }
378
+
379
+ /*************************************************
380
+ * Name: keccak_finalize
381
+ *
382
+ * Description: Finalize absorb step.
383
+ *
384
+ * Arguments: - uint64_t *s: pointer to Keccak state
385
+ * - unsigned int pos: position in current block to be absorbed
386
+ * - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
387
+ * - uint8_t p: domain separation byte
388
+ **************************************************/
389
+ static void keccak_finalize(uint64_t s[25], unsigned int pos, unsigned int r,
390
+ uint8_t p) {
391
+ s[pos / 8] ^= (uint64_t)p << 8 * (pos % 8);
392
+ s[r / 8 - 1] ^= 1ULL << 63;
393
+ }
394
+
395
+ /*************************************************
396
+ * Name: keccak_squeeze
397
+ *
398
+ * Description: Squeeze step of Keccak. Squeezes arbitratrily many bytes.
399
+ * Modifies the state. Can be called multiple times to keep
400
+ * squeezing, i.e., is incremental.
401
+ *
402
+ * Arguments: - uint8_t *out: pointer to output
403
+ * - size_t outlen: number of bytes to be squeezed (written to out)
404
+ * - uint64_t *s: pointer to input/output Keccak state
405
+ * - unsigned int pos: number of bytes in current block already
406
+ * squeezed
407
+ * - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
408
+ *
409
+ * Returns new position pos in current block
410
+ **************************************************/
411
+ static unsigned int keccak_squeeze(uint8_t *out, size_t outlen, uint64_t s[25],
412
+ unsigned int pos, unsigned int r) {
413
+ unsigned int i;
414
+
415
+ while (outlen) {
416
+ if (pos == r) {
417
+ KeccakF1600_StatePermute(s);
418
+ pos = 0;
419
+ }
420
+ for (i = pos; i < r && i < pos + outlen; ++i)
421
+ *out++ = s[i / 8] >> 8 * (i % 8);
422
+ outlen -= i - pos;
423
+ pos = i;
424
+ }
425
+
426
+ return pos;
427
+ }
428
+
429
+ /*************************************************
430
+ * Name: keccak_absorb_once
431
+ *
432
+ * Description: Absorb step of Keccak;
433
+ * non-incremental, starts by zeroeing the state.
434
+ *
435
+ * Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
436
+ * - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
437
+ * - const uint8_t *in: pointer to input to be absorbed into s
438
+ * - size_t inlen: length of input in bytes
439
+ * - uint8_t p: domain-separation byte for different Keccak-derived
440
+ *functions
441
+ **************************************************/
442
+ static void keccak_absorb_once(uint64_t s[25], unsigned int r,
443
+ const uint8_t *in, size_t inlen, uint8_t p) {
444
+ unsigned int i;
445
+
446
+ for (i = 0; i < 25; ++i)
447
+ s[i] = 0;
448
+
449
+ while (inlen >= r) {
450
+ for (i = 0; i < r / 8; ++i)
451
+ s[i] ^= load64(in + 8 * i);
452
+ in += r;
453
+ inlen -= r;
454
+ KeccakF1600_StatePermute(s);
455
+ }
456
+
457
+ for (i = 0; i < inlen; ++i)
458
+ s[i / 8] ^= (uint64_t)in[i] << 8 * (i % 8);
459
+
460
+ s[i / 8] ^= (uint64_t)p << 8 * (i % 8);
461
+ s[(r - 1) / 8] ^= 1ULL << 63;
462
+ }
463
+
464
+ /*************************************************
465
+ * Name: keccak_squeezeblocks
466
+ *
467
+ * Description: Squeeze step of Keccak. Squeezes full blocks of r bytes each.
468
+ * Modifies the state. Can be called multiple times to keep
469
+ * squeezing, i.e., is incremental. Assumes zero bytes of current
470
+ * block have already been squeezed.
471
+ *
472
+ * Arguments: - uint8_t *out: pointer to output blocks
473
+ * - size_t nblocks: number of blocks to be squeezed (written to
474
+ * out)
475
+ * - uint64_t *s: pointer to input/output Keccak state
476
+ * - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
477
+ **************************************************/
478
+ static void keccak_squeezeblocks(uint8_t *out, size_t nblocks, uint64_t s[25],
479
+ unsigned int r) {
480
+ unsigned int i;
481
+
482
+ while (nblocks) {
483
+ KeccakF1600_StatePermute(s);
484
+ for (i = 0; i < r / 8; ++i)
485
+ store64(out + 8 * i, s[i]);
486
+ out += r;
487
+ nblocks -= 1;
488
+ }
489
+ }
490
+
491
+ /*************************************************
492
+ * Name: shake128_init
493
+ *
494
+ * Description: Initilizes Keccak state for use as SHAKE128 XOF
495
+ *
496
+ * Arguments: - keccak_state *state: pointer to (uninitialized) Keccak state
497
+ **************************************************/
498
+ void shake128_init(keccak_state *state) {
499
+ keccak_init(state->s);
500
+ state->pos = 0;
501
+ }
502
+
503
+ /*************************************************
504
+ * Name: shake128_absorb
505
+ *
506
+ * Description: Absorb step of the SHAKE128 XOF; incremental.
507
+ *
508
+ * Arguments: - keccak_state *state: pointer to (initialized) output Keccak
509
+ * state
510
+ * - const uint8_t *in: pointer to input to be absorbed into s
511
+ * - size_t inlen: length of input in bytes
512
+ **************************************************/
513
+ void shake128_absorb(keccak_state *state, const uint8_t *in, size_t inlen) {
514
+ state->pos = keccak_absorb(state->s, state->pos, SHAKE128_RATE, in, inlen);
515
+ }
516
+
517
+ /*************************************************
518
+ * Name: shake128_finalize
519
+ *
520
+ * Description: Finalize absorb step of the SHAKE128 XOF.
521
+ *
522
+ * Arguments: - keccak_state *state: pointer to Keccak state
523
+ **************************************************/
524
+ void shake128_finalize(keccak_state *state) {
525
+ keccak_finalize(state->s, state->pos, SHAKE128_RATE, 0x1F);
526
+ state->pos = SHAKE128_RATE;
527
+ }
528
+
529
+ /*************************************************
530
+ * Name: shake128_squeeze
531
+ *
532
+ * Description: Squeeze step of SHAKE128 XOF. Squeezes arbitraily many
533
+ * bytes. Can be called multiple times to keep squeezing.
534
+ *
535
+ * Arguments: - uint8_t *out: pointer to output blocks
536
+ * - size_t outlen : number of bytes to be squeezed (written to
537
+ * output)
538
+ * - keccak_state *s: pointer to input/output Keccak state
539
+ **************************************************/
540
+ void shake128_squeeze(uint8_t *out, size_t outlen, keccak_state *state) {
541
+ state->pos = keccak_squeeze(out, outlen, state->s, state->pos, SHAKE128_RATE);
542
+ }
543
+
544
+ /*************************************************
545
+ * Name: shake128_absorb_once
546
+ *
547
+ * Description: Initialize, absorb into and finalize SHAKE128 XOF;
548
+ *non-incremental.
549
+ *
550
+ * Arguments: - keccak_state *state: pointer to (uninitialized) output Keccak
551
+ * state
552
+ * - const uint8_t *in: pointer to input to be absorbed into s
553
+ * - size_t inlen: length of input in bytes
554
+ **************************************************/
555
+ void shake128_absorb_once(keccak_state *state, const uint8_t *in,
556
+ size_t inlen) {
557
+ keccak_absorb_once(state->s, SHAKE128_RATE, in, inlen, 0x1F);
558
+ state->pos = SHAKE128_RATE;
559
+ }
560
+
561
+ /*************************************************
562
+ * Name: shake128_squeezeblocks
563
+ *
564
+ * Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of
565
+ * SHAKE128_RATE bytes each. Can be called multiple times
566
+ * to keep squeezing. Assumes new block has not yet been
567
+ * started (state->pos = SHAKE128_RATE).
568
+ *
569
+ * Arguments: - uint8_t *out: pointer to output blocks
570
+ * - size_t nblocks: number of blocks to be squeezed (written to
571
+ * output)
572
+ * - keccak_state *s: pointer to input/output Keccak state
573
+ **************************************************/
574
+ void shake128_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state) {
575
+ keccak_squeezeblocks(out, nblocks, state->s, SHAKE128_RATE);
576
+ }
577
+
578
+ /*************************************************
579
+ * Name: shake256_init
580
+ *
581
+ * Description: Initilizes Keccak state for use as SHAKE256 XOF
582
+ *
583
+ * Arguments: - keccak_state *state: pointer to (uninitialized) Keccak state
584
+ **************************************************/
585
+ void shake256_init(keccak_state *state) {
586
+ keccak_init(state->s);
587
+ state->pos = 0;
588
+ }
589
+
590
+ /*************************************************
591
+ * Name: shake256_absorb
592
+ *
593
+ * Description: Absorb step of the SHAKE256 XOF; incremental.
594
+ *
595
+ * Arguments: - keccak_state *state: pointer to (initialized) output Keccak
596
+ * state
597
+ * - const uint8_t *in: pointer to input to be absorbed into s
598
+ * - size_t inlen: length of input in bytes
599
+ **************************************************/
600
+ void shake256_absorb(keccak_state *state, const uint8_t *in, size_t inlen) {
601
+ state->pos = keccak_absorb(state->s, state->pos, SHAKE256_RATE, in, inlen);
602
+ }
603
+
604
+ /*************************************************
605
+ * Name: shake256_finalize
606
+ *
607
+ * Description: Finalize absorb step of the SHAKE256 XOF.
608
+ *
609
+ * Arguments: - keccak_state *state: pointer to Keccak state
610
+ **************************************************/
611
+ void shake256_finalize(keccak_state *state) {
612
+ keccak_finalize(state->s, state->pos, SHAKE256_RATE, 0x1F);
613
+ state->pos = SHAKE256_RATE;
614
+ }
615
+
616
+ /*************************************************
617
+ * Name: shake256_squeeze
618
+ *
619
+ * Description: Squeeze step of SHAKE256 XOF. Squeezes arbitraily many
620
+ * bytes. Can be called multiple times to keep squeezing.
621
+ *
622
+ * Arguments: - uint8_t *out: pointer to output blocks
623
+ * - size_t outlen : number of bytes to be squeezed (written to
624
+ * output)
625
+ * - keccak_state *s: pointer to input/output Keccak state
626
+ **************************************************/
627
+ void shake256_squeeze(uint8_t *out, size_t outlen, keccak_state *state) {
628
+ state->pos = 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) output Keccak
638
+ * 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: pointer to output (32 bytes)
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: pointer to output (64 bytes)
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
+ }