void Encrypt(uint8_t *block, uint8_t *keyBytes) { uint32_t *v = (uint32_t *)block; uint32_t *k = (uint32_t *)keyBytes; uint8_t i; /* Whitening */ v[0] ^= READ_ROUND_KEY_DOUBLE_WORD(k[0]); v[1] ^= READ_ROUND_KEY_DOUBLE_WORD(k[1]); v[2] ^= READ_ROUND_KEY_DOUBLE_WORD(k[2]); v[3] ^= READ_ROUND_KEY_DOUBLE_WORD(k[3]); /* Chaskey permutation */ for (i = 0; i < NUMBER_OF_ROUNDS; ++i) { v[0] += v[1]; v[1]=rot32l5(v[1]); v[1] ^= v[0]; v[0]=rot32l16(v[0]); v[2] += v[3]; v[3]=rot32l8(v[3]); v[3] ^= v[2]; v[0] += v[3]; v[3]=rot32l13(v[3]); v[3] ^= v[0]; v[2] += v[1]; v[1]=rot32l7(v[1]); v[1] ^= v[2]; v[2]=rot32l16(v[2]); } /* Whitening */ v[0] ^= READ_ROUND_KEY_DOUBLE_WORD(k[0]); v[1] ^= READ_ROUND_KEY_DOUBLE_WORD(k[1]); v[2] ^= READ_ROUND_KEY_DOUBLE_WORD(k[2]); v[3] ^= READ_ROUND_KEY_DOUBLE_WORD(k[3]); }
void round_f(uint32_t *left, uint32_t *right, uint32_t *roundKeys) { uint32_t temp; uint8_t i; uint16_t *b0_l = (uint16_t *)left; uint16_t *b0_r = (uint16_t *)left + 1; uint16_t *b1_l = (uint16_t *)right; uint16_t *b1_r = (uint16_t *)right + 1; /* left branch */ for (i = 0; i < 3; i++) { *left ^= READ_ROUND_KEY_DOUBLE_WORD(roundKeys[i]); speckey(b0_l, b0_r); } /* right branch */ for (i = 0; i < 3; i++) { *right ^= READ_ROUND_KEY_DOUBLE_WORD(roundKeys[i + 3]); speckey(b1_l, b1_r); } /* linear layer */ temp = *left; *right ^= *left ^ rot32l8(*left) ^ rot32r8(*left); *left = *right; *right = temp; }
void QuarterRound(uint32_t *state, uint8_t a, uint8_t b, uint8_t c, uint8_t d) { state[a] += state[b]; state[d] ^= state[a]; state[d] = rot32l16(state[d]); state[c] += state[d]; state[b] ^= state[c]; state[b] = rot32l12(state[b]); state[a] += state[b]; state[d] ^= state[a]; state[d] = rot32l8(state[d]); state[c] += state[d]; state[b] ^= state[c]; state[b] = rot32l7(state[b]); }
void Decrypt(uint8_t *block, uint8_t *roundKeys) { uint32_t *block32 = (uint32_t *)block; const uint32_t *rk = (uint32_t *)roundKeys; uint32_t y = block32[0]; uint32_t x = block32[1]; int8_t i; for (i = NUMBER_OF_ROUNDS - 1; i >= 0; --i) { y = rot32r3(x ^ y); x = rot32l8((x ^ READ_ROUND_KEY_DOUBLE_WORD(rk[i])) - y); } block32[0] = y; block32[1] = x; }
void round_f_inverse(uint32_t *left, uint32_t *right, uint32_t *roundKeys) { uint32_t temp; uint16_t *b0_l = (uint16_t *)left; uint16_t *b0_r = (uint16_t *)left + 1; uint16_t *b1_l = (uint16_t *)right; uint16_t *b1_r = (uint16_t *)right + 1; /* linear layer */ temp = *right; *left ^= *right ^ rot32l8(*right) ^ rot32r8(*right); *right = *left; *left = temp; /* right branch */ speckey_inverse(b1_l, b1_r); *right ^= READ_ROUND_KEY_DOUBLE_WORD(roundKeys[5]); speckey_inverse(b1_l, b1_r); *right ^= READ_ROUND_KEY_DOUBLE_WORD(roundKeys[4]); speckey_inverse(b1_l, b1_r); *right ^= READ_ROUND_KEY_DOUBLE_WORD(roundKeys[3]); /* left branch */ speckey_inverse(b0_l, b0_r); *left ^= READ_ROUND_KEY_DOUBLE_WORD(roundKeys[2]); speckey_inverse(b0_l, b0_r); *left ^= READ_ROUND_KEY_DOUBLE_WORD(roundKeys[1]); speckey_inverse(b0_l, b0_r); *left ^= READ_ROUND_KEY_DOUBLE_WORD(roundKeys[0]); }
void Decrypt(uint8_t *block, uint8_t *roundKeys) { uint32_t *block32 = (uint32_t *)block; const uint32_t *rk = (uint32_t *)roundKeys; uint32_t y = block32[0]; uint32_t x = block32[1]; int8_t i; uint32_t tmp; for (i = NUMBER_OF_ROUNDS - 1; i >= 0; i--) { tmp = y; y = x ^ ( rot32l1(y) & rot32l8(y) ) ^ ( rot32l1(rot32l1(y)) ) ^ READ_ROUND_KEY_DOUBLE_WORD(rk[i]); x = tmp; } block32[0] = y; block32[1] = x; }