23 #include "skinny128-cipher.h"
24 #include "skinny128-ctr-internal.h"
25 #include "skinny-internal.h"
28 #if SKINNY_VEC256_MATH
31 #define SKINNY128_CTR_BLOCK_SIZE (SKINNY128_BLOCK_SIZE * 8)
40 SkinnyVector8x32_t counter[4];
43 unsigned char ecounter[SKINNY128_CTR_BLOCK_SIZE];
51 } Skinny128CTRVec256Ctx_t;
55 Skinny128CTRVec256Ctx_t *ctx;
57 if ((ctx = skinny_calloc(
sizeof(Skinny128CTRVec256Ctx_t), &base_ptr)) == NULL)
59 ctx->base_ptr = base_ptr;
60 ctx->offset = SKINNY128_CTR_BLOCK_SIZE;
68 Skinny128CTRVec256Ctx_t *ctx = ctr->
ctx;
69 void *base_ptr = ctx->base_ptr;
70 skinny_cleanse(ctx,
sizeof(Skinny128CTRVec256Ctx_t));
76 static int skinny128_ctr_vec256_set_key
79 Skinny128CTRVec256Ctx_t *ctx;
93 ctx->offset = SKINNY128_CTR_BLOCK_SIZE;
97 static int skinny128_ctr_vec256_set_tweaked_key
100 Skinny128CTRVec256Ctx_t *ctx;
114 ctx->offset = SKINNY128_CTR_BLOCK_SIZE;
118 static int skinny128_ctr_vec256_set_tweak
121 Skinny128CTRVec256Ctx_t *ctx;
133 ctx->offset = SKINNY128_CTR_BLOCK_SIZE;
138 STATIC_INLINE
void skinny128_ctr_increment
139 (SkinnyVector8x32_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) * 8;
147 #if SKINNY_LITTLE_ENDIAN
150 ptr += 3 - (index & 0x03);
153 ptr[0] = (uint8_t)inc;
158 static int skinny128_ctr_vec256_set_counter
161 Skinny128CTRVec256Ctx_t *ctx;
178 ctx->offset = SKINNY128_CTR_BLOCK_SIZE;
181 ctx->counter[0] = skinny_to_vec8x32(READ_WORD32(block, 0));
182 ctx->counter[1] = skinny_to_vec8x32(READ_WORD32(block, 4));
183 ctx->counter[2] = skinny_to_vec8x32(READ_WORD32(block, 8));
184 ctx->counter[3] = skinny_to_vec8x32(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);
190 skinny128_ctr_increment(ctx->counter, 4, 4);
191 skinny128_ctr_increment(ctx->counter, 5, 5);
192 skinny128_ctr_increment(ctx->counter, 6, 6);
193 skinny128_ctr_increment(ctx->counter, 7, 7);
196 skinny_cleanse(block,
sizeof(block));
200 STATIC_INLINE SkinnyVector8x32_t skinny128_rotate_right
201 (SkinnyVector8x32_t x,
unsigned count)
206 return (x << count) | (x >> (32 - count));
213 STATIC_INLINE
void skinny128_sbox_four
214 (SkinnyVector8x32_t *u, SkinnyVector8x32_t *v,
215 SkinnyVector8x32_t *s, SkinnyVector8x32_t *t)
217 SkinnyVector8x32_t x1 = *u;
218 SkinnyVector8x32_t y1;
219 SkinnyVector8x32_t x2 = *v;
220 SkinnyVector8x32_t y2;
221 SkinnyVector8x32_t x3 = *s;
222 SkinnyVector8x32_t y3;
223 SkinnyVector8x32_t x4 = *t;
224 SkinnyVector8x32_t y4;
226 x1 ^= ((~((x1 >> 2) | (x1 >> 3))) & 0x11111111U);
227 x2 ^= ((~((x2 >> 2) | (x2 >> 3))) & 0x11111111U);
228 x3 ^= ((~((x3 >> 2) | (x3 >> 3))) & 0x11111111U);
229 x4 ^= ((~((x4 >> 2) | (x4 >> 3))) & 0x11111111U);
231 y1 = ((~((x1 << 5) | (x1 << 1))) & 0x20202020U);
232 y2 = ((~((x2 << 5) | (x2 << 1))) & 0x20202020U);
233 y3 = ((~((x3 << 5) | (x3 << 1))) & 0x20202020U);
234 y4 = ((~((x4 << 5) | (x4 << 1))) & 0x20202020U);
236 x1 ^= ((~((x1 << 5) | (x1 << 4))) & 0x40404040U) ^ y1;
237 x2 ^= ((~((x2 << 5) | (x2 << 4))) & 0x40404040U) ^ y2;
238 x3 ^= ((~((x3 << 5) | (x3 << 4))) & 0x40404040U) ^ y3;
239 x4 ^= ((~((x4 << 5) | (x4 << 4))) & 0x40404040U) ^ y4;
241 y1 = ((~((x1 << 2) | (x1 << 1))) & 0x80808080U);
242 y2 = ((~((x2 << 2) | (x2 << 1))) & 0x80808080U);
243 y3 = ((~((x3 << 2) | (x3 << 1))) & 0x80808080U);
244 y4 = ((~((x4 << 2) | (x4 << 1))) & 0x80808080U);
246 x1 ^= ((~((x1 >> 2) | (x1 << 1))) & 0x02020202U) ^ y1;
247 x2 ^= ((~((x2 >> 2) | (x2 << 1))) & 0x02020202U) ^ y2;
248 x3 ^= ((~((x3 >> 2) | (x3 << 1))) & 0x02020202U) ^ y3;
249 x4 ^= ((~((x4 >> 2) | (x4 << 1))) & 0x02020202U) ^ y4;
251 y1 = ((~((x1 >> 5) | (x1 << 1))) & 0x04040404U);
252 y2 = ((~((x2 >> 5) | (x2 << 1))) & 0x04040404U);
253 y3 = ((~((x3 >> 5) | (x3 << 1))) & 0x04040404U);
254 y4 = ((~((x4 >> 5) | (x4 << 1))) & 0x04040404U);
256 x1 ^= ((~((x1 >> 1) | (x1 >> 2))) & 0x08080808U) ^ y1;
257 x2 ^= ((~((x2 >> 1) | (x2 >> 2))) & 0x08080808U) ^ y2;
258 x3 ^= ((~((x3 >> 1) | (x3 >> 2))) & 0x08080808U) ^ y3;
259 x4 ^= ((~((x4 >> 1) | (x4 >> 2))) & 0x08080808U) ^ y4;
261 *u = ((x1 & 0x08080808U) << 1) |
262 ((x1 & 0x32323232U) << 2) |
263 ((x1 & 0x01010101U) << 5) |
264 ((x1 & 0x80808080U) >> 6) |
265 ((x1 & 0x40404040U) >> 4) |
266 ((x1 & 0x04040404U) >> 2);
268 *v = ((x2 & 0x08080808U) << 1) |
269 ((x2 & 0x32323232U) << 2) |
270 ((x2 & 0x01010101U) << 5) |
271 ((x2 & 0x80808080U) >> 6) |
272 ((x2 & 0x40404040U) >> 4) |
273 ((x2 & 0x04040404U) >> 2);
275 *s = ((x3 & 0x08080808U) << 1) |
276 ((x3 & 0x32323232U) << 2) |
277 ((x3 & 0x01010101U) << 5) |
278 ((x3 & 0x80808080U) >> 6) |
279 ((x3 & 0x40404040U) >> 4) |
280 ((x3 & 0x04040404U) >> 2);
282 *t = ((x4 & 0x08080808U) << 1) |
283 ((x4 & 0x32323232U) << 2) |
284 ((x4 & 0x01010101U) << 5) |
285 ((x4 & 0x80808080U) >> 6) |
286 ((x4 & 0x40404040U) >> 4) |
287 ((x4 & 0x04040404U) >> 2);
290 static void skinny128_ecb_encrypt_eight
291 (
void *output,
const SkinnyVector8x32_t *input,
const Skinny128Key_t *ks)
293 SkinnyVector8x32_t row0;
294 SkinnyVector8x32_t row1;
295 SkinnyVector8x32_t row2;
296 SkinnyVector8x32_t row3;
299 SkinnyVector8x32_t temp;
309 for (index = ks->
rounds; index > 0; --index, ++schedule) {
311 skinny128_sbox_four(&row0, &row1, &row2, &row3);
314 row0 ^= schedule->
row[0];
315 row1 ^= schedule->
row[1];
319 row1 = skinny128_rotate_right(row1, 8);
320 row2 = skinny128_rotate_right(row2, 16);
321 row3 = skinny128_rotate_right(row3, 24);
334 #if SKINNY_LITTLE_ENDIAN && SKINNY_UNALIGNED
335 *((SkinnyVector8x32U_t *)output) =
336 (SkinnyVector8x32_t){row0[0], row1[0], row2[0], row3[0],
337 row0[1], row1[1], row2[1], row3[1]};
338 *((SkinnyVector8x32U_t *)(output + 32)) =
339 (SkinnyVector8x32_t){row0[2], row1[2], row2[2], row3[2],
340 row0[3], row1[3], row2[3], row3[3]};
341 *((SkinnyVector8x32U_t *)(output + 64)) =
342 (SkinnyVector8x32_t){row0[4], row1[4], row2[4], row3[4],
343 row0[5], row1[5], row2[5], row3[5]};
344 *((SkinnyVector8x32U_t *)(output + 96)) =
345 (SkinnyVector8x32_t){row0[6], row1[6], row2[6], row3[6],
346 row0[7], row1[7], row2[7], row3[7]};
348 WRITE_WORD32(output, 0, row0[0]);
349 WRITE_WORD32(output, 4, row1[0]);
350 WRITE_WORD32(output, 8, row2[0]);
351 WRITE_WORD32(output, 12, row3[0]);
352 WRITE_WORD32(output, 16, row0[1]);
353 WRITE_WORD32(output, 20, row1[1]);
354 WRITE_WORD32(output, 24, row2[1]);
355 WRITE_WORD32(output, 28, row3[1]);
356 WRITE_WORD32(output, 32, row0[2]);
357 WRITE_WORD32(output, 36, row1[2]);
358 WRITE_WORD32(output, 40, row2[2]);
359 WRITE_WORD32(output, 44, row3[2]);
360 WRITE_WORD32(output, 48, row0[3]);
361 WRITE_WORD32(output, 52, row1[3]);
362 WRITE_WORD32(output, 56, row2[3]);
363 WRITE_WORD32(output, 60, row3[3]);
364 WRITE_WORD32(output, 64, row0[4]);
365 WRITE_WORD32(output, 68, row1[4]);
366 WRITE_WORD32(output, 72, row2[4]);
367 WRITE_WORD32(output, 76, row3[4]);
368 WRITE_WORD32(output, 80, row0[5]);
369 WRITE_WORD32(output, 84, row1[5]);
370 WRITE_WORD32(output, 88, row2[5]);
371 WRITE_WORD32(output, 92, row3[5]);
372 WRITE_WORD32(output, 96, row0[6]);
373 WRITE_WORD32(output, 100, row1[6]);
374 WRITE_WORD32(output, 104, row2[6]);
375 WRITE_WORD32(output, 108, row3[6]);
376 WRITE_WORD32(output, 112, row0[7]);
377 WRITE_WORD32(output, 116, row1[7]);
378 WRITE_WORD32(output, 120, row2[7]);
379 WRITE_WORD32(output, 124, row3[7]);
383 static int skinny128_ctr_vec256_encrypt
384 (
void *output,
const void *input,
size_t size,
Skinny128CTR_t *ctr)
386 Skinny128CTRVec256Ctx_t *ctx;
387 uint8_t *out = (uint8_t *)output;
388 const uint8_t *in = (
const uint8_t *)input;
391 if (!output || !input)
399 if (ctx->offset >= SKINNY128_CTR_BLOCK_SIZE) {
401 skinny128_ecb_encrypt_eight
402 (ctx->ecounter, ctx->counter, &(ctx->kt.ks));
403 skinny128_ctr_increment(ctx->counter, 0, 8);
404 skinny128_ctr_increment(ctx->counter, 1, 8);
405 skinny128_ctr_increment(ctx->counter, 2, 8);
406 skinny128_ctr_increment(ctx->counter, 3, 8);
407 skinny128_ctr_increment(ctx->counter, 4, 8);
408 skinny128_ctr_increment(ctx->counter, 5, 8);
409 skinny128_ctr_increment(ctx->counter, 6, 8);
410 skinny128_ctr_increment(ctx->counter, 7, 8);
413 if (size >= SKINNY128_CTR_BLOCK_SIZE) {
414 skinny128_xor(out, in, ctx->ecounter);
436 out += SKINNY128_CTR_BLOCK_SIZE;
437 in += SKINNY128_CTR_BLOCK_SIZE;
438 size -= SKINNY128_CTR_BLOCK_SIZE;
441 skinny_xor(out, in, ctx->ecounter, size);
447 size_t temp = SKINNY128_CTR_BLOCK_SIZE - ctx->offset;
450 skinny_xor(out, in, ctx->ecounter + ctx->offset, temp);
461 Skinny128CTRVtable_t
const _skinny128_ctr_vec256 = {
462 skinny128_ctr_vec256_init,
463 skinny128_ctr_vec256_cleanup,
464 skinny128_ctr_vec256_set_key,
465 skinny128_ctr_vec256_set_tweaked_key,
466 skinny128_ctr_vec256_set_tweak,
467 skinny128_ctr_vec256_set_counter,
468 skinny128_ctr_vec256_encrypt
474 Skinny128CTRVtable_t
const _skinny128_ctr_vec256;
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.