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.
Precompiled header file.
Classes for the Threefish block cipher.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68