Crypto++  8.8 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
Classes for working with NameValuePairs.
Standard names for retrieving values by name when working with NameValuePairs.
static const int KEYLENGTH
The default key length used by the algorithm provided as a constant.
Definition: seckey.h:129
Access a block of memory.
Definition: misc.h:2975
Interface for retrieving values given their names.
Definition: cryptlib.h:327
Access a block of memory.
Definition: misc.h:3016
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:836
void New(size_type newSize)
Change size without preserving contents.
Definition: secblock.h:1126
Library configuration file.
#define W64LIT(x)
Declare an unsigned word64.
Definition: config_int.h:129
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:72
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:101
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Definition: cryptlib.h:150
Utility functions for the Crypto++ library.
T rotlConstant(T x)
Performs a left rotate.
Definition: misc.h:1757
T rotlVariable(T x, unsigned int y)
Performs a left rotate.
Definition: misc.h:1857
T rotrConstant(T x)
Performs a right rotate.
Definition: misc.h:1783
void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen)
Copy bytes in a buffer to an array of elements in big-endian order.
Definition: misc.h:2500
T rotrVariable(T x, unsigned int y)
Performs a right rotate.
Definition: misc.h:1877
Crypto++ library namespace.