23 #include "skinny128-cipher.h"
24 #include "skinny128-ctr-internal.h"
25 #include "skinny-internal.h"
28 #if SKINNY_VEC128_MATH
31 #define SKINNY128_CTR_BLOCK_SIZE (SKINNY128_BLOCK_SIZE * 4)
40 SkinnyVector4x32_t counter[4];
43 unsigned char ecounter[SKINNY128_CTR_BLOCK_SIZE];
51 } Skinny128CTRVec128Ctx_t;
55 Skinny128CTRVec128Ctx_t *ctx;
57 if ((ctx = skinny_calloc(
sizeof(Skinny128CTRVec128Ctx_t), &base_ptr)) == NULL)
59 ctx->base_ptr = base_ptr;
60 ctx->offset = SKINNY128_CTR_BLOCK_SIZE;
68 Skinny128CTRVec128Ctx_t *ctx = ctr->
ctx;
69 void *base_ptr = ctx->base_ptr;
70 skinny_cleanse(ctx,
sizeof(Skinny128CTRVec128Ctx_t));
76 static int skinny128_ctr_vec128_set_key
79 Skinny128CTRVec128Ctx_t *ctx;
93 ctx->offset = SKINNY128_CTR_BLOCK_SIZE;
97 static int skinny128_ctr_vec128_set_tweaked_key
100 Skinny128CTRVec128Ctx_t *ctx;
114 ctx->offset = SKINNY128_CTR_BLOCK_SIZE;
118 static int skinny128_ctr_vec128_set_tweak
121 Skinny128CTRVec128Ctx_t *ctx;
133 ctx->offset = SKINNY128_CTR_BLOCK_SIZE;
138 STATIC_INLINE
void skinny128_ctr_increment
139 (SkinnyVector4x32_t *counter,
unsigned column,
unsigned inc)
141 uint8_t *ctr = ((uint8_t *)counter) + column * 4;
144 for (index = 16; index > 0; ) {
146 ptr = ctr + (index & 0x0C) * 4;
147 #if SKINNY_LITTLE_ENDIAN
150 ptr += 3 - (index & 0x03);
153 ptr[0] = (uint8_t)inc;
158 static int skinny128_ctr_vec128_set_counter
161 Skinny128CTRVec128Ctx_t *ctx;
178 ctx->offset = SKINNY128_CTR_BLOCK_SIZE;
181 ctx->counter[0] = skinny_to_vec4x32(READ_WORD32(block, 0));
182 ctx->counter[1] = skinny_to_vec4x32(READ_WORD32(block, 4));
183 ctx->counter[2] = skinny_to_vec4x32(READ_WORD32(block, 8));
184 ctx->counter[3] = skinny_to_vec4x32(READ_WORD32(block, 12));
187 skinny128_ctr_increment(ctx->counter, 1, 1);
188 skinny128_ctr_increment(ctx->counter, 2, 2);
189 skinny128_ctr_increment(ctx->counter, 3, 3);
192 skinny_cleanse(block,
sizeof(block));
196 STATIC_INLINE SkinnyVector4x32_t skinny128_rotate_right
197 (SkinnyVector4x32_t x,
unsigned count)
202 return (x << count) | (x >> (32 - count));
211 STATIC_INLINE
void skinny128_sbox_four
212 (SkinnyVector4x32_t *u, SkinnyVector4x32_t *v,
213 SkinnyVector4x32_t *s, SkinnyVector4x32_t *t)
215 SkinnyVector4x32_t x1 = *u;
216 SkinnyVector4x32_t y1;
217 SkinnyVector4x32_t x2 = *v;
218 SkinnyVector4x32_t y2;
219 SkinnyVector4x32_t x3 = *s;
220 SkinnyVector4x32_t y3;
221 SkinnyVector4x32_t x4 = *t;
222 SkinnyVector4x32_t y4;
224 x1 ^= ((~((x1 >> 2) | (x1 >> 3))) & 0x11111111U);
225 x2 ^= ((~((x2 >> 2) | (x2 >> 3))) & 0x11111111U);
226 x3 ^= ((~((x3 >> 2) | (x3 >> 3))) & 0x11111111U);
227 x4 ^= ((~((x4 >> 2) | (x4 >> 3))) & 0x11111111U);
229 y1 = ((~((x1 << 5) | (x1 << 1))) & 0x20202020U);
230 y2 = ((~((x2 << 5) | (x2 << 1))) & 0x20202020U);
231 y3 = ((~((x3 << 5) | (x3 << 1))) & 0x20202020U);
232 y4 = ((~((x4 << 5) | (x4 << 1))) & 0x20202020U);
234 x1 ^= ((~((x1 << 5) | (x1 << 4))) & 0x40404040U) ^ y1;
235 x2 ^= ((~((x2 << 5) | (x2 << 4))) & 0x40404040U) ^ y2;
236 x3 ^= ((~((x3 << 5) | (x3 << 4))) & 0x40404040U) ^ y3;
237 x4 ^= ((~((x4 << 5) | (x4 << 4))) & 0x40404040U) ^ y4;
239 y1 = ((~((x1 << 2) | (x1 << 1))) & 0x80808080U);
240 y2 = ((~((x2 << 2) | (x2 << 1))) & 0x80808080U);
241 y3 = ((~((x3 << 2) | (x3 << 1))) & 0x80808080U);
242 y4 = ((~((x4 << 2) | (x4 << 1))) & 0x80808080U);
244 x1 ^= ((~((x1 >> 2) | (x1 << 1))) & 0x02020202U) ^ y1;
245 x2 ^= ((~((x2 >> 2) | (x2 << 1))) & 0x02020202U) ^ y2;
246 x3 ^= ((~((x3 >> 2) | (x3 << 1))) & 0x02020202U) ^ y3;
247 x4 ^= ((~((x4 >> 2) | (x4 << 1))) & 0x02020202U) ^ y4;
249 y1 = ((~((x1 >> 5) | (x1 << 1))) & 0x04040404U);
250 y2 = ((~((x2 >> 5) | (x2 << 1))) & 0x04040404U);
251 y3 = ((~((x3 >> 5) | (x3 << 1))) & 0x04040404U);
252 y4 = ((~((x4 >> 5) | (x4 << 1))) & 0x04040404U);
254 x1 ^= ((~((x1 >> 1) | (x1 >> 2))) & 0x08080808U) ^ y1;
255 x2 ^= ((~((x2 >> 1) | (x2 >> 2))) & 0x08080808U) ^ y2;
256 x3 ^= ((~((x3 >> 1) | (x3 >> 2))) & 0x08080808U) ^ y3;
257 x4 ^= ((~((x4 >> 1) | (x4 >> 2))) & 0x08080808U) ^ y4;
259 *u = ((x1 & 0x08080808U) << 1) |
260 ((x1 & 0x32323232U) << 2) |
261 ((x1 & 0x01010101U) << 5) |
262 ((x1 & 0x80808080U) >> 6) |
263 ((x1 & 0x40404040U) >> 4) |
264 ((x1 & 0x04040404U) >> 2);
266 *v = ((x2 & 0x08080808U) << 1) |
267 ((x2 & 0x32323232U) << 2) |
268 ((x2 & 0x01010101U) << 5) |
269 ((x2 & 0x80808080U) >> 6) |
270 ((x2 & 0x40404040U) >> 4) |
271 ((x2 & 0x04040404U) >> 2);
273 *s = ((x3 & 0x08080808U) << 1) |
274 ((x3 & 0x32323232U) << 2) |
275 ((x3 & 0x01010101U) << 5) |
276 ((x3 & 0x80808080U) >> 6) |
277 ((x3 & 0x40404040U) >> 4) |
278 ((x3 & 0x04040404U) >> 2);
280 *t = ((x4 & 0x08080808U) << 1) |
281 ((x4 & 0x32323232U) << 2) |
282 ((x4 & 0x01010101U) << 5) |
283 ((x4 & 0x80808080U) >> 6) |
284 ((x4 & 0x40404040U) >> 4) |
285 ((x4 & 0x04040404U) >> 2);
294 STATIC_INLINE
void skinny128_sbox_two
295 (SkinnyVector4x32_t *u, SkinnyVector4x32_t *v)
297 SkinnyVector4x32_t x1 = *u;
298 SkinnyVector4x32_t y1;
299 SkinnyVector4x32_t x2 = *v;
300 SkinnyVector4x32_t y2;
302 x1 ^= ((~((x1 >> 2) | (x1 >> 3))) & 0x11111111U);
303 x2 ^= ((~((x2 >> 2) | (x2 >> 3))) & 0x11111111U);
305 y1 = ((~((x1 << 5) | (x1 << 1))) & 0x20202020U);
306 y2 = ((~((x2 << 5) | (x2 << 1))) & 0x20202020U);
308 x1 ^= ((~((x1 << 5) | (x1 << 4))) & 0x40404040U) ^ y1;
309 x2 ^= ((~((x2 << 5) | (x2 << 4))) & 0x40404040U) ^ y2;
311 y1 = ((~((x1 << 2) | (x1 << 1))) & 0x80808080U);
312 y2 = ((~((x2 << 2) | (x2 << 1))) & 0x80808080U);
314 x1 ^= ((~((x1 >> 2) | (x1 << 1))) & 0x02020202U) ^ y1;
315 x2 ^= ((~((x2 >> 2) | (x2 << 1))) & 0x02020202U) ^ y2;
317 y1 = ((~((x1 >> 5) | (x1 << 1))) & 0x04040404U);
318 y2 = ((~((x2 >> 5) | (x2 << 1))) & 0x04040404U);
320 x1 ^= ((~((x1 >> 1) | (x1 >> 2))) & 0x08080808U) ^ y1;
321 x2 ^= ((~((x2 >> 1) | (x2 >> 2))) & 0x08080808U) ^ y2;
323 *u = ((x1 & 0x08080808U) << 1) |
324 ((x1 & 0x32323232U) << 2) |
325 ((x1 & 0x01010101U) << 5) |
326 ((x1 & 0x80808080U) >> 6) |
327 ((x1 & 0x40404040U) >> 4) |
328 ((x1 & 0x04040404U) >> 2);
330 *v = ((x2 & 0x08080808U) << 1) |
331 ((x2 & 0x32323232U) << 2) |
332 ((x2 & 0x01010101U) << 5) |
333 ((x2 & 0x80808080U) >> 6) |
334 ((x2 & 0x40404040U) >> 4) |
335 ((x2 & 0x04040404U) >> 2);
340 static void skinny128_ecb_encrypt_four
341 (
void *output,
const SkinnyVector4x32_t *input,
const Skinny128Key_t *ks)
343 SkinnyVector4x32_t row0;
344 SkinnyVector4x32_t row1;
345 SkinnyVector4x32_t row2;
346 SkinnyVector4x32_t row3;
349 SkinnyVector4x32_t temp;
359 for (index = ks->
rounds; index > 0; --index, ++schedule) {
362 skinny128_sbox_four(&row0, &row1, &row2, &row3);
364 skinny128_sbox_two(&row0, &row1);
365 skinny128_sbox_two(&row2, &row3);
369 row0 ^= schedule->
row[0];
370 row1 ^= schedule->
row[1];
374 row1 = skinny128_rotate_right(row1, 8);
375 row2 = skinny128_rotate_right(row2, 16);
376 row3 = skinny128_rotate_right(row3, 24);
389 #if SKINNY_LITTLE_ENDIAN && SKINNY_UNALIGNED
390 *((SkinnyVector4x32U_t *)output) =
391 (SkinnyVector4x32_t){row0[0], row1[0], row2[0], row3[0]};
392 *((SkinnyVector4x32U_t *)(output + 16)) =
393 (SkinnyVector4x32_t){row0[1], row1[1], row2[1], row3[1]};
394 *((SkinnyVector4x32U_t *)(output + 32)) =
395 (SkinnyVector4x32_t){row0[2], row1[2], row2[2], row3[2]};
396 *((SkinnyVector4x32U_t *)(output + 48)) =
397 (SkinnyVector4x32_t){row0[3], row1[3], row2[3], row3[3]};
399 WRITE_WORD32(output, 0, row0[0]);
400 WRITE_WORD32(output, 4, row1[0]);
401 WRITE_WORD32(output, 8, row2[0]);
402 WRITE_WORD32(output, 12, row3[0]);
403 WRITE_WORD32(output, 16, row0[1]);
404 WRITE_WORD32(output, 20, row1[1]);
405 WRITE_WORD32(output, 24, row2[1]);
406 WRITE_WORD32(output, 28, row3[1]);
407 WRITE_WORD32(output, 32, row0[2]);
408 WRITE_WORD32(output, 36, row1[2]);
409 WRITE_WORD32(output, 40, row2[2]);
410 WRITE_WORD32(output, 44, row3[2]);
411 WRITE_WORD32(output, 48, row0[3]);
412 WRITE_WORD32(output, 52, row1[3]);
413 WRITE_WORD32(output, 56, row2[3]);
414 WRITE_WORD32(output, 60, row3[3]);
418 static int skinny128_ctr_vec128_encrypt
419 (
void *output,
const void *input,
size_t size,
Skinny128CTR_t *ctr)
421 Skinny128CTRVec128Ctx_t *ctx;
422 uint8_t *out = (uint8_t *)output;
423 const uint8_t *in = (
const uint8_t *)input;
426 if (!output || !input)
434 if (ctx->offset >= SKINNY128_CTR_BLOCK_SIZE) {
436 skinny128_ecb_encrypt_four
437 (ctx->ecounter, ctx->counter, &(ctx->kt.ks));
438 skinny128_ctr_increment(ctx->counter, 0, 4);
439 skinny128_ctr_increment(ctx->counter, 1, 4);
440 skinny128_ctr_increment(ctx->counter, 2, 4);
441 skinny128_ctr_increment(ctx->counter, 3, 4);
444 if (size >= SKINNY128_CTR_BLOCK_SIZE) {
445 skinny128_xor(out, in, ctx->ecounter);
455 out += SKINNY128_CTR_BLOCK_SIZE;
456 in += SKINNY128_CTR_BLOCK_SIZE;
457 size -= SKINNY128_CTR_BLOCK_SIZE;
460 skinny_xor(out, in, ctx->ecounter, size);
466 size_t temp = SKINNY128_CTR_BLOCK_SIZE - ctx->offset;
469 skinny_xor(out, in, ctx->ecounter + ctx->offset, temp);
480 Skinny128CTRVtable_t
const _skinny128_ctr_vec128 = {
481 skinny128_ctr_vec128_init,
482 skinny128_ctr_vec128_cleanup,
483 skinny128_ctr_vec128_set_key,
484 skinny128_ctr_vec128_set_tweaked_key,
485 skinny128_ctr_vec128_set_tweak,
486 skinny128_ctr_vec128_set_counter,
487 skinny128_ctr_vec128_encrypt
493 Skinny128CTRVtable_t
const _skinny128_ctr_vec128;
Union that describes a 64-bit 2x4 array of cells.
Skinny128HalfCells_t schedule[SKINNY128_MAX_ROUNDS]
State information for Skinny-128 in CTR mode.
Key schedule for Skinny128 block ciphers when a tweak is in use.
int skinny128_set_tweaked_key(Skinny128TweakedKey_t *ks, const void *key, unsigned key_size)
Sets the key schedule for a Skinny128 block cipher, and prepare for tweaked encryption.
Key schedule for Skinny128 block ciphers.
int skinny128_set_key(Skinny128Key_t *ks, const void *key, unsigned size)
Sets the key schedule for a Skinny128 block cipher.
#define SKINNY128_BLOCK_SIZE
Size of a block for Skinny128 block ciphers.
int skinny128_set_tweak(Skinny128TweakedKey_t *ks, const void *tweak, unsigned tweak_size)
Changes the tweak value for a previously-initialized key schedule.