maxtweak added to block
[rofl0r-kripto.git] / lib / block / noekeon.c
blobfaf2fb68afa9cccdd46065afdf0829d80f1fb348
1 /*
2 * Written in 2011 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 <limits.h>
18 #include <kripto/cast.h>
19 #include <kripto/loadstore.h>
20 #include <kripto/rotate.h>
21 #include <kripto/memwipe.h>
22 #include <kripto/block.h>
23 #include <kripto/desc/block.h>
24 #include <kripto/object/block.h>
26 #include <kripto/block/noekeon.h>
28 struct kripto_block
30 struct kripto_block_object obj;
31 unsigned int rounds;
32 uint32_t k[4];
33 uint32_t dk[4];
36 static const uint8_t rc[34] =
38 0x80, 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A,
39 0x2F, 0x5E, 0xBC, 0x63, 0xC6, 0x97, 0x35, 0x6A,
40 0xD4, 0xB3, 0x7D, 0xFA, 0xEF, 0xC5, 0x91, 0x39,
41 0x72, 0xE4, 0xD3, 0xBD, 0x61, 0xC2, 0x9F, 0x25,
42 0x4A, 0x94
45 #define THETA(X0, X1, X2, X3, K0, K1, K2, K3) \
46 { \
47 T = X0 ^ X2; \
48 T ^= ROL32_08(T) ^ ROR32_08(T); \
49 X1 ^= T; \
50 X3 ^= T; \
51 X0 ^= K0; X1 ^= K1; X2 ^= K2; X3 ^= K3; \
52 T = X1 ^ X3; \
53 T ^= ROL32_08(T) ^ ROR32_08(T); \
54 X0 ^= T; \
55 X2 ^= T; \
58 #define GAMMA(X0, X1, X2, X3) \
59 { \
60 X1 ^= ~(X3 | X2); \
61 X0 ^= X2 & X1; \
62 T = X3; X3 = X0; X0 = T; \
63 X2 ^= X0 ^ X1 ^ X3; \
64 X1 ^= ~(X3 | X2); \
65 X0 ^= X2 & X1; \
68 #define PI1(X1, X2, X3) \
69 { \
70 X1 = ROL32_01(X1); \
71 X2 = ROL32_05(X2); \
72 X3 = ROL32_02(X3); \
75 #define PI2(X1, X2, X3) \
76 { \
77 X1 = ROR32_01(X1); \
78 X2 = ROR32_05(X2); \
79 X3 = ROR32_02(X3); \
82 static void noekeon_encrypt
84 const kripto_block *s,
85 const void *pt,
86 void *ct
89 uint32_t x0;
90 uint32_t x1;
91 uint32_t x2;
92 uint32_t x3;
93 uint32_t T;
94 unsigned int r;
96 x0 = LOAD32B(CU8(pt));
97 x1 = LOAD32B(CU8(pt) + 4);
98 x2 = LOAD32B(CU8(pt) + 8);
99 x3 = LOAD32B(CU8(pt) + 12);
101 for(r = 0; r < s->rounds; r++)
103 x0 ^= rc[r];
104 THETA(x0, x1, x2, x3, s->k[0], s->k[1], s->k[2], s->k[3]);
105 PI1(x1, x2, x3);
106 GAMMA(x0, x1, x2, x3);
107 PI2(x1, x2, x3);
109 x0 ^= rc[r];
110 THETA(x0, x1, x2, x3, s->k[0], s->k[1], s->k[2], s->k[3]);
112 STORE32B(x0, U8(ct));
113 STORE32B(x1, U8(ct) + 4);
114 STORE32B(x2, U8(ct) + 8);
115 STORE32B(x3, U8(ct) + 12);
118 static void noekeon_decrypt
120 const kripto_block *s,
121 const void *ct,
122 void *pt
125 uint32_t x0;
126 uint32_t x1;
127 uint32_t x2;
128 uint32_t x3;
129 uint32_t T;
130 unsigned int r;
132 x0 = LOAD32B(CU8(ct));
133 x1 = LOAD32B(CU8(ct) + 4);
134 x2 = LOAD32B(CU8(ct) + 8);
135 x3 = LOAD32B(CU8(ct) + 12);
137 for(r = s->rounds; r; r--)
139 THETA(x0, x1, x2, x3, s->dk[0], s->dk[1], s->dk[2], s->dk[3]);
140 x0 ^= rc[r];
141 PI1(x1, x2, x3);
142 GAMMA(x0, x1, x2, x3);
143 PI2(x1, x2, x3);
145 THETA(x0, x1, x2, x3, s->dk[0], s->dk[1], s->dk[2], s->dk[3]);
146 x0 ^= rc[r];
148 STORE32B(x0, U8(pt));
149 STORE32B(x1, U8(pt) + 4);
150 STORE32B(x2, U8(pt) + 8);
151 STORE32B(x3, U8(pt) + 12);
154 static void noekeon_setup
156 kripto_block *s,
157 const uint8_t *key,
158 unsigned int key_len
161 unsigned int i;
162 uint32_t T;
164 if(!s->rounds) s->rounds = 16;
166 /* direct mode */
167 s->k[0] = s->k[1] = s->k[2] = s->k[3] = 0;
169 for(i = 0; i < key_len; i++)
170 s->k[i >> 2] |= key[i] << (24 - ((i & 3) << 3));
172 /* decryption key */
173 s->dk[0] = s->k[0];
174 s->dk[1] = s->k[1];
175 s->dk[2] = s->k[2];
176 s->dk[3] = s->k[3];
177 THETA(s->dk[0], s->dk[1], s->dk[2], s->dk[3], 0, 0, 0, 0);
180 static kripto_block *noekeon_create
182 unsigned int r,
183 const void *key,
184 unsigned int key_len
187 kripto_block *s;
189 s = malloc(sizeof(kripto_block));
190 if(!s) return 0;
192 s->obj.desc = kripto_block_noekeon;
193 s->rounds = r;
195 noekeon_setup(s, key, key_len);
197 return s;
200 static kripto_block *noekeon_recreate
202 kripto_block *s,
203 unsigned int r,
204 const void *key,
205 unsigned int key_len
208 s->rounds = r;
209 noekeon_setup(s, key, key_len);
211 return s;
214 static void noekeon_destroy(kripto_block *s)
216 kripto_memwipe(s, sizeof(kripto_block));
217 free(s);
220 static const kripto_block_desc noekeon =
222 &noekeon_create,
223 &noekeon_recreate,
224 0, /* tweak */
225 &noekeon_encrypt,
226 &noekeon_decrypt,
227 &noekeon_destroy,
228 16, /* block size */
229 16, /* max key */
230 0 /* max tweak */
233 const kripto_block_desc *const kripto_block_noekeon = &noekeon;