2 * Copyright (C) 2013 Gregor Pintar <grpintar@gmail.com>
4 * Permission is granted to deal in this work without any restriction,
5 * including unlimited rights to use, publicly perform, publish,
6 * reproduce, relicence, modify, merge, and/or distribute in any form,
7 * for any purpose, with or without fee, and by any means.
9 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind,
10 * to the utmost extent permitted by applicable law. In no event
11 * shall a licensor, author or contributor be held liable for any
12 * issues arising in any way out of dealing in the work.
20 #include <kripto/loadstore.h>
21 #include <kripto/rotate.h>
22 #include <kripto/memwipe.h>
23 #include <kripto/block.h>
24 #include <kripto/desc/block.h>
26 #include <kripto/block/threefish512.h>
28 #define C240 0x1BD11BDAA9FC1A22
32 const kripto_block_desc
*desc
;
38 static void threefish512_tweak
45 s
->t
[0] = s
->t
[1] = 0;
47 while(--len
!= UINT_MAX
)
48 s
->t
[len
>> 3] = (s
->t
[len
>> 3] << 8) | CU8(tweak
)[len
];
50 s
->t
[2] = s
->t
[0] ^ s
->t
[1];
53 static void threefish512_encrypt
55 const kripto_block
*s
,
60 uint64_t x0
= LOAD64L(CU8(pt
)) + s
->k
[0];
61 uint64_t x1
= LOAD64L(CU8(pt
) + 8) + s
->k
[1];
62 uint64_t x2
= LOAD64L(CU8(pt
) + 16) + s
->k
[2];
63 uint64_t x3
= LOAD64L(CU8(pt
) + 24) + s
->k
[3];
64 uint64_t x4
= LOAD64L(CU8(pt
) + 32) + s
->k
[4];
65 uint64_t x5
= LOAD64L(CU8(pt
) + 40) + s
->k
[5] + s
->t
[0];
66 uint64_t x6
= LOAD64L(CU8(pt
) + 48) + s
->k
[6] + s
->t
[1];
67 uint64_t x7
= LOAD64L(CU8(pt
) + 56) + s
->k
[7];
70 while(r
<= s
->rounds
>> 2)
72 x0
+= x1
; x1
= ROL64(x1
, 46); x1
^= x0
;
73 x2
+= x3
; x3
= ROL64(x3
, 36); x3
^= x2
;
74 x4
+= x5
; x5
= ROL64(x5
, 19); x5
^= x4
;
75 x6
+= x7
; x7
= ROL64(x7
, 37); x7
^= x6
;
77 x2
+= x1
; x1
= ROL64(x1
, 33); x1
^= x2
;
78 x4
+= x7
; x7
= ROL64(x7
, 27); x7
^= x4
;
79 x6
+= x5
; x5
= ROL64(x5
, 14); x5
^= x6
;
80 x0
+= x3
; x3
= ROL64(x3
, 42); x3
^= x0
;
82 x4
+= x1
; x1
= ROL64(x1
, 17); x1
^= x4
;
83 x6
+= x3
; x3
= ROL64(x3
, 49); x3
^= x6
;
84 x0
+= x5
; x5
= ROL64(x5
, 36); x5
^= x0
;
85 x2
+= x7
; x7
= ROL64(x7
, 39); x7
^= x2
;
87 x6
+= x1
; x1
= ROL64(x1
, 44); x1
^= x6
;
88 x0
+= x7
; x7
= ROL64(x7
, 9); x7
^= x0
;
89 x2
+= x5
; x5
= ROL64(x5
, 54); x5
^= x2
;
90 x4
+= x3
; x3
= ROL64(x3
, 56); x3
^= x4
;
93 x1
+= s
->k
[(r
+ 1) % 9];
94 x2
+= s
->k
[(r
+ 2) % 9];
95 x3
+= s
->k
[(r
+ 3) % 9];
96 x4
+= s
->k
[(r
+ 4) % 9];
97 x5
+= s
->k
[(r
+ 5) % 9] + s
->t
[r
% 3];
98 x6
+= s
->k
[(r
+ 6) % 9] + s
->t
[(r
+ 1) % 3];
99 x7
+= s
->k
[(r
+ 7) % 9] + r
;
102 x0
+= x1
; x1
= ROL64(x1
, 39); x1
^= x0
;
103 x2
+= x3
; x3
= ROL64(x3
, 30); x3
^= x2
;
104 x4
+= x5
; x5
= ROL64(x5
, 34); x5
^= x4
;
105 x6
+= x7
; x7
= ROL64(x7
, 24); x7
^= x6
;
107 x2
+= x1
; x1
= ROL64(x1
, 13); x1
^= x2
;
108 x4
+= x7
; x7
= ROL64(x7
, 50); x7
^= x4
;
109 x6
+= x5
; x5
= ROL64(x5
, 10); x5
^= x6
;
110 x0
+= x3
; x3
= ROL64(x3
, 17); x3
^= x0
;
112 x4
+= x1
; x1
= ROL64(x1
, 25); x1
^= x4
;
113 x6
+= x3
; x3
= ROL64(x3
, 29); x3
^= x6
;
114 x0
+= x5
; x5
= ROL64(x5
, 39); x5
^= x0
;
115 x2
+= x7
; x7
= ROL64(x7
, 43); x7
^= x2
;
117 x6
+= x1
; x1
= ROL64(x1
, 8); x1
^= x6
;
118 x0
+= x7
; x7
= ROL64(x7
, 35); x7
^= x0
;
119 x2
+= x5
; x5
= ROL64(x5
, 56); x5
^= x2
;
120 x4
+= x3
; x3
= ROL64(x3
, 22); x3
^= x4
;
123 x1
+= s
->k
[(r
+ 1) % 9];
124 x2
+= s
->k
[(r
+ 2) % 9];
125 x3
+= s
->k
[(r
+ 3) % 9];
126 x4
+= s
->k
[(r
+ 4) % 9];
127 x5
+= s
->k
[(r
+ 5) % 9] + s
->t
[r
% 3];
128 x6
+= s
->k
[(r
+ 6) % 9] + s
->t
[(r
+ 1) % 3];
129 x7
+= s
->k
[(r
+ 7) % 9] + r
;
133 STORE64L(x0
, U8(ct
));
134 STORE64L(x1
, U8(ct
) + 8);
135 STORE64L(x2
, U8(ct
) + 16);
136 STORE64L(x3
, U8(ct
) + 24);
137 STORE64L(x4
, U8(ct
) + 32);
138 STORE64L(x5
, U8(ct
) + 40);
139 STORE64L(x6
, U8(ct
) + 48);
140 STORE64L(x7
, U8(ct
) + 56);
143 static void threefish512_decrypt
145 const kripto_block
*s
,
150 uint64_t x0
= LOAD64L(CU8(ct
));
151 uint64_t x1
= LOAD64L(CU8(ct
) + 8);
152 uint64_t x2
= LOAD64L(CU8(ct
) + 16);
153 uint64_t x3
= LOAD64L(CU8(ct
) + 24);
154 uint64_t x4
= LOAD64L(CU8(ct
) + 32);
155 uint64_t x5
= LOAD64L(CU8(ct
) + 40);
156 uint64_t x6
= LOAD64L(CU8(ct
) + 48);
157 uint64_t x7
= LOAD64L(CU8(ct
) + 56);
158 unsigned int r
= s
->rounds
>> 2;
163 x1
-= s
->k
[(r
+ 1) % 9];
164 x2
-= s
->k
[(r
+ 2) % 9];
165 x3
-= s
->k
[(r
+ 3) % 9];
166 x4
-= s
->k
[(r
+ 4) % 9];
167 x5
-= s
->k
[(r
+ 5) % 9] + s
->t
[r
% 3];
168 x6
-= s
->k
[(r
+ 6) % 9] + s
->t
[(r
+ 1) % 3];
169 x7
-= s
->k
[(r
+ 7) % 9] + r
;
172 x3
= ROR64(x3
^ x4
, 22); x4
-= x3
;
173 x5
= ROR64(x5
^ x2
, 56); x2
-= x5
;
174 x7
= ROR64(x7
^ x0
, 35); x0
-= x7
;
175 x1
= ROR64(x1
^ x6
, 8); x6
-= x1
;
177 x7
= ROR64(x7
^ x2
, 43); x2
-= x7
;
178 x5
= ROR64(x5
^ x0
, 39); x0
-= x5
;
179 x3
= ROR64(x3
^ x6
, 29); x6
-= x3
;
180 x1
= ROR64(x1
^ x4
, 25); x4
-= x1
;
182 x3
= ROR64(x3
^ x0
, 17); x0
-= x3
;
183 x5
= ROR64(x5
^ x6
, 10); x6
-= x5
;
184 x7
= ROR64(x7
^ x4
, 50); x4
-= x7
;
185 x1
= ROR64(x1
^ x2
, 13); x2
-= x1
;
187 x7
= ROR64(x7
^ x6
, 24); x6
-= x7
;
188 x5
= ROR64(x5
^ x4
, 34); x4
-= x5
;
189 x3
= ROR64(x3
^ x2
, 30); x2
-= x3
;
190 x1
= ROR64(x1
^ x0
, 39); x0
-= x1
;
193 x1
-= s
->k
[(r
+ 1) % 9];
194 x2
-= s
->k
[(r
+ 2) % 9];
195 x3
-= s
->k
[(r
+ 3) % 9];
196 x4
-= s
->k
[(r
+ 4) % 9];
197 x5
-= s
->k
[(r
+ 5) % 9] + s
->t
[r
% 3];
198 x6
-= s
->k
[(r
+ 6) % 9] + s
->t
[(r
+ 1) % 3];
199 x7
-= s
->k
[(r
+ 7) % 9] + r
;
202 x3
= ROR64(x3
^ x4
, 56); x4
-= x3
;
203 x5
= ROR64(x5
^ x2
, 54); x2
-= x5
;
204 x7
= ROR64(x7
^ x0
, 9); x0
-= x7
;
205 x1
= ROR64(x1
^ x6
, 44); x6
-= x1
;
207 x7
= ROR64(x7
^ x2
, 39); x2
-= x7
;
208 x5
= ROR64(x5
^ x0
, 36); x0
-= x5
;
209 x3
= ROR64(x3
^ x6
, 49); x6
-= x3
;
210 x1
= ROR64(x1
^ x4
, 17); x4
-= x1
;
212 x3
= ROR64(x3
^ x0
, 42); x0
-= x3
;
213 x5
= ROR64(x5
^ x6
, 14); x6
-= x5
;
214 x7
= ROR64(x7
^ x4
, 27); x4
-= x7
;
215 x1
= ROR64(x1
^ x2
, 33); x2
-= x1
;
217 x7
= ROR64(x7
^ x6
, 37); x6
-= x7
;
218 x5
= ROR64(x5
^ x4
, 19); x4
-= x5
;
219 x3
= ROR64(x3
^ x2
, 36); x2
-= x3
;
220 x1
= ROR64(x1
^ x0
, 46); x0
-= x1
;
228 x5
-= s
->k
[5] + s
->t
[0];
229 x6
-= s
->k
[6] + s
->t
[1];
232 STORE64L(x0
, U8(pt
));
233 STORE64L(x1
, U8(pt
) + 8);
234 STORE64L(x2
, U8(pt
) + 16);
235 STORE64L(x3
, U8(pt
) + 24);
236 STORE64L(x4
, U8(pt
) + 32);
237 STORE64L(x5
, U8(pt
) + 40);
238 STORE64L(x6
, U8(pt
) + 48);
239 STORE64L(x7
, U8(pt
) + 56);
242 static kripto_block
*threefish512_recreate
253 if(!s
->rounds
) s
->rounds
= 72;
257 for(i
= key_len
- 1; i
!= UINT_MAX
; i
--)
258 s
->k
[i
>> 3] = (s
->k
[i
>> 3] << 8) | CU8(key
)[i
];
260 s
->k
[8] = s
->k
[0] ^ s
->k
[1] ^ s
->k
[2] ^ s
->k
[3]
261 ^ s
->k
[4] ^ s
->k
[5] ^ s
->k
[6] ^ s
->k
[7] ^ C240
;
263 s
->t
[0] = s
->t
[1] = s
->t
[2] = 0;
268 static kripto_block
*threefish512_create
277 s
= malloc(sizeof(kripto_block
));
280 s
->desc
= kripto_block_threefish512
;
282 (void)threefish512_recreate(s
, r
, key
, key_len
);
287 static void threefish512_destroy(kripto_block
*s
)
289 kripto_memwipe(s
, sizeof(kripto_block
));
293 static const kripto_block_desc threefish512
=
295 &threefish512_create
,
296 &threefish512_recreate
,
298 &threefish512_encrypt
,
299 &threefish512_decrypt
,
300 &threefish512_destroy
,
305 const kripto_block_desc
*const kripto_block_threefish512
= &threefish512
;