maxtweak added to block
[rofl0r-kripto.git] / lib / block / threefish256.c
blob90e7372a50c949dc11679c070e94ecb4ad81bf5b
1 /*
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.
7 *
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/>.
14 #include <stdint.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <limits.h>
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
31 struct kripto_block
33 struct kripto_block_object obj;
34 unsigned int rounds;
35 uint64_t t[3];
36 uint64_t k[5];
39 static void threefish256_tweak
41 kripto_block *s,
42 const void *tweak,
43 unsigned int len
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,
57 const void *pt,
58 void *ct
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];
65 unsigned int r = 1;
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;
81 x0 += s->k[r % 5];
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;
85 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;
99 x0 += s->k[r % 5];
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;
103 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,
115 const void *ct,
116 void *pt
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;
125 while(r > 1)
127 x0 -= s->k[r % 5];
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;
131 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;
145 x0 -= s->k[r % 5];
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;
149 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;
164 x0 -= s->k[0];
165 x1 -= s->k[1] + s->t[0];
166 x2 -= s->k[2] + s->t[1];
167 x3 -= s->k[3];
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
177 kripto_block *s,
178 unsigned int r,
179 const void *key,
180 unsigned int key_len
183 unsigned int i;
185 s->rounds = r;
186 if(!s->rounds) s->rounds = 72;
188 memset(s->k, 0, 32);
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;
197 return s;
200 static kripto_block *threefish256_create
202 unsigned int r,
203 const void *key,
204 unsigned int key_len
207 kripto_block *s;
209 s = malloc(sizeof(kripto_block));
210 if(!s) return 0;
212 s->obj.desc = kripto_block_threefish256;
214 (void)threefish256_recreate(s, r, key, key_len);
216 return s;
219 static void threefish256_destroy(kripto_block *s)
221 kripto_memwipe(s, sizeof(kripto_block));
222 free(s);
225 static const kripto_block_desc threefish256 =
227 &threefish256_create,
228 &threefish256_recreate,
229 &threefish256_tweak,
230 &threefish256_encrypt,
231 &threefish256_decrypt,
232 &threefish256_destroy,
233 32, /* block size */
234 32, /* max key */
235 16 /* max tweak */
238 const kripto_block_desc *const kripto_block_threefish256 = &threefish256;