2 * Written in 2013 by Gregor Pintar <grpintar@gmail.com>
4 * To the extent possible under law, the author(s) have dedicated
5 * all copyright and related and neighboring rights to this software
6 * to the public domain worldwide.
8 * This software is distributed without any warranty.
10 * You should have received a copy of the CC0 Public Domain Dedication.
11 * If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
19 #include <kripto/cast.h>
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>
25 #include <kripto/object/block.h>
27 #include <kripto/block/threefish256.h>
29 #define C240 0x1BD11BDAA9FC1A22
33 struct kripto_block_object obj
;
39 static void threefish256_tweak
46 s
->t
[0] = s
->t
[1] = 0;
48 while(--len
!= UINT_MAX
)
49 s
->t
[len
>> 3] = (s
->t
[len
>> 3] << 8) | CU8(tweak
)[len
];
51 s
->t
[2] = s
->t
[0] ^ s
->t
[1];
54 static void threefish256_encrypt
56 const kripto_block
*s
,
61 uint64_t x0
= LOAD64L(CU8(pt
)) + s
->k
[0];
62 uint64_t x1
= LOAD64L(CU8(pt
) + 8) + s
->k
[1] + s
->t
[0];
63 uint64_t x2
= LOAD64L(CU8(pt
) + 16) + s
->k
[2] + s
->t
[1];
64 uint64_t x3
= LOAD64L(CU8(pt
) + 24) + s
->k
[3];
67 while(r
<= s
->rounds
>> 2)
69 x0
+= x1
; x1
= ROL64_14(x1
); x1
^= x0
;
70 x2
+= x3
; x3
= ROL64_16(x3
); x3
^= x2
;
72 x0
+= x3
; x3
= ROL64_52(x3
); x3
^= x0
;
73 x2
+= x1
; x1
= ROL64_57(x1
); x1
^= x2
;
75 x0
+= x1
; x1
= ROL64_23(x1
); x1
^= x0
;
76 x2
+= x3
; x3
= ROL64_40(x3
); x3
^= x2
;
78 x0
+= x3
; x3
= ROL64_05(x3
); x3
^= x0
;
79 x2
+= x1
; x1
= ROL64_37(x1
); x1
^= x2
;
82 x1
+= s
->k
[(r
+ 1) % 5] + s
->t
[r
% 3];
83 x2
+= s
->k
[(r
+ 2) % 5] + s
->t
[(r
+ 1) % 3];
84 x3
+= s
->k
[(r
+ 3) % 5] + r
;
87 x0
+= x1
; x1
= ROL64_25(x1
); x1
^= x0
;
88 x2
+= x3
; x3
= ROL64_33(x3
); x3
^= x2
;
90 x0
+= x3
; x3
= ROL64_46(x3
); x3
^= x0
;
91 x2
+= x1
; x1
= ROL64_12(x1
); x1
^= x2
;
93 x0
+= x1
; x1
= ROL64_58(x1
); x1
^= x0
;
94 x2
+= x3
; x3
= ROL64_22(x3
); x3
^= x2
;
96 x0
+= x3
; x3
= ROL64_32(x3
); x3
^= x0
;
97 x2
+= x1
; x1
= ROL64_32(x1
); x1
^= x2
;
100 x1
+= s
->k
[(r
+ 1) % 5] + s
->t
[r
% 3];
101 x2
+= s
->k
[(r
+ 2) % 5] + s
->t
[(r
+ 1) % 3];
102 x3
+= s
->k
[(r
+ 3) % 5] + r
;
106 STORE64L(x0
, U8(ct
));
107 STORE64L(x1
, U8(ct
) + 8);
108 STORE64L(x2
, U8(ct
) + 16);
109 STORE64L(x3
, U8(ct
) + 24);
112 static void threefish256_decrypt
114 const kripto_block
*s
,
119 uint64_t x0
= LOAD64L(CU8(ct
));
120 uint64_t x1
= LOAD64L(CU8(ct
) + 8);
121 uint64_t x2
= LOAD64L(CU8(ct
) + 16);
122 uint64_t x3
= LOAD64L(CU8(ct
) + 24);
123 unsigned int r
= s
->rounds
>> 2;
128 x1
-= s
->k
[(r
+ 1) % 5] + s
->t
[r
% 3];
129 x2
-= s
->k
[(r
+ 2) % 5] + s
->t
[(r
+ 1) % 3];
130 x3
-= s
->k
[(r
+ 3) % 5] + r
;
133 x1
= ROR64_32(x1
^ x2
); x2
-= x1
;
134 x3
= ROR64_32(x3
^ x0
); x0
-= x3
;
136 x3
= ROR64_22(x3
^ x2
); x2
-= x3
;
137 x1
= ROR64_58(x1
^ x0
); x0
-= x1
;
139 x1
= ROR64_12(x1
^ x2
); x2
-= x1
;
140 x3
= ROR64_46(x3
^ x0
); x0
-= x3
;
142 x3
= ROR64_33(x3
^ x2
); x2
-= x3
;
143 x1
= ROR64_25(x1
^ x0
); x0
-= x1
;
146 x1
-= s
->k
[(r
+ 1) % 5] + s
->t
[r
% 3];
147 x2
-= s
->k
[(r
+ 2) % 5] + s
->t
[(r
+ 1) % 3];
148 x3
-= s
->k
[(r
+ 3) % 5] + r
;
151 x1
= ROR64_37(x1
^ x2
); x2
-= x1
;
152 x3
= ROR64_05(x3
^ x0
); x0
-= x3
;
154 x3
= ROR64_40(x3
^ x2
); x2
-= x3
;
155 x1
= ROR64_23(x1
^ x0
); x0
-= x1
;
157 x1
= ROR64_57(x1
^ x2
); x2
-= x1
;
158 x3
= ROR64_52(x3
^ x0
); x0
-= x3
;
160 x3
= ROR64_16(x3
^ x2
); x2
-= x3
;
161 x1
= ROR64_14(x1
^ x0
); x0
-= x1
;
165 x1
-= s
->k
[1] + s
->t
[0];
166 x2
-= s
->k
[2] + s
->t
[1];
169 STORE64L(x0
, U8(pt
));
170 STORE64L(x1
, U8(pt
) + 8);
171 STORE64L(x2
, U8(pt
) + 16);
172 STORE64L(x3
, U8(pt
) + 24);
175 static kripto_block
*threefish256_recreate
186 if(!s
->rounds
) s
->rounds
= 72;
190 for(i
= key_len
- 1; i
!= UINT_MAX
; i
--)
191 s
->k
[i
>> 3] = (s
->k
[i
>> 3] << 8) | CU8(key
)[i
];
193 s
->k
[4] = s
->k
[0] ^ s
->k
[1] ^ s
->k
[2] ^ s
->k
[3] ^ C240
;
195 s
->t
[0] = s
->t
[1] = s
->t
[2] = 0;
200 static kripto_block
*threefish256_create
209 s
= malloc(sizeof(kripto_block
));
212 s
->obj
.desc
= kripto_block_threefish256
;
214 (void)threefish256_recreate(s
, r
, key
, key_len
);
219 static void threefish256_destroy(kripto_block
*s
)
221 kripto_memwipe(s
, sizeof(kripto_block
));
225 static const kripto_block_desc threefish256
=
227 &threefish256_create
,
228 &threefish256_recreate
,
230 &threefish256_encrypt
,
231 &threefish256_decrypt
,
232 &threefish256_destroy
,
238 const kripto_block_desc
*const kripto_block_threefish256
= &threefish256
;