macros.h replaced with smaller headers, U8TO*_?E() renamed and converted to static...
[rofl0r-kripto.git] / lib / block / threefish512.c
blob909817579e9bdcd1bce42cd7420c131715b0aee0
1 /*
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.
15 #include <stdint.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <limits.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>
26 #include <kripto/block/threefish512.h>
28 #define C240 0x1BD11BDAA9FC1A22
30 struct kripto_block
32 const kripto_block_desc *desc;
33 unsigned int rounds;
34 uint64_t t[3];
35 uint64_t k[9];
38 static void threefish512_tweak
40 kripto_block *s,
41 const void *tweak,
42 unsigned int len
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,
56 const void *pt,
57 void *ct
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];
68 unsigned int r = 1;
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;
92 x0 += s->k[r % 9];
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;
100 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;
122 x0 += s->k[r % 9];
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;
130 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,
146 const void *ct,
147 void *pt
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;
160 while(r > 1)
162 x0 -= s->k[r % 9];
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;
170 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;
192 x0 -= s->k[r % 9];
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;
200 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;
223 x0 -= s->k[0];
224 x1 -= s->k[1];
225 x2 -= s->k[2];
226 x3 -= s->k[3];
227 x4 -= s->k[4];
228 x5 -= s->k[5] + s->t[0];
229 x6 -= s->k[6] + s->t[1];
230 x7 -= s->k[7];
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
244 kripto_block *s,
245 unsigned int r,
246 const void *key,
247 unsigned int key_len
250 unsigned int i;
252 s->rounds = r;
253 if(!s->rounds) s->rounds = 72;
255 memset(s->k, 0, 64);
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;
265 return s;
268 static kripto_block *threefish512_create
270 unsigned int r,
271 const void *key,
272 unsigned int key_len
275 kripto_block *s;
277 s = malloc(sizeof(kripto_block));
278 if(!s) return 0;
280 s->desc = kripto_block_threefish512;
282 (void)threefish512_recreate(s, r, key, key_len);
284 return s;
287 static void threefish512_destroy(kripto_block *s)
289 kripto_memwipe(s, sizeof(kripto_block));
290 free(s);
293 static const kripto_block_desc threefish512 =
295 &threefish512_create,
296 &threefish512_recreate,
297 &threefish512_tweak,
298 &threefish512_encrypt,
299 &threefish512_decrypt,
300 &threefish512_destroy,
301 64, /* block size */
302 64 /* max key */
305 const kripto_block_desc *const kripto_block_threefish512 = &threefish512;