23 #include "skinny64-cipher.h"
24 #include "skinny64-ctr-internal.h"
25 #include "skinny-internal.h"
28 #if SKINNY_VEC128_MATH
31 #define SKINNY64_CTR_BLOCK_SIZE (SKINNY64_BLOCK_SIZE * 8)
40 SkinnyVector8x16_t counter[4];
43 unsigned char ecounter[SKINNY64_CTR_BLOCK_SIZE];
51 } Skinny64CTRVec128Ctx_t;
55 Skinny64CTRVec128Ctx_t *ctx;
57 if ((ctx = skinny_calloc(
sizeof(Skinny64CTRVec128Ctx_t), &base_ptr)) == NULL)
59 ctx->base_ptr = base_ptr;
60 ctx->offset = SKINNY64_CTR_BLOCK_SIZE;
68 Skinny64CTRVec128Ctx_t *ctx = ctr->
ctx;
69 void *base_ptr = ctx->base_ptr;
70 skinny_cleanse(ctx,
sizeof(Skinny64CTRVec128Ctx_t));
76 static int skinny64_ctr_vec128_set_key(
Skinny64CTR_t *ctr,
const void *key,
unsigned size)
78 Skinny64CTRVec128Ctx_t *ctx;
92 ctx->offset = SKINNY64_CTR_BLOCK_SIZE;
96 static int skinny64_ctr_vec128_set_tweaked_key
99 Skinny64CTRVec128Ctx_t *ctx;
113 ctx->offset = SKINNY64_CTR_BLOCK_SIZE;
117 static int skinny64_ctr_vec128_set_tweak
120 Skinny64CTRVec128Ctx_t *ctx;
132 ctx->offset = SKINNY64_CTR_BLOCK_SIZE;
137 STATIC_INLINE
void skinny64_ctr_increment
138 (SkinnyVector8x16_t *counter,
unsigned column,
unsigned inc)
140 uint8_t *ctr = ((uint8_t *)counter) + column * 2;
143 for (index = 8; index > 0; ) {
145 ptr = ctr + (index & 0x06) * 8;
146 #if SKINNY_LITTLE_ENDIAN
149 ptr += 1 - (index & 0x01);
152 ptr[0] = (uint8_t)inc;
157 static int skinny64_ctr_vec128_set_counter
160 Skinny64CTRVec128Ctx_t *ctx;
177 ctx->offset = SKINNY64_CTR_BLOCK_SIZE;
180 ctx->counter[0] = skinny_to_vec8x16(READ_WORD16(block, 0));
181 ctx->counter[1] = skinny_to_vec8x16(READ_WORD16(block, 2));
182 ctx->counter[2] = skinny_to_vec8x16(READ_WORD16(block, 4));
183 ctx->counter[3] = skinny_to_vec8x16(READ_WORD16(block, 6));
186 skinny64_ctr_increment(ctx->counter, 1, 1);
187 skinny64_ctr_increment(ctx->counter, 2, 2);
188 skinny64_ctr_increment(ctx->counter, 3, 3);
189 skinny64_ctr_increment(ctx->counter, 4, 4);
190 skinny64_ctr_increment(ctx->counter, 5, 5);
191 skinny64_ctr_increment(ctx->counter, 6, 6);
192 skinny64_ctr_increment(ctx->counter, 7, 7);
195 skinny_cleanse(block,
sizeof(block));
199 STATIC_INLINE SkinnyVector8x16_t skinny64_rotate_right
200 (SkinnyVector8x16_t x,
unsigned count)
202 return (x >> count) | (x << (16 - count));
205 STATIC_INLINE SkinnyVector8x16_t skinny64_sbox(SkinnyVector8x16_t x)
207 SkinnyVector8x16_t bit0 = ~x;
208 SkinnyVector8x16_t bit1 = bit0 >> 1;
209 SkinnyVector8x16_t bit2 = bit0 >> 2;
210 SkinnyVector8x16_t bit3 = bit0 >> 3;
215 x = ((bit0 << 3) & 0x8888U) |
217 ((bit2 << 1) & 0x2222U) |
218 ((bit3 << 2) & 0x4444U);
222 static void skinny64_ecb_encrypt_eight
223 (
void *output,
const SkinnyVector8x16_t *input,
const Skinny64Key_t *ks)
225 SkinnyVector8x16_t row0;
226 SkinnyVector8x16_t row1;
227 SkinnyVector8x16_t row2;
228 SkinnyVector8x16_t row3;
231 SkinnyVector8x16_t temp;
241 for (index = ks->
rounds; index > 0; --index, ++schedule) {
243 row0 = skinny64_sbox(row0);
244 row1 = skinny64_sbox(row1);
245 row2 = skinny64_sbox(row2);
246 row3 = skinny64_sbox(row3);
249 row0 ^= schedule->
row[0];
250 row1 ^= schedule->
row[1];
254 row1 = skinny64_rotate_right(row1, 4);
255 row2 = skinny64_rotate_right(row2, 8);
256 row3 = skinny64_rotate_right(row3, 12);
273 *((SkinnyVector8x16U_t *)output) =
274 (SkinnyVector8x16_t){row0[0], row1[0], row2[0], row3[0],
275 row0[1], row1[1], row2[1], row3[1]};
276 *((SkinnyVector8x16U_t *)(output + 16)) =
277 (SkinnyVector8x16_t){row0[2], row1[2], row2[2], row3[2],
278 row0[3], row1[3], row2[3], row3[3]};
279 *((SkinnyVector8x16U_t *)(output + 32)) =
280 (SkinnyVector8x16_t){row0[4], row1[4], row2[4], row3[4],
281 row0[5], row1[5], row2[5], row3[5]};
282 *((SkinnyVector8x16U_t *)(output + 48)) =
283 (SkinnyVector8x16_t){row0[6], row1[6], row2[6], row3[6],
284 row0[7], row1[7], row2[7], row3[7]};
286 WRITE_WORD16(output, 0, row0[0]);
287 WRITE_WORD16(output, 2, row1[0]);
288 WRITE_WORD16(output, 4, row2[0]);
289 WRITE_WORD16(output, 6, row3[0]);
290 WRITE_WORD16(output, 8, row0[1]);
291 WRITE_WORD16(output, 10, row1[1]);
292 WRITE_WORD16(output, 12, row2[1]);
293 WRITE_WORD16(output, 14, row3[1]);
294 WRITE_WORD16(output, 16, row0[2]);
295 WRITE_WORD16(output, 18, row1[2]);
296 WRITE_WORD16(output, 20, row2[2]);
297 WRITE_WORD16(output, 22, row3[2]);
298 WRITE_WORD16(output, 24, row0[3]);
299 WRITE_WORD16(output, 26, row1[3]);
300 WRITE_WORD16(output, 28, row2[3]);
301 WRITE_WORD16(output, 30, row3[3]);
302 WRITE_WORD16(output, 32, row0[4]);
303 WRITE_WORD16(output, 34, row1[4]);
304 WRITE_WORD16(output, 36, row2[4]);
305 WRITE_WORD16(output, 38, row3[4]);
306 WRITE_WORD16(output, 40, row0[5]);
307 WRITE_WORD16(output, 42, row1[5]);
308 WRITE_WORD16(output, 44, row2[5]);
309 WRITE_WORD16(output, 46, row3[5]);
310 WRITE_WORD16(output, 48, row0[6]);
311 WRITE_WORD16(output, 50, row1[6]);
312 WRITE_WORD16(output, 52, row2[6]);
313 WRITE_WORD16(output, 54, row3[6]);
314 WRITE_WORD16(output, 56, row0[7]);
315 WRITE_WORD16(output, 58, row1[7]);
316 WRITE_WORD16(output, 60, row2[7]);
317 WRITE_WORD16(output, 62, row3[7]);
321 static int skinny64_ctr_vec128_encrypt
322 (
void *output,
const void *input,
size_t size,
Skinny64CTR_t *ctr)
324 Skinny64CTRVec128Ctx_t *ctx;
325 uint8_t *out = (uint8_t *)output;
326 const uint8_t *in = (
const uint8_t *)input;
329 if (!output || !input)
337 if (ctx->offset >= SKINNY64_CTR_BLOCK_SIZE) {
339 skinny64_ecb_encrypt_eight
340 (ctx->ecounter, ctx->counter, &(ctx->kt.ks));
341 skinny64_ctr_increment(ctx->counter, 0, 8);
342 skinny64_ctr_increment(ctx->counter, 1, 8);
343 skinny64_ctr_increment(ctx->counter, 2, 8);
344 skinny64_ctr_increment(ctx->counter, 3, 8);
345 skinny64_ctr_increment(ctx->counter, 4, 8);
346 skinny64_ctr_increment(ctx->counter, 5, 8);
347 skinny64_ctr_increment(ctx->counter, 6, 8);
348 skinny64_ctr_increment(ctx->counter, 7, 8);
351 if (size >= SKINNY64_CTR_BLOCK_SIZE) {
352 skinny64_xor(out, in, ctx->ecounter);
374 out += SKINNY64_CTR_BLOCK_SIZE;
375 in += SKINNY64_CTR_BLOCK_SIZE;
376 size -= SKINNY64_CTR_BLOCK_SIZE;
379 skinny_xor(out, in, ctx->ecounter, size);
385 size_t temp = SKINNY64_CTR_BLOCK_SIZE - ctx->offset;
388 skinny_xor(out, in, ctx->ecounter + ctx->offset, temp);
399 Skinny64CTRVtable_t
const _skinny64_ctr_vec128 = {
400 skinny64_ctr_vec128_init,
401 skinny64_ctr_vec128_cleanup,
402 skinny64_ctr_vec128_set_key,
403 skinny64_ctr_vec128_set_tweaked_key,
404 skinny64_ctr_vec128_set_tweak,
405 skinny64_ctr_vec128_set_counter,
406 skinny64_ctr_vec128_encrypt
412 Skinny64CTRVtable_t
const _skinny64_ctr_vec128;
int skinny64_set_tweak(Skinny64TweakedKey_t *ks, const void *tweak, unsigned tweak_size)
Changes the tweak value for a previously-initialized key schedule.
int skinny64_set_key(Skinny64Key_t *ks, const void *key, unsigned size)
Sets the key schedule for a Skinny64 block cipher.
int skinny64_set_tweaked_key(Skinny64TweakedKey_t *ks, const void *key, unsigned key_size)
Sets the key schedule for a Skinny64 block cipher, and prepare for tweaked encryption.
Key schedule for Skinny64 block ciphers when a tweak is in use.
Skinny64HalfCells_t schedule[SKINNY64_MAX_ROUNDS]
Key schedule for Skinny64 block ciphers.
Union that describes a 32-bit 2x4 array of cells.
#define SKINNY64_BLOCK_SIZE
Size of a block for Skinny64 block ciphers.
State information for Skinny-64 in CTR mode.