maxtweak added to block
[rofl0r-kripto.git] / lib / block / speck128.c
blob83528cc9bd338d9dd307cc4fd87b78c3fc0ce493
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/speck128.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 R(A, B, K) \
37 { \
38 A = (ROR64_08(A) + B) ^ (K); \
39 B = ROL64_03(B) ^ A; \
42 #define IR(A, B, K) \
43 { \
44 B = ROR64_03(B ^ A); \
45 A = ROL64_08((A ^ (K)) - B); \
48 static void speck128_encrypt
50 const kripto_block *s,
51 const void *pt,
52 void *ct
55 uint64_t a;
56 uint64_t b;
57 unsigned int i;
59 a = LOAD64B(CU8(pt));
60 b = LOAD64B(CU8(pt) + 8);
62 for(i = 0; i < s->rounds; i++)
63 R(a, b, s->k[i]);
65 STORE64B(a, U8(ct));
66 STORE64B(b, U8(ct) + 8);
69 static void speck128_decrypt
71 const kripto_block *s,
72 const void *ct,
73 void *pt
76 uint64_t a;
77 uint64_t b;
78 unsigned int i;
80 a = LOAD64B(CU8(ct));
81 b = LOAD64B(CU8(ct) + 8);
83 for(i = s->rounds; i--;)
84 IR(a, b, s->k[i]);
86 STORE64B(a, U8(pt));
87 STORE64B(b, U8(pt) + 8);
90 static void speck128_setup
92 kripto_block *s,
93 const uint8_t *key,
94 unsigned int len
97 unsigned int i;
98 unsigned int m;
99 uint64_t k[4] = {0, 0, 0, 0};
101 if(len > 24) m = 3;
102 else if(len > 16) m = 2;
103 else m = 1;
105 for(i = 0; i < len; i++)
106 k[m - (i >> 3)] |= (uint64_t)key[i] << (56 - ((i & 7) << 3));
108 s->k[0] = k[0];
110 for(i = 0; i < s->rounds - 1;)
112 R(k[(i % m) + 1], k[0], i);
113 s->k[++i] = k[0];
116 kripto_memwipe(k, 32);
119 static kripto_block *speck128_create
121 unsigned int r,
122 const void *key,
123 unsigned int key_len
126 kripto_block *s;
128 if(!r) r = 30 + ((key_len + 7) >> 3);
130 s = malloc(sizeof(kripto_block) + (r << 3));
131 if(!s) return 0;
133 s->obj.desc = kripto_block_speck128;
134 s->size = sizeof(kripto_block) + (r << 3);
135 s->k = (uint64_t *)(((uint8_t *)s) + sizeof(kripto_block));
136 s->rounds = r;
138 speck128_setup(s, key, key_len);
140 return s;
143 static void speck128_destroy(kripto_block *s)
145 kripto_memwipe(s, s->size);
146 free(s);
149 static kripto_block *speck128_recreate
151 kripto_block *s,
152 unsigned int r,
153 const void *key,
154 unsigned int key_len
157 if(!r) r = 30 + ((key_len + 7) >> 3);
159 if(sizeof(kripto_block) + (r << 3) > s->size)
161 speck128_destroy(s);
162 s = speck128_create(r, key, key_len);
164 else
166 s->rounds = r;
167 speck128_setup(s, key, key_len);
170 return s;
173 static const kripto_block_desc speck128 =
175 &speck128_create,
176 &speck128_recreate,
177 0, /* tweak */
178 &speck128_encrypt,
179 &speck128_decrypt,
180 &speck128_destroy,
181 16, /* block size */
182 32, /* max key */
183 0 /* max tweak */
186 const kripto_block_desc *const kripto_block_speck128 = &speck128;