Crypto++  8.6 Free C++ class library of cryptographic schemes
threefish.cpp
1 // threefish.cpp - written and placed in the public domain by Jeffrey Walton
2 // Based on public domain code by Keru Kuro. Kuro's code is
3 // available at http://cppcrypto.sourceforge.net/.
4
5 #include "pch.h"
6 #include "config.h"
7
8 #include "threefish.h"
9 #include "misc.h"
10 #include "algparam.h"
11 #include "argnames.h"
12
13 ANONYMOUS_NAMESPACE_BEGIN
14
15 using CryptoPP::word32;
16 using CryptoPP::word64;
21
22 template <unsigned int C0, unsigned int C1>
23 inline void G256(word64& G0, word64& G1, word64& G2, word64& G3)
24 {
25  G0 += G1;
26  G1 = rotlConstant<C0>(G1) ^ G0;
27  G2 += G3;
28  G3 = rotlConstant<C1>(G3) ^ G2;
29 }
30
31 template <unsigned int C0, unsigned int C1>
32 inline void IG256(word64& G0, word64& G1, word64& G2, word64& G3)
33 {
34  G3 = rotrConstant<C1>(G3 ^ G2);
35  G2 -= G3;
36  G1 = rotrConstant<C0>(G1 ^ G0);
37  G0 -= G1;
38 }
39
40 #define KS256(r) \
41  G0 += m_rkey[(r + 1) % 5]; \
42  G1 += m_rkey[(r + 2) % 5] + m_tweak[(r + 1) % 3]; \
43  G2 += m_rkey[(r + 3) % 5] + m_tweak[(r + 2) % 3]; \
44  G3 += m_rkey[(r + 4) % 5] + r + 1;
45
46 #define IKS256(r) \
47  G0 -= m_rkey[(r + 1) % 5]; \
48  G1 -= (m_rkey[(r + 2) % 5] + m_tweak[(r + 1) % 3]); \
49  G2 -= (m_rkey[(r + 3) % 5] + m_tweak[(r + 2) % 3]); \
50  G3 -= (m_rkey[(r + 4) % 5] + r + 1);
51
52 #define G256x8(r) \
53  G256<14, 16>(G0, G1, G2, G3); \
54  G256<52, 57>(G0, G3, G2, G1); \
55  G256<23, 40>(G0, G1, G2, G3); \
56  G256< 5, 37>(G0, G3, G2, G1); \
57  KS256(r); \
58  G256<25, 33>(G0, G1, G2, G3); \
59  G256<46, 12>(G0, G3, G2, G1); \
60  G256<58, 22>(G0, G1, G2, G3); \
61  G256<32, 32>(G0, G3, G2, G1); \
62  KS256(r + 1);
63
64 #define IG256x8(r) \
65  IG256<32, 32>(G0, G3, G2, G1); \
66  IG256<58, 22>(G0, G1, G2, G3); \
67  IG256<46, 12>(G0, G3, G2, G1); \
68  IG256<25, 33>(G0, G1, G2, G3); \
69  IKS256(r); \
70  IG256< 5, 37>(G0, G3, G2, G1); \
71  IG256<23, 40>(G0, G1, G2, G3); \
72  IG256<52, 57>(G0, G3, G2, G1); \
73  IG256<14, 16>(G0, G1, G2, G3); \
74  IKS256(r - 1);
75
76 ///////////////////
77
78 template <unsigned int C0, unsigned int C1, unsigned int C2, unsigned int C3>
79 inline void G512(word64& G0, word64& G1, word64& G2, word64& G3, word64& G4, word64& G5, word64& G6, word64& G7)
80 {
81  G0 += G1;
82  G1 = rotlConstant<C0>(G1) ^ G0;
83  G2 += G3;
84  G3 = rotlConstant<C1>(G3) ^ G2;
85  G4 += G5;
86  G5 = rotlConstant<C2>(G5) ^ G4;
87  G6 += G7;
88  G7 = rotlConstant<C3>(G7) ^ G6;
89 }
90
91 template <unsigned int C0, unsigned int C1, unsigned int C2, unsigned int C3>
92 inline void IG512(word64& G0, word64& G1, word64& G2, word64& G3, word64& G4, word64& G5, word64& G6, word64& G7)
93 {
94  G7 = rotrConstant<C3>(G7 ^ G6);
95  G6 -= G7;
96  G5 = rotrConstant<C2>(G5 ^ G4);
97  G4 -= G5;
98  G3 = rotrConstant<C1>(G3 ^ G2);
99  G2 -= G3;
100  G1 = rotrConstant<C0>(G1 ^ G0);
101  G0 -= G1;
102 }
103
104 #define KS512(r) \
105  G0 += m_rkey[(r + 1) % 9]; \
106  G1 += m_rkey[(r + 2) % 9]; \
107  G2 += m_rkey[(r + 3) % 9]; \
108  G3 += m_rkey[(r + 4) % 9]; \
109  G4 += m_rkey[(r + 5) % 9]; \
110  G5 += m_rkey[(r + 6) % 9] + m_tweak[(r + 1) % 3]; \
111  G6 += m_rkey[(r + 7) % 9] + m_tweak[(r + 2) % 3]; \
112  G7 += m_rkey[(r + 8) % 9] + r + 1;
113
114 #define IKS512(r) \
115  G0 -= m_rkey[(r + 1) % 9]; \
116  G1 -= m_rkey[(r + 2) % 9]; \
117  G2 -= m_rkey[(r + 3) % 9]; \
118  G3 -= m_rkey[(r + 4) % 9]; \
119  G4 -= m_rkey[(r + 5) % 9]; \
120  G5 -= (m_rkey[(r + 6) % 9] + m_tweak[(r + 1) % 3]); \
121  G6 -= (m_rkey[(r + 7) % 9] + m_tweak[(r + 2) % 3]); \
122  G7 -= (m_rkey[(r + 8) % 9] + r + 1);
123
124 #define IG512x8(r) \
125  IG512< 8, 35, 56, 22>(G6, G1, G0, G7, G2, G5, G4, G3); \
126  IG512<25, 29, 39, 43>(G4, G1, G6, G3, G0, G5, G2, G7); \
127  IG512<13, 50, 10, 17>(G2, G1, G4, G7, G6, G5, G0, G3); \
128  IG512<39, 30, 34, 24>(G0, G1, G2, G3, G4, G5, G6, G7); \
129  IKS512(r) \
130  IG512<44, 9, 54, 56>(G6, G1, G0, G7, G2, G5, G4, G3); \
131  IG512<17, 49, 36, 39>(G4, G1, G6, G3, G0, G5, G2, G7); \
132  IG512<33, 27, 14, 42>(G2, G1, G4, G7, G6, G5, G0, G3); \
133  IG512<46, 36, 19, 37>(G0, G1, G2, G3, G4, G5, G6, G7); \
134  IKS512(r - 1)
135
136 #define G512x8(r) \
137  G512<46, 36, 19, 37>(G0, G1, G2, G3, G4, G5, G6, G7); \
138  G512<33, 27, 14, 42>(G2, G1, G4, G7, G6, G5, G0, G3); \
139  G512<17, 49, 36, 39>(G4, G1, G6, G3, G0, G5, G2, G7); \
140  G512<44, 9, 54, 56>(G6, G1, G0, G7, G2, G5, G4, G3); \
141  KS512(r) \
142  G512<39, 30, 34, 24>(G0, G1, G2, G3, G4, G5, G6, G7); \
143  G512<13, 50, 10, 17>(G2, G1, G4, G7, G6, G5, G0, G3); \
144  G512<25, 29, 39, 43>(G4, G1, G6, G3, G0, G5, G2, G7); \
145  G512< 8, 35, 56, 22>(G6, G1, G0, G7, G2, G5, G4, G3); \
146  KS512(r + 1)
147
148 ///////////////////
149
150 template <unsigned int C0, unsigned int C1, unsigned int C2, unsigned int C3>
151 inline void G1024A(word64& G0, word64& G1, word64& G2, word64& G3,
152  word64& G4, word64& G5, word64& G6, word64& G7)
153 {
154  G0 += G1;
155  G1 = rotlConstant<C0>(G1) ^ G0;
156  G2 += G3;
157  G3 = rotlConstant<C1>(G3) ^ G2;
158  G4 += G5;
159  G5 = rotlConstant<C2>(G5) ^ G4;
160  G6 += G7;
161  G7 = rotlConstant<C3>(G7) ^ G6;
162 }
163
164 template <unsigned int C4, unsigned int C5, unsigned int C6, unsigned int C7>
165 inline void G1024B(word64& G8, word64& G9, word64& G10, word64& G11,
166  word64& G12, word64& G13, word64& G14, word64& G15)
167 {
168  G8 += G9;
169  G9 = rotlConstant<C4>(G9) ^ G8;
170  G10 += G11;
171  G11 = rotlConstant<C5>(G11) ^ G10;
172  G12 += G13;
173  G13 = rotlConstant<C6>(G13) ^ G12;
174  G14 += G15;
175  G15 = rotlConstant<C7>(G15) ^ G14;
176 }
177
178 template <unsigned int C0, unsigned int C1, unsigned int C2, unsigned int C3,
179  unsigned int C4, unsigned int C5, unsigned int C6, unsigned int C7>
180 inline void G1024(word64& G0, word64& G1, word64& G2, word64& G3, word64& G4, word64& G5,
181  word64& G6, word64& G7, word64& G8, word64& G9, word64& G10, word64& G11, word64& G12,
182  word64& G13, word64& G14, word64& G15)
183 {
184  // The extra gyrations promote inlining. Without it Threefish1024 looses 10 cpb.
185  G1024A<C0, C1, C2, C3>(G0, G1, G2, G3, G4, G5, G6, G7);
186  G1024B<C4, C5, C6, C7>(G8, G9, G10, G11, G12, G13, G14, G15);
187 }
188
189 template <unsigned int C4, unsigned int C5, unsigned int C6, unsigned int C7>
190 inline void IG1024A(word64& G8, word64& G9, word64& G10, word64& G11,
191  word64& G12, word64& G13, word64& G14, word64& G15)
192 {
193  G15 = rotrConstant<C7>(G15 ^ G14);
194  G14 -= G15;
195  G13 = rotrConstant<C6>(G13 ^ G12);
196  G12 -= G13;
197  G11 = rotrConstant<C5>(G11 ^ G10);
198  G10 -= G11;
199  G9 = rotrConstant<C4>(G9 ^ G8);
200  G8 -= G9;
201 }
202
203 template <unsigned int C0, unsigned int C1, unsigned int C2, unsigned int C3>
204 inline void IG1024B(word64& G0, word64& G1, word64& G2, word64& G3,
205  word64& G4, word64& G5, word64& G6, word64& G7)
206 {
207  G7 = rotrConstant<C3>(G7 ^ G6);
208  G6 -= G7;
209  G5 = rotrConstant<C2>(G5 ^ G4);
210  G4 -= G5;
211  G3 = rotrConstant<C1>(G3 ^ G2);
212  G2 -= G3;
213  G1 = rotrConstant<C0>(G1 ^ G0);
214  G0 -= G1;
215 }
216
217 template <unsigned int C0, unsigned int C1, unsigned int C2, unsigned int C3,
218  unsigned int C4, unsigned int C5, unsigned int C6, unsigned int C7>
219 inline void IG1024(word64& G0, word64& G1, word64& G2, word64& G3, word64& G4, word64& G5,
220  word64& G6, word64& G7, word64& G8, word64& G9, word64& G10, word64& G11, word64& G12,
221  word64& G13, word64& G14, word64& G15)
222 {
223  // The extra gyrations promote inlining. Without it Threefish1024 looses 10 cpb.
224  IG1024A<C4, C5, C6, C7>(G8, G9, G10, G11, G12, G13, G14, G15);
225  IG1024B<C0, C1, C2, C3>(G0, G1, G2, G3, G4, G5, G6, G7);
226 }
227
228 #define KS1024(r) \
229  G0 += m_rkey[(r + 1) % 17]; \
230  G1 += m_rkey[(r + 2) % 17]; \
231  G2 += m_rkey[(r + 3) % 17]; \
232  G3 += m_rkey[(r + 4) % 17]; \
233  G4 += m_rkey[(r + 5) % 17]; \
234  G5 += m_rkey[(r + 6) % 17]; \
235  G6 += m_rkey[(r + 7) % 17]; \
236  G7 += m_rkey[(r + 8) % 17]; \
237  G8 += m_rkey[(r + 9) % 17]; \
238  G9 += m_rkey[(r + 10) % 17]; \
239  G10 += m_rkey[(r + 11) % 17]; \
240  G11 += m_rkey[(r + 12) % 17]; \
241  G12 += m_rkey[(r + 13) % 17]; \
242  G13 += m_rkey[(r + 14) % 17] + m_tweak[(r + 1) % 3]; \
243  G14 += m_rkey[(r + 15) % 17] + m_tweak[(r + 2) % 3]; \
244  G15 += m_rkey[(r + 16) % 17] + r + 1;
245
246 #define IKS1024(r) \
247  G0 -= m_rkey[(r + 1) % 17]; \
248  G1 -= m_rkey[(r + 2) % 17]; \
249  G2 -= m_rkey[(r + 3) % 17]; \
250  G3 -= m_rkey[(r + 4) % 17]; \
251  G4 -= m_rkey[(r + 5) % 17]; \
252  G5 -= m_rkey[(r + 6) % 17]; \
253  G6 -= m_rkey[(r + 7) % 17]; \
254  G7 -= m_rkey[(r + 8) % 17]; \
255  G8 -= m_rkey[(r + 9) % 17]; \
256  G9 -= m_rkey[(r + 10) % 17]; \
257  G10 -= m_rkey[(r + 11) % 17]; \
258  G11 -= m_rkey[(r + 12) % 17]; \
259  G12 -= m_rkey[(r + 13) % 17]; \
260  G13 -= (m_rkey[(r + 14) % 17] + m_tweak[(r + 1) % 3]); \
261  G14 -= (m_rkey[(r + 15) % 17] + m_tweak[(r + 2) % 3]); \
262  G15 -= (m_rkey[(r + 16) % 17] + r + 1);
263
264 #define G1024x8(r) \
265  G1024A<24, 13, 8, 47>(G0, G1, G2, G3, G4, G5, G6, G7); \
266  G1024B< 8, 17, 22, 37>(G8, G9, G10, G11, G12, G13, G14, G15); \
267  G1024A<38, 19, 10, 55>(G0, G9, G2, G13, G6, G11, G4, G15); \
268  G1024B<49, 18, 23, 52>(G10, G7, G12, G3, G14, G5, G8, G1); \
269  G1024A<33, 4, 51, 13>(G0, G7, G2, G5, G4, G3, G6, G1); \
270  G1024B<34, 41, 59, 17>(G12, G15, G14, G13, G8, G11, G10, G9); \
271  G1024A< 5, 20, 48, 41>(G0, G15, G2, G11, G6, G13, G4, G9); \
272  G1024B<47, 28, 16, 25>(G14, G1, G8, G5, G10, G3, G12, G7); \
273  KS1024(r); \
274  G1024A<41, 9, 37, 31>(G0, G1, G2, G3, G4, G5, G6, G7); \
275  G1024B<12, 47, 44, 30>(G8, G9, G10, G11, G12, G13, G14, G15); \
276  G1024A<16, 34, 56, 51>(G0, G9, G2, G13, G6, G11, G4, G15); \
277  G1024B< 4, 53, 42, 41>(G10, G7, G12, G3, G14, G5, G8, G1); \
278  G1024A<31, 44, 47, 46>(G0, G7, G2, G5, G4, G3, G6, G1); \
279  G1024B<19, 42, 44, 25>(G12, G15, G14, G13, G8, G11, G10, G9); \
280  G1024A< 9, 48, 35, 52>(G0, G15, G2, G11, G6, G13, G4, G9); \
281  G1024B<23, 31, 37, 20>(G14, G1, G8, G5, G10, G3, G12, G7); \
282  KS1024(r + 1);
283
284 #define IG1024x8(r) \
285  IG1024A< 9, 48, 35, 52>(G0, G15, G2, G11, G6, G13, G4, G9); \
286  IG1024B<23, 31, 37, 20>(G14, G1, G8, G5, G10, G3, G12, G7); \
287  IG1024A<31, 44, 47, 46>(G0, G7, G2, G5, G4, G3, G6, G1); \
288  IG1024B<19, 42, 44, 25>(G12, G15, G14, G13, G8, G11, G10, G9); \
289  IG1024A<16, 34, 56, 51>(G0, G9, G2, G13, G6, G11, G4, G15); \
290  IG1024B< 4, 53, 42, 41>(G10, G7, G12, G3, G14, G5, G8, G1); \
291  IG1024A<41, 9, 37, 31>(G0, G1, G2, G3, G4, G5, G6, G7); \
292  IG1024B<12, 47, 44, 30>(G8, G9, G10, G11, G12, G13, G14, G15); \
293  IKS1024(r); \
294  IG1024A< 5, 20, 48, 41>(G0, G15, G2, G11, G6, G13, G4, G9); \
295  IG1024B<47, 28, 16, 25>(G14, G1, G8, G5, G10, G3, G12, G7); \
296  IG1024A<33, 4, 51, 13>(G0, G7, G2, G5, G4, G3, G6, G1); \
297  IG1024B<34, 41, 59, 17>(G12, G15, G14, G13, G8, G11, G10, G9); \
298  IG1024A<38, 19, 10, 55>(G0, G9, G2, G13, G6, G11, G4, G15); \
299  IG1024B<49, 18, 23, 52>(G10, G7, G12, G3, G14, G5, G8, G1); \
300  IG1024A<24, 13, 8, 47>(G0, G1, G2, G3, G4, G5, G6, G7); \
301  IG1024B< 8, 17, 22, 37>(G8, G9, G10, G11, G12, G13, G14, G15); \
302  IKS1024(r - 1);
303
304 ANONYMOUS_NAMESPACE_END
305
306 ///////////////////////////////////////////////////////////////////////////////
307 ///////////////////////////////////////////////////////////////////////////////
308
309 NAMESPACE_BEGIN(CryptoPP)
310
311 void Threefish256::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
312 {
313  // Blocksize is Keylength for Threefish
314  CRYPTOPP_ASSERT(keyLength == KEYLENGTH);
315
316  m_rkey.New(5);
317  m_wspace.New(4);
318
319  GetUserKey(LITTLE_ENDIAN_ORDER, m_rkey.begin(), 4, userKey, keyLength);
320  m_rkey[4] = W64LIT(0x1BD11BDAA9FC1A22) ^ m_rkey[0] ^ m_rkey[1] ^ m_rkey[2] ^ m_rkey[3];
321
322  SetTweak(params);
323 }
324
325 void Threefish256::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
326 {
327  word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3];
328
329  // Reverse bytes on BigEndian; align pointer on LittleEndian
331  InBlock iblk(inBlock);
332  iblk(G0)(G1)(G2)(G3);
333
334  G0 += m_rkey[0]; G1 += m_rkey[1]; G2 += m_rkey[2];
335  G3 += m_rkey[3]; G1 += m_tweak[0]; G2 += m_tweak[1];
336
337  G256x8(0); G256x8(2); G256x8(4); G256x8(6); G256x8(8);
338  G256x8(10); G256x8(12); G256x8(14); G256x8(16);
339
340  // Reverse bytes on BigEndian; align pointer on LittleEndian
341  typedef PutBlock<word64, LittleEndian, false> OutBlock;
342  OutBlock oblk(xorBlock, outBlock);
343  oblk(G0)(G1)(G2)(G3);
344 }
345
346 void Threefish256::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
347 {
348  word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3];
349
350  // Reverse bytes on BigEndian; align pointer on LittleEndian
352  InBlock iblk(inBlock);
353  iblk(G0)(G1)(G2)(G3);
354
355  G0 -= m_rkey[3]; G1 -= m_rkey[4]; G2 -= m_rkey[0]; G3 -= m_rkey[1];
356  G1 -= m_tweak[0]; G2 -= m_tweak[1]; G3 -= 18;
357
358  IG256x8(16); IG256x8(14); IG256x8(12); IG256x8(10);
359  IG256x8(8); IG256x8(6); IG256x8(4); IG256x8(2); IG256x8(0);
360
361  // Reverse bytes on BigEndian; align pointer on LittleEndian
362  typedef PutBlock<word64, LittleEndian, false> OutBlock;
363  OutBlock oblk(xorBlock, outBlock);
364  oblk(G0)(G1)(G2)(G3);
365 }
366
367 /////////////////////////////////////////////////////////////////
368
369 void Threefish512::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
370 {
371  // Blocksize is Keylength for Threefish
372  CRYPTOPP_ASSERT(keyLength == KEYLENGTH);
373
374  m_rkey.New(9);
375  m_wspace.New(8);
376
377  GetUserKey(LITTLE_ENDIAN_ORDER, m_rkey.begin(), 8, userKey, keyLength);
378  m_rkey[8] = W64LIT(0x1BD11BDAA9FC1A22) ^ m_rkey[0] ^ m_rkey[1] ^ m_rkey[2] ^ m_rkey[3] ^
379  m_rkey[4] ^ m_rkey[5] ^ m_rkey[6] ^ m_rkey[7];
380
381  SetTweak(params);
382 }
383
384 void Threefish512::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
385 {
386  word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3];
387  word64 &G4=m_wspace[4], &G5=m_wspace[5], &G6=m_wspace[6], &G7=m_wspace[7];
388
389  // Reverse bytes on BigEndian; align pointer on LittleEndian
391  InBlock iblk(inBlock);
392  iblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7);
393
394  // 34 integer instructions total
395  G0 += m_rkey[0]; G1 += m_rkey[1]; G2 += m_rkey[2]; G3 += m_rkey[3];
396  G4 += m_rkey[4]; G5 += m_rkey[5]; G6 += m_rkey[6]; G7 += m_rkey[7];
397  G5 += m_tweak[0]; G6 += m_tweak[1];
398
399  G512x8(0); G512x8(2); G512x8(4); G512x8(6); G512x8(8);
400  G512x8(10); G512x8(12); G512x8(14); G512x8(16);
401
402  // Reverse bytes on BigEndian; align pointer on LittleEndian
403  typedef PutBlock<word64, LittleEndian, false> OutBlock;
404  OutBlock oblk(xorBlock, outBlock);
405  oblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7);
406 }
407
408 void Threefish512::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
409 {
410  word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3];
411  word64 &G4=m_wspace[4], &G5=m_wspace[5], &G6=m_wspace[6], &G7=m_wspace[7];
412
413  // Reverse bytes on BigEndian; align pointer on LittleEndian
415  InBlock iblk(inBlock);
416  iblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7);
417
418  G0 -= m_rkey[0]; G1 -= m_rkey[1]; G2 -= m_rkey[2]; G3 -= m_rkey[3];
419  G4 -= m_rkey[4]; G5 -= m_rkey[5]; G6 -= m_rkey[6]; G7 -= m_rkey[7];
420  G5 -= m_tweak[0]; G6 -= m_tweak[1]; G7 -= 18;
421
422  IG512x8(16); IG512x8(14); IG512x8(12); IG512x8(10);
423  IG512x8(8); IG512x8(6); IG512x8(4); IG512x8(2); IG512x8(0);
424
425  // Reverse bytes on BigEndian; align pointer on LittleEndian
426  typedef PutBlock<word64, LittleEndian, false> OutBlock;
427  OutBlock oblk(xorBlock, outBlock);
428  oblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7);
429 }
430
431 /////////////////////////////////////////////////////////////////
432
433 void Threefish1024::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
434 {
435  // Blocksize is Keylength for Threefish
436  CRYPTOPP_ASSERT(keyLength == KEYLENGTH);
437
438  m_rkey.New(17);
439  m_wspace.New(16);
440
441  GetUserKey(LITTLE_ENDIAN_ORDER, m_rkey.begin(), 16, userKey, keyLength);
442  m_rkey[16] = W64LIT(0x1BD11BDAA9FC1A22) ^ m_rkey[0] ^ m_rkey[1] ^ m_rkey[2] ^ m_rkey[3] ^ m_rkey[4] ^
443  m_rkey[5] ^ m_rkey[6] ^ m_rkey[7] ^ m_rkey[8] ^ m_rkey[9] ^ m_rkey[10] ^ m_rkey[11] ^ m_rkey[12] ^
444  m_rkey[13] ^ m_rkey[14] ^ m_rkey[15];
445
446  SetTweak(params);
447 }
448
449 void Threefish1024::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
450 {
451  word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3];
452  word64 &G4=m_wspace[4], &G5=m_wspace[5], &G6=m_wspace[6], &G7=m_wspace[7];
453  word64 &G8=m_wspace[8], &G9=m_wspace[9], &G10=m_wspace[10], &G11=m_wspace[11];
454  word64 &G12=m_wspace[12], &G13=m_wspace[13], &G14=m_wspace[14], &G15=m_wspace[15];
455
456  // Reverse bytes on BigEndian; align pointer on LittleEndian
458  InBlock iblk(inBlock);
459  iblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8)(G9)(G10)(G11)(G12)(G13)(G14)(G15);
460
461  G0 += m_rkey[0]; G1 += m_rkey[1]; G2 += m_rkey[2]; G3 += m_rkey[3];
462  G4 += m_rkey[4]; G5 += m_rkey[5]; G6 += m_rkey[6]; G7 += m_rkey[7];
463  G8 += m_rkey[8]; G9 += m_rkey[9]; G10 += m_rkey[10]; G11 += m_rkey[11];
464  G12 += m_rkey[12]; G13 += m_rkey[13]; G14 += m_rkey[14]; G15 += m_rkey[15];
465  G13 += m_tweak[0]; G14 += m_tweak[1];
466
467  G1024x8(0); G1024x8(2); G1024x8(4); G1024x8(6); G1024x8(8);
468  G1024x8(10); G1024x8(12); G1024x8(14); G1024x8(16); G1024x8(18);
469
470  // Reverse bytes on BigEndian; align pointer on LittleEndian
471  typedef PutBlock<word64, LittleEndian, false> OutBlock;
472  OutBlock oblk(xorBlock, outBlock);
473  oblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8)(G9)(G10)(G11)(G12)(G13)(G14)(G15);
474 }
475
476 void Threefish1024::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
477 {
478  word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3];
479  word64 &G4=m_wspace[4], &G5=m_wspace[5], &G6=m_wspace[6], &G7=m_wspace[7];
480  word64 &G8=m_wspace[8], &G9=m_wspace[9], &G10=m_wspace[10], &G11=m_wspace[11];
481  word64 &G12=m_wspace[12], &G13=m_wspace[13], &G14=m_wspace[14], &G15=m_wspace[15];
482
483  // Reverse bytes on BigEndian; align pointer on LittleEndian
485  InBlock iblk(inBlock);
486  iblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8)(G9)(G10)(G11)(G12)(G13)(G14)(G15);
487
488  G0 -= m_rkey[3]; G1 -= m_rkey[4]; G2 -= m_rkey[5]; G3 -= m_rkey[6];
489  G4 -= m_rkey[7]; G5 -= m_rkey[8]; G6 -= m_rkey[9]; G7 -= m_rkey[10];
490  G8 -= m_rkey[11]; G9 -= m_rkey[12]; G10 -= m_rkey[13]; G11 -= m_rkey[14];
491  G12 -= m_rkey[15]; G13 -= m_rkey[16]; G14 -= m_rkey[0]; G15 -= m_rkey[1];
492  G13 -= m_tweak[2]; G14 -= m_tweak[0]; G15 -= 20;
493
494  IG1024x8(18); IG1024x8(16); IG1024x8(14); IG1024x8(12); IG1024x8(10);
495  IG1024x8(8); IG1024x8(6); IG1024x8(4); IG1024x8(2); IG1024x8(0);
496
497  // Reverse bytes on BigEndian; align pointer on LittleEndian
498  typedef PutBlock<word64, LittleEndian, false> OutBlock;
499  OutBlock oblk(xorBlock, outBlock);
500  oblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8)(G9)(G10)(G11)(G12)(G13)(G14)(G15);
501 }
502
503 NAMESPACE_END
SecBlock::begin
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:836
W64LIT
#define W64LIT(x)
Declare an unsigned word64.
Definition: config_int.h:119
CRYPTOPP_ASSERT
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68
LITTLE_ENDIAN_ORDER
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Definition: cryptlib.h:145
FixedKeyLength< BS >::KEYLENGTH
static const int KEYLENGTH
The default key length used by the algorithm provided as a constant.
Definition: seckey.h:129
word64
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:91
rotlConstant
T rotlConstant(T x)
Performs a left rotate.
Definition: misc.h:1547
pch.h
word32
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:62
GetBlock
Access a block of memory.
Definition: misc.h:2528
argnames.h
Standard names for retrieving values by name when working with NameValuePairs.
misc.h
Utility functions for the Crypto++ library.
rotrConstant
T rotrConstant(T x)
Performs a right rotate.
Definition: misc.h:1573
PutBlock
Access a block of memory.
Definition: misc.h:2569
rotrVariable
T rotrVariable(T x, unsigned int y)
Performs a right rotate.
Definition: misc.h:1667
SecBlock::New
void New(size_type newSize)
Change size without preserving contents.
Definition: secblock.h:1126
CryptoPP
Crypto++ library namespace.
config.h
Library configuration file.
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:321
algparam.h
Classes for working with NameValuePairs.
rotlVariable
T rotlVariable(T x, unsigned int y)
Performs a left rotate.
Definition: misc.h:1647
threefish.h
Classes for the Threefish block cipher.