install.sh and uninstall.sh
[rofl0r-kripto.git] / lib / block / simon128.c
blob320c6b2bcc4e7922397600bae8e25d34f78982d7
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/simon128.h>
28 struct kripto_block
30 struct kripto_block_object obj;
31 unsigned int rounds;
32 size_t size;
33 uint64_t *k;
36 #define F(X) ((ROL64_01(X) & ROL64_08(X)) ^ ROL64_02(X))
38 static void simon128_encrypt
40 const kripto_block *s,
41 const void *pt,
42 void *ct
45 uint64_t a;
46 uint64_t b;
47 unsigned int i = 0;
49 a = LOAD64B(CU8(pt));
50 b = LOAD64B(CU8(pt) + 8);
52 while(i < s->rounds)
54 b ^= F(a) ^ s->k[i++];
56 if(i == s->rounds)
58 STORE64B(a, U8(ct) + 8);
59 STORE64B(b, U8(ct));
60 return;
63 a ^= F(b) ^ s->k[i++];
66 STORE64B(a, U8(ct));
67 STORE64B(b, U8(ct) + 8);
70 static void simon128_decrypt
72 const kripto_block *s,
73 const void *ct,
74 void *pt
77 uint64_t a;
78 uint64_t b;
79 unsigned int i = s->rounds;
81 a = LOAD64B(CU8(ct));
82 b = LOAD64B(CU8(ct) + 8);
84 while(i)
86 a ^= F(b) ^ s->k[--i];
88 if(!i)
90 STORE64B(a, U8(pt) + 8);
91 STORE64B(b, U8(pt));
92 return;
95 b ^= F(a) ^ s->k[--i];
98 STORE64B(a, U8(pt));
99 STORE64B(b, U8(pt) + 8);
102 static const uint64_t z[3] =
104 0x3369F885192C0EF5,
105 0x3C2CE51207A635DB,
106 0x3DC94C3A046D678B
109 static void simon128_setup
111 kripto_block *s,
112 const uint8_t *key,
113 unsigned int len
116 unsigned int i;
117 unsigned int m;
118 uint64_t t;
120 m = (len + 7) >> 3;
121 if(m < 2) m = 2;
123 for(i = 0; i < m; i++)
124 s->k[i] = 0;
126 for(i = 0; i < len; i++)
127 s->k[m - 1 - (i >> 3)] |=
128 (uint64_t)key[i] << (56 - ((i & 7) << 3));
130 for(i = m; i < s->rounds; i++)
132 t = ROR64_03(s->k[i - 1]);
133 if(m == 4) t ^= s->k[i - 3];
134 t ^= ROR64_01(t) ^ ~s->k[i - m] ^ 3;
135 s->k[i] = t ^ ((z[m - 2] >> ((i - m) % 62)) & 1);
138 kripto_memwipe(&t, sizeof(uint64_t));
141 static kripto_block *simon128_create
143 unsigned int r,
144 const void *key,
145 unsigned int key_len
148 kripto_block *s;
150 if(!r)
152 switch((key_len + 7) >> 3)
154 case 3: r = 69; break;
155 case 4: r = 72; break;
156 default: r = 68; break;
160 s = malloc(sizeof(kripto_block) + (r << 3));
161 if(!s) return 0;
163 s->obj.desc = kripto_block_simon128;
164 s->size = sizeof(kripto_block) + (r << 3);
165 s->k = (uint64_t *)(((uint8_t *)s) + sizeof(kripto_block));
166 s->rounds = r;
168 simon128_setup(s, key, key_len);
170 return s;
173 static void simon128_destroy(kripto_block *s)
175 kripto_memwipe(s, s->size);
176 free(s);
179 static kripto_block *simon128_recreate
181 kripto_block *s,
182 unsigned int r,
183 const void *key,
184 unsigned int key_len
187 if(!r)
189 switch((key_len + 7) >> 3)
191 case 3: r = 69; break;
192 case 4: r = 72; break;
193 default: r = 68; break;
197 if(sizeof(kripto_block) + (r << 3) > s->size)
199 simon128_destroy(s);
200 s = simon128_create(r, key, key_len);
202 else
204 s->rounds = r;
205 simon128_setup(s, key, key_len);
208 return s;
211 static const kripto_block_desc simon128 =
213 &simon128_create,
214 &simon128_recreate,
216 &simon128_encrypt,
217 &simon128_decrypt,
218 &simon128_destroy,
219 16, /* block size */
220 32 /* max key */
223 const kripto_block_desc *const kripto_block_simon128 = &simon128;