maxtweak added to block
[rofl0r-kripto.git] / lib / block / simon32.c
blob3ffd4e8493a49afcc654f6bf55e36be69c0d2b57
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 <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/simon32.h>
28 struct kripto_block
30 struct kripto_block_object obj;
31 unsigned int rounds;
32 size_t size;
33 uint16_t *k;
36 #define F(X) ((ROL16_01(X) & ROL16_08(X)) ^ ROL16_02(X))
38 static void simon32_encrypt
40 const kripto_block *s,
41 const void *pt,
42 void *ct
45 uint16_t a;
46 uint16_t b;
47 unsigned int i = 0;
49 a = LOAD16B(CU8(pt));
50 b = LOAD16B(CU8(pt) + 2);
52 while(i < s->rounds)
54 b ^= F(a) ^ s->k[i++];
56 if(i == s->rounds)
58 STORE16B(a, U8(ct) + 2);
59 STORE16B(b, U8(ct));
60 return;
63 a ^= F(b) ^ s->k[i++];
66 STORE16B(a, U8(ct));
67 STORE16B(b, U8(ct) + 2);
70 static void simon32_decrypt
72 const kripto_block *s,
73 const void *ct,
74 void *pt
77 uint16_t a;
78 uint16_t b;
79 unsigned int i = s->rounds;
81 a = LOAD16B(CU8(ct));
82 b = LOAD16B(CU8(ct) + 2);
84 while(i)
86 a ^= F(b) ^ s->k[--i];
88 if(!i)
90 STORE16B(a, U8(pt) + 2);
91 STORE16B(b, U8(pt));
92 return;
95 b ^= F(a) ^ s->k[--i];
98 STORE16B(a, U8(pt));
99 STORE16B(b, U8(pt) + 2);
102 static void simon32_setup
104 kripto_block *s,
105 const uint8_t *key,
106 unsigned int len
109 unsigned int i;
110 uint16_t t;
112 for(i = 0; i < 4; i++)
113 s->k[i] = 0;
115 for(i = 0; i < len; i++)
116 s->k[3 - (i >> 1)] |=
117 (uint16_t)key[i] << (8 - ((i & 1) << 3));
119 for(i = 4; i < s->rounds; i++)
121 t = ROR16_03(s->k[i - 1]) ^ s->k[i - 3];
122 t ^= ROR16_01(t) ^ ~s->k[i - 4] ^ 3;
123 s->k[i] = t ^ ((0x19C3522FB386A45F >> ((i - 4) % 62)) & 1);
126 kripto_memwipe(&t, sizeof(uint16_t));
129 static kripto_block *simon32_create
131 unsigned int r,
132 const void *key,
133 unsigned int key_len
136 kripto_block *s;
138 if(!r) r = 32;
140 s = malloc(sizeof(kripto_block) + (r << 1));
141 if(!s) return 0;
143 s->obj.desc = kripto_block_simon32;
144 s->size = sizeof(kripto_block) + (r << 1);
145 s->k = (uint16_t *)(((uint8_t *)s) + sizeof(kripto_block));
146 s->rounds = r;
148 simon32_setup(s, key, key_len);
150 return s;
153 static void simon32_destroy(kripto_block *s)
155 kripto_memwipe(s, s->size);
156 free(s);
159 static kripto_block *simon32_recreate
161 kripto_block *s,
162 unsigned int r,
163 const void *key,
164 unsigned int key_len
167 if(!r) r = 32;
169 if(sizeof(kripto_block) + (r << 1) > s->size)
171 simon32_destroy(s);
172 s = simon32_create(r, key, key_len);
174 else
176 s->rounds = r;
177 simon32_setup(s, key, key_len);
180 return s;
183 static const kripto_block_desc simon32 =
185 &simon32_create,
186 &simon32_recreate,
187 0, /* tweak */
188 &simon32_encrypt,
189 &simon32_decrypt,
190 &simon32_destroy,
191 4, /* block size */
192 8, /* max key */
193 0 /* max tweak */
196 const kripto_block_desc *const kripto_block_simon32 = &simon32;