Commit 526bda82 by Enrico Pozzobon

Merge branch 'rhys'

parent 745e7f1d
......@@ -52,23 +52,6 @@ static void hyena_double_delta(unsigned char D[8])
}
/**
* \brief Triples a delta value in the F(2^64) field.
*
* \param D The delta value to be tripled.
*
* D' = D ^ (D << 1) if the top-most bit is 0, or D' = D ^ (D << 1) ^ 0x1B
* otherwise.
*/
static void hyena_triple_delta(unsigned char D[8])
{
unsigned index;
unsigned char mask = (unsigned char)(((signed char)(D[0])) >> 7);
for (index = 0; index < 7; ++index)
D[index] ^= (D[index] << 1) | (D[index + 1] >> 7);
D[7] ^= (D[7] << 1) ^ (mask & 0x1B);
}
/**
* \brief Process the associated data for HYENA.
*
* \param ks Key schedule for the GIFT-128 cipher.
......@@ -83,26 +66,27 @@ static void hyena_process_ad
unsigned long long adlen)
{
unsigned char feedback[16];
hyena_double_delta(D);
while (adlen > 16) {
hyena_double_delta(D);
memcpy(feedback, ad, 16);
lw_xor_block(feedback + 8, Y + 8, 8);
lw_xor_block(feedback + 8, D, 8);
lw_xor_block(Y, feedback, 16);
gift128n_encrypt(ks, Y, Y);
hyena_double_delta(D);
ad += 16;
adlen -= 16;
}
if (adlen == 16) {
hyena_triple_delta(D);
hyena_double_delta(D);
memcpy(feedback, ad, 16);
lw_xor_block(feedback + 8, Y + 8, 8);
lw_xor_block(feedback + 8, D, 8);
lw_xor_block(Y, feedback, 16);
} else {
unsigned temp = (unsigned)adlen;
hyena_triple_delta(D);
hyena_triple_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
memcpy(feedback, ad, temp);
feedback[temp] = 0x01;
memset(feedback + temp + 1, 0, 15 - temp);
......@@ -132,7 +116,8 @@ int hyena_aead_encrypt
*clen = mlen + HYENA_TAG_SIZE;
/* Set up the key schedule and use it to encrypt the nonce */
gift128n_init(&ks, k);
if (!gift128n_init(&ks, k, HYENA_KEY_SIZE))
return -1;
Y[0] = 0;
if (adlen == 0)
Y[0] |= 0x01;
......@@ -164,7 +149,8 @@ int hyena_aead_encrypt
}
gift128n_encrypt(&ks, Y, Y);
if (mlen == 16) {
hyena_triple_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
memcpy(feedback, m, 16);
lw_xor_block(feedback + 8, Y + 8, 8);
lw_xor_block(feedback + 8, D, 8);
......@@ -173,8 +159,9 @@ int hyena_aead_encrypt
c += 16;
} else {
unsigned temp = (unsigned)mlen;
hyena_triple_delta(D);
hyena_triple_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
memcpy(feedback, m, temp);
feedback[temp] = 0x01;
memset(feedback + temp + 1, 0, 15 - temp);
......@@ -220,7 +207,8 @@ int hyena_aead_decrypt
*mlen = clen - HYENA_TAG_SIZE;
/* Set up the key schedule and use it to encrypt the nonce */
gift128n_init(&ks, k);
if (!gift128n_init(&ks, k, HYENA_KEY_SIZE))
return -1;
Y[0] = 0;
if (adlen == 0)
Y[0] |= 0x01;
......@@ -254,7 +242,8 @@ int hyena_aead_decrypt
}
gift128n_encrypt(&ks, Y, Y);
if (clen == 16) {
hyena_triple_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
memcpy(feedback + 8, c + 8, 8);
lw_xor_block_2_src(m, c, Y, 16);
memcpy(feedback, m, 8);
......@@ -263,8 +252,9 @@ int hyena_aead_decrypt
c += 16;
} else {
unsigned temp = (unsigned)clen;
hyena_triple_delta(D);
hyena_triple_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
if (temp > 8) {
memcpy(feedback + 8, c + 8, temp - 8);
lw_xor_block_2_src(m, c, Y, temp);
......
......@@ -23,12 +23,8 @@
#include "internal-gift128.h"
#include "internal-util.h"
#if !GIFT128_VARIANT_ASM
#if GIFT128_VARIANT != GIFT128_VARIANT_TINY
/* Round constants for GIFT-128 in the fixsliced representation */
static uint32_t const GIFT128_RC_fixsliced[40] = {
static uint32_t const GIFT128_RC[40] = {
0x10000008, 0x80018000, 0x54000002, 0x01010181, 0x8000001f, 0x10888880,
0x6001e000, 0x51500002, 0x03030180, 0x8000002f, 0x10088880, 0x60016000,
0x41500002, 0x03030080, 0x80000027, 0x10008880, 0x4001e000, 0x11500002,
......@@ -38,246 +34,6 @@ static uint32_t const GIFT128_RC_fixsliced[40] = {
0xc001a000, 0x14500002, 0x01020181, 0x8000001a
};
#endif
#if GIFT128_VARIANT != GIFT128_VARIANT_FULL
/* Round constants for GIFT-128 in the bitsliced representation */
static uint8_t const GIFT128_RC[40] = {
0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3E, 0x3D, 0x3B,
0x37, 0x2F, 0x1E, 0x3C, 0x39, 0x33, 0x27, 0x0E,
0x1D, 0x3A, 0x35, 0x2B, 0x16, 0x2C, 0x18, 0x30,
0x21, 0x02, 0x05, 0x0B, 0x17, 0x2E, 0x1C, 0x38,
0x31, 0x23, 0x06, 0x0D, 0x1B, 0x36, 0x2D, 0x1A
};
#endif
/* http://programming.sirrida.de/perm_fn.html#bit_permute_step */
#define bit_permute_step(_y, mask, shift) \
do { \
uint32_t y = (_y); \
uint32_t t = ((y >> (shift)) ^ y) & (mask); \
(_y) = (y ^ t) ^ (t << (shift)); \
} while (0)
/*
* The permutation below was generated by the online permuation generator at
* "http://programming.sirrida.de/calcperm.php".
*
* All of the permutuations are essentially the same, except that each is
* rotated by 8 bits with respect to the next:
*
* P0: 0 24 16 8 1 25 17 9 2 26 18 10 3 27 19 11 4 28 20 12 5 29 21 13 6 30 22 14 7 31 23 15
* P1: 8 0 24 16 9 1 25 17 10 2 26 18 11 3 27 19 12 4 28 20 13 5 29 21 14 6 30 22 15 7 31 23
* P2: 16 8 0 24 17 9 1 25 18 10 2 26 19 11 3 27 20 12 4 28 21 13 5 29 22 14 6 30 23 15 7 31
* P3: 24 16 8 0 25 17 9 1 26 18 10 2 27 19 11 3 28 20 12 4 29 21 13 5 30 22 14 6 31 23 15 7
*
* The most efficient permutation from the online generator was P3, so we
* perform it as the core of the others, and then perform a final rotation.
*
* It is possible to do slightly better than "P3 then rotate" on desktop and
* server architectures for the other permutations. But the advantage isn't
* as evident on embedded platforms so we keep things simple.
*/
#define PERM3_INNER(x) \
do { \
bit_permute_step(x, 0x0a0a0a0a, 3); \
bit_permute_step(x, 0x00cc00cc, 6); \
bit_permute_step(x, 0x0000f0f0, 12); \
bit_permute_step(x, 0x000000ff, 24); \
} while (0)
#define PERM0(x) \
do { \
uint32_t _x = (x); \
PERM3_INNER(_x); \
(x) = leftRotate8(_x); \
} while (0)
#define PERM1(x) \
do { \
uint32_t _x = (x); \
PERM3_INNER(_x); \
(x) = leftRotate16(_x); \
} while (0)
#define PERM2(x) \
do { \
uint32_t _x = (x); \
PERM3_INNER(_x); \
(x) = leftRotate24(_x); \
} while (0)
#define PERM3(x) \
do { \
uint32_t _x = (x); \
PERM3_INNER(_x); \
(x) = _x; \
} while (0)
#define INV_PERM3_INNER(x) \
do { \
bit_permute_step(x, 0x00550055, 9); \
bit_permute_step(x, 0x00003333, 18); \
bit_permute_step(x, 0x000f000f, 12); \
bit_permute_step(x, 0x000000ff, 24); \
} while (0)
#define INV_PERM0(x) \
do { \
uint32_t _x = rightRotate8(x); \
INV_PERM3_INNER(_x); \
(x) = _x; \
} while (0)
#define INV_PERM1(x) \
do { \
uint32_t _x = rightRotate16(x); \
INV_PERM3_INNER(_x); \
(x) = _x; \
} while (0)
#define INV_PERM2(x) \
do { \
uint32_t _x = rightRotate24(x); \
INV_PERM3_INNER(_x); \
(x) = _x; \
} while (0)
#define INV_PERM3(x) \
do { \
uint32_t _x = (x); \
INV_PERM3_INNER(_x); \
(x) = _x; \
} while (0)
/**
* \brief Converts the GIFT-128 nibble-based representation into word-based.
*
* \param output Output buffer to write the word-based version to.
* \param input Input buffer to read the nibble-based version from.
*
* The \a input and \a output buffers can be the same buffer.
*/
static void gift128n_to_words
(unsigned char *output, const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
/* Load the input buffer into 32-bit words. We use the nibble order
* from the HYENA submission to NIST which is byte-reversed with respect
* to the nibble order of the original GIFT-128 paper. Nibble zero is in
* the first byte instead of the last, which means little-endian order. */
s0 = le_load_word32(input + 12);
s1 = le_load_word32(input + 8);
s2 = le_load_word32(input + 4);
s3 = le_load_word32(input);
/* Rearrange the bits so that bits 0..3 of each nibble are
* scattered to bytes 0..3 of each word. The permutation is:
*
* 0 8 16 24 1 9 17 25 2 10 18 26 3 11 19 27 4 12 20 28 5 13 21 29 6 14 22 30 7 15 23 31
*
* Generated with "http://programming.sirrida.de/calcperm.php".
*/
#define PERM_WORDS(_x) \
do { \
uint32_t x = (_x); \
bit_permute_step(x, 0x0a0a0a0a, 3); \
bit_permute_step(x, 0x00cc00cc, 6); \
bit_permute_step(x, 0x0000f0f0, 12); \
bit_permute_step(x, 0x0000ff00, 8); \
(_x) = x; \
} while (0)
PERM_WORDS(s0);
PERM_WORDS(s1);
PERM_WORDS(s2);
PERM_WORDS(s3);
/* Rearrange the bytes and write them to the output buffer */
output[0] = (uint8_t)s0;
output[1] = (uint8_t)s1;
output[2] = (uint8_t)s2;
output[3] = (uint8_t)s3;
output[4] = (uint8_t)(s0 >> 8);
output[5] = (uint8_t)(s1 >> 8);
output[6] = (uint8_t)(s2 >> 8);
output[7] = (uint8_t)(s3 >> 8);
output[8] = (uint8_t)(s0 >> 16);
output[9] = (uint8_t)(s1 >> 16);
output[10] = (uint8_t)(s2 >> 16);
output[11] = (uint8_t)(s3 >> 16);
output[12] = (uint8_t)(s0 >> 24);
output[13] = (uint8_t)(s1 >> 24);
output[14] = (uint8_t)(s2 >> 24);
output[15] = (uint8_t)(s3 >> 24);
}
/**
* \brief Converts the GIFT-128 word-based representation into nibble-based.
*
* \param output Output buffer to write the nibble-based version to.
* \param input Input buffer to read the word-based version from.
*/
static void gift128n_to_nibbles
(unsigned char *output, const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
/* Load the input bytes and rearrange them so that s0 contains the
* most significant nibbles and s3 contains the least significant */
s0 = (((uint32_t)(input[12])) << 24) |
(((uint32_t)(input[8])) << 16) |
(((uint32_t)(input[4])) << 8) |
((uint32_t)(input[0]));
s1 = (((uint32_t)(input[13])) << 24) |
(((uint32_t)(input[9])) << 16) |
(((uint32_t)(input[5])) << 8) |
((uint32_t)(input[1]));
s2 = (((uint32_t)(input[14])) << 24) |
(((uint32_t)(input[10])) << 16) |
(((uint32_t)(input[6])) << 8) |
((uint32_t)(input[2]));
s3 = (((uint32_t)(input[15])) << 24) |
(((uint32_t)(input[11])) << 16) |
(((uint32_t)(input[7])) << 8) |
((uint32_t)(input[3]));
/* Apply the inverse of PERM_WORDS() from the function above */
#define INV_PERM_WORDS(_x) \
do { \
uint32_t x = (_x); \
bit_permute_step(x, 0x00aa00aa, 7); \
bit_permute_step(x, 0x0000cccc, 14); \
bit_permute_step(x, 0x00f000f0, 4); \
bit_permute_step(x, 0x0000ff00, 8); \
(_x) = x; \
} while (0)
INV_PERM_WORDS(s0);
INV_PERM_WORDS(s1);
INV_PERM_WORDS(s2);
INV_PERM_WORDS(s3);
/* Store the result into the output buffer as 32-bit words */
le_store_word32(output + 12, s0);
le_store_word32(output + 8, s1);
le_store_word32(output + 4, s2);
le_store_word32(output, s3);
}
void gift128n_encrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
{
gift128n_to_words(output, input);
gift128b_encrypt(ks, output, output);
gift128n_to_nibbles(output, output);
}
void gift128n_decrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
{
gift128n_to_words(output, input);
gift128b_decrypt(ks, output, output);
gift128n_to_nibbles(output, output);
}
#if GIFT128_VARIANT != GIFT128_VARIANT_TINY
/**
* \brief Swaps bits within two words.
*
......@@ -446,27 +202,21 @@ static void gift128b_compute_round_keys
/* Keys 8, 9, 18, and 19 do not need any adjustment */
}
#if GIFT128_VARIANT == GIFT128_VARIANT_FULL
/* Derive the fixsliced keys for the remaining rounds 11..40 */
for (index = 20; index < 80; index += 10) {
gift128b_derive_keys(ks->k + index, ks->k + index - 20);
}
#endif
}
void gift128b_init(gift128b_key_schedule_t *ks, const unsigned char *key)
int gift128b_init
(gift128b_key_schedule_t *ks, const unsigned char *key, size_t key_len)
{
if (!ks || !key || key_len != 16)
return 0;
gift128b_compute_round_keys
(ks, be_load_word32(key), be_load_word32(key + 4),
be_load_word32(key + 8), be_load_word32(key + 12));
}
void gift128n_init(gift128n_key_schedule_t *ks, const unsigned char *key)
{
/* Use the little-endian key byte order from the HYENA submission */
gift128b_compute_round_keys
(ks, le_load_word32(key + 12), le_load_word32(key + 8),
le_load_word32(key + 4), le_load_word32(key));
return 1;
}
/**
......@@ -771,37 +521,11 @@ void gift128n_init(gift128n_key_schedule_t *ks, const unsigned char *key)
gift128b_inv_sbox(s3, s1, s2, s0); \
} while (0)
#else /* GIFT128_VARIANT_TINY */
void gift128b_init(gift128b_key_schedule_t *ks, const unsigned char *key)
{
/* Mirror the fixslicing word order of 3, 1, 2, 0 */
ks->k[0] = be_load_word32(key + 12);
ks->k[1] = be_load_word32(key + 4);
ks->k[2] = be_load_word32(key + 8);
ks->k[3] = be_load_word32(key);
}
void gift128n_init(gift128n_key_schedule_t *ks, const unsigned char *key)
{
/* Use the little-endian key byte order from the HYENA submission
* and mirror the fixslicing word order of 3, 1, 2, 0 */
ks->k[0] = le_load_word32(key);
ks->k[1] = le_load_word32(key + 8);
ks->k[2] = le_load_word32(key + 4);
ks->k[3] = le_load_word32(key + 12);
}
#endif /* GIFT128_VARIANT_TINY */
#if GIFT128_VARIANT == GIFT128_VARIANT_SMALL
void gift128b_encrypt
(const gift128b_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
uint32_t k[20];
/* Copy the plaintext into the state buffer and convert from big endian */
s0 = be_load_word32(input);
......@@ -810,20 +534,14 @@ void gift128b_encrypt
s3 = be_load_word32(input + 12);
/* Perform all 40 rounds five at a time using the fixsliced method */
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
gift128b_derive_keys(k, ks->k);
gift128b_derive_keys(k + 10, ks->k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 10);
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 15);
gift128b_derive_keys(k, k);
gift128b_derive_keys(k + 10, k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 20);
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 25);
gift128b_derive_keys(k, k);
gift128b_derive_keys(k + 10, k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 30);
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 35);
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC);
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC + 5);
gift128b_encrypt_5_rounds(ks->k + 20, GIFT128_RC + 10);
gift128b_encrypt_5_rounds(ks->k + 30, GIFT128_RC + 15);
gift128b_encrypt_5_rounds(ks->k + 40, GIFT128_RC + 20);
gift128b_encrypt_5_rounds(ks->k + 50, GIFT128_RC + 25);
gift128b_encrypt_5_rounds(ks->k + 60, GIFT128_RC + 30);
gift128b_encrypt_5_rounds(ks->k + 70, GIFT128_RC + 35);
/* Pack the state into the ciphertext buffer in big endian */
be_store_word32(output, s0);
......@@ -837,7 +555,6 @@ void gift128b_encrypt_preloaded
const uint32_t input[4])
{
uint32_t s0, s1, s2, s3;
uint32_t k[20];
/* Copy the plaintext into local variables */
s0 = input[0];
......@@ -846,20 +563,14 @@ void gift128b_encrypt_preloaded
s3 = input[3];
/* Perform all 40 rounds five at a time using the fixsliced method */
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
gift128b_derive_keys(k, ks->k);
gift128b_derive_keys(k + 10, ks->k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 10);
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 15);
gift128b_derive_keys(k, k);
gift128b_derive_keys(k + 10, k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 20);
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 25);
gift128b_derive_keys(k, k);
gift128b_derive_keys(k + 10, k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 30);
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 35);
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC);
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC + 5);
gift128b_encrypt_5_rounds(ks->k + 20, GIFT128_RC + 10);
gift128b_encrypt_5_rounds(ks->k + 30, GIFT128_RC + 15);
gift128b_encrypt_5_rounds(ks->k + 40, GIFT128_RC + 20);
gift128b_encrypt_5_rounds(ks->k + 50, GIFT128_RC + 25);
gift128b_encrypt_5_rounds(ks->k + 60, GIFT128_RC + 30);
gift128b_encrypt_5_rounds(ks->k + 70, GIFT128_RC + 35);
/* Pack the state into the ciphertext buffer */
output[0] = s0;
......@@ -868,55 +579,7 @@ void gift128b_encrypt_preloaded
output[3] = s3;
}
void gift128t_encrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak)
{
uint32_t s0, s1, s2, s3;
uint32_t k[20];
/* Copy the plaintext into the state buffer and convert from nibbles */
gift128n_to_words(output, input);
s0 = be_load_word32(output);
s1 = be_load_word32(output + 4);
s2 = be_load_word32(output + 8);
s3 = be_load_word32(output + 12);
/* Perform all 40 rounds five at a time using the fixsliced method.
* Every 5 rounds except the last we add the tweak value to the state */
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
s0 ^= tweak;
gift128b_derive_keys(k, ks->k);
gift128b_derive_keys(k + 10, ks->k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 10);
s0 ^= tweak;
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 15);
s0 ^= tweak;
gift128b_derive_keys(k, k);
gift128b_derive_keys(k + 10, k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 20);
s0 ^= tweak;
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 25);
s0 ^= tweak;
gift128b_derive_keys(k, k);
gift128b_derive_keys(k + 10, k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 30);
s0 ^= tweak;
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 35);
/* Pack the state into the ciphertext buffer in nibble form */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
gift128n_to_nibbles(output, output);
}
#elif GIFT128_VARIANT == GIFT128_VARIANT_FULL
void gift128b_encrypt
void gift128b_decrypt
(const gift128b_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
{
......@@ -929,14 +592,14 @@ void gift128b_encrypt
s3 = be_load_word32(input + 12);
/* Perform all 40 rounds five at a time using the fixsliced method */
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
gift128b_encrypt_5_rounds(ks->k + 20, GIFT128_RC_fixsliced + 10);
gift128b_encrypt_5_rounds(ks->k + 30, GIFT128_RC_fixsliced + 15);
gift128b_encrypt_5_rounds(ks->k + 40, GIFT128_RC_fixsliced + 20);
gift128b_encrypt_5_rounds(ks->k + 50, GIFT128_RC_fixsliced + 25);
gift128b_encrypt_5_rounds(ks->k + 60, GIFT128_RC_fixsliced + 30);
gift128b_encrypt_5_rounds(ks->k + 70, GIFT128_RC_fixsliced + 35);
gift128b_decrypt_5_rounds(ks->k + 70, GIFT128_RC + 35);
gift128b_decrypt_5_rounds(ks->k + 60, GIFT128_RC + 30);
gift128b_decrypt_5_rounds(ks->k + 50, GIFT128_RC + 25);
gift128b_decrypt_5_rounds(ks->k + 40, GIFT128_RC + 20);
gift128b_decrypt_5_rounds(ks->k + 30, GIFT128_RC + 15);
gift128b_decrypt_5_rounds(ks->k + 20, GIFT128_RC + 10);
gift128b_decrypt_5_rounds(ks->k + 10, GIFT128_RC + 5);
gift128b_decrypt_5_rounds(ks->k, GIFT128_RC);
/* Pack the state into the ciphertext buffer in big endian */
be_store_word32(output, s0);
......@@ -945,308 +608,173 @@ void gift128b_encrypt
be_store_word32(output + 12, s3);
}
void gift128b_encrypt_preloaded
(const gift128b_key_schedule_t *ks, uint32_t output[4],
const uint32_t input[4])
int gift128n_init
(gift128n_key_schedule_t *ks, const unsigned char *key, size_t key_len)
{
uint32_t s0, s1, s2, s3;
/* Copy the plaintext into local variables */
s0 = input[0];
s1 = input[1];
s2 = input[2];
s3 = input[3];
/* Perform all 40 rounds five at a time using the fixsliced method */
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
gift128b_encrypt_5_rounds(ks->k + 20, GIFT128_RC_fixsliced + 10);
gift128b_encrypt_5_rounds(ks->k + 30, GIFT128_RC_fixsliced + 15);
gift128b_encrypt_5_rounds(ks->k + 40, GIFT128_RC_fixsliced + 20);
gift128b_encrypt_5_rounds(ks->k + 50, GIFT128_RC_fixsliced + 25);
gift128b_encrypt_5_rounds(ks->k + 60, GIFT128_RC_fixsliced + 30);
gift128b_encrypt_5_rounds(ks->k + 70, GIFT128_RC_fixsliced + 35);
/* Pack the state into the ciphertext buffer */
output[0] = s0;
output[1] = s1;
output[2] = s2;
output[3] = s3;
}
void gift128t_encrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak)
{
uint32_t s0, s1, s2, s3;
/* Copy the plaintext into the state buffer and convert from nibbles */
gift128n_to_words(output, input);
s0 = be_load_word32(output);
s1 = be_load_word32(output + 4);
s2 = be_load_word32(output + 8);
s3 = be_load_word32(output + 12);
/* Perform all 40 rounds five at a time using the fixsliced method.
* Every 5 rounds except the last we add the tweak value to the state */
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 20, GIFT128_RC_fixsliced + 10);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 30, GIFT128_RC_fixsliced + 15);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 40, GIFT128_RC_fixsliced + 20);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 50, GIFT128_RC_fixsliced + 25);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 60, GIFT128_RC_fixsliced + 30);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 70, GIFT128_RC_fixsliced + 35);
/* Pack the state into the ciphertext buffer in nibble form */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
gift128n_to_nibbles(output, output);
/* Use the little-endian key byte order from the HYENA submission */
if (!ks || !key || key_len != 16)
return 0;
gift128b_compute_round_keys
(ks, le_load_word32(key + 12), le_load_word32(key + 8),
le_load_word32(key + 4), le_load_word32(key));
return 1;
}
#else /* GIFT128_VARIANT_TINY */
/* http://programming.sirrida.de/perm_fn.html#bit_permute_step */
#define bit_permute_step(_y, mask, shift) \
do { \
uint32_t y = (_y); \
uint32_t t = ((y >> (shift)) ^ y) & (mask); \
(_y) = (y ^ t) ^ (t << (shift)); \
} while (0)
void gift128b_encrypt
(const gift128b_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
/**
* \brief Converts the GIFT-128 nibble-based representation into word-based.
*
* \param output Output buffer to write the word-based version to.
* \param input Input buffer to read the nibble-based version from.
*
* The \a input and \a output buffers can be the same buffer.
*/
static void gift128n_to_words
(unsigned char *output, const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
uint32_t w0, w1, w2, w3;
uint32_t temp;
uint8_t round;
/* Copy the plaintext into the state buffer and convert from big endian */
s0 = be_load_word32(input);
s1 = be_load_word32(input + 4);
s2 = be_load_word32(input + 8);
s3 = be_load_word32(input + 12);
/* Load the input buffer into 32-bit words. We use the nibble order
* from the HYENA submission to NIST which is byte-reversed with respect
* to the nibble order of the original GIFT-128 paper. Nibble zero is in
* the first byte instead of the last, which means little-endian order. */
s0 = le_load_word32(input + 12);
s1 = le_load_word32(input + 8);
s2 = le_load_word32(input + 4);
s3 = le_load_word32(input);
/* The key schedule is initialized with the key itself */
w0 = ks->k[3];
w1 = ks->k[1];
w2 = ks->k[2];
w3 = ks->k[0];
/* Perform all 40 rounds */
for (round = 0; round < 40; ++round) {
/* SubCells - apply the S-box */
s1 ^= s0 & s2;
s0 ^= s1 & s3;
s2 ^= s0 | s1;
s3 ^= s2;
s1 ^= s3;
s3 ^= 0xFFFFFFFFU;
s2 ^= s0 & s1;
temp = s0;
s0 = s3;
s3 = temp;
/* PermBits - apply the 128-bit permutation */
PERM0(s0);
PERM1(s1);
PERM2(s2);
PERM3(s3);
/* AddRoundKey - XOR in the key schedule and the round constant */
s2 ^= w1;
s1 ^= w3;
s3 ^= 0x80000000U ^ GIFT128_RC[round];
/* Rotate the key schedule */
temp = w3;
w3 = w2;
w2 = w1;
w1 = w0;
w0 = ((temp & 0xFFFC0000U) >> 2) | ((temp & 0x00030000U) << 14) |
((temp & 0x00000FFFU) << 4) | ((temp & 0x0000F000U) >> 12);
}
/* Rearrange the bits so that bits 0..3 of each nibble are
* scattered to bytes 0..3 of each word. The permutation is:
*
* 0 8 16 24 1 9 17 25 2 10 18 26 3 11 19 27 4 12 20 28 5 13 21 29 6 14 22 30 7 15 23 31
*
* Generated with "http://programming.sirrida.de/calcperm.php".
*/
#define PERM_WORDS(_x) \
do { \
uint32_t x = (_x); \
bit_permute_step(x, 0x0a0a0a0a, 3); \
bit_permute_step(x, 0x00cc00cc, 6); \
bit_permute_step(x, 0x0000f0f0, 12); \
bit_permute_step(x, 0x0000ff00, 8); \
(_x) = x; \
} while (0)
PERM_WORDS(s0);
PERM_WORDS(s1);
PERM_WORDS(s2);
PERM_WORDS(s3);
/* Pack the state into the ciphertext buffer in big endian */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
/* Rearrange the bytes and write them to the output buffer */
output[0] = (uint8_t)s0;
output[1] = (uint8_t)s1;
output[2] = (uint8_t)s2;
output[3] = (uint8_t)s3;
output[4] = (uint8_t)(s0 >> 8);
output[5] = (uint8_t)(s1 >> 8);
output[6] = (uint8_t)(s2 >> 8);
output[7] = (uint8_t)(s3 >> 8);
output[8] = (uint8_t)(s0 >> 16);
output[9] = (uint8_t)(s1 >> 16);
output[10] = (uint8_t)(s2 >> 16);
output[11] = (uint8_t)(s3 >> 16);
output[12] = (uint8_t)(s0 >> 24);
output[13] = (uint8_t)(s1 >> 24);
output[14] = (uint8_t)(s2 >> 24);
output[15] = (uint8_t)(s3 >> 24);
}
void gift128b_encrypt_preloaded
(const gift128b_key_schedule_t *ks, uint32_t output[4],
const uint32_t input[4])
/**
* \brief Converts the GIFT-128 word-based representation into nibble-based.
*
* \param output Output buffer to write the nibble-based version to.
* \param input Input buffer to read the word-based version from.
*/
static void gift128n_to_nibbles
(unsigned char *output, const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
uint32_t w0, w1, w2, w3;
uint32_t temp;
uint8_t round;
/* Copy the plaintext into the state buffer */
s0 = input[0];
s1 = input[1];
s2 = input[2];
s3 = input[3];
/* Load the input bytes and rearrange them so that s0 contains the
* most significant nibbles and s3 contains the least significant */
s0 = (((uint32_t)(input[12])) << 24) |
(((uint32_t)(input[8])) << 16) |
(((uint32_t)(input[4])) << 8) |
((uint32_t)(input[0]));
s1 = (((uint32_t)(input[13])) << 24) |
(((uint32_t)(input[9])) << 16) |
(((uint32_t)(input[5])) << 8) |
((uint32_t)(input[1]));
s2 = (((uint32_t)(input[14])) << 24) |
(((uint32_t)(input[10])) << 16) |
(((uint32_t)(input[6])) << 8) |
((uint32_t)(input[2]));
s3 = (((uint32_t)(input[15])) << 24) |
(((uint32_t)(input[11])) << 16) |
(((uint32_t)(input[7])) << 8) |
((uint32_t)(input[3]));
/* The key schedule is initialized with the key itself */
w0 = ks->k[3];
w1 = ks->k[1];
w2 = ks->k[2];
w3 = ks->k[0];
/* Perform all 40 rounds */
for (round = 0; round < 40; ++round) {
/* SubCells - apply the S-box */
s1 ^= s0 & s2;
s0 ^= s1 & s3;
s2 ^= s0 | s1;
s3 ^= s2;
s1 ^= s3;
s3 ^= 0xFFFFFFFFU;
s2 ^= s0 & s1;
temp = s0;
s0 = s3;
s3 = temp;
/* PermBits - apply the 128-bit permutation */
PERM0(s0);
PERM1(s1);
PERM2(s2);
PERM3(s3);
/* AddRoundKey - XOR in the key schedule and the round constant */
s2 ^= w1;
s1 ^= w3;
s3 ^= 0x80000000U ^ GIFT128_RC[round];
/* Rotate the key schedule */
temp = w3;
w3 = w2;
w2 = w1;
w1 = w0;
w0 = ((temp & 0xFFFC0000U) >> 2) | ((temp & 0x00030000U) << 14) |
((temp & 0x00000FFFU) << 4) | ((temp & 0x0000F000U) >> 12);
}
/* Apply the inverse of PERM_WORDS() from the function above */
#define INV_PERM_WORDS(_x) \
do { \
uint32_t x = (_x); \
bit_permute_step(x, 0x00aa00aa, 7); \
bit_permute_step(x, 0x0000cccc, 14); \
bit_permute_step(x, 0x00f000f0, 4); \
bit_permute_step(x, 0x0000ff00, 8); \
(_x) = x; \
} while (0)
INV_PERM_WORDS(s0);
INV_PERM_WORDS(s1);
INV_PERM_WORDS(s2);
INV_PERM_WORDS(s3);
/* Pack the state into the ciphertext buffer */
output[0] = s0;
output[1] = s1;
output[2] = s2;
output[3] = s3;
/* Store the result into the output buffer as 32-bit words */
le_store_word32(output + 12, s0);
le_store_word32(output + 8, s1);
le_store_word32(output + 4, s2);
le_store_word32(output, s3);
}
void gift128t_encrypt
void gift128n_encrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak)
const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
uint32_t w0, w1, w2, w3;
uint32_t temp;
uint8_t round;
/* Copy the plaintext into the state buffer and convert from nibbles */
gift128n_to_words(output, input);
s0 = be_load_word32(output);
s1 = be_load_word32(output + 4);
s2 = be_load_word32(output + 8);
s3 = be_load_word32(output + 12);
/* The key schedule is initialized with the key itself */
w0 = ks->k[3];
w1 = ks->k[1];
w2 = ks->k[2];
w3 = ks->k[0];
/* Perform all 40 rounds */
for (round = 0; round < 40; ++round) {
/* SubCells - apply the S-box */
s1 ^= s0 & s2;
s0 ^= s1 & s3;
s2 ^= s0 | s1;
s3 ^= s2;
s1 ^= s3;
s3 ^= 0xFFFFFFFFU;
s2 ^= s0 & s1;
temp = s0;
s0 = s3;
s3 = temp;
/* PermBits - apply the 128-bit permutation */
PERM0(s0);
PERM1(s1);
PERM2(s2);
PERM3(s3);
/* AddRoundKey - XOR in the key schedule and the round constant */
s2 ^= w1;
s1 ^= w3;
s3 ^= 0x80000000U ^ GIFT128_RC[round];
/* AddTweak - XOR in the tweak every 5 rounds except the last */
if (((round + 1) % 5) == 0 && round < 39)
s0 ^= tweak;
/* Rotate the key schedule */
temp = w3;
w3 = w2;
w2 = w1;
w1 = w0;
w0 = ((temp & 0xFFFC0000U) >> 2) | ((temp & 0x00030000U) << 14) |
((temp & 0x00000FFFU) << 4) | ((temp & 0x0000F000U) >> 12);
}
/* Pack the state into the ciphertext buffer in nibble form */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
gift128b_encrypt(ks, output, output);
gift128n_to_nibbles(output, output);
}
#endif /* GIFT128_VARIANT_TINY */
#if GIFT128_VARIANT == GIFT128_VARIANT_FULL
void gift128b_decrypt
(const gift128b_key_schedule_t *ks, unsigned char *output,
void gift128n_decrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
/* Copy the plaintext into the state buffer and convert from big endian */
s0 = be_load_word32(input);
s1 = be_load_word32(input + 4);
s2 = be_load_word32(input + 8);
s3 = be_load_word32(input + 12);
/* Perform all 40 rounds five at a time using the fixsliced method */
gift128b_decrypt_5_rounds(ks->k + 70, GIFT128_RC_fixsliced + 35);
gift128b_decrypt_5_rounds(ks->k + 60, GIFT128_RC_fixsliced + 30);
gift128b_decrypt_5_rounds(ks->k + 50, GIFT128_RC_fixsliced + 25);
gift128b_decrypt_5_rounds(ks->k + 40, GIFT128_RC_fixsliced + 20);
gift128b_decrypt_5_rounds(ks->k + 30, GIFT128_RC_fixsliced + 15);
gift128b_decrypt_5_rounds(ks->k + 20, GIFT128_RC_fixsliced + 10);
gift128b_decrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
gift128b_decrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
/* Pack the state into the ciphertext buffer in big endian */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
gift128n_to_words(output, input);
gift128b_decrypt(ks, output, output);
gift128n_to_nibbles(output, output);
}
void gift128t_decrypt
/* 4-bit tweak values expanded to 32-bit */
static uint32_t const GIFT128_tweaks[16] = {
0x00000000, 0xe1e1e1e1, 0xd2d2d2d2, 0x33333333,
0xb4b4b4b4, 0x55555555, 0x66666666, 0x87878787,
0x78787878, 0x99999999, 0xaaaaaaaa, 0x4b4b4b4b,
0xcccccccc, 0x2d2d2d2d, 0x1e1e1e1e, 0xffffffff
};
void gift128t_encrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak)
const unsigned char *input, unsigned char tweak)
{
uint32_t s0, s1, s2, s3;
uint32_t s0, s1, s2, s3, tword;
/* Copy the ciphertext into the state buffer and convert from nibbles */
/* Copy the plaintext into the state buffer and convert from nibbles */
gift128n_to_words(output, input);
s0 = be_load_word32(output);
s1 = be_load_word32(output + 4);
......@@ -1254,24 +782,25 @@ void gift128t_decrypt
s3 = be_load_word32(output + 12);
/* Perform all 40 rounds five at a time using the fixsliced method.
* Every 5 rounds except the first we add the tweak value to the state */
gift128b_decrypt_5_rounds(ks->k + 70, GIFT128_RC_fixsliced + 35);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k + 60, GIFT128_RC_fixsliced + 30);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k + 50, GIFT128_RC_fixsliced + 25);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k + 40, GIFT128_RC_fixsliced + 20);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k + 30, GIFT128_RC_fixsliced + 15);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k + 20, GIFT128_RC_fixsliced + 10);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
* Every 5 rounds except the last we add the tweak value to the state */
tword = GIFT128_tweaks[tweak];
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC);
s0 ^= tword;
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC + 5);
s0 ^= tword;
gift128b_encrypt_5_rounds(ks->k + 20, GIFT128_RC + 10);
s0 ^= tword;
gift128b_encrypt_5_rounds(ks->k + 30, GIFT128_RC + 15);
s0 ^= tword;
gift128b_encrypt_5_rounds(ks->k + 40, GIFT128_RC + 20);
s0 ^= tword;
gift128b_encrypt_5_rounds(ks->k + 50, GIFT128_RC + 25);
s0 ^= tword;
gift128b_encrypt_5_rounds(ks->k + 60, GIFT128_RC + 30);
s0 ^= tword;
gift128b_encrypt_5_rounds(ks->k + 70, GIFT128_RC + 35);
/* Pack the state into the plaintext buffer in nibble form */
/* Pack the state into the ciphertext buffer in nibble form */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
......@@ -1279,211 +808,37 @@ void gift128t_decrypt
gift128n_to_nibbles(output, output);
}
#else /* GIFT128_VARIANT_SMALL || GIFT128_VARIANT_TINY */
/* The small variant uses fixslicing for encryption, but we need to change
* to bitslicing for decryption because of the difficulty of fast-forwarding
* the fixsliced key schedule to the end. So the tiny variant is used for
* decryption when the small variant is selected. Since the NIST AEAD modes
* for GIFT-128 only use the block encrypt operation, the inefficiencies
* in decryption don't matter all that much */
/**
* \def gift128b_load_and_forward_schedule()
* \brief Generate the decryption key at the end of the last round.
*
* To do that, we run the block operation forward to determine the
* final state of the key schedule after the last round:
*
* w0 = ks->k[0];
* w1 = ks->k[1];
* w2 = ks->k[2];
* w3 = ks->k[3];
* for (round = 0; round < 40; ++round) {
* temp = w3;
* w3 = w2;
* w2 = w1;
* w1 = w0;
* w0 = ((temp & 0xFFFC0000U) >> 2) | ((temp & 0x00030000U) << 14) |
* ((temp & 0x00000FFFU) << 4) | ((temp & 0x0000F000U) >> 12);
* }
*
* We can short-cut all of the above by noticing that we don't need
* to do the word rotations. Every 4 rounds, the rotation alignment
* returns to the original position and each word has been rotated
* by applying the "2 right and 4 left" bit-rotation step to it.
* We then repeat that 10 times for the full 40 rounds. The overall
* effect is to apply a "20 right and 40 left" bit-rotation to every
* word in the key schedule. That is equivalent to "4 right and 8 left"
* on the 16-bit sub-words.
*/
#if GIFT128_VARIANT != GIFT128_VARIANT_SMALL
#define gift128b_load_and_forward_schedule() \
do { \
w0 = ks->k[3]; \
w1 = ks->k[1]; \
w2 = ks->k[2]; \
w3 = ks->k[0]; \
w0 = ((w0 & 0xFFF00000U) >> 4) | ((w0 & 0x000F0000U) << 12) | \
((w0 & 0x000000FFU) << 8) | ((w0 & 0x0000FF00U) >> 8); \
w1 = ((w1 & 0xFFF00000U) >> 4) | ((w1 & 0x000F0000U) << 12) | \
((w1 & 0x000000FFU) << 8) | ((w1 & 0x0000FF00U) >> 8); \
w2 = ((w2 & 0xFFF00000U) >> 4) | ((w2 & 0x000F0000U) << 12) | \
((w2 & 0x000000FFU) << 8) | ((w2 & 0x0000FF00U) >> 8); \
w3 = ((w3 & 0xFFF00000U) >> 4) | ((w3 & 0x000F0000U) << 12) | \
((w3 & 0x000000FFU) << 8) | ((w3 & 0x0000FF00U) >> 8); \
} while (0)
#else
/* The small variant needs to also undo some of the rotations that were
* done to generate the fixsliced version of the key schedule */
#define gift128b_load_and_forward_schedule() \
do { \
w0 = ks->k[3]; \
w1 = ks->k[1]; \
w2 = ks->k[2]; \
w3 = ks->k[0]; \
gift128b_swap_move(w3, w3, 0x000000FFU, 24); \
gift128b_swap_move(w3, w3, 0x00003333U, 18); \
gift128b_swap_move(w3, w3, 0x000F000FU, 12); \
gift128b_swap_move(w3, w3, 0x00550055U, 9); \
gift128b_swap_move(w1, w1, 0x000000FFU, 24); \
gift128b_swap_move(w1, w1, 0x00003333U, 18); \
gift128b_swap_move(w1, w1, 0x000F000FU, 12); \
gift128b_swap_move(w1, w1, 0x00550055U, 9); \
gift128b_swap_move(w2, w2, 0x000000FFU, 24); \
gift128b_swap_move(w2, w2, 0x000F000FU, 12); \
gift128b_swap_move(w2, w2, 0x03030303U, 6); \
gift128b_swap_move(w2, w2, 0x11111111U, 3); \
gift128b_swap_move(w0, w0, 0x000000FFU, 24); \
gift128b_swap_move(w0, w0, 0x000F000FU, 12); \
gift128b_swap_move(w0, w0, 0x03030303U, 6); \
gift128b_swap_move(w0, w0, 0x11111111U, 3); \
w0 = ((w0 & 0xFFF00000U) >> 4) | ((w0 & 0x000F0000U) << 12) | \
((w0 & 0x000000FFU) << 8) | ((w0 & 0x0000FF00U) >> 8); \
w1 = ((w1 & 0xFFF00000U) >> 4) | ((w1 & 0x000F0000U) << 12) | \
((w1 & 0x000000FFU) << 8) | ((w1 & 0x0000FF00U) >> 8); \
w2 = ((w2 & 0xFFF00000U) >> 4) | ((w2 & 0x000F0000U) << 12) | \
((w2 & 0x000000FFU) << 8) | ((w2 & 0x0000FF00U) >> 8); \
w3 = ((w3 & 0xFFF00000U) >> 4) | ((w3 & 0x000F0000U) << 12) | \
((w3 & 0x000000FFU) << 8) | ((w3 & 0x0000FF00U) >> 8); \
} while (0)
#endif
void gift128b_decrypt
(const gift128b_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
uint32_t w0, w1, w2, w3;
uint32_t temp;
uint8_t round;
/* Copy the ciphertext into the state buffer and convert from big endian */
s0 = be_load_word32(input);
s1 = be_load_word32(input + 4);
s2 = be_load_word32(input + 8);
s3 = be_load_word32(input + 12);
/* Generate the decryption key at the end of the last round */
gift128b_load_and_forward_schedule();
/* Perform all 40 rounds */
for (round = 40; round > 0; --round) {
/* Rotate the key schedule backwards */
temp = w0;
w0 = w1;
w1 = w2;
w2 = w3;
w3 = ((temp & 0x3FFF0000U) << 2) | ((temp & 0xC0000000U) >> 14) |
((temp & 0x0000FFF0U) >> 4) | ((temp & 0x0000000FU) << 12);
/* AddRoundKey - XOR in the key schedule and the round constant */
s2 ^= w1;
s1 ^= w3;
s3 ^= 0x80000000U ^ GIFT128_RC[round - 1];
/* InvPermBits - apply the inverse of the 128-bit permutation */
INV_PERM0(s0);
INV_PERM1(s1);
INV_PERM2(s2);
INV_PERM3(s3);
/* InvSubCells - apply the inverse of the S-box */
temp = s0;
s0 = s3;
s3 = temp;
s2 ^= s0 & s1;
s3 ^= 0xFFFFFFFFU;
s1 ^= s3;
s3 ^= s2;
s2 ^= s0 | s1;
s0 ^= s1 & s3;
s1 ^= s0 & s2;
}
/* Pack the state into the plaintext buffer in big endian */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
}
void gift128t_decrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak)
const unsigned char *input, unsigned char tweak)
{
uint32_t s0, s1, s2, s3;
uint32_t w0, w1, w2, w3;
uint32_t temp;
uint8_t round;
uint32_t s0, s1, s2, s3, tword;
/* Copy the plaintext into the state buffer and convert from nibbles */
/* Copy the ciphertext into the state buffer and convert from nibbles */
gift128n_to_words(output, input);
s0 = be_load_word32(output);
s1 = be_load_word32(output + 4);
s2 = be_load_word32(output + 8);
s3 = be_load_word32(output + 12);
/* Generate the decryption key at the end of the last round */
gift128b_load_and_forward_schedule();
/* Perform all 40 rounds */
for (round = 40; round > 0; --round) {
/* Rotate the key schedule backwards */
temp = w0;
w0 = w1;
w1 = w2;
w2 = w3;
w3 = ((temp & 0x3FFF0000U) << 2) | ((temp & 0xC0000000U) >> 14) |
((temp & 0x0000FFF0U) >> 4) | ((temp & 0x0000000FU) << 12);
/* AddTweak - XOR in the tweak every 5 rounds except the last */
if ((round % 5) == 0 && round < 40)
s0 ^= tweak;
/* AddRoundKey - XOR in the key schedule and the round constant */
s2 ^= w1;
s1 ^= w3;
s3 ^= 0x80000000U ^ GIFT128_RC[round - 1];
/* InvPermBits - apply the inverse of the 128-bit permutation */
INV_PERM0(s0);
INV_PERM1(s1);
INV_PERM2(s2);
INV_PERM3(s3);
/* InvSubCells - apply the inverse of the S-box */
temp = s0;
s0 = s3;
s3 = temp;
s2 ^= s0 & s1;
s3 ^= 0xFFFFFFFFU;
s1 ^= s3;
s3 ^= s2;
s2 ^= s0 | s1;
s0 ^= s1 & s3;
s1 ^= s0 & s2;
}
/* Perform all 40 rounds five at a time using the fixsliced method.
* Every 5 rounds except the first we add the tweak value to the state */
tword = GIFT128_tweaks[tweak];
gift128b_decrypt_5_rounds(ks->k + 70, GIFT128_RC + 35);
s0 ^= tword;
gift128b_decrypt_5_rounds(ks->k + 60, GIFT128_RC + 30);
s0 ^= tword;
gift128b_decrypt_5_rounds(ks->k + 50, GIFT128_RC + 25);
s0 ^= tword;
gift128b_decrypt_5_rounds(ks->k + 40, GIFT128_RC + 20);
s0 ^= tword;
gift128b_decrypt_5_rounds(ks->k + 30, GIFT128_RC + 15);
s0 ^= tword;
gift128b_decrypt_5_rounds(ks->k + 20, GIFT128_RC + 10);
s0 ^= tword;
gift128b_decrypt_5_rounds(ks->k + 10, GIFT128_RC + 5);
s0 ^= tword;
gift128b_decrypt_5_rounds(ks->k, GIFT128_RC);
/* Pack the state into the plaintext buffer in nibble form */
be_store_word32(output, s0);
......@@ -1492,7 +847,3 @@ void gift128t_decrypt
be_store_word32(output + 12, s3);
gift128n_to_nibbles(output, output);
}
#endif /* GIFT128_VARIANT_SMALL || GIFT128_VARIANT_TINY */
#endif /* !GIFT128_VARIANT_ASM */
......@@ -47,13 +47,11 @@
* in any of the NIST submissions so we don't bother with it in this library.
*
* References: https://eprint.iacr.org/2017/622.pdf,
* https://eprint.iacr.org/2020/412.pdf,
* https://giftcipher.github.io/gift/
*/
#include <stddef.h>
#include <stdint.h>
#include "internal-gift128-config.h"
#ifdef __cplusplus
extern "C" {
......@@ -65,23 +63,16 @@ extern "C" {
#define GIFT128_BLOCK_SIZE 16
/**
* \var GIFT128_ROUND_KEYS
* \brief Number of round keys for the GIFT-128 key schedule.
* \brief Number of round keys for the fixsliced representation of GIFT-128.
*/
#if GIFT128_VARIANT == GIFT128_VARIANT_TINY
#define GIFT128_ROUND_KEYS 4
#elif GIFT128_VARIANT == GIFT128_VARIANT_SMALL
#define GIFT128_ROUND_KEYS 20
#else
#define GIFT128_ROUND_KEYS 80
#endif
/**
* \brief Structure of the key schedule for GIFT-128 (bit-sliced).
*/
typedef struct
{
/** Pre-computed round keys for bit-sliced GIFT-128 */
/** Pre-computed round keys in the fixsliced form */
uint32_t k[GIFT128_ROUND_KEYS];
} gift128b_key_schedule_t;
......@@ -90,9 +81,14 @@ typedef struct
* \brief Initializes the key schedule for GIFT-128 (bit-sliced).
*
* \param ks Points to the key schedule to initialize.
* \param key Points to the 16 bytes of the key data.
* \param key Points to the key data.
* \param key_len Length of the key data, which must be 16.
*
* \return Non-zero on success or zero if there is something wrong
* with the parameters.
*/
void gift128b_init(gift128b_key_schedule_t *ks, const unsigned char *key);
int gift128b_init
(gift128b_key_schedule_t *ks, const unsigned char *key, size_t key_len);
/**
* \brief Encrypts a 128-bit block with GIFT-128 (bit-sliced).
......@@ -149,9 +145,14 @@ typedef gift128b_key_schedule_t gift128n_key_schedule_t;
* \brief Initializes the key schedule for GIFT-128 (nibble-based).
*
* \param ks Points to the key schedule to initialize.
* \param key Points to the 16 bytes of the key data.
* \param key Points to the key data.
* \param key_len Length of the key data, which must be 16.
*
* \return Non-zero on success or zero if there is something wrong
* with the parameters.
*/
void gift128n_init(gift128n_key_schedule_t *ks, const unsigned char *key);
int gift128n_init
(gift128n_key_schedule_t *ks, const unsigned char *key, size_t key_len);
/**
* \brief Encrypts a 128-bit block with GIFT-128 (nibble-based).
......@@ -181,31 +182,13 @@ void gift128n_decrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input);
/* 4-bit tweak values expanded to 32-bit for TweGIFT-128 */
#define GIFT128T_TWEAK_0 0x00000000 /**< TweGIFT-128 tweak value 0 */
#define GIFT128T_TWEAK_1 0xe1e1e1e1 /**< TweGIFT-128 tweak value 1 */
#define GIFT128T_TWEAK_2 0xd2d2d2d2 /**< TweGIFT-128 tweak value 2 */
#define GIFT128T_TWEAK_3 0x33333333 /**< TweGIFT-128 tweak value 3 */
#define GIFT128T_TWEAK_4 0xb4b4b4b4 /**< TweGIFT-128 tweak value 4 */
#define GIFT128T_TWEAK_5 0x55555555 /**< TweGIFT-128 tweak value 5 */
#define GIFT128T_TWEAK_6 0x66666666 /**< TweGIFT-128 tweak value 6 */
#define GIFT128T_TWEAK_7 0x87878787 /**< TweGIFT-128 tweak value 7 */
#define GIFT128T_TWEAK_8 0x78787878 /**< TweGIFT-128 tweak value 8 */
#define GIFT128T_TWEAK_9 0x99999999 /**< TweGIFT-128 tweak value 9 */
#define GIFT128T_TWEAK_10 0xaaaaaaaa /**< TweGIFT-128 tweak value 10 */
#define GIFT128T_TWEAK_11 0x4b4b4b4b /**< TweGIFT-128 tweak value 11 */
#define GIFT128T_TWEAK_12 0xcccccccc /**< TweGIFT-128 tweak value 12 */
#define GIFT128T_TWEAK_13 0x2d2d2d2d /**< TweGIFT-128 tweak value 13 */
#define GIFT128T_TWEAK_14 0x1e1e1e1e /**< TweGIFT-128 tweak value 14 */
#define GIFT128T_TWEAK_15 0xffffffff /**< TweGIFT-128 tweak value 15 */
/**
* \brief Encrypts a 128-bit block with TweGIFT-128 (tweakable variant).
*
* \param ks Points to the GIFT-128 key schedule.
* \param output Output buffer which must be at least 16 bytes in length.
* \param input Input buffer which must be at least 16 bytes in length.
* \param tweak 4-bit tweak value expanded to 32-bit.
* \param tweak 4-bit tweak value.
*
* The \a input and \a output buffers can be the same buffer for
* in-place encryption.
......@@ -217,7 +200,7 @@ void gift128n_decrypt
*/
void gift128t_encrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak);
const unsigned char *input, unsigned char tweak);
/**
* \brief Decrypts a 128-bit block with TweGIFT-128 (tweakable variant).
......@@ -225,7 +208,7 @@ void gift128t_encrypt
* \param ks Points to the GIFT-128 key schedule.
* \param output Output buffer which must be at least 16 bytes in length.
* \param input Input buffer which must be at least 16 bytes in length.
* \param tweak 4-bit tweak value expanded to 32-bit.
* \param tweak 4-bit tweak value.
*
* The \a input and \a output buffers can be the same buffer for
* in-place encryption.
......@@ -237,7 +220,7 @@ void gift128t_encrypt
*/
void gift128t_decrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak);
const unsigned char *input, unsigned char tweak);
#ifdef __cplusplus
}
......
......@@ -238,17 +238,6 @@
} \
} while (0)
/* Rotation functions need to be optimised for best performance on AVR.
* The most efficient rotations are where the number of bits is 1 or a
* multiple of 8, so we compose the efficient rotations to produce all
* other rotation counts of interest. */
#if defined(__AVR__)
#define LW_CRYPTO_ROTATE32_COMPOSED 1
#else
#define LW_CRYPTO_ROTATE32_COMPOSED 0
#endif
/* Rotation macros for 32-bit arguments */
/* Generic left rotate */
......@@ -265,8 +254,6 @@
(_temp >> (bits)) | (_temp << (32 - (bits))); \
}))
#if !LW_CRYPTO_ROTATE32_COMPOSED
/* Left rotate by a specific number of bits. These macros may be replaced
* with more efficient ones on platforms that lack a barrel shifter */
#define leftRotate1(a) (leftRotate((a), 1))
......@@ -335,138 +322,6 @@
#define rightRotate30(a) (rightRotate((a), 30))
#define rightRotate31(a) (rightRotate((a), 31))
#else /* LW_CRYPTO_ROTATE32_COMPOSED */
/* Composed rotation macros where 1 and 8 are fast, but others are slow */
/* Left rotate by 1 */
#define leftRotate1(a) (leftRotate((a), 1))
/* Left rotate by 2 */
#define leftRotate2(a) (leftRotate(leftRotate((a), 1), 1))
/* Left rotate by 3 */
#define leftRotate3(a) (leftRotate(leftRotate(leftRotate((a), 1), 1), 1))
/* Left rotate by 4 */
#define leftRotate4(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 1), 1), 1), 1))
/* Left rotate by 5: Rotate left by 8, then right by 3 */
#define leftRotate5(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 8), 1), 1), 1))
/* Left rotate by 6: Rotate left by 8, then right by 2 */
#define leftRotate6(a) (rightRotate(rightRotate(leftRotate((a), 8), 1), 1))
/* Left rotate by 7: Rotate left by 8, then right by 1 */
#define leftRotate7(a) (rightRotate(leftRotate((a), 8), 1))
/* Left rotate by 8 */
#define leftRotate8(a) (leftRotate((a), 8))
/* Left rotate by 9: Rotate left by 8, then left by 1 */
#define leftRotate9(a) (leftRotate(leftRotate((a), 8), 1))
/* Left rotate by 10: Rotate left by 8, then left by 2 */
#define leftRotate10(a) (leftRotate(leftRotate(leftRotate((a), 8), 1), 1))
/* Left rotate by 11: Rotate left by 8, then left by 3 */
#define leftRotate11(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 8), 1), 1), 1))
/* Left rotate by 12: Rotate left by 16, then right by 4 */
#define leftRotate12(a) (rightRotate(rightRotate(rightRotate(rightRotate(leftRotate((a), 16), 1), 1), 1), 1))
/* Left rotate by 13: Rotate left by 16, then right by 3 */
#define leftRotate13(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 16), 1), 1), 1))
/* Left rotate by 14: Rotate left by 16, then right by 2 */
#define leftRotate14(a) (rightRotate(rightRotate(leftRotate((a), 16), 1), 1))
/* Left rotate by 15: Rotate left by 16, then right by 1 */
#define leftRotate15(a) (rightRotate(leftRotate((a), 16), 1))
/* Left rotate by 16 */
#define leftRotate16(a) (leftRotate((a), 16))
/* Left rotate by 17: Rotate left by 16, then left by 1 */
#define leftRotate17(a) (leftRotate(leftRotate((a), 16), 1))
/* Left rotate by 18: Rotate left by 16, then left by 2 */
#define leftRotate18(a) (leftRotate(leftRotate(leftRotate((a), 16), 1), 1))
/* Left rotate by 19: Rotate left by 16, then left by 3 */
#define leftRotate19(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 16), 1), 1), 1))
/* Left rotate by 20: Rotate left by 16, then left by 4 */
#define leftRotate20(a) (leftRotate(leftRotate(leftRotate(leftRotate(leftRotate((a), 16), 1), 1), 1), 1))
/* Left rotate by 21: Rotate left by 24, then right by 3 */
#define leftRotate21(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 24), 1), 1), 1))
/* Left rotate by 22: Rotate left by 24, then right by 2 */
#define leftRotate22(a) (rightRotate(rightRotate(leftRotate((a), 24), 1), 1))
/* Left rotate by 23: Rotate left by 24, then right by 1 */
#define leftRotate23(a) (rightRotate(leftRotate((a), 24), 1))
/* Left rotate by 24 */
#define leftRotate24(a) (leftRotate((a), 24))
/* Left rotate by 25: Rotate left by 24, then left by 1 */
#define leftRotate25(a) (leftRotate(leftRotate((a), 24), 1))
/* Left rotate by 26: Rotate left by 24, then left by 2 */
#define leftRotate26(a) (leftRotate(leftRotate(leftRotate((a), 24), 1), 1))
/* Left rotate by 27: Rotate left by 24, then left by 3 */
#define leftRotate27(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 24), 1), 1), 1))
/* Left rotate by 28: Rotate right by 4 */
#define leftRotate28(a) (rightRotate(rightRotate(rightRotate(rightRotate((a), 1), 1), 1), 1))
/* Left rotate by 29: Rotate right by 3 */
#define leftRotate29(a) (rightRotate(rightRotate(rightRotate((a), 1), 1), 1))
/* Left rotate by 30: Rotate right by 2 */
#define leftRotate30(a) (rightRotate(rightRotate((a), 1), 1))
/* Left rotate by 31: Rotate right by 1 */
#define leftRotate31(a) (rightRotate((a), 1))
/* Define the 32-bit right rotations in terms of left rotations */
#define rightRotate1(a) (leftRotate31((a)))
#define rightRotate2(a) (leftRotate30((a)))
#define rightRotate3(a) (leftRotate29((a)))
#define rightRotate4(a) (leftRotate28((a)))
#define rightRotate5(a) (leftRotate27((a)))
#define rightRotate6(a) (leftRotate26((a)))
#define rightRotate7(a) (leftRotate25((a)))
#define rightRotate8(a) (leftRotate24((a)))
#define rightRotate9(a) (leftRotate23((a)))
#define rightRotate10(a) (leftRotate22((a)))
#define rightRotate11(a) (leftRotate21((a)))
#define rightRotate12(a) (leftRotate20((a)))
#define rightRotate13(a) (leftRotate19((a)))
#define rightRotate14(a) (leftRotate18((a)))
#define rightRotate15(a) (leftRotate17((a)))
#define rightRotate16(a) (leftRotate16((a)))
#define rightRotate17(a) (leftRotate15((a)))
#define rightRotate18(a) (leftRotate14((a)))
#define rightRotate19(a) (leftRotate13((a)))
#define rightRotate20(a) (leftRotate12((a)))
#define rightRotate21(a) (leftRotate11((a)))
#define rightRotate22(a) (leftRotate10((a)))
#define rightRotate23(a) (leftRotate9((a)))
#define rightRotate24(a) (leftRotate8((a)))
#define rightRotate25(a) (leftRotate7((a)))
#define rightRotate26(a) (leftRotate6((a)))
#define rightRotate27(a) (leftRotate5((a)))
#define rightRotate28(a) (leftRotate4((a)))
#define rightRotate29(a) (leftRotate3((a)))
#define rightRotate30(a) (leftRotate2((a)))
#define rightRotate31(a) (leftRotate1((a)))
#endif /* LW_CRYPTO_ROTATE32_COMPOSED */
/* Rotation macros for 64-bit arguments */
/* Generic left rotate */
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "aead-common.h"
int aead_check_tag
(unsigned char *plaintext, unsigned long long plaintext_len,
const unsigned char *tag1, const unsigned char *tag2,
unsigned size)
{
/* Set "accum" to -1 if the tags match, or 0 if they don't match */
int accum = 0;
while (size > 0) {
accum |= (*tag1++ ^ *tag2++);
--size;
}
accum = (accum - 1) >> 8;
/* Destroy the plaintext if the tag match failed */
while (plaintext_len > 0) {
*plaintext++ &= accum;
--plaintext_len;
}
/* If "accum" is 0, return -1, otherwise return 0 */
return ~accum;
}
int aead_check_tag_precheck
(unsigned char *plaintext, unsigned long long plaintext_len,
const unsigned char *tag1, const unsigned char *tag2,
unsigned size, int precheck)
{
/* Set "accum" to -1 if the tags match, or 0 if they don't match */
int accum = 0;
while (size > 0) {
accum |= (*tag1++ ^ *tag2++);
--size;
}
accum = ((accum - 1) >> 8) & precheck;
/* Destroy the plaintext if the tag match failed */
while (plaintext_len > 0) {
*plaintext++ &= accum;
--plaintext_len;
}
/* If "accum" is 0, return -1, otherwise return 0 */
return ~accum;
}
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef LWCRYPTO_AEAD_COMMON_H
#define LWCRYPTO_AEAD_COMMON_H
#include <stddef.h>
/**
* \file aead-common.h
* \brief Definitions that are common across AEAD schemes.
*
* AEAD stands for "Authenticated Encryption with Associated Data".
* It is a standard API pattern for securely encrypting and
* authenticating packets of data.
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Encrypts and authenticates a packet with an AEAD scheme.
*
* \param c Buffer to receive the output.
* \param clen On exit, set to the length of the output which includes
* the ciphertext and the authentication tag.
* \param m Buffer that contains the plaintext message to encrypt.
* \param mlen Length of the plaintext message in bytes.
* \param ad Buffer that contains associated data to authenticate
* along with the packet but which does not need to be encrypted.
* \param adlen Length of the associated data in bytes.
* \param nsec Secret nonce - normally not used by AEAD schemes.
* \param npub Points to the public nonce for the packet.
* \param k Points to the key to use to encrypt the packet.
*
* \return 0 on success, or a negative value if there was an error in
* the parameters.
*/
typedef int (*aead_cipher_encrypt_t)
(unsigned char *c, unsigned long long *clen,
const unsigned char *m, unsigned long long mlen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with an AEAD scheme.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \param nsec Secret nonce - normally not used by AEAD schemes.
* \param c Buffer that contains the ciphertext and authentication
* tag to decrypt.
* \param clen Length of the input data in bytes, which includes the
* ciphertext and the authentication tag.
* \param ad Buffer that contains associated data to authenticate
* along with the packet but which does not need to be encrypted.
* \param adlen Length of the associated data in bytes.
* \param npub Points to the public nonce for the packet.
* \param k Points to the key to use to decrypt the packet.
*
* \return 0 on success, -1 if the authentication tag was incorrect,
* or some other negative number if there was an error in the parameters.
*/
typedef int (*aead_cipher_decrypt_t)
(unsigned char *m, unsigned long long *mlen,
unsigned char *nsec,
const unsigned char *c, unsigned long long clen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Hashes a block of input data.
*
* \param out Buffer to receive the hash output.
* \param in Points to the input data to be hashed.
* \param inlen Length of the input data in bytes.
*
* \return Returns zero on success or -1 if there was an error in the
* parameters.
*/
typedef int (*aead_hash_t)
(unsigned char *out, const unsigned char *in, unsigned long long inlen);
/**
* \brief Initializes the state for a hashing operation.
*
* \param state Hash state to be initialized.
*/
typedef void (*aead_hash_init_t)(void *state);
/**
* \brief Updates a hash state with more input data.
*
* \param state Hash state to be updated.
* \param in Points to the input data to be incorporated into the state.
* \param inlen Length of the input data to be incorporated into the state.
*/
typedef void (*aead_hash_update_t)
(void *state, const unsigned char *in, unsigned long long inlen);
/**
* \brief Returns the final hash value from a hashing operation.
*
* \param Hash state to be finalized.
* \param out Points to the output buffer to receive the hash value.
*/
typedef void (*aead_hash_finalize_t)(void *state, unsigned char *out);
/**
* \brief Aborbs more input data into an XOF state.
*
* \param state XOF state to be updated.
* \param in Points to the input data to be absorbed into the state.
* \param inlen Length of the input data to be absorbed into the state.
*
* \sa ascon_xof_init(), ascon_xof_squeeze()
*/
typedef void (*aead_xof_absorb_t)
(void *state, const unsigned char *in, unsigned long long inlen);
/**
* \brief Squeezes output data from an XOF state.
*
* \param state XOF state to squeeze the output data from.
* \param out Points to the output buffer to receive the squeezed data.
* \param outlen Number of bytes of data to squeeze out of the state.
*/
typedef void (*aead_xof_squeeze_t)
(void *state, unsigned char *out, unsigned long long outlen);
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
*
* If this flag is not present, then the natural byte order of the
* AEAD cipher should be assumed to be big-endian.
*
* The natural byte order may be useful when formatting packet sequence
* numbers as nonces. The application needs to know whether the sequence
* number should be packed into the leading or trailing bytes of the nonce.
*/
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief Meta-information about an AEAD cipher.
*/
typedef struct
{
const char *name; /**< Name of the cipher */
unsigned key_len; /**< Length of the key in bytes */
unsigned nonce_len; /**< Length of the nonce in bytes */
unsigned tag_len; /**< Length of the tag in bytes */
unsigned flags; /**< Flags for extra features */
aead_cipher_encrypt_t encrypt; /**< AEAD encryption function */
aead_cipher_decrypt_t decrypt; /**< AEAD decryption function */
} aead_cipher_t;
/**
* \brief Meta-information about a hash algorithm that is related to an AEAD.
*
* Regular hash algorithms should provide the "hash", "init", "update",
* and "finalize" functions. Extensible Output Functions (XOF's) should
* proivde the "hash", "init", "absorb", and "squeeze" functions.
*/
typedef struct
{
const char *name; /**< Name of the hash algorithm */
size_t state_size; /**< Size of the incremental state structure */
unsigned hash_len; /**< Length of the hash in bytes */
unsigned flags; /**< Flags for extra features */
aead_hash_t hash; /**< All in one hashing function */
aead_hash_init_t init; /**< Incremental hash/XOF init function */
aead_hash_update_t update; /**< Incremental hash update function */
aead_hash_finalize_t finalize; /**< Incremental hash finalize function */
aead_xof_absorb_t absorb; /**< Incremental XOF absorb function */
aead_xof_squeeze_t squeeze; /**< Incremental XOF squeeze function */
} aead_hash_algorithm_t;
/**
* \brief Check an authentication tag in constant time.
*
* \param plaintext Points to the plaintext data.
* \param plaintext_len Length of the plaintext in bytes.
* \param tag1 First tag to compare.
* \param tag2 Second tag to compare.
* \param tag_len Length of the tags in bytes.
*
* \return Returns -1 if the tag check failed or 0 if the check succeeded.
*
* If the tag check fails, then the \a plaintext will also be zeroed to
* prevent it from being used accidentally by the application when the
* ciphertext was invalid.
*/
int aead_check_tag
(unsigned char *plaintext, unsigned long long plaintext_len,
const unsigned char *tag1, const unsigned char *tag2,
unsigned tag_len);
/**
* \brief Check an authentication tag in constant time with a previous check.
*
* \param plaintext Points to the plaintext data.
* \param plaintext_len Length of the plaintext in bytes.
* \param tag1 First tag to compare.
* \param tag2 Second tag to compare.
* \param tag_len Length of the tags in bytes.
* \param precheck Set to -1 if previous check succeeded or 0 if it failed.
*
* \return Returns -1 if the tag check failed or 0 if the check succeeded.
*
* If the tag check fails, then the \a plaintext will also be zeroed to
* prevent it from being used accidentally by the application when the
* ciphertext was invalid.
*
* This version can be used to incorporate other information about the
* correctness of the plaintext into the final result.
*/
int aead_check_tag_precheck
(unsigned char *plaintext, unsigned long long plaintext_len,
const unsigned char *tag1, const unsigned char *tag2,
unsigned tag_len, int precheck);
#ifdef __cplusplus
}
#endif
#endif
#define CRYPTO_KEYBYTES 16
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 12
#define CRYPTO_ABYTES 16
#define CRYPTO_NOOVERLAP 1
#include "hyena.h"
int crypto_aead_encrypt
(unsigned char *c, unsigned long long *clen,
const unsigned char *m, unsigned long long mlen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k)
{
return hyena_aead_encrypt
(c, clen, m, mlen, ad, adlen, nsec, npub, k);
}
int crypto_aead_decrypt
(unsigned char *m, unsigned long long *mlen,
unsigned char *nsec,
const unsigned char *c, unsigned long long clen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k)
{
return hyena_aead_decrypt
(m, mlen, nsec, c, clen, ad, adlen, npub, k);
}
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "hyena.h"
#include "internal-gift128.h"
#include "internal-util.h"
#include <string.h>
aead_cipher_t const hyena_cipher = {
"HYENA",
HYENA_KEY_SIZE,
HYENA_NONCE_SIZE,
HYENA_TAG_SIZE,
AEAD_FLAG_LITTLE_ENDIAN,
hyena_aead_encrypt,
hyena_aead_decrypt
};
/**
* \brief Doubles a delta value in the F(2^64) field.
*
* \param D The delta value to be doubled.
*
* D = D << 1 if the top-most bit is 0, or D = (D << 1) ^ 0x1B otherwise.
*/
static void hyena_double_delta(unsigned char D[8])
{
unsigned index;
unsigned char mask = (unsigned char)(((signed char)(D[0])) >> 7);
for (index = 0; index < 7; ++index)
D[index] = (D[index] << 1) | (D[index + 1] >> 7);
D[7] = (D[7] << 1) ^ (mask & 0x1B);
}
/**
* \brief Triples a delta value in the F(2^64) field.
*
* \param D The delta value to be tripled.
*
* D' = D ^ (D << 1) if the top-most bit is 0, or D' = D ^ (D << 1) ^ 0x1B
* otherwise.
*/
static void hyena_triple_delta(unsigned char D[8])
{
unsigned index;
unsigned char mask = (unsigned char)(((signed char)(D[0])) >> 7);
for (index = 0; index < 7; ++index)
D[index] ^= (D[index] << 1) | (D[index + 1] >> 7);
D[7] ^= (D[7] << 1) ^ (mask & 0x1B);
}
/**
* \brief Process the associated data for HYENA.
*
* \param ks Key schedule for the GIFT-128 cipher.
* \param Y Internal hash state of HYENA.
* \param D Internal hash state of HYENA.
* \param ad Points to the associated data.
* \param adlen Length of the associated data in bytes.
*/
static void hyena_process_ad
(const gift128n_key_schedule_t *ks, unsigned char Y[16],
unsigned char D[8], const unsigned char *ad,
unsigned long long adlen)
{
unsigned char feedback[16];
while (adlen > 16) {
hyena_double_delta(D);
memcpy(feedback, ad, 16);
lw_xor_block(feedback + 8, Y + 8, 8);
lw_xor_block(feedback + 8, D, 8);
lw_xor_block(Y, feedback, 16);
gift128n_encrypt(ks, Y, Y);
ad += 16;
adlen -= 16;
}
if (adlen == 16) {
hyena_triple_delta(D);
memcpy(feedback, ad, 16);
lw_xor_block(feedback + 8, Y + 8, 8);
lw_xor_block(feedback + 8, D, 8);
lw_xor_block(Y, feedback, 16);
} else {
unsigned temp = (unsigned)adlen;
hyena_triple_delta(D);
hyena_triple_delta(D);
memcpy(feedback, ad, temp);
feedback[temp] = 0x01;
memset(feedback + temp + 1, 0, 15 - temp);
if (temp > 8)
lw_xor_block(feedback + 8, Y + 8, temp - 8);
lw_xor_block(feedback + 8, D, 8);
lw_xor_block(Y, feedback, 16);
}
}
int hyena_aead_encrypt
(unsigned char *c, unsigned long long *clen,
const unsigned char *m, unsigned long long mlen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k)
{
gift128n_key_schedule_t ks;
unsigned char Y[16];
unsigned char D[8];
unsigned char feedback[16];
unsigned index;
(void)nsec;
/* Set the length of the returned ciphertext */
*clen = mlen + HYENA_TAG_SIZE;
/* Set up the key schedule and use it to encrypt the nonce */
gift128n_init(&ks, k);
Y[0] = 0;
if (adlen == 0)
Y[0] |= 0x01;
if (adlen == 0 && mlen == 0)
Y[0] |= 0x02;
Y[1] = 0;
Y[2] = 0;
Y[3] = 0;
memcpy(Y + 4, npub, HYENA_NONCE_SIZE);
gift128n_encrypt(&ks, Y, Y);
memcpy(D, Y + 8, 8);
/* Process the associated data */
hyena_process_ad(&ks, Y, D, ad, adlen);
/* Encrypt the plaintext to produce the ciphertext */
if (mlen > 0) {
while (mlen > 16) {
gift128n_encrypt(&ks, Y, Y);
hyena_double_delta(D);
memcpy(feedback, m, 16);
lw_xor_block(feedback + 8, Y + 8, 8);
lw_xor_block(feedback + 8, D, 8);
lw_xor_block_2_src(c, m, Y, 16);
lw_xor_block(Y, feedback, 16);
c += 16;
m += 16;
mlen -= 16;
}
gift128n_encrypt(&ks, Y, Y);
if (mlen == 16) {
hyena_triple_delta(D);
memcpy(feedback, m, 16);
lw_xor_block(feedback + 8, Y + 8, 8);
lw_xor_block(feedback + 8, D, 8);
lw_xor_block_2_src(c, m, Y, 16);
lw_xor_block(Y, feedback, 16);
c += 16;
} else {
unsigned temp = (unsigned)mlen;
hyena_triple_delta(D);
hyena_triple_delta(D);
memcpy(feedback, m, temp);
feedback[temp] = 0x01;
memset(feedback + temp + 1, 0, 15 - temp);
if (temp > 8)
lw_xor_block(feedback + 8, Y + 8, temp - 8);
lw_xor_block(feedback + 8, D, 8);
lw_xor_block_2_src(c, m, Y, temp);
lw_xor_block(Y, feedback, 16);
c += temp;
}
}
/* Swap the two halves of Y and generate the authentication tag */
for (index = 0; index < 8; ++index) {
unsigned char temp1 = Y[index];
unsigned char temp2 = Y[index + 8];
Y[index] = temp2;
Y[index + 8] = temp1;
}
gift128n_encrypt(&ks, c, Y);
return 0;
}
int hyena_aead_decrypt
(unsigned char *m, unsigned long long *mlen,
unsigned char *nsec,
const unsigned char *c, unsigned long long clen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k)
{
gift128n_key_schedule_t ks;
unsigned char Y[16];
unsigned char D[8];
unsigned char feedback[16];
unsigned char *mtemp;
unsigned index;
(void)nsec;
/* Validate the ciphertext length and set the return "mlen" value */
if (clen < HYENA_TAG_SIZE)
return -1;
*mlen = clen - HYENA_TAG_SIZE;
/* Set up the key schedule and use it to encrypt the nonce */
gift128n_init(&ks, k);
Y[0] = 0;
if (adlen == 0)
Y[0] |= 0x01;
if (adlen == 0 && clen == HYENA_TAG_SIZE)
Y[0] |= 0x02;
Y[1] = 0;
Y[2] = 0;
Y[3] = 0;
memcpy(Y + 4, npub, HYENA_NONCE_SIZE);
gift128n_encrypt(&ks, Y, Y);
memcpy(D, Y + 8, 8);
/* Process the associated data */
hyena_process_ad(&ks, Y, D, ad, adlen);
/* Decrypt the ciphertext to produce the plaintext */
clen -= HYENA_TAG_SIZE;
mtemp = m;
if (clen > 0) {
while (clen > 16) {
gift128n_encrypt(&ks, Y, Y);
hyena_double_delta(D);
memcpy(feedback + 8, c + 8, 8);
lw_xor_block_2_src(m, c, Y, 16);
memcpy(feedback, m, 8);
lw_xor_block(feedback + 8, D, 8);
lw_xor_block(Y, feedback, 16);
c += 16;
m += 16;
clen -= 16;
}
gift128n_encrypt(&ks, Y, Y);
if (clen == 16) {
hyena_triple_delta(D);
memcpy(feedback + 8, c + 8, 8);
lw_xor_block_2_src(m, c, Y, 16);
memcpy(feedback, m, 8);
lw_xor_block(feedback + 8, D, 8);
lw_xor_block(Y, feedback, 16);
c += 16;
} else {
unsigned temp = (unsigned)clen;
hyena_triple_delta(D);
hyena_triple_delta(D);
if (temp > 8) {
memcpy(feedback + 8, c + 8, temp - 8);
lw_xor_block_2_src(m, c, Y, temp);
memcpy(feedback, m, 8);
} else {
lw_xor_block_2_src(m, c, Y, temp);
memcpy(feedback, m, temp);
}
feedback[temp] = 0x01;
memset(feedback + temp + 1, 0, 15 - temp);
lw_xor_block(feedback + 8, D, 8);
lw_xor_block(Y, feedback, 16);
c += temp;
}
}
/* Swap the two halves of Y and check the authentication tag */
for (index = 0; index < 8; ++index) {
unsigned char temp1 = Y[index];
unsigned char temp2 = Y[index + 8];
Y[index] = temp2;
Y[index + 8] = temp1;
}
gift128n_encrypt(&ks, Y, Y);
return aead_check_tag(mtemp, *mlen, Y, c, HYENA_TAG_SIZE);
}
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef LWCRYPTO_HYENA_H
#define LWCRYPTO_HYENA_H
#include "aead-common.h"
/**
* \file hyena.h
* \brief HYENA authenticated encryption algorithm.
*
* HYENA is an authenticated encryption algorithm that is built around the
* GIFT-128 block cipher. The algorithm has a 128-bit key, a 96-bit nonce,
* and a 128-bit authentication tag.
*
* References: https://www.isical.ac.in/~lightweight/hyena/
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Size of the key for HYENA.
*/
#define HYENA_KEY_SIZE 16
/**
* \brief Size of the authentication tag for HYENA.
*/
#define HYENA_TAG_SIZE 16
/**
* \brief Size of the nonce for HYENA.
*/
#define HYENA_NONCE_SIZE 12
/**
* \brief Meta-information block for the HYENA cipher.
*/
extern aead_cipher_t const hyena_cipher;
/**
* \brief Encrypts and authenticates a packet with HYENA.
*
* \param c Buffer to receive the output.
* \param clen On exit, set to the length of the output which includes
* the ciphertext and the 16 byte authentication tag.
* \param m Buffer that contains the plaintext message to encrypt.
* \param mlen Length of the plaintext message in bytes.
* \param ad Buffer that contains associated data to authenticate
* along with the packet but which does not need to be encrypted.
* \param adlen Length of the associated data in bytes.
* \param nsec Secret nonce - not used by this algorithm.
* \param npub Points to the public nonce for the packet which must
* be 12 bytes in length.
* \param k Points to the 16 bytes of the key to use to encrypt the packet.
*
* \return 0 on success, or a negative value if there was an error in
* the parameters.
*
* \sa hyena_aead_decrypt()
*/
int hyena_aead_encrypt
(unsigned char *c, unsigned long long *clen,
const unsigned char *m, unsigned long long mlen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with HYENA.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \param nsec Secret nonce - not used by this algorithm.
* \param c Buffer that contains the ciphertext and authentication
* tag to decrypt.
* \param clen Length of the input data in bytes, which includes the
* ciphertext and the 16 byte authentication tag.
* \param ad Buffer that contains associated data to authenticate
* along with the packet but which does not need to be encrypted.
* \param adlen Length of the associated data in bytes.
* \param npub Points to the public nonce for the packet which must
* be 12 bytes in length.
* \param k Points to the 16 bytes of the key to use to decrypt the packet.
*
* \return 0 on success, -1 if the authentication tag was incorrect,
* or some other negative number if there was an error in the parameters.
*
* \sa hyena_aead_encrypt()
*/
int hyena_aead_decrypt
(unsigned char *m, unsigned long long *mlen,
unsigned char *nsec,
const unsigned char *c, unsigned long long clen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef LW_INTERNAL_GIFT128_CONFIG_H
#define LW_INTERNAL_GIFT128_CONFIG_H
/**
* \file internal-gift128-config.h
* \brief Configures the variant of GIFT-128 to use.
*/
/**
* \brief Select the full variant of GIFT-128.
*
* The full variant requires 320 bytes for the key schedule and uses the
* fixslicing method to implement encryption and decryption.
*/
#define GIFT128_VARIANT_FULL 0
/**
* \brief Select the small variant of GIFT-128.
*
* The small variant requires 80 bytes for the key schedule. The rest
* of the key schedule is expanded on the fly during encryption.
*
* The fixslicing method is used to implement encryption and the slower
* bitslicing method is used to implement decryption. The small variant
* is suitable when memory is at a premium, decryption is not needed,
* but encryption performance is still important.
*/
#define GIFT128_VARIANT_SMALL 1
/**
* \brief Select the tiny variant of GIFT-128.
*
* The tiny variant requires 16 bytes for the key schedule and uses the
* bitslicing method to implement encryption and decryption. It is suitable
* for use when memory is very tight and performance is not critical.
*/
#define GIFT128_VARIANT_TINY 2
/**
* \def GIFT128_VARIANT
* \brief Selects the default variant of GIFT-128 to use on this platform.
*/
/**
* \def GIFT128_VARIANT_ASM
* \brief Defined to 1 if the GIFT-128 implementation has been replaced
* with an assembly code version.
*/
#if defined(__AVR__) && !defined(GIFT128_VARIANT_ASM)
#define GIFT128_VARIANT_ASM 1
#endif
#if !defined(GIFT128_VARIANT)
#define GIFT128_VARIANT GIFT128_VARIANT_FULL
#endif
#if !defined(GIFT128_VARIANT_ASM)
#define GIFT128_VARIANT_ASM 0
#endif
#endif
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "internal-gift128.h"
#include "internal-util.h"
#if !GIFT128_VARIANT_ASM
#if GIFT128_VARIANT != GIFT128_VARIANT_TINY
/* Round constants for GIFT-128 in the fixsliced representation */
static uint32_t const GIFT128_RC_fixsliced[40] = {
0x10000008, 0x80018000, 0x54000002, 0x01010181, 0x8000001f, 0x10888880,
0x6001e000, 0x51500002, 0x03030180, 0x8000002f, 0x10088880, 0x60016000,
0x41500002, 0x03030080, 0x80000027, 0x10008880, 0x4001e000, 0x11500002,
0x03020180, 0x8000002b, 0x10080880, 0x60014000, 0x01400002, 0x02020080,
0x80000021, 0x10000080, 0x0001c000, 0x51000002, 0x03010180, 0x8000002e,
0x10088800, 0x60012000, 0x40500002, 0x01030080, 0x80000006, 0x10008808,
0xc001a000, 0x14500002, 0x01020181, 0x8000001a
};
#endif
#if GIFT128_VARIANT != GIFT128_VARIANT_FULL
/* Round constants for GIFT-128 in the bitsliced representation */
static uint8_t const GIFT128_RC[40] = {
0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3E, 0x3D, 0x3B,
0x37, 0x2F, 0x1E, 0x3C, 0x39, 0x33, 0x27, 0x0E,
0x1D, 0x3A, 0x35, 0x2B, 0x16, 0x2C, 0x18, 0x30,
0x21, 0x02, 0x05, 0x0B, 0x17, 0x2E, 0x1C, 0x38,
0x31, 0x23, 0x06, 0x0D, 0x1B, 0x36, 0x2D, 0x1A
};
#endif
/* http://programming.sirrida.de/perm_fn.html#bit_permute_step */
#define bit_permute_step(_y, mask, shift) \
do { \
uint32_t y = (_y); \
uint32_t t = ((y >> (shift)) ^ y) & (mask); \
(_y) = (y ^ t) ^ (t << (shift)); \
} while (0)
/*
* The permutation below was generated by the online permuation generator at
* "http://programming.sirrida.de/calcperm.php".
*
* All of the permutuations are essentially the same, except that each is
* rotated by 8 bits with respect to the next:
*
* P0: 0 24 16 8 1 25 17 9 2 26 18 10 3 27 19 11 4 28 20 12 5 29 21 13 6 30 22 14 7 31 23 15
* P1: 8 0 24 16 9 1 25 17 10 2 26 18 11 3 27 19 12 4 28 20 13 5 29 21 14 6 30 22 15 7 31 23
* P2: 16 8 0 24 17 9 1 25 18 10 2 26 19 11 3 27 20 12 4 28 21 13 5 29 22 14 6 30 23 15 7 31
* P3: 24 16 8 0 25 17 9 1 26 18 10 2 27 19 11 3 28 20 12 4 29 21 13 5 30 22 14 6 31 23 15 7
*
* The most efficient permutation from the online generator was P3, so we
* perform it as the core of the others, and then perform a final rotation.
*
* It is possible to do slightly better than "P3 then rotate" on desktop and
* server architectures for the other permutations. But the advantage isn't
* as evident on embedded platforms so we keep things simple.
*/
#define PERM3_INNER(x) \
do { \
bit_permute_step(x, 0x0a0a0a0a, 3); \
bit_permute_step(x, 0x00cc00cc, 6); \
bit_permute_step(x, 0x0000f0f0, 12); \
bit_permute_step(x, 0x000000ff, 24); \
} while (0)
#define PERM0(x) \
do { \
uint32_t _x = (x); \
PERM3_INNER(_x); \
(x) = leftRotate8(_x); \
} while (0)
#define PERM1(x) \
do { \
uint32_t _x = (x); \
PERM3_INNER(_x); \
(x) = leftRotate16(_x); \
} while (0)
#define PERM2(x) \
do { \
uint32_t _x = (x); \
PERM3_INNER(_x); \
(x) = leftRotate24(_x); \
} while (0)
#define PERM3(x) \
do { \
uint32_t _x = (x); \
PERM3_INNER(_x); \
(x) = _x; \
} while (0)
#define INV_PERM3_INNER(x) \
do { \
bit_permute_step(x, 0x00550055, 9); \
bit_permute_step(x, 0x00003333, 18); \
bit_permute_step(x, 0x000f000f, 12); \
bit_permute_step(x, 0x000000ff, 24); \
} while (0)
#define INV_PERM0(x) \
do { \
uint32_t _x = rightRotate8(x); \
INV_PERM3_INNER(_x); \
(x) = _x; \
} while (0)
#define INV_PERM1(x) \
do { \
uint32_t _x = rightRotate16(x); \
INV_PERM3_INNER(_x); \
(x) = _x; \
} while (0)
#define INV_PERM2(x) \
do { \
uint32_t _x = rightRotate24(x); \
INV_PERM3_INNER(_x); \
(x) = _x; \
} while (0)
#define INV_PERM3(x) \
do { \
uint32_t _x = (x); \
INV_PERM3_INNER(_x); \
(x) = _x; \
} while (0)
/**
* \brief Converts the GIFT-128 nibble-based representation into word-based.
*
* \param output Output buffer to write the word-based version to.
* \param input Input buffer to read the nibble-based version from.
*
* The \a input and \a output buffers can be the same buffer.
*/
static void gift128n_to_words
(unsigned char *output, const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
/* Load the input buffer into 32-bit words. We use the nibble order
* from the HYENA submission to NIST which is byte-reversed with respect
* to the nibble order of the original GIFT-128 paper. Nibble zero is in
* the first byte instead of the last, which means little-endian order. */
s0 = le_load_word32(input + 12);
s1 = le_load_word32(input + 8);
s2 = le_load_word32(input + 4);
s3 = le_load_word32(input);
/* Rearrange the bits so that bits 0..3 of each nibble are
* scattered to bytes 0..3 of each word. The permutation is:
*
* 0 8 16 24 1 9 17 25 2 10 18 26 3 11 19 27 4 12 20 28 5 13 21 29 6 14 22 30 7 15 23 31
*
* Generated with "http://programming.sirrida.de/calcperm.php".
*/
#define PERM_WORDS(_x) \
do { \
uint32_t x = (_x); \
bit_permute_step(x, 0x0a0a0a0a, 3); \
bit_permute_step(x, 0x00cc00cc, 6); \
bit_permute_step(x, 0x0000f0f0, 12); \
bit_permute_step(x, 0x0000ff00, 8); \
(_x) = x; \
} while (0)
PERM_WORDS(s0);
PERM_WORDS(s1);
PERM_WORDS(s2);
PERM_WORDS(s3);
/* Rearrange the bytes and write them to the output buffer */
output[0] = (uint8_t)s0;
output[1] = (uint8_t)s1;
output[2] = (uint8_t)s2;
output[3] = (uint8_t)s3;
output[4] = (uint8_t)(s0 >> 8);
output[5] = (uint8_t)(s1 >> 8);
output[6] = (uint8_t)(s2 >> 8);
output[7] = (uint8_t)(s3 >> 8);
output[8] = (uint8_t)(s0 >> 16);
output[9] = (uint8_t)(s1 >> 16);
output[10] = (uint8_t)(s2 >> 16);
output[11] = (uint8_t)(s3 >> 16);
output[12] = (uint8_t)(s0 >> 24);
output[13] = (uint8_t)(s1 >> 24);
output[14] = (uint8_t)(s2 >> 24);
output[15] = (uint8_t)(s3 >> 24);
}
/**
* \brief Converts the GIFT-128 word-based representation into nibble-based.
*
* \param output Output buffer to write the nibble-based version to.
* \param input Input buffer to read the word-based version from.
*/
static void gift128n_to_nibbles
(unsigned char *output, const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
/* Load the input bytes and rearrange them so that s0 contains the
* most significant nibbles and s3 contains the least significant */
s0 = (((uint32_t)(input[12])) << 24) |
(((uint32_t)(input[8])) << 16) |
(((uint32_t)(input[4])) << 8) |
((uint32_t)(input[0]));
s1 = (((uint32_t)(input[13])) << 24) |
(((uint32_t)(input[9])) << 16) |
(((uint32_t)(input[5])) << 8) |
((uint32_t)(input[1]));
s2 = (((uint32_t)(input[14])) << 24) |
(((uint32_t)(input[10])) << 16) |
(((uint32_t)(input[6])) << 8) |
((uint32_t)(input[2]));
s3 = (((uint32_t)(input[15])) << 24) |
(((uint32_t)(input[11])) << 16) |
(((uint32_t)(input[7])) << 8) |
((uint32_t)(input[3]));
/* Apply the inverse of PERM_WORDS() from the function above */
#define INV_PERM_WORDS(_x) \
do { \
uint32_t x = (_x); \
bit_permute_step(x, 0x00aa00aa, 7); \
bit_permute_step(x, 0x0000cccc, 14); \
bit_permute_step(x, 0x00f000f0, 4); \
bit_permute_step(x, 0x0000ff00, 8); \
(_x) = x; \
} while (0)
INV_PERM_WORDS(s0);
INV_PERM_WORDS(s1);
INV_PERM_WORDS(s2);
INV_PERM_WORDS(s3);
/* Store the result into the output buffer as 32-bit words */
le_store_word32(output + 12, s0);
le_store_word32(output + 8, s1);
le_store_word32(output + 4, s2);
le_store_word32(output, s3);
}
void gift128n_encrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
{
gift128n_to_words(output, input);
gift128b_encrypt(ks, output, output);
gift128n_to_nibbles(output, output);
}
void gift128n_decrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
{
gift128n_to_words(output, input);
gift128b_decrypt(ks, output, output);
gift128n_to_nibbles(output, output);
}
#if GIFT128_VARIANT != GIFT128_VARIANT_TINY
/**
* \brief Swaps bits within two words.
*
* \param a The first word.
* \param b The second word.
* \param mask Mask for the bits to shift.
* \param shift Shift amount in bits.
*/
#define gift128b_swap_move(a, b, mask, shift) \
do { \
uint32_t tmp = ((b) ^ ((a) >> (shift))) & (mask); \
(b) ^= tmp; \
(a) ^= tmp << (shift); \
} while (0)
/**
* \brief Derives the next 10 fixsliced keys in the key schedule.
*
* \param next Points to the buffer to receive the next 10 keys.
* \param prev Points to the buffer holding the previous 10 keys.
*
* The \a next and \a prev buffers are allowed to be the same.
*/
#define gift128b_derive_keys(next, prev) \
do { \
/* Key 0 */ \
uint32_t s = (prev)[0]; \
uint32_t t = (prev)[1]; \
gift128b_swap_move(t, t, 0x00003333U, 16); \
gift128b_swap_move(t, t, 0x55554444U, 1); \
(next)[0] = t; \
/* Key 1 */ \
s = leftRotate8(s & 0x33333333U) | leftRotate16(s & 0xCCCCCCCCU); \
gift128b_swap_move(s, s, 0x55551100U, 1); \
(next)[1] = s; \
/* Key 2 */ \
s = (prev)[2]; \
t = (prev)[3]; \
(next)[2] = ((t >> 4) & 0x0F000F00U) | ((t & 0x0F000F00U) << 4) | \
((t >> 6) & 0x00030003U) | ((t & 0x003F003FU) << 2); \
/* Key 3 */ \
(next)[3] = ((s >> 6) & 0x03000300U) | ((s & 0x3F003F00U) << 2) | \
((s >> 5) & 0x00070007U) | ((s & 0x001F001FU) << 3); \
/* Key 4 */ \
s = (prev)[4]; \
t = (prev)[5]; \
(next)[4] = leftRotate8(t & 0xAAAAAAAAU) | \
leftRotate16(t & 0x55555555U); \
/* Key 5 */ \
(next)[5] = leftRotate8(s & 0x55555555U) | \
leftRotate12(s & 0xAAAAAAAAU); \
/* Key 6 */ \
s = (prev)[6]; \
t = (prev)[7]; \
(next)[6] = ((t >> 2) & 0x03030303U) | ((t & 0x03030303U) << 2) | \
((t >> 1) & 0x70707070U) | ((t & 0x10101010U) << 3); \
/* Key 7 */ \
(next)[7] = ((s >> 18) & 0x00003030U) | ((s & 0x01010101U) << 3) | \
((s >> 14) & 0x0000C0C0U) | ((s & 0x0000E0E0U) << 15) | \
((s >> 1) & 0x07070707U) | ((s & 0x00001010U) << 19); \
/* Key 8 */ \
s = (prev)[8]; \
t = (prev)[9]; \
(next)[8] = ((t >> 4) & 0x0FFF0000U) | ((t & 0x000F0000U) << 12) | \
((t >> 8) & 0x000000FFU) | ((t & 0x000000FFU) << 8); \
/* Key 9 */ \
(next)[9] = ((s >> 6) & 0x03FF0000U) | ((s & 0x003F0000U) << 10) | \
((s >> 4) & 0x00000FFFU) | ((s & 0x0000000FU) << 12); \
} while (0)
/**
* \brief Compute the round keys for GIFT-128 in the fixsliced representation.
*
* \param ks Points to the key schedule to initialize.
* \param k0 First key word.
* \param k1 Second key word.
* \param k2 Third key word.
* \param k3 Fourth key word.
*/
static void gift128b_compute_round_keys
(gift128b_key_schedule_t *ks,
uint32_t k0, uint32_t k1, uint32_t k2, uint32_t k3)
{
unsigned index;
uint32_t temp;
/* Set the regular key with k0 and k3 pre-swapped for the round function */
ks->k[0] = k3;
ks->k[1] = k1;
ks->k[2] = k2;
ks->k[3] = k0;
/* Pre-compute the keys for rounds 3..10 and permute into fixsliced form */
for (index = 4; index < 20; index += 2) {
ks->k[index] = ks->k[index - 3];
temp = ks->k[index - 4];
temp = ((temp & 0xFFFC0000U) >> 2) | ((temp & 0x00030000U) << 14) |
((temp & 0x00000FFFU) << 4) | ((temp & 0x0000F000U) >> 12);
ks->k[index + 1] = temp;
}
for (index = 0; index < 20; index += 10) {
/* Keys 0 and 10 */
temp = ks->k[index];
gift128b_swap_move(temp, temp, 0x00550055U, 9);
gift128b_swap_move(temp, temp, 0x000F000FU, 12);
gift128b_swap_move(temp, temp, 0x00003333U, 18);
gift128b_swap_move(temp, temp, 0x000000FFU, 24);
ks->k[index] = temp;
/* Keys 1 and 11 */
temp = ks->k[index + 1];
gift128b_swap_move(temp, temp, 0x00550055U, 9);
gift128b_swap_move(temp, temp, 0x000F000FU, 12);
gift128b_swap_move(temp, temp, 0x00003333U, 18);
gift128b_swap_move(temp, temp, 0x000000FFU, 24);
ks->k[index + 1] = temp;
/* Keys 2 and 12 */
temp = ks->k[index + 2];
gift128b_swap_move(temp, temp, 0x11111111U, 3);
gift128b_swap_move(temp, temp, 0x03030303U, 6);
gift128b_swap_move(temp, temp, 0x000F000FU, 12);
gift128b_swap_move(temp, temp, 0x000000FFU, 24);
ks->k[index + 2] = temp;
/* Keys 3 and 13 */
temp = ks->k[index + 3];
gift128b_swap_move(temp, temp, 0x11111111U, 3);
gift128b_swap_move(temp, temp, 0x03030303U, 6);
gift128b_swap_move(temp, temp, 0x000F000FU, 12);
gift128b_swap_move(temp, temp, 0x000000FFU, 24);
ks->k[index + 3] = temp;
/* Keys 4 and 14 */
temp = ks->k[index + 4];
gift128b_swap_move(temp, temp, 0x0000AAAAU, 15);
gift128b_swap_move(temp, temp, 0x00003333U, 18);
gift128b_swap_move(temp, temp, 0x0000F0F0U, 12);
gift128b_swap_move(temp, temp, 0x000000FFU, 24);
ks->k[index + 4] = temp;
/* Keys 5 and 15 */
temp = ks->k[index + 5];
gift128b_swap_move(temp, temp, 0x0000AAAAU, 15);
gift128b_swap_move(temp, temp, 0x00003333U, 18);
gift128b_swap_move(temp, temp, 0x0000F0F0U, 12);
gift128b_swap_move(temp, temp, 0x000000FFU, 24);
ks->k[index + 5] = temp;
/* Keys 6 and 16 */
temp = ks->k[index + 6];
gift128b_swap_move(temp, temp, 0x0A0A0A0AU, 3);
gift128b_swap_move(temp, temp, 0x00CC00CCU, 6);
gift128b_swap_move(temp, temp, 0x0000F0F0U, 12);
gift128b_swap_move(temp, temp, 0x000000FFU, 24);
ks->k[index + 6] = temp;
/* Keys 7 and 17 */
temp = ks->k[index + 7];
gift128b_swap_move(temp, temp, 0x0A0A0A0AU, 3);
gift128b_swap_move(temp, temp, 0x00CC00CCU, 6);
gift128b_swap_move(temp, temp, 0x0000F0F0U, 12);
gift128b_swap_move(temp, temp, 0x000000FFU, 24);
ks->k[index + 7] = temp;
/* Keys 8, 9, 18, and 19 do not need any adjustment */
}
#if GIFT128_VARIANT == GIFT128_VARIANT_FULL
/* Derive the fixsliced keys for the remaining rounds 11..40 */
for (index = 20; index < 80; index += 10) {
gift128b_derive_keys(ks->k + index, ks->k + index - 20);
}
#endif
}
void gift128b_init(gift128b_key_schedule_t *ks, const unsigned char *key)
{
gift128b_compute_round_keys
(ks, be_load_word32(key), be_load_word32(key + 4),
be_load_word32(key + 8), be_load_word32(key + 12));
}
void gift128n_init(gift128n_key_schedule_t *ks, const unsigned char *key)
{
/* Use the little-endian key byte order from the HYENA submission */
gift128b_compute_round_keys
(ks, le_load_word32(key + 12), le_load_word32(key + 8),
le_load_word32(key + 4), le_load_word32(key));
}
/**
* \brief Performs the GIFT-128 S-box on the bit-sliced state.
*
* \param s0 First word of the bit-sliced state.
* \param s1 Second word of the bit-sliced state.
* \param s2 Third word of the bit-sliced state.
* \param s3 Fourth word of the bit-sliced state.
*/
#define gift128b_sbox(s0, s1, s2, s3) \
do { \
s1 ^= s0 & s2; \
s0 ^= s1 & s3; \
s2 ^= s0 | s1; \
s3 ^= s2; \
s1 ^= s3; \
s3 ^= 0xFFFFFFFFU; \
s2 ^= s0 & s1; \
} while (0)
/**
* \brief Performs the inverse of the GIFT-128 S-box on the bit-sliced state.
*
* \param s0 First word of the bit-sliced state.
* \param s1 Second word of the bit-sliced state.
* \param s2 Third word of the bit-sliced state.
* \param s3 Fourth word of the bit-sliced state.
*/
#define gift128b_inv_sbox(s0, s1, s2, s3) \
do { \
s2 ^= s3 & s1; \
s0 ^= 0xFFFFFFFFU; \
s1 ^= s0; \
s0 ^= s2; \
s2 ^= s3 | s1; \
s3 ^= s1 & s0; \
s1 ^= s3 & s2; \
} while (0)
/**
* \brief Permutes the GIFT-128 state between the 1st and 2nd mini-rounds.
*
* \param s0 First word of the bit-sliced state.
* \param s1 Second word of the bit-sliced state.
* \param s2 Third word of the bit-sliced state.
* \param s3 Fourth word of the bit-sliced state.
*/
#define gift128b_permute_state_1(s0, s1, s2, s3) \
do { \
s1 = ((s1 >> 2) & 0x33333333U) | ((s1 & 0x33333333U) << 2); \
s2 = ((s2 >> 3) & 0x11111111U) | ((s2 & 0x77777777U) << 1); \
s3 = ((s3 >> 1) & 0x77777777U) | ((s3 & 0x11111111U) << 3); \
} while (0);
/**
* \brief Permutes the GIFT-128 state between the 2nd and 3rd mini-rounds.
*
* \param s0 First word of the bit-sliced state.
* \param s1 Second word of the bit-sliced state.
* \param s2 Third word of the bit-sliced state.
* \param s3 Fourth word of the bit-sliced state.
*/
#define gift128b_permute_state_2(s0, s1, s2, s3) \
do { \
s0 = ((s0 >> 4) & 0x0FFF0FFFU) | ((s0 & 0x000F000FU) << 12); \
s1 = ((s1 >> 8) & 0x00FF00FFU) | ((s1 & 0x00FF00FFU) << 8); \
s2 = ((s2 >> 12) & 0x000F000FU) | ((s2 & 0x0FFF0FFFU) << 4); \
} while (0);
/**
* \brief Permutes the GIFT-128 state between the 3rd and 4th mini-rounds.
*
* \param s0 First word of the bit-sliced state.
* \param s1 Second word of the bit-sliced state.
* \param s2 Third word of the bit-sliced state.
* \param s3 Fourth word of the bit-sliced state.
*/
#define gift128b_permute_state_3(s0, s1, s2, s3) \
do { \
gift128b_swap_move(s1, s1, 0x55555555U, 1); \
s2 = leftRotate16(s2); \
gift128b_swap_move(s2, s2, 0x00005555U, 1); \
s3 = leftRotate16(s3); \
gift128b_swap_move(s3, s3, 0x55550000U, 1); \
} while (0);
/**
* \brief Permutes the GIFT-128 state between the 4th and 5th mini-rounds.
*
* \param s0 First word of the bit-sliced state.
* \param s1 Second word of the bit-sliced state.
* \param s2 Third word of the bit-sliced state.
* \param s3 Fourth word of the bit-sliced state.
*/
#define gift128b_permute_state_4(s0, s1, s2, s3) \
do { \
s0 = ((s0 >> 6) & 0x03030303U) | ((s0 & 0x3F3F3F3FU) << 2); \
s1 = ((s1 >> 4) & 0x0F0F0F0FU) | ((s1 & 0x0F0F0F0FU) << 4); \
s2 = ((s2 >> 2) & 0x3F3F3F3FU) | ((s2 & 0x03030303U) << 6); \
} while (0);
/**
* \brief Permutes the GIFT-128 state between the 5th and 1st mini-rounds.
*
* \param s0 First word of the bit-sliced state.
* \param s1 Second word of the bit-sliced state.
* \param s2 Third word of the bit-sliced state.
* \param s3 Fourth word of the bit-sliced state.
*/
#define gift128b_permute_state_5(s0, s1, s2, s3) \
do { \
s1 = leftRotate16(s1); \
s2 = rightRotate8(s2); \
s3 = leftRotate8(s3); \
} while (0);
/**
* \brief Inverts the GIFT-128 state between the 1st and 2nd mini-rounds.
*
* \param s0 First word of the bit-sliced state.
* \param s1 Second word of the bit-sliced state.
* \param s2 Third word of the bit-sliced state.
* \param s3 Fourth word of the bit-sliced state.
*/
#define gift128b_inv_permute_state_1(s0, s1, s2, s3) \
do { \
s1 = ((s1 >> 2) & 0x33333333U) | ((s1 & 0x33333333U) << 2); \
s2 = ((s2 >> 1) & 0x77777777U) | ((s2 & 0x11111111U) << 3); \
s3 = ((s3 >> 3) & 0x11111111U) | ((s3 & 0x77777777U) << 1); \
} while (0);
/**
* \brief Inverts the GIFT-128 state between the 2nd and 3rd mini-rounds.
*
* \param s0 First word of the bit-sliced state.
* \param s1 Second word of the bit-sliced state.
* \param s2 Third word of the bit-sliced state.
* \param s3 Fourth word of the bit-sliced state.
*/
#define gift128b_inv_permute_state_2(s0, s1, s2, s3) \
do { \
s0 = ((s0 >> 12) & 0x000F000FU) | ((s0 & 0x0FFF0FFFU) << 4); \
s1 = ((s1 >> 8) & 0x00FF00FFU) | ((s1 & 0x00FF00FFU) << 8); \
s2 = ((s2 >> 4) & 0x0FFF0FFFU) | ((s2 & 0x000F000FU) << 12); \
} while (0);
/**
* \brief Inverts the GIFT-128 state between the 3rd and 4th mini-rounds.
*
* \param s0 First word of the bit-sliced state.
* \param s1 Second word of the bit-sliced state.
* \param s2 Third word of the bit-sliced state.
* \param s3 Fourth word of the bit-sliced state.
*/
#define gift128b_inv_permute_state_3(s0, s1, s2, s3) \
do { \
gift128b_swap_move(s1, s1, 0x55555555U, 1); \
gift128b_swap_move(s2, s2, 0x00005555U, 1); \
s2 = leftRotate16(s2); \
gift128b_swap_move(s3, s3, 0x55550000U, 1); \
s3 = leftRotate16(s3); \
} while (0);
/**
* \brief Inverts the GIFT-128 state between the 4th and 5th mini-rounds.
*
* \param s0 First word of the bit-sliced state.
* \param s1 Second word of the bit-sliced state.
* \param s2 Third word of the bit-sliced state.
* \param s3 Fourth word of the bit-sliced state.
*/
#define gift128b_inv_permute_state_4(s0, s1, s2, s3) \
do { \
s0 = ((s0 >> 2) & 0x3F3F3F3FU) | ((s0 & 0x03030303U) << 6); \
s1 = ((s1 >> 4) & 0x0F0F0F0FU) | ((s1 & 0x0F0F0F0FU) << 4); \
s2 = ((s2 >> 6) & 0x03030303U) | ((s2 & 0x3F3F3F3FU) << 2); \
} while (0);
/**
* \brief Inverts the GIFT-128 state between the 5th and 1st mini-rounds.
*
* \param s0 First word of the bit-sliced state.
* \param s1 Second word of the bit-sliced state.
* \param s2 Third word of the bit-sliced state.
* \param s3 Fourth word of the bit-sliced state.
*/
#define gift128b_inv_permute_state_5(s0, s1, s2, s3) \
do { \
s1 = leftRotate16(s1); \
s2 = leftRotate8(s2); \
s3 = rightRotate8(s3); \
} while (0);
/**
* \brief Performs five fixsliced encryption rounds for GIFT-128.
*
* \param rk Points to the 10 round keys for these rounds.
* \param rc Points to the round constants for these rounds.
*
* We perform all 40 rounds of the fixsliced GIFT-128 five at a time.
*
* The permutation is restructured so that one of the words each round
* does not need to be permuted, with the others rotating left, up, right,
* and down to keep the bits in line with their non-moving counterparts.
* This reduces the number of shifts required significantly.
*
* At the end of five rounds, the bit ordering will return to the
* original position. We then repeat the process for the next 5 rounds.
*/
#define gift128b_encrypt_5_rounds(rk, rc) \
do { \
/* 1st round - S-box, rotate left, add round key */ \
gift128b_sbox(s0, s1, s2, s3); \
gift128b_permute_state_1(s0, s1, s2, s3); \
s1 ^= (rk)[0]; \
s2 ^= (rk)[1]; \
s0 ^= (rc)[0]; \
\
/* 2nd round - S-box, rotate up, add round key */ \
gift128b_sbox(s3, s1, s2, s0); \
gift128b_permute_state_2(s0, s1, s2, s3); \
s1 ^= (rk)[2]; \
s2 ^= (rk)[3]; \
s3 ^= (rc)[1]; \
\
/* 3rd round - S-box, swap columns, add round key */ \
gift128b_sbox(s0, s1, s2, s3); \
gift128b_permute_state_3(s0, s1, s2, s3); \
s1 ^= (rk)[4]; \
s2 ^= (rk)[5]; \
s0 ^= (rc)[2]; \
\
/* 4th round - S-box, rotate left and swap rows, add round key */ \
gift128b_sbox(s3, s1, s2, s0); \
gift128b_permute_state_4(s0, s1, s2, s3); \
s1 ^= (rk)[6]; \
s2 ^= (rk)[7]; \
s3 ^= (rc)[3]; \
\
/* 5th round - S-box, rotate up, add round key */ \
gift128b_sbox(s0, s1, s2, s3); \
gift128b_permute_state_5(s0, s1, s2, s3); \
s1 ^= (rk)[8]; \
s2 ^= (rk)[9]; \
s0 ^= (rc)[4]; \
\
/* Swap s0 and s3 in preparation for the next 1st round */ \
s0 ^= s3; \
s3 ^= s0; \
s0 ^= s3; \
} while (0)
/**
* \brief Performs five fixsliced decryption rounds for GIFT-128.
*
* \param rk Points to the 10 round keys for these rounds.
* \param rc Points to the round constants for these rounds.
*
* We perform all 40 rounds of the fixsliced GIFT-128 five at a time.
*/
#define gift128b_decrypt_5_rounds(rk, rc) \
do { \
/* Swap s0 and s3 in preparation for the next 5th round */ \
s0 ^= s3; \
s3 ^= s0; \
s0 ^= s3; \
\
/* 5th round - S-box, rotate down, add round key */ \
s1 ^= (rk)[8]; \
s2 ^= (rk)[9]; \
s0 ^= (rc)[4]; \
gift128b_inv_permute_state_5(s0, s1, s2, s3); \
gift128b_inv_sbox(s3, s1, s2, s0); \
\
/* 4th round - S-box, rotate right and swap rows, add round key */ \
s1 ^= (rk)[6]; \
s2 ^= (rk)[7]; \
s3 ^= (rc)[3]; \
gift128b_inv_permute_state_4(s0, s1, s2, s3); \
gift128b_inv_sbox(s0, s1, s2, s3); \
\
/* 3rd round - S-box, swap columns, add round key */ \
s1 ^= (rk)[4]; \
s2 ^= (rk)[5]; \
s0 ^= (rc)[2]; \
gift128b_inv_permute_state_3(s0, s1, s2, s3); \
gift128b_inv_sbox(s3, s1, s2, s0); \
\
/* 2nd round - S-box, rotate down, add round key */ \
s1 ^= (rk)[2]; \
s2 ^= (rk)[3]; \
s3 ^= (rc)[1]; \
gift128b_inv_permute_state_2(s0, s1, s2, s3); \
gift128b_inv_sbox(s0, s1, s2, s3); \
\
/* 1st round - S-box, rotate right, add round key */ \
s1 ^= (rk)[0]; \
s2 ^= (rk)[1]; \
s0 ^= (rc)[0]; \
gift128b_inv_permute_state_1(s0, s1, s2, s3); \
gift128b_inv_sbox(s3, s1, s2, s0); \
} while (0)
#else /* GIFT128_VARIANT_TINY */
void gift128b_init(gift128b_key_schedule_t *ks, const unsigned char *key)
{
/* Mirror the fixslicing word order of 3, 1, 2, 0 */
ks->k[0] = be_load_word32(key + 12);
ks->k[1] = be_load_word32(key + 4);
ks->k[2] = be_load_word32(key + 8);
ks->k[3] = be_load_word32(key);
}
void gift128n_init(gift128n_key_schedule_t *ks, const unsigned char *key)
{
/* Use the little-endian key byte order from the HYENA submission
* and mirror the fixslicing word order of 3, 1, 2, 0 */
ks->k[0] = le_load_word32(key);
ks->k[1] = le_load_word32(key + 8);
ks->k[2] = le_load_word32(key + 4);
ks->k[3] = le_load_word32(key + 12);
}
#endif /* GIFT128_VARIANT_TINY */
#if GIFT128_VARIANT == GIFT128_VARIANT_SMALL
void gift128b_encrypt
(const gift128b_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
uint32_t k[20];
/* Copy the plaintext into the state buffer and convert from big endian */
s0 = be_load_word32(input);
s1 = be_load_word32(input + 4);
s2 = be_load_word32(input + 8);
s3 = be_load_word32(input + 12);
/* Perform all 40 rounds five at a time using the fixsliced method */
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
gift128b_derive_keys(k, ks->k);
gift128b_derive_keys(k + 10, ks->k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 10);
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 15);
gift128b_derive_keys(k, k);
gift128b_derive_keys(k + 10, k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 20);
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 25);
gift128b_derive_keys(k, k);
gift128b_derive_keys(k + 10, k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 30);
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 35);
/* Pack the state into the ciphertext buffer in big endian */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
}
void gift128b_encrypt_preloaded
(const gift128b_key_schedule_t *ks, uint32_t output[4],
const uint32_t input[4])
{
uint32_t s0, s1, s2, s3;
uint32_t k[20];
/* Copy the plaintext into local variables */
s0 = input[0];
s1 = input[1];
s2 = input[2];
s3 = input[3];
/* Perform all 40 rounds five at a time using the fixsliced method */
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
gift128b_derive_keys(k, ks->k);
gift128b_derive_keys(k + 10, ks->k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 10);
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 15);
gift128b_derive_keys(k, k);
gift128b_derive_keys(k + 10, k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 20);
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 25);
gift128b_derive_keys(k, k);
gift128b_derive_keys(k + 10, k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 30);
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 35);
/* Pack the state into the ciphertext buffer */
output[0] = s0;
output[1] = s1;
output[2] = s2;
output[3] = s3;
}
void gift128t_encrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak)
{
uint32_t s0, s1, s2, s3;
uint32_t k[20];
/* Copy the plaintext into the state buffer and convert from nibbles */
gift128n_to_words(output, input);
s0 = be_load_word32(output);
s1 = be_load_word32(output + 4);
s2 = be_load_word32(output + 8);
s3 = be_load_word32(output + 12);
/* Perform all 40 rounds five at a time using the fixsliced method.
* Every 5 rounds except the last we add the tweak value to the state */
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
s0 ^= tweak;
gift128b_derive_keys(k, ks->k);
gift128b_derive_keys(k + 10, ks->k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 10);
s0 ^= tweak;
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 15);
s0 ^= tweak;
gift128b_derive_keys(k, k);
gift128b_derive_keys(k + 10, k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 20);
s0 ^= tweak;
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 25);
s0 ^= tweak;
gift128b_derive_keys(k, k);
gift128b_derive_keys(k + 10, k + 10);
gift128b_encrypt_5_rounds(k, GIFT128_RC_fixsliced + 30);
s0 ^= tweak;
gift128b_encrypt_5_rounds(k + 10, GIFT128_RC_fixsliced + 35);
/* Pack the state into the ciphertext buffer in nibble form */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
gift128n_to_nibbles(output, output);
}
#elif GIFT128_VARIANT == GIFT128_VARIANT_FULL
void gift128b_encrypt
(const gift128b_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
/* Copy the plaintext into the state buffer and convert from big endian */
s0 = be_load_word32(input);
s1 = be_load_word32(input + 4);
s2 = be_load_word32(input + 8);
s3 = be_load_word32(input + 12);
/* Perform all 40 rounds five at a time using the fixsliced method */
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
gift128b_encrypt_5_rounds(ks->k + 20, GIFT128_RC_fixsliced + 10);
gift128b_encrypt_5_rounds(ks->k + 30, GIFT128_RC_fixsliced + 15);
gift128b_encrypt_5_rounds(ks->k + 40, GIFT128_RC_fixsliced + 20);
gift128b_encrypt_5_rounds(ks->k + 50, GIFT128_RC_fixsliced + 25);
gift128b_encrypt_5_rounds(ks->k + 60, GIFT128_RC_fixsliced + 30);
gift128b_encrypt_5_rounds(ks->k + 70, GIFT128_RC_fixsliced + 35);
/* Pack the state into the ciphertext buffer in big endian */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
}
void gift128b_encrypt_preloaded
(const gift128b_key_schedule_t *ks, uint32_t output[4],
const uint32_t input[4])
{
uint32_t s0, s1, s2, s3;
/* Copy the plaintext into local variables */
s0 = input[0];
s1 = input[1];
s2 = input[2];
s3 = input[3];
/* Perform all 40 rounds five at a time using the fixsliced method */
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
gift128b_encrypt_5_rounds(ks->k + 20, GIFT128_RC_fixsliced + 10);
gift128b_encrypt_5_rounds(ks->k + 30, GIFT128_RC_fixsliced + 15);
gift128b_encrypt_5_rounds(ks->k + 40, GIFT128_RC_fixsliced + 20);
gift128b_encrypt_5_rounds(ks->k + 50, GIFT128_RC_fixsliced + 25);
gift128b_encrypt_5_rounds(ks->k + 60, GIFT128_RC_fixsliced + 30);
gift128b_encrypt_5_rounds(ks->k + 70, GIFT128_RC_fixsliced + 35);
/* Pack the state into the ciphertext buffer */
output[0] = s0;
output[1] = s1;
output[2] = s2;
output[3] = s3;
}
void gift128t_encrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak)
{
uint32_t s0, s1, s2, s3;
/* Copy the plaintext into the state buffer and convert from nibbles */
gift128n_to_words(output, input);
s0 = be_load_word32(output);
s1 = be_load_word32(output + 4);
s2 = be_load_word32(output + 8);
s3 = be_load_word32(output + 12);
/* Perform all 40 rounds five at a time using the fixsliced method.
* Every 5 rounds except the last we add the tweak value to the state */
gift128b_encrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 20, GIFT128_RC_fixsliced + 10);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 30, GIFT128_RC_fixsliced + 15);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 40, GIFT128_RC_fixsliced + 20);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 50, GIFT128_RC_fixsliced + 25);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 60, GIFT128_RC_fixsliced + 30);
s0 ^= tweak;
gift128b_encrypt_5_rounds(ks->k + 70, GIFT128_RC_fixsliced + 35);
/* Pack the state into the ciphertext buffer in nibble form */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
gift128n_to_nibbles(output, output);
}
#else /* GIFT128_VARIANT_TINY */
void gift128b_encrypt
(const gift128b_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
uint32_t w0, w1, w2, w3;
uint32_t temp;
uint8_t round;
/* Copy the plaintext into the state buffer and convert from big endian */
s0 = be_load_word32(input);
s1 = be_load_word32(input + 4);
s2 = be_load_word32(input + 8);
s3 = be_load_word32(input + 12);
/* The key schedule is initialized with the key itself */
w0 = ks->k[3];
w1 = ks->k[1];
w2 = ks->k[2];
w3 = ks->k[0];
/* Perform all 40 rounds */
for (round = 0; round < 40; ++round) {
/* SubCells - apply the S-box */
s1 ^= s0 & s2;
s0 ^= s1 & s3;
s2 ^= s0 | s1;
s3 ^= s2;
s1 ^= s3;
s3 ^= 0xFFFFFFFFU;
s2 ^= s0 & s1;
temp = s0;
s0 = s3;
s3 = temp;
/* PermBits - apply the 128-bit permutation */
PERM0(s0);
PERM1(s1);
PERM2(s2);
PERM3(s3);
/* AddRoundKey - XOR in the key schedule and the round constant */
s2 ^= w1;
s1 ^= w3;
s3 ^= 0x80000000U ^ GIFT128_RC[round];
/* Rotate the key schedule */
temp = w3;
w3 = w2;
w2 = w1;
w1 = w0;
w0 = ((temp & 0xFFFC0000U) >> 2) | ((temp & 0x00030000U) << 14) |
((temp & 0x00000FFFU) << 4) | ((temp & 0x0000F000U) >> 12);
}
/* Pack the state into the ciphertext buffer in big endian */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
}
void gift128b_encrypt_preloaded
(const gift128b_key_schedule_t *ks, uint32_t output[4],
const uint32_t input[4])
{
uint32_t s0, s1, s2, s3;
uint32_t w0, w1, w2, w3;
uint32_t temp;
uint8_t round;
/* Copy the plaintext into the state buffer */
s0 = input[0];
s1 = input[1];
s2 = input[2];
s3 = input[3];
/* The key schedule is initialized with the key itself */
w0 = ks->k[3];
w1 = ks->k[1];
w2 = ks->k[2];
w3 = ks->k[0];
/* Perform all 40 rounds */
for (round = 0; round < 40; ++round) {
/* SubCells - apply the S-box */
s1 ^= s0 & s2;
s0 ^= s1 & s3;
s2 ^= s0 | s1;
s3 ^= s2;
s1 ^= s3;
s3 ^= 0xFFFFFFFFU;
s2 ^= s0 & s1;
temp = s0;
s0 = s3;
s3 = temp;
/* PermBits - apply the 128-bit permutation */
PERM0(s0);
PERM1(s1);
PERM2(s2);
PERM3(s3);
/* AddRoundKey - XOR in the key schedule and the round constant */
s2 ^= w1;
s1 ^= w3;
s3 ^= 0x80000000U ^ GIFT128_RC[round];
/* Rotate the key schedule */
temp = w3;
w3 = w2;
w2 = w1;
w1 = w0;
w0 = ((temp & 0xFFFC0000U) >> 2) | ((temp & 0x00030000U) << 14) |
((temp & 0x00000FFFU) << 4) | ((temp & 0x0000F000U) >> 12);
}
/* Pack the state into the ciphertext buffer */
output[0] = s0;
output[1] = s1;
output[2] = s2;
output[3] = s3;
}
void gift128t_encrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak)
{
uint32_t s0, s1, s2, s3;
uint32_t w0, w1, w2, w3;
uint32_t temp;
uint8_t round;
/* Copy the plaintext into the state buffer and convert from nibbles */
gift128n_to_words(output, input);
s0 = be_load_word32(output);
s1 = be_load_word32(output + 4);
s2 = be_load_word32(output + 8);
s3 = be_load_word32(output + 12);
/* The key schedule is initialized with the key itself */
w0 = ks->k[3];
w1 = ks->k[1];
w2 = ks->k[2];
w3 = ks->k[0];
/* Perform all 40 rounds */
for (round = 0; round < 40; ++round) {
/* SubCells - apply the S-box */
s1 ^= s0 & s2;
s0 ^= s1 & s3;
s2 ^= s0 | s1;
s3 ^= s2;
s1 ^= s3;
s3 ^= 0xFFFFFFFFU;
s2 ^= s0 & s1;
temp = s0;
s0 = s3;
s3 = temp;
/* PermBits - apply the 128-bit permutation */
PERM0(s0);
PERM1(s1);
PERM2(s2);
PERM3(s3);
/* AddRoundKey - XOR in the key schedule and the round constant */
s2 ^= w1;
s1 ^= w3;
s3 ^= 0x80000000U ^ GIFT128_RC[round];
/* AddTweak - XOR in the tweak every 5 rounds except the last */
if (((round + 1) % 5) == 0 && round < 39)
s0 ^= tweak;
/* Rotate the key schedule */
temp = w3;
w3 = w2;
w2 = w1;
w1 = w0;
w0 = ((temp & 0xFFFC0000U) >> 2) | ((temp & 0x00030000U) << 14) |
((temp & 0x00000FFFU) << 4) | ((temp & 0x0000F000U) >> 12);
}
/* Pack the state into the ciphertext buffer in nibble form */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
gift128n_to_nibbles(output, output);
}
#endif /* GIFT128_VARIANT_TINY */
#if GIFT128_VARIANT == GIFT128_VARIANT_FULL
void gift128b_decrypt
(const gift128b_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
/* Copy the plaintext into the state buffer and convert from big endian */
s0 = be_load_word32(input);
s1 = be_load_word32(input + 4);
s2 = be_load_word32(input + 8);
s3 = be_load_word32(input + 12);
/* Perform all 40 rounds five at a time using the fixsliced method */
gift128b_decrypt_5_rounds(ks->k + 70, GIFT128_RC_fixsliced + 35);
gift128b_decrypt_5_rounds(ks->k + 60, GIFT128_RC_fixsliced + 30);
gift128b_decrypt_5_rounds(ks->k + 50, GIFT128_RC_fixsliced + 25);
gift128b_decrypt_5_rounds(ks->k + 40, GIFT128_RC_fixsliced + 20);
gift128b_decrypt_5_rounds(ks->k + 30, GIFT128_RC_fixsliced + 15);
gift128b_decrypt_5_rounds(ks->k + 20, GIFT128_RC_fixsliced + 10);
gift128b_decrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
gift128b_decrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
/* Pack the state into the ciphertext buffer in big endian */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
}
void gift128t_decrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak)
{
uint32_t s0, s1, s2, s3;
/* Copy the ciphertext into the state buffer and convert from nibbles */
gift128n_to_words(output, input);
s0 = be_load_word32(output);
s1 = be_load_word32(output + 4);
s2 = be_load_word32(output + 8);
s3 = be_load_word32(output + 12);
/* Perform all 40 rounds five at a time using the fixsliced method.
* Every 5 rounds except the first we add the tweak value to the state */
gift128b_decrypt_5_rounds(ks->k + 70, GIFT128_RC_fixsliced + 35);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k + 60, GIFT128_RC_fixsliced + 30);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k + 50, GIFT128_RC_fixsliced + 25);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k + 40, GIFT128_RC_fixsliced + 20);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k + 30, GIFT128_RC_fixsliced + 15);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k + 20, GIFT128_RC_fixsliced + 10);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k + 10, GIFT128_RC_fixsliced + 5);
s0 ^= tweak;
gift128b_decrypt_5_rounds(ks->k, GIFT128_RC_fixsliced);
/* Pack the state into the plaintext buffer in nibble form */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
gift128n_to_nibbles(output, output);
}
#else /* GIFT128_VARIANT_SMALL || GIFT128_VARIANT_TINY */
/* The small variant uses fixslicing for encryption, but we need to change
* to bitslicing for decryption because of the difficulty of fast-forwarding
* the fixsliced key schedule to the end. So the tiny variant is used for
* decryption when the small variant is selected. Since the NIST AEAD modes
* for GIFT-128 only use the block encrypt operation, the inefficiencies
* in decryption don't matter all that much */
/**
* \def gift128b_load_and_forward_schedule()
* \brief Generate the decryption key at the end of the last round.
*
* To do that, we run the block operation forward to determine the
* final state of the key schedule after the last round:
*
* w0 = ks->k[0];
* w1 = ks->k[1];
* w2 = ks->k[2];
* w3 = ks->k[3];
* for (round = 0; round < 40; ++round) {
* temp = w3;
* w3 = w2;
* w2 = w1;
* w1 = w0;
* w0 = ((temp & 0xFFFC0000U) >> 2) | ((temp & 0x00030000U) << 14) |
* ((temp & 0x00000FFFU) << 4) | ((temp & 0x0000F000U) >> 12);
* }
*
* We can short-cut all of the above by noticing that we don't need
* to do the word rotations. Every 4 rounds, the rotation alignment
* returns to the original position and each word has been rotated
* by applying the "2 right and 4 left" bit-rotation step to it.
* We then repeat that 10 times for the full 40 rounds. The overall
* effect is to apply a "20 right and 40 left" bit-rotation to every
* word in the key schedule. That is equivalent to "4 right and 8 left"
* on the 16-bit sub-words.
*/
#if GIFT128_VARIANT != GIFT128_VARIANT_SMALL
#define gift128b_load_and_forward_schedule() \
do { \
w0 = ks->k[3]; \
w1 = ks->k[1]; \
w2 = ks->k[2]; \
w3 = ks->k[0]; \
w0 = ((w0 & 0xFFF00000U) >> 4) | ((w0 & 0x000F0000U) << 12) | \
((w0 & 0x000000FFU) << 8) | ((w0 & 0x0000FF00U) >> 8); \
w1 = ((w1 & 0xFFF00000U) >> 4) | ((w1 & 0x000F0000U) << 12) | \
((w1 & 0x000000FFU) << 8) | ((w1 & 0x0000FF00U) >> 8); \
w2 = ((w2 & 0xFFF00000U) >> 4) | ((w2 & 0x000F0000U) << 12) | \
((w2 & 0x000000FFU) << 8) | ((w2 & 0x0000FF00U) >> 8); \
w3 = ((w3 & 0xFFF00000U) >> 4) | ((w3 & 0x000F0000U) << 12) | \
((w3 & 0x000000FFU) << 8) | ((w3 & 0x0000FF00U) >> 8); \
} while (0)
#else
/* The small variant needs to also undo some of the rotations that were
* done to generate the fixsliced version of the key schedule */
#define gift128b_load_and_forward_schedule() \
do { \
w0 = ks->k[3]; \
w1 = ks->k[1]; \
w2 = ks->k[2]; \
w3 = ks->k[0]; \
gift128b_swap_move(w3, w3, 0x000000FFU, 24); \
gift128b_swap_move(w3, w3, 0x00003333U, 18); \
gift128b_swap_move(w3, w3, 0x000F000FU, 12); \
gift128b_swap_move(w3, w3, 0x00550055U, 9); \
gift128b_swap_move(w1, w1, 0x000000FFU, 24); \
gift128b_swap_move(w1, w1, 0x00003333U, 18); \
gift128b_swap_move(w1, w1, 0x000F000FU, 12); \
gift128b_swap_move(w1, w1, 0x00550055U, 9); \
gift128b_swap_move(w2, w2, 0x000000FFU, 24); \
gift128b_swap_move(w2, w2, 0x000F000FU, 12); \
gift128b_swap_move(w2, w2, 0x03030303U, 6); \
gift128b_swap_move(w2, w2, 0x11111111U, 3); \
gift128b_swap_move(w0, w0, 0x000000FFU, 24); \
gift128b_swap_move(w0, w0, 0x000F000FU, 12); \
gift128b_swap_move(w0, w0, 0x03030303U, 6); \
gift128b_swap_move(w0, w0, 0x11111111U, 3); \
w0 = ((w0 & 0xFFF00000U) >> 4) | ((w0 & 0x000F0000U) << 12) | \
((w0 & 0x000000FFU) << 8) | ((w0 & 0x0000FF00U) >> 8); \
w1 = ((w1 & 0xFFF00000U) >> 4) | ((w1 & 0x000F0000U) << 12) | \
((w1 & 0x000000FFU) << 8) | ((w1 & 0x0000FF00U) >> 8); \
w2 = ((w2 & 0xFFF00000U) >> 4) | ((w2 & 0x000F0000U) << 12) | \
((w2 & 0x000000FFU) << 8) | ((w2 & 0x0000FF00U) >> 8); \
w3 = ((w3 & 0xFFF00000U) >> 4) | ((w3 & 0x000F0000U) << 12) | \
((w3 & 0x000000FFU) << 8) | ((w3 & 0x0000FF00U) >> 8); \
} while (0)
#endif
void gift128b_decrypt
(const gift128b_key_schedule_t *ks, unsigned char *output,
const unsigned char *input)
{
uint32_t s0, s1, s2, s3;
uint32_t w0, w1, w2, w3;
uint32_t temp;
uint8_t round;
/* Copy the ciphertext into the state buffer and convert from big endian */
s0 = be_load_word32(input);
s1 = be_load_word32(input + 4);
s2 = be_load_word32(input + 8);
s3 = be_load_word32(input + 12);
/* Generate the decryption key at the end of the last round */
gift128b_load_and_forward_schedule();
/* Perform all 40 rounds */
for (round = 40; round > 0; --round) {
/* Rotate the key schedule backwards */
temp = w0;
w0 = w1;
w1 = w2;
w2 = w3;
w3 = ((temp & 0x3FFF0000U) << 2) | ((temp & 0xC0000000U) >> 14) |
((temp & 0x0000FFF0U) >> 4) | ((temp & 0x0000000FU) << 12);
/* AddRoundKey - XOR in the key schedule and the round constant */
s2 ^= w1;
s1 ^= w3;
s3 ^= 0x80000000U ^ GIFT128_RC[round - 1];
/* InvPermBits - apply the inverse of the 128-bit permutation */
INV_PERM0(s0);
INV_PERM1(s1);
INV_PERM2(s2);
INV_PERM3(s3);
/* InvSubCells - apply the inverse of the S-box */
temp = s0;
s0 = s3;
s3 = temp;
s2 ^= s0 & s1;
s3 ^= 0xFFFFFFFFU;
s1 ^= s3;
s3 ^= s2;
s2 ^= s0 | s1;
s0 ^= s1 & s3;
s1 ^= s0 & s2;
}
/* Pack the state into the plaintext buffer in big endian */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
}
void gift128t_decrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak)
{
uint32_t s0, s1, s2, s3;
uint32_t w0, w1, w2, w3;
uint32_t temp;
uint8_t round;
/* Copy the plaintext into the state buffer and convert from nibbles */
gift128n_to_words(output, input);
s0 = be_load_word32(output);
s1 = be_load_word32(output + 4);
s2 = be_load_word32(output + 8);
s3 = be_load_word32(output + 12);
/* Generate the decryption key at the end of the last round */
gift128b_load_and_forward_schedule();
/* Perform all 40 rounds */
for (round = 40; round > 0; --round) {
/* Rotate the key schedule backwards */
temp = w0;
w0 = w1;
w1 = w2;
w2 = w3;
w3 = ((temp & 0x3FFF0000U) << 2) | ((temp & 0xC0000000U) >> 14) |
((temp & 0x0000FFF0U) >> 4) | ((temp & 0x0000000FU) << 12);
/* AddTweak - XOR in the tweak every 5 rounds except the last */
if ((round % 5) == 0 && round < 40)
s0 ^= tweak;
/* AddRoundKey - XOR in the key schedule and the round constant */
s2 ^= w1;
s1 ^= w3;
s3 ^= 0x80000000U ^ GIFT128_RC[round - 1];
/* InvPermBits - apply the inverse of the 128-bit permutation */
INV_PERM0(s0);
INV_PERM1(s1);
INV_PERM2(s2);
INV_PERM3(s3);
/* InvSubCells - apply the inverse of the S-box */
temp = s0;
s0 = s3;
s3 = temp;
s2 ^= s0 & s1;
s3 ^= 0xFFFFFFFFU;
s1 ^= s3;
s3 ^= s2;
s2 ^= s0 | s1;
s0 ^= s1 & s3;
s1 ^= s0 & s2;
}
/* Pack the state into the plaintext buffer in nibble form */
be_store_word32(output, s0);
be_store_word32(output + 4, s1);
be_store_word32(output + 8, s2);
be_store_word32(output + 12, s3);
gift128n_to_nibbles(output, output);
}
#endif /* GIFT128_VARIANT_SMALL || GIFT128_VARIANT_TINY */
#endif /* !GIFT128_VARIANT_ASM */
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef LW_INTERNAL_GIFT128_H
#define LW_INTERNAL_GIFT128_H
/**
* \file internal-gift128.h
* \brief GIFT-128 block cipher.
*
* There are three versions of GIFT-128 in use within the second round
* submissions to the NIST lightweight cryptography competition.
*
* The most efficient version for 32-bit software implementation is the
* GIFT-128-b bit-sliced version from GIFT-COFB and SUNDAE-GIFT.
*
* The second is the nibble-based version from HYENA. We implement the
* HYENA version as a wrapper around the bit-sliced version.
*
* The third version is a variant on the HYENA nibble-based version that
* includes a 4-bit tweak value for domain separation. It is used by
* the ESTATE submission to NIST.
*
* Technically there is a fourth version of GIFT-128 which is the one that
* appeared in the original GIFT-128 paper. It is almost the same as the
* HYENA version except that the byte ordering is big-endian instead of
* HYENA's little-endian. The original version of GIFT-128 doesn't appear
* in any of the NIST submissions so we don't bother with it in this library.
*
* References: https://eprint.iacr.org/2017/622.pdf,
* https://eprint.iacr.org/2020/412.pdf,
* https://giftcipher.github.io/gift/
*/
#include <stddef.h>
#include <stdint.h>
#include "internal-gift128-config.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Size of a GIFT-128 block in bytes.
*/
#define GIFT128_BLOCK_SIZE 16
/**
* \var GIFT128_ROUND_KEYS
* \brief Number of round keys for the GIFT-128 key schedule.
*/
#if GIFT128_VARIANT == GIFT128_VARIANT_TINY
#define GIFT128_ROUND_KEYS 4
#elif GIFT128_VARIANT == GIFT128_VARIANT_SMALL
#define GIFT128_ROUND_KEYS 20
#else
#define GIFT128_ROUND_KEYS 80
#endif
/**
* \brief Structure of the key schedule for GIFT-128 (bit-sliced).
*/
typedef struct
{
/** Pre-computed round keys for bit-sliced GIFT-128 */
uint32_t k[GIFT128_ROUND_KEYS];
} gift128b_key_schedule_t;
/**
* \brief Initializes the key schedule for GIFT-128 (bit-sliced).
*
* \param ks Points to the key schedule to initialize.
* \param key Points to the 16 bytes of the key data.
*/
void gift128b_init(gift128b_key_schedule_t *ks, const unsigned char *key);
/**
* \brief Encrypts a 128-bit block with GIFT-128 (bit-sliced).
*
* \param ks Points to the GIFT-128 key schedule.
* \param output Output buffer which must be at least 16 bytes in length.
* \param input Input buffer which must be at least 16 bytes in length.
*
* The \a input and \a output buffers can be the same buffer for
* in-place encryption.
*/
void gift128b_encrypt
(const gift128b_key_schedule_t *ks, unsigned char *output,
const unsigned char *input);
/**
* \brief Encrypts a 128-bit block with GIFT-128 (bit-sliced and pre-loaded).
*
* \param ks Points to the GIFT-128 key schedule.
* \param output Output buffer which must be at least 16 bytes in length.
* \param input Input buffer which must be at least 16 bytes in length.
*
* The \a input and \a output buffers can be the same buffer for
* in-place encryption.
*
* This version assumes that the input has already been pre-loaded from
* big-endian into host byte order in the supplied word array. The output
* is delivered in the same way.
*/
void gift128b_encrypt_preloaded
(const gift128b_key_schedule_t *ks, uint32_t output[4],
const uint32_t input[4]);
/**
* \brief Decrypts a 128-bit block with GIFT-128 (bit-sliced).
*
* \param ks Points to the GIFT-128 key schedule.
* \param output Output buffer which must be at least 16 bytes in length.
* \param input Input buffer which must be at least 16 bytes in length.
*
* The \a input and \a output buffers can be the same buffer for
* in-place decryption.
*/
void gift128b_decrypt
(const gift128b_key_schedule_t *ks, unsigned char *output,
const unsigned char *input);
/**
* \brief Structure of the key schedule for GIFT-128 (nibble-based).
*/
typedef gift128b_key_schedule_t gift128n_key_schedule_t;
/**
* \brief Initializes the key schedule for GIFT-128 (nibble-based).
*
* \param ks Points to the key schedule to initialize.
* \param key Points to the 16 bytes of the key data.
*/
void gift128n_init(gift128n_key_schedule_t *ks, const unsigned char *key);
/**
* \brief Encrypts a 128-bit block with GIFT-128 (nibble-based).
*
* \param ks Points to the GIFT-128 key schedule.
* \param output Output buffer which must be at least 16 bytes in length.
* \param input Input buffer which must be at least 16 bytes in length.
*
* The \a input and \a output buffers can be the same buffer for
* in-place encryption.
*/
void gift128n_encrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input);
/**
* \brief Decrypts a 128-bit block with GIFT-128 (nibble-based).
*
* \param ks Points to the GIFT-128 key schedule.
* \param output Output buffer which must be at least 16 bytes in length.
* \param input Input buffer which must be at least 16 bytes in length.
*
* The \a input and \a output buffers can be the same buffer for
* in-place decryption.
*/
void gift128n_decrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input);
/* 4-bit tweak values expanded to 32-bit for TweGIFT-128 */
#define GIFT128T_TWEAK_0 0x00000000 /**< TweGIFT-128 tweak value 0 */
#define GIFT128T_TWEAK_1 0xe1e1e1e1 /**< TweGIFT-128 tweak value 1 */
#define GIFT128T_TWEAK_2 0xd2d2d2d2 /**< TweGIFT-128 tweak value 2 */
#define GIFT128T_TWEAK_3 0x33333333 /**< TweGIFT-128 tweak value 3 */
#define GIFT128T_TWEAK_4 0xb4b4b4b4 /**< TweGIFT-128 tweak value 4 */
#define GIFT128T_TWEAK_5 0x55555555 /**< TweGIFT-128 tweak value 5 */
#define GIFT128T_TWEAK_6 0x66666666 /**< TweGIFT-128 tweak value 6 */
#define GIFT128T_TWEAK_7 0x87878787 /**< TweGIFT-128 tweak value 7 */
#define GIFT128T_TWEAK_8 0x78787878 /**< TweGIFT-128 tweak value 8 */
#define GIFT128T_TWEAK_9 0x99999999 /**< TweGIFT-128 tweak value 9 */
#define GIFT128T_TWEAK_10 0xaaaaaaaa /**< TweGIFT-128 tweak value 10 */
#define GIFT128T_TWEAK_11 0x4b4b4b4b /**< TweGIFT-128 tweak value 11 */
#define GIFT128T_TWEAK_12 0xcccccccc /**< TweGIFT-128 tweak value 12 */
#define GIFT128T_TWEAK_13 0x2d2d2d2d /**< TweGIFT-128 tweak value 13 */
#define GIFT128T_TWEAK_14 0x1e1e1e1e /**< TweGIFT-128 tweak value 14 */
#define GIFT128T_TWEAK_15 0xffffffff /**< TweGIFT-128 tweak value 15 */
/**
* \brief Encrypts a 128-bit block with TweGIFT-128 (tweakable variant).
*
* \param ks Points to the GIFT-128 key schedule.
* \param output Output buffer which must be at least 16 bytes in length.
* \param input Input buffer which must be at least 16 bytes in length.
* \param tweak 4-bit tweak value expanded to 32-bit.
*
* The \a input and \a output buffers can be the same buffer for
* in-place encryption.
*
* This variant of GIFT-128 is used by the ESTATE submission to the
* NIST Lightweight Cryptography Competition. A 4-bit tweak is added to
* some of the rounds to provide domain separation. If the tweak is
* zero, then this function is identical to gift128n_encrypt().
*/
void gift128t_encrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak);
/**
* \brief Decrypts a 128-bit block with TweGIFT-128 (tweakable variant).
*
* \param ks Points to the GIFT-128 key schedule.
* \param output Output buffer which must be at least 16 bytes in length.
* \param input Input buffer which must be at least 16 bytes in length.
* \param tweak 4-bit tweak value expanded to 32-bit.
*
* The \a input and \a output buffers can be the same buffer for
* in-place encryption.
*
* This variant of GIFT-128 is used by the ESTATE submission to the
* NIST Lightweight Cryptography Competition. A 4-bit tweak is added to
* some of the rounds to provide domain separation. If the tweak is
* zero, then this function is identical to gift128n_encrypt().
*/
void gift128t_decrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak);
#ifdef __cplusplus
}
#endif
#endif
#if defined(__AVR__)
#include <avr/io.h>
/* Automatically generated - do not edit */
#include "internal-gift128-config.h"
#if GIFT128_VARIANT == GIFT128_VARIANT_FULL
.section .progmem.data,"a",@progbits
.p2align 8
.type table_0, @object
.size table_0, 160
table_0:
.byte 8
.byte 0
.byte 0
.byte 16
.byte 0
.byte 128
.byte 1
.byte 128
.byte 2
.byte 0
.byte 0
.byte 84
.byte 129
.byte 1
.byte 1
.byte 1
.byte 31
.byte 0
.byte 0
.byte 128
.byte 128
.byte 136
.byte 136
.byte 16
.byte 0
.byte 224
.byte 1
.byte 96
.byte 2
.byte 0
.byte 80
.byte 81
.byte 128
.byte 1
.byte 3
.byte 3
.byte 47
.byte 0
.byte 0
.byte 128
.byte 128
.byte 136
.byte 8
.byte 16
.byte 0
.byte 96
.byte 1
.byte 96
.byte 2
.byte 0
.byte 80
.byte 65
.byte 128
.byte 0
.byte 3
.byte 3
.byte 39
.byte 0
.byte 0
.byte 128
.byte 128
.byte 136
.byte 0
.byte 16
.byte 0
.byte 224
.byte 1
.byte 64
.byte 2
.byte 0
.byte 80
.byte 17
.byte 128
.byte 1
.byte 2
.byte 3
.byte 43
.byte 0
.byte 0
.byte 128
.byte 128
.byte 8
.byte 8
.byte 16
.byte 0
.byte 64
.byte 1
.byte 96
.byte 2
.byte 0
.byte 64
.byte 1
.byte 128
.byte 0
.byte 2
.byte 2
.byte 33
.byte 0
.byte 0
.byte 128
.byte 128
.byte 0
.byte 0
.byte 16
.byte 0
.byte 192
.byte 1
.byte 0
.byte 2
.byte 0
.byte 0
.byte 81
.byte 128
.byte 1
.byte 1
.byte 3
.byte 46
.byte 0
.byte 0
.byte 128
.byte 0
.byte 136
.byte 8
.byte 16
.byte 0
.byte 32
.byte 1
.byte 96
.byte 2
.byte 0
.byte 80
.byte 64
.byte 128
.byte 0
.byte 3
.byte 1
.byte 6
.byte 0
.byte 0
.byte 128
.byte 8
.byte 136
.byte 0
.byte 16
.byte 0
.byte 160
.byte 1
.byte 192
.byte 2
.byte 0
.byte 80
.byte 20
.byte 129
.byte 1
.byte 2
.byte 1
.byte 26
.byte 0
.byte 0
.byte 128
.text
.global gift128n_init
.type gift128n_init, @function
gift128n_init:
push r28
push r29
push r2
push r3
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push r16
push r17
movw r30,r24
movw r26,r22
.L__stack_usage = 18
ld r22,X+
ld r23,X+
ld r28,X+
ld r29,X+
ld r6,X+
ld r7,X+
ld r8,X+
ld r9,X+
ld r2,X+
ld r3,X+
ld r4,X+
ld r5,X+
ld r10,X+
ld r11,X+
ld r12,X+
ld r13,X+
st Z+,r22
st Z+,r23
st Z+,r28
st Z+,r29
st Z+,r2
st Z+,r3
st Z+,r4
st Z+,r5
st Z+,r6
st Z+,r7
st Z+,r8
st Z+,r9
st Z+,r10
st Z+,r11
st Z+,r12
st Z+,r13
ldi r24,4
33:
st Z+,r2
st Z+,r3
st Z+,r4
st Z+,r5
lsl r22
rol r23
adc r22,r1
lsl r22
rol r23
adc r22,r1
lsl r22
rol r23
adc r22,r1
lsl r22
rol r23
adc r22,r1
mov r0,r1
lsr r29
ror r28
ror r0
lsr r29
ror r28
ror r0
or r29,r0
st Z+,r22
st Z+,r23
st Z+,r28
st Z+,r29
mov r0,r22
mov r22,r2
mov r2,r0
mov r0,r23
mov r23,r3
mov r3,r0
mov r0,r28
mov r28,r4
mov r4,r0
mov r0,r29
mov r29,r5
mov r5,r0
st Z+,r10
st Z+,r11
st Z+,r12
st Z+,r13
lsl r6
rol r7
adc r6,r1
lsl r6
rol r7
adc r6,r1
lsl r6
rol r7
adc r6,r1
lsl r6
rol r7
adc r6,r1
mov r0,r1
lsr r9
ror r8
ror r0
lsr r9
ror r8
ror r0
or r9,r0
st Z+,r6
st Z+,r7
st Z+,r8
st Z+,r9
mov r0,r6
mov r6,r10
mov r10,r0
mov r0,r7
mov r7,r11
mov r11,r0
mov r0,r8
mov r8,r12
mov r12,r0
mov r0,r9
mov r9,r13
mov r13,r0
dec r24
breq 5115f
rjmp 33b
5115:
subi r30,80
sbc r31,r1
ldi r24,2
119:
ld r22,Z
ldd r23,Z+1
ldd r28,Z+2
ldd r29,Z+3
movw r18,r22
movw r20,r28
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,85
mov r19,r1
andi r20,85
mov r21,r1
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r1
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,15
mov r19,r1
andi r20,15
mov r21,r1
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r1
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
movw r18,r20
mov r20,r1
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
andi r18,51
andi r19,51
eor r22,r18
eor r23,r19
mov r20,r1
mov r21,r1
movw r20,r18
mov r18,r1
mov r19,r1
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
st Z,r29
std Z+1,r23
std Z+2,r28
std Z+3,r22
ldd r22,Z+4
ldd r23,Z+5
ldd r28,Z+6
ldd r29,Z+7
movw r18,r22
movw r20,r28
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,85
mov r19,r1
andi r20,85
mov r21,r1
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r1
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,15
mov r19,r1
andi r20,15
mov r21,r1
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r1
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
movw r18,r20
mov r20,r1
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
andi r18,51
andi r19,51
eor r22,r18
eor r23,r19
mov r20,r1
mov r21,r1
movw r20,r18
mov r18,r1
mov r19,r1
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
std Z+4,r29
std Z+5,r23
std Z+6,r28
std Z+7,r22
ldd r22,Z+8
ldd r23,Z+9
ldd r28,Z+10
ldd r29,Z+11
movw r18,r22
movw r20,r28
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,17
andi r19,17
andi r20,17
andi r21,17
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
mov r0,r1
lsl r18
rol r19
rol r20
rol r21
rol r0
lsl r18
rol r19
rol r20
rol r21
rol r0
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r0
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,3
andi r19,3
andi r20,3
andi r21,3
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
mov r0,r1
lsr r21
ror r20
ror r19
ror r18
ror r0
lsr r21
ror r20
ror r19
ror r18
ror r0
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r0
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,15
mov r19,r1
andi r20,15
mov r21,r1
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r1
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
std Z+8,r29
std Z+9,r23
std Z+10,r28
std Z+11,r22
ldd r22,Z+12
ldd r23,Z+13
ldd r28,Z+14
ldd r29,Z+15
movw r18,r22
movw r20,r28
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,17
andi r19,17
andi r20,17
andi r21,17
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
mov r0,r1
lsl r18
rol r19
rol r20
rol r21
rol r0
lsl r18
rol r19
rol r20
rol r21
rol r0
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r0
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,3
andi r19,3
andi r20,3
andi r21,3
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
mov r0,r1
lsr r21
ror r20
ror r19
ror r18
ror r0
lsr r21
ror r20
ror r19
ror r18
ror r0
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r0
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,15
mov r19,r1
andi r20,15
mov r21,r1
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r1
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
std Z+12,r29
std Z+13,r23
std Z+14,r28
std Z+15,r22
ldd r22,Z+16
ldd r23,Z+17
ldd r28,Z+18
ldd r29,Z+19
movw r18,r22
movw r20,r28
mov r0,r1
lsl r19
rol r20
rol r21
rol r0
movw r18,r20
mov r20,r0
mov r21,r1
eor r18,r22
eor r19,r23
andi r18,170
andi r19,170
eor r22,r18
eor r23,r19
mov r20,r1
mov r21,r1
mov r0,r1
lsr r20
ror r19
ror r18
ror r0
movw r20,r18
mov r19,r0
mov r18,r1
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
movw r18,r20
mov r20,r1
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
andi r18,51
andi r19,51
eor r22,r18
eor r23,r19
mov r20,r1
mov r21,r1
movw r20,r18
mov r18,r1
mov r19,r1
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
andi r18,240
andi r19,240
eor r22,r18
eor r23,r19
mov r20,r1
mov r21,r1
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r1
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
std Z+16,r29
std Z+17,r23
std Z+18,r28
std Z+19,r22
ldd r22,Z+20
ldd r23,Z+21
ldd r28,Z+22
ldd r29,Z+23
movw r18,r22
movw r20,r28
mov r0,r1
lsl r19
rol r20
rol r21
rol r0
movw r18,r20
mov r20,r0
mov r21,r1
eor r18,r22
eor r19,r23
andi r18,170
andi r19,170
eor r22,r18
eor r23,r19
mov r20,r1
mov r21,r1
mov r0,r1
lsr r20
ror r19
ror r18
ror r0
movw r20,r18
mov r19,r0
mov r18,r1
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
movw r18,r20
mov r20,r1
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
andi r18,51
andi r19,51
eor r22,r18
eor r23,r19
mov r20,r1
mov r21,r1
movw r20,r18
mov r18,r1
mov r19,r1
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
andi r18,240
andi r19,240
eor r22,r18
eor r23,r19
mov r20,r1
mov r21,r1
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r1
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
std Z+20,r29
std Z+21,r23
std Z+22,r28
std Z+23,r22
ldd r22,Z+24
ldd r23,Z+25
ldd r28,Z+26
ldd r29,Z+27
movw r18,r22
movw r20,r28
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,10
andi r19,10
andi r20,10
andi r21,10
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
mov r0,r1
lsl r18
rol r19
rol r20
rol r21
rol r0
lsl r18
rol r19
rol r20
rol r21
rol r0
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r0
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,204
mov r19,r1
andi r20,204
mov r21,r1
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
mov r0,r1
lsr r21
ror r20
ror r19
ror r18
ror r0
lsr r21
ror r20
ror r19
ror r18
ror r0
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r0
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
andi r18,240
andi r19,240
eor r22,r18
eor r23,r19
mov r20,r1
mov r21,r1
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r1
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
std Z+24,r29
std Z+25,r23
std Z+26,r28
std Z+27,r22
ldd r22,Z+28
ldd r23,Z+29
ldd r28,Z+30
ldd r29,Z+31
movw r18,r22
movw r20,r28
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,10
andi r19,10
andi r20,10
andi r21,10
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
mov r0,r1
lsl r18
rol r19
rol r20
rol r21
rol r0
lsl r18
rol r19
rol r20
rol r21
rol r0
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r0
eor r18,r22
eor r19,r23
eor r20,r28
eor r21,r29
andi r18,204
mov r19,r1
andi r20,204
mov r21,r1
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
mov r0,r1
lsr r21
ror r20
ror r19
ror r18
ror r0
lsr r21
ror r20
ror r19
ror r18
ror r0
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r0
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
movw r18,r22
movw r20,r28
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r1
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r22
eor r19,r23
andi r18,240
andi r19,240
eor r22,r18
eor r23,r19
mov r20,r1
mov r21,r1
mov r21,r20
mov r20,r19
mov r19,r18
mov r18,r1
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r22,r18
eor r23,r19
eor r28,r20
eor r29,r21
std Z+28,r29
std Z+29,r23
std Z+30,r28
std Z+31,r22
dec r24
breq 1268f
adiw r30,40
rjmp 119b
1268:
adiw r30,40
movw r26,r30
subi r26,80
sbc r27,r1
ldi r24,6
1274:
ld r22,X+
ld r23,X+
ld r28,X+
ld r29,X+
ld r2,X+
ld r3,X+
ld r4,X+
ld r5,X+
movw r18,r2
movw r20,r4
movw r18,r20
mov r20,r1
mov r21,r1
eor r18,r2
eor r19,r3
andi r18,51
andi r19,51
eor r2,r18
eor r3,r19
mov r20,r1
mov r21,r1
movw r20,r18
mov r18,r1
mov r19,r1
eor r2,r18
eor r3,r19
eor r4,r20
eor r5,r21
movw r18,r2
movw r20,r4
lsr r21
ror r20
ror r19
ror r18
eor r18,r2
eor r19,r3
eor r20,r4
eor r21,r5
andi r18,68
andi r19,68
andi r20,85
andi r21,85
eor r2,r18
eor r3,r19
eor r4,r20
eor r5,r21
lsl r18
rol r19
rol r20
rol r21
eor r2,r18
eor r3,r19
eor r4,r20
eor r5,r21
st Z,r2
std Z+1,r3
std Z+2,r4
std Z+3,r5
movw r18,r22
movw r20,r28
andi r18,51
andi r19,51
andi r20,51
andi r21,51
andi r22,204
andi r23,204
andi r28,204
andi r29,204
or r28,r21
or r29,r18
or r22,r19
or r23,r20
movw r18,r28
movw r20,r22
lsr r21
ror r20
ror r19
ror r18
eor r18,r28
eor r19,r29
eor r20,r22
eor r21,r23
mov r18,r1
andi r19,17
andi r20,85
andi r21,85
eor r28,r18
eor r29,r19
eor r22,r20
eor r23,r21
lsl r18
rol r19
rol r20
rol r21
eor r28,r18
eor r29,r19
eor r22,r20
eor r23,r21
std Z+4,r28
std Z+5,r29
std Z+6,r22
std Z+7,r23
ld r22,X+
ld r23,X+
ld r28,X+
ld r29,X+
ld r2,X+
ld r3,X+
ld r4,X+
ld r5,X+
lsl r2
adc r2,r1
lsl r2
adc r2,r1
swap r3
lsl r4
adc r4,r1
lsl r4
adc r4,r1
swap r5
std Z+8,r2
std Z+9,r3
std Z+10,r4
std Z+11,r5
lsl r22
adc r22,r1
lsl r22
adc r22,r1
lsl r22
adc r22,r1
lsl r23
adc r23,r1
lsl r23
adc r23,r1
lsl r28
adc r28,r1
lsl r28
adc r28,r1
lsl r28
adc r28,r1
lsl r29
adc r29,r1
lsl r29
adc r29,r1
std Z+12,r22
std Z+13,r23
std Z+14,r28
std Z+15,r29
ld r22,X+
ld r23,X+
ld r28,X+
ld r29,X+
ld r2,X+
ld r3,X+
ld r4,X+
ld r5,X+
movw r18,r2
movw r20,r4
andi r18,170
andi r19,170
andi r20,170
andi r21,170
ldi r25,85
and r2,r25
and r3,r25
and r4,r25
and r5,r25
or r2,r19
or r3,r20
or r4,r21
or r5,r18
std Z+16,r4
std Z+17,r5
std Z+18,r2
std Z+19,r3
movw r18,r22
movw r20,r28
andi r18,85
andi r19,85
andi r20,85
andi r21,85
andi r22,170
andi r23,170
andi r28,170
andi r29,170
lsl r22
rol r23
rol r28
rol r29
adc r22,r1
lsl r22
rol r23
rol r28
rol r29
adc r22,r1
lsl r22
rol r23
rol r28
rol r29
adc r22,r1
lsl r22
rol r23
rol r28
rol r29
adc r22,r1
or r22,r18
or r23,r19
or r28,r20
or r29,r21
std Z+20,r29
std Z+21,r22
std Z+22,r23
std Z+23,r28
ld r22,X+
ld r23,X+
ld r28,X+
ld r29,X+
ld r2,X+
ld r3,X+
ld r4,X+
ld r5,X+
movw r18,r2
movw r20,r4
lsr r21
ror r20
ror r19
ror r18
lsr r21
ror r20
ror r19
ror r18
eor r18,r2
eor r19,r3
eor r20,r4
eor r21,r5
andi r18,3
andi r19,3
andi r20,3
andi r21,3
eor r2,r18
eor r3,r19
eor r4,r20
eor r5,r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
eor r2,r18
eor r3,r19
eor r4,r20
eor r5,r21
movw r18,r2
movw r20,r4
lsr r21
ror r20
ror r19
ror r18
andi r18,120
andi r19,120
andi r20,120
andi r21,120
movw r14,r18
movw r16,r20
lsr r17
ror r16
ror r15
ror r14
lsr r17
ror r16
ror r15
ror r14
lsr r17
ror r16
ror r15
ror r14
lsr r17
ror r16
ror r15
ror r14
eor r14,r18
eor r15,r19
eor r16,r20
eor r17,r21
ldi r25,8
and r14,r25
and r15,r25
andi r16,8
andi r17,8
eor r18,r14
eor r19,r15
eor r20,r16
eor r21,r17
lsl r14
rol r15
rol r16
rol r17
lsl r14
rol r15
rol r16
rol r17
lsl r14
rol r15
rol r16
rol r17
lsl r14
rol r15
rol r16
rol r17
eor r18,r14
eor r19,r15
eor r20,r16
eor r21,r17
ldi r17,15
and r2,r17
and r3,r17
and r4,r17
and r5,r17
or r2,r18
or r3,r19
or r4,r20
or r5,r21
std Z+24,r2
std Z+25,r3
std Z+26,r4
std Z+27,r5
movw r18,r28
lsr r19
ror r18
lsr r19
ror r18
andi r18,48
andi r19,48
movw r2,r22
movw r4,r28
ldi r16,1
and r2,r16
and r3,r16
and r4,r16
and r5,r16
lsl r2
rol r3
rol r4
rol r5
lsl r2
rol r3
rol r4
rol r5
lsl r2
rol r3
rol r4
rol r5
or r2,r18
or r3,r19
movw r18,r28
lsl r18
rol r19
lsl r18
rol r19
andi r18,192
andi r19,192
or r2,r18
or r3,r19
movw r18,r22
andi r18,224
andi r19,224
lsr r19
ror r18
or r4,r18
or r5,r19
movw r18,r22
movw r20,r28
lsr r21
ror r20
ror r19
ror r18
andi r18,7
andi r19,7
andi r20,7
andi r21,7
or r2,r18
or r3,r19
or r4,r20
or r5,r21
andi r22,16
andi r23,16
lsl r22
rol r23
lsl r22
rol r23
lsl r22
rol r23
or r4,r22
or r5,r23
std Z+28,r2
std Z+29,r3
std Z+30,r4
std Z+31,r5
ld r22,X+
ld r23,X+
ld r28,X+
ld r29,X+
ld r2,X+
ld r3,X+
ld r4,X+
ld r5,X+
mov r0,r1
lsr r5
ror r4
ror r0
lsr r5
ror r4
ror r0
lsr r5
ror r4
ror r0
lsr r5
ror r4
ror r0
or r5,r0
std Z+32,r3
std Z+33,r2
std Z+34,r4
std Z+35,r5
mov r0,r1
lsr r23
ror r22
ror r0
lsr r23
ror r22
ror r0
lsr r23
ror r22
ror r0
lsr r23
ror r22
ror r0
or r23,r0
mov r0,r28
mov r28,r29
mov r29,r0
lsl r28
rol r29
adc r28,r1
lsl r28
rol r29
adc r28,r1
std Z+36,r22
std Z+37,r23
std Z+38,r28
std Z+39,r29
dec r24
breq 1733f
adiw r30,40
rjmp 1274b
1733:
pop r17
pop r16
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
pop r3
pop r2
pop r29
pop r28
ret
.size gift128n_init, .-gift128n_init
.text
.global gift128n_encrypt
.type gift128n_encrypt, @function
gift128n_encrypt:
push r28
push r29
push r2
push r3
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push r17
push r23
push r22
movw r30,r24
movw r26,r20
in r28,0x3d
in r29,0x3e
.L__stack_usage = 19
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
bst r18,0
bld r22,0
bst r18,1
bld r4,0
bst r18,2
bld r8,0
bst r18,3
bld r12,0
bst r18,4
bld r22,1
bst r18,5
bld r4,1
bst r18,6
bld r8,1
bst r18,7
bld r12,1
bst r19,0
bld r22,2
bst r19,1
bld r4,2
bst r19,2
bld r8,2
bst r19,3
bld r12,2
bst r19,4
bld r22,3
bst r19,5
bld r4,3
bst r19,6
bld r8,3
bst r19,7
bld r12,3
bst r20,0
bld r22,4
bst r20,1
bld r4,4
bst r20,2
bld r8,4
bst r20,3
bld r12,4
bst r20,4
bld r22,5
bst r20,5
bld r4,5
bst r20,6
bld r8,5
bst r20,7
bld r12,5
bst r21,0
bld r22,6
bst r21,1
bld r4,6
bst r21,2
bld r8,6
bst r21,3
bld r12,6
bst r21,4
bld r22,7
bst r21,5
bld r4,7
bst r21,6
bld r8,7
bst r21,7
bld r12,7
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
bst r18,0
bld r23,0
bst r18,1
bld r5,0
bst r18,2
bld r9,0
bst r18,3
bld r13,0
bst r18,4
bld r23,1
bst r18,5
bld r5,1
bst r18,6
bld r9,1
bst r18,7
bld r13,1
bst r19,0
bld r23,2
bst r19,1
bld r5,2
bst r19,2
bld r9,2
bst r19,3
bld r13,2
bst r19,4
bld r23,3
bst r19,5
bld r5,3
bst r19,6
bld r9,3
bst r19,7
bld r13,3
bst r20,0
bld r23,4
bst r20,1
bld r5,4
bst r20,2
bld r9,4
bst r20,3
bld r13,4
bst r20,4
bld r23,5
bst r20,5
bld r5,5
bst r20,6
bld r9,5
bst r20,7
bld r13,5
bst r21,0
bld r23,6
bst r21,1
bld r5,6
bst r21,2
bld r9,6
bst r21,3
bld r13,6
bst r21,4
bld r23,7
bst r21,5
bld r5,7
bst r21,6
bld r9,7
bst r21,7
bld r13,7
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
bst r18,0
bld r2,0
bst r18,1
bld r6,0
bst r18,2
bld r10,0
bst r18,3
bld r14,0
bst r18,4
bld r2,1
bst r18,5
bld r6,1
bst r18,6
bld r10,1
bst r18,7
bld r14,1
bst r19,0
bld r2,2
bst r19,1
bld r6,2
bst r19,2
bld r10,2
bst r19,3
bld r14,2
bst r19,4
bld r2,3
bst r19,5
bld r6,3
bst r19,6
bld r10,3
bst r19,7
bld r14,3
bst r20,0
bld r2,4
bst r20,1
bld r6,4
bst r20,2
bld r10,4
bst r20,3
bld r14,4
bst r20,4
bld r2,5
bst r20,5
bld r6,5
bst r20,6
bld r10,5
bst r20,7
bld r14,5
bst r21,0
bld r2,6
bst r21,1
bld r6,6
bst r21,2
bld r10,6
bst r21,3
bld r14,6
bst r21,4
bld r2,7
bst r21,5
bld r6,7
bst r21,6
bld r10,7
bst r21,7
bld r14,7
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
bst r18,0
bld r3,0
bst r18,1
bld r7,0
bst r18,2
bld r11,0
bst r18,3
bld r15,0
bst r18,4
bld r3,1
bst r18,5
bld r7,1
bst r18,6
bld r11,1
bst r18,7
bld r15,1
bst r19,0
bld r3,2
bst r19,1
bld r7,2
bst r19,2
bld r11,2
bst r19,3
bld r15,2
bst r19,4
bld r3,3
bst r19,5
bld r7,3
bst r19,6
bld r11,3
bst r19,7
bld r15,3
bst r20,0
bld r3,4
bst r20,1
bld r7,4
bst r20,2
bld r11,4
bst r20,3
bld r15,4
bst r20,4
bld r3,5
bst r20,5
bld r7,5
bst r20,6
bld r11,5
bst r20,7
bld r15,5
bst r21,0
bld r3,6
bst r21,1
bld r7,6
bst r21,2
bld r11,6
bst r21,3
bld r15,6
bst r21,4
bld r3,7
bst r21,5
bld r7,7
bst r21,6
bld r11,7
bst r21,7
bld r15,7
movw r26,r30
ldi r30,lo8(table_0)
ldi r31,hi8(table_0)
#if defined(RAMPZ)
ldi r24,hh8(table_0)
in r0,_SFR_IO_ADDR(RAMPZ)
push r0
out _SFR_IO_ADDR(RAMPZ),r24
#endif
rcall 283f
rcall 283f
rcall 283f
rcall 283f
rcall 283f
rcall 283f
rcall 283f
rcall 283f
rjmp 1021f
283:
mov r0,r22
and r0,r8
eor r4,r0
mov r0,r23
and r0,r9
eor r5,r0
mov r0,r2
and r0,r10
eor r6,r0
mov r0,r3
and r0,r11
eor r7,r0
mov r0,r4
and r0,r12
eor r22,r0
mov r0,r5
and r0,r13
eor r23,r0
mov r0,r6
and r0,r14
eor r2,r0
mov r0,r7
and r0,r15
eor r3,r0
mov r0,r22
or r0,r4
eor r8,r0
mov r0,r23
or r0,r5
eor r9,r0
mov r0,r2
or r0,r6
eor r10,r0
mov r0,r3
or r0,r7
eor r11,r0
eor r12,r8
eor r13,r9
eor r14,r10
eor r15,r11
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
com r12
com r13
com r14
com r15
mov r0,r22
and r0,r4
eor r8,r0
mov r0,r23
and r0,r5
eor r9,r0
mov r0,r2
and r0,r6
eor r10,r0
mov r0,r3
and r0,r7
eor r11,r0
movw r18,r4
movw r20,r6
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
andi r18,204
andi r19,204
andi r20,204
andi r21,204
lsr r7
ror r6
ror r5
ror r4
lsr r7
ror r6
ror r5
ror r4
ldi r25,51
and r4,r25
and r5,r25
and r6,r25
and r7,r25
or r4,r18
or r5,r19
or r6,r20
or r7,r21
movw r18,r8
movw r20,r10
lsl r18
rol r19
rol r20
rol r21
andi r18,238
andi r19,238
andi r20,238
andi r21,238
lsr r11
ror r10
ror r9
ror r8
lsr r11
ror r10
ror r9
ror r8
lsr r11
ror r10
ror r9
ror r8
ldi r24,17
and r8,r24
and r9,r24
and r10,r24
and r11,r24
or r8,r18
or r9,r19
or r10,r20
or r11,r21
movw r18,r12
movw r20,r14
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
andi r18,136
andi r19,136
andi r20,136
andi r21,136
lsr r15
ror r14
ror r13
ror r12
ldi r17,119
and r12,r17
and r13,r17
and r14,r17
and r15,r17
or r12,r18
or r13,r19
or r14,r20
or r15,r21
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
eor r8,r18
eor r9,r19
eor r10,r20
eor r11,r21
#if defined(RAMPZ)
elpm r18,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r18,Z
#elif defined(__AVR_TINY__)
ld r18,Z
#else
lpm
mov r18,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r19,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r19,Z
#elif defined(__AVR_TINY__)
ld r19,Z
#else
lpm
mov r19,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
inc r30
eor r22,r18
eor r23,r19
eor r2,r20
eor r3,r21
mov r0,r12
and r0,r8
eor r4,r0
mov r0,r13
and r0,r9
eor r5,r0
mov r0,r14
and r0,r10
eor r6,r0
mov r0,r15
and r0,r11
eor r7,r0
mov r0,r4
and r0,r22
eor r12,r0
mov r0,r5
and r0,r23
eor r13,r0
mov r0,r6
and r0,r2
eor r14,r0
mov r0,r7
and r0,r3
eor r15,r0
mov r0,r12
or r0,r4
eor r8,r0
mov r0,r13
or r0,r5
eor r9,r0
mov r0,r14
or r0,r6
eor r10,r0
mov r0,r15
or r0,r7
eor r11,r0
eor r22,r8
eor r23,r9
eor r2,r10
eor r3,r11
eor r4,r22
eor r5,r23
eor r6,r2
eor r7,r3
com r22
com r23
com r2
com r3
mov r0,r12
and r0,r4
eor r8,r0
mov r0,r13
and r0,r5
eor r9,r0
mov r0,r14
and r0,r6
eor r10,r0
mov r0,r15
and r0,r7
eor r11,r0
mov r0,r1
lsr r23
ror r22
ror r0
lsr r23
ror r22
ror r0
lsr r23
ror r22
ror r0
lsr r23
ror r22
ror r0
or r23,r0
mov r0,r1
lsr r3
ror r2
ror r0
lsr r3
ror r2
ror r0
lsr r3
ror r2
ror r0
lsr r3
ror r2
ror r0
or r3,r0
mov r0,r5
mov r5,r4
mov r4,r0
mov r0,r7
mov r7,r6
mov r6,r0
lsl r8
rol r9
adc r8,r1
lsl r8
rol r9
adc r8,r1
lsl r8
rol r9
adc r8,r1
lsl r8
rol r9
adc r8,r1
lsl r10
rol r11
adc r10,r1
lsl r10
rol r11
adc r10,r1
lsl r10
rol r11
adc r10,r1
lsl r10
rol r11
adc r10,r1
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
eor r8,r18
eor r9,r19
eor r10,r20
eor r11,r21
#if defined(RAMPZ)
elpm r18,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r18,Z
#elif defined(__AVR_TINY__)
ld r18,Z
#else
lpm
mov r18,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r19,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r19,Z
#elif defined(__AVR_TINY__)
ld r19,Z
#else
lpm
mov r19,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
inc r30
eor r12,r18
eor r13,r19
eor r14,r20
eor r15,r21
mov r0,r22
and r0,r8
eor r4,r0
mov r0,r23
and r0,r9
eor r5,r0
mov r0,r2
and r0,r10
eor r6,r0
mov r0,r3
and r0,r11
eor r7,r0
mov r0,r4
and r0,r12
eor r22,r0
mov r0,r5
and r0,r13
eor r23,r0
mov r0,r6
and r0,r14
eor r2,r0
mov r0,r7
and r0,r15
eor r3,r0
mov r0,r22
or r0,r4
eor r8,r0
mov r0,r23
or r0,r5
eor r9,r0
mov r0,r2
or r0,r6
eor r10,r0
mov r0,r3
or r0,r7
eor r11,r0
eor r12,r8
eor r13,r9
eor r14,r10
eor r15,r11
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
com r12
com r13
com r14
com r15
mov r0,r22
and r0,r4
eor r8,r0
mov r0,r23
and r0,r5
eor r9,r0
mov r0,r2
and r0,r6
eor r10,r0
mov r0,r3
and r0,r7
eor r11,r0
movw r18,r4
movw r20,r6
lsr r21
ror r20
ror r19
ror r18
eor r18,r4
eor r19,r5
eor r20,r6
eor r21,r7
andi r18,85
andi r19,85
andi r20,85
andi r21,85
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
lsl r18
rol r19
rol r20
rol r21
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
mov r0,r10
mov r10,r8
mov r8,r0
mov r0,r11
mov r11,r9
mov r9,r0
movw r18,r8
movw r20,r10
lsr r21
ror r20
ror r19
ror r18
eor r18,r8
eor r19,r9
andi r18,85
andi r19,85
eor r8,r18
eor r9,r19
mov r20,r1
mov r21,r1
lsl r18
rol r19
rol r20
rol r21
eor r8,r18
eor r9,r19
eor r10,r20
eor r11,r21
mov r0,r14
mov r14,r12
mov r12,r0
mov r0,r15
mov r15,r13
mov r13,r0
movw r18,r14
lsr r19
ror r18
eor r18,r14
eor r19,r15
andi r18,85
andi r19,85
eor r14,r18
eor r15,r19
lsl r18
rol r19
eor r14,r18
eor r15,r19
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
eor r8,r18
eor r9,r19
eor r10,r20
eor r11,r21
#if defined(RAMPZ)
elpm r18,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r18,Z
#elif defined(__AVR_TINY__)
ld r18,Z
#else
lpm
mov r18,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r19,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r19,Z
#elif defined(__AVR_TINY__)
ld r19,Z
#else
lpm
mov r19,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
inc r30
eor r22,r18
eor r23,r19
eor r2,r20
eor r3,r21
mov r0,r12
and r0,r8
eor r4,r0
mov r0,r13
and r0,r9
eor r5,r0
mov r0,r14
and r0,r10
eor r6,r0
mov r0,r15
and r0,r11
eor r7,r0
mov r0,r4
and r0,r22
eor r12,r0
mov r0,r5
and r0,r23
eor r13,r0
mov r0,r6
and r0,r2
eor r14,r0
mov r0,r7
and r0,r3
eor r15,r0
mov r0,r12
or r0,r4
eor r8,r0
mov r0,r13
or r0,r5
eor r9,r0
mov r0,r14
or r0,r6
eor r10,r0
mov r0,r15
or r0,r7
eor r11,r0
eor r22,r8
eor r23,r9
eor r2,r10
eor r3,r11
eor r4,r22
eor r5,r23
eor r6,r2
eor r7,r3
com r22
com r23
com r2
com r3
mov r0,r12
and r0,r4
eor r8,r0
mov r0,r13
and r0,r5
eor r9,r0
mov r0,r14
and r0,r6
eor r10,r0
mov r0,r15
and r0,r7
eor r11,r0
lsl r22
adc r22,r1
lsl r22
adc r22,r1
lsl r23
adc r23,r1
lsl r23
adc r23,r1
lsl r2
adc r2,r1
lsl r2
adc r2,r1
lsl r3
adc r3,r1
lsl r3
adc r3,r1
swap r4
swap r5
swap r6
swap r7
mov r0,r1
lsr r8
ror r0
lsr r8
ror r0
or r8,r0
mov r0,r1
lsr r9
ror r0
lsr r9
ror r0
or r9,r0
mov r0,r1
lsr r10
ror r0
lsr r10
ror r0
or r10,r0
mov r0,r1
lsr r11
ror r0
lsr r11
ror r0
or r11,r0
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
eor r8,r18
eor r9,r19
eor r10,r20
eor r11,r21
#if defined(RAMPZ)
elpm r18,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r18,Z
#elif defined(__AVR_TINY__)
ld r18,Z
#else
lpm
mov r18,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r19,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r19,Z
#elif defined(__AVR_TINY__)
ld r19,Z
#else
lpm
mov r19,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
inc r30
eor r12,r18
eor r13,r19
eor r14,r20
eor r15,r21
mov r0,r22
and r0,r8
eor r4,r0
mov r0,r23
and r0,r9
eor r5,r0
mov r0,r2
and r0,r10
eor r6,r0
mov r0,r3
and r0,r11
eor r7,r0
mov r0,r4
and r0,r12
eor r22,r0
mov r0,r5
and r0,r13
eor r23,r0
mov r0,r6
and r0,r14
eor r2,r0
mov r0,r7
and r0,r15
eor r3,r0
mov r0,r22
or r0,r4
eor r8,r0
mov r0,r23
or r0,r5
eor r9,r0
mov r0,r2
or r0,r6
eor r10,r0
mov r0,r3
or r0,r7
eor r11,r0
eor r12,r8
eor r13,r9
eor r14,r10
eor r15,r11
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
com r12
com r13
com r14
com r15
mov r0,r22
and r0,r4
eor r8,r0
mov r0,r23
and r0,r5
eor r9,r0
mov r0,r2
and r0,r6
eor r10,r0
mov r0,r3
and r0,r7
eor r11,r0
mov r0,r6
mov r6,r4
mov r4,r0
mov r0,r7
mov r7,r5
mov r5,r0
mov r0,r8
mov r8,r9
mov r9,r10
mov r10,r11
mov r11,r0
mov r0,r15
mov r15,r14
mov r14,r13
mov r13,r12
mov r12,r0
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
eor r8,r18
eor r9,r19
eor r10,r20
eor r11,r21
#if defined(RAMPZ)
elpm r18,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r18,Z
#elif defined(__AVR_TINY__)
ld r18,Z
#else
lpm
mov r18,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r19,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r19,Z
#elif defined(__AVR_TINY__)
ld r19,Z
#else
lpm
mov r19,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
inc r30
eor r22,r18
eor r23,r19
eor r2,r20
eor r3,r21
eor r22,r12
eor r23,r13
eor r2,r14
eor r3,r15
eor r12,r22
eor r13,r23
eor r14,r2
eor r15,r3
eor r22,r12
eor r23,r13
eor r2,r14
eor r3,r15
ret
1021:
#if defined(RAMPZ)
pop r0
out _SFR_IO_ADDR(RAMPZ),r0
#endif
ldd r26,Y+1
ldd r27,Y+2
bst r22,0
bld r18,0
bst r4,0
bld r18,1
bst r8,0
bld r18,2
bst r12,0
bld r18,3
bst r22,1
bld r18,4
bst r4,1
bld r18,5
bst r8,1
bld r18,6
bst r12,1
bld r18,7
bst r22,2
bld r19,0
bst r4,2
bld r19,1
bst r8,2
bld r19,2
bst r12,2
bld r19,3
bst r22,3
bld r19,4
bst r4,3
bld r19,5
bst r8,3
bld r19,6
bst r12,3
bld r19,7
bst r22,4
bld r20,0
bst r4,4
bld r20,1
bst r8,4
bld r20,2
bst r12,4
bld r20,3
bst r22,5
bld r20,4
bst r4,5
bld r20,5
bst r8,5
bld r20,6
bst r12,5
bld r20,7
bst r22,6
bld r21,0
bst r4,6
bld r21,1
bst r8,6
bld r21,2
bst r12,6
bld r21,3
bst r22,7
bld r21,4
bst r4,7
bld r21,5
bst r8,7
bld r21,6
bst r12,7
bld r21,7
st X+,r18
st X+,r19
st X+,r20
st X+,r21
bst r23,0
bld r18,0
bst r5,0
bld r18,1
bst r9,0
bld r18,2
bst r13,0
bld r18,3
bst r23,1
bld r18,4
bst r5,1
bld r18,5
bst r9,1
bld r18,6
bst r13,1
bld r18,7
bst r23,2
bld r19,0
bst r5,2
bld r19,1
bst r9,2
bld r19,2
bst r13,2
bld r19,3
bst r23,3
bld r19,4
bst r5,3
bld r19,5
bst r9,3
bld r19,6
bst r13,3
bld r19,7
bst r23,4
bld r20,0
bst r5,4
bld r20,1
bst r9,4
bld r20,2
bst r13,4
bld r20,3
bst r23,5
bld r20,4
bst r5,5
bld r20,5
bst r9,5
bld r20,6
bst r13,5
bld r20,7
bst r23,6
bld r21,0
bst r5,6
bld r21,1
bst r9,6
bld r21,2
bst r13,6
bld r21,3
bst r23,7
bld r21,4
bst r5,7
bld r21,5
bst r9,7
bld r21,6
bst r13,7
bld r21,7
st X+,r18
st X+,r19
st X+,r20
st X+,r21
bst r2,0
bld r18,0
bst r6,0
bld r18,1
bst r10,0
bld r18,2
bst r14,0
bld r18,3
bst r2,1
bld r18,4
bst r6,1
bld r18,5
bst r10,1
bld r18,6
bst r14,1
bld r18,7
bst r2,2
bld r19,0
bst r6,2
bld r19,1
bst r10,2
bld r19,2
bst r14,2
bld r19,3
bst r2,3
bld r19,4
bst r6,3
bld r19,5
bst r10,3
bld r19,6
bst r14,3
bld r19,7
bst r2,4
bld r20,0
bst r6,4
bld r20,1
bst r10,4
bld r20,2
bst r14,4
bld r20,3
bst r2,5
bld r20,4
bst r6,5
bld r20,5
bst r10,5
bld r20,6
bst r14,5
bld r20,7
bst r2,6
bld r21,0
bst r6,6
bld r21,1
bst r10,6
bld r21,2
bst r14,6
bld r21,3
bst r2,7
bld r21,4
bst r6,7
bld r21,5
bst r10,7
bld r21,6
bst r14,7
bld r21,7
st X+,r18
st X+,r19
st X+,r20
st X+,r21
bst r3,0
bld r18,0
bst r7,0
bld r18,1
bst r11,0
bld r18,2
bst r15,0
bld r18,3
bst r3,1
bld r18,4
bst r7,1
bld r18,5
bst r11,1
bld r18,6
bst r15,1
bld r18,7
bst r3,2
bld r19,0
bst r7,2
bld r19,1
bst r11,2
bld r19,2
bst r15,2
bld r19,3
bst r3,3
bld r19,4
bst r7,3
bld r19,5
bst r11,3
bld r19,6
bst r15,3
bld r19,7
bst r3,4
bld r20,0
bst r7,4
bld r20,1
bst r11,4
bld r20,2
bst r15,4
bld r20,3
bst r3,5
bld r20,4
bst r7,5
bld r20,5
bst r11,5
bld r20,6
bst r15,5
bld r20,7
bst r3,6
bld r21,0
bst r7,6
bld r21,1
bst r11,6
bld r21,2
bst r15,6
bld r21,3
bst r3,7
bld r21,4
bst r7,7
bld r21,5
bst r11,7
bld r21,6
bst r15,7
bld r21,7
st X+,r18
st X+,r19
st X+,r20
st X+,r21
pop r0
pop r0
pop r17
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
pop r3
pop r2
pop r29
pop r28
ret
.size gift128n_encrypt, .-gift128n_encrypt
.text
.global gift128n_decrypt
.type gift128n_decrypt, @function
gift128n_decrypt:
push r28
push r29
push r2
push r3
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push r17
push r23
push r22
movw r30,r24
movw r26,r20
in r28,0x3d
in r29,0x3e
.L__stack_usage = 19
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
bst r18,0
bld r22,0
bst r18,1
bld r4,0
bst r18,2
bld r8,0
bst r18,3
bld r12,0
bst r18,4
bld r22,1
bst r18,5
bld r4,1
bst r18,6
bld r8,1
bst r18,7
bld r12,1
bst r19,0
bld r22,2
bst r19,1
bld r4,2
bst r19,2
bld r8,2
bst r19,3
bld r12,2
bst r19,4
bld r22,3
bst r19,5
bld r4,3
bst r19,6
bld r8,3
bst r19,7
bld r12,3
bst r20,0
bld r22,4
bst r20,1
bld r4,4
bst r20,2
bld r8,4
bst r20,3
bld r12,4
bst r20,4
bld r22,5
bst r20,5
bld r4,5
bst r20,6
bld r8,5
bst r20,7
bld r12,5
bst r21,0
bld r22,6
bst r21,1
bld r4,6
bst r21,2
bld r8,6
bst r21,3
bld r12,6
bst r21,4
bld r22,7
bst r21,5
bld r4,7
bst r21,6
bld r8,7
bst r21,7
bld r12,7
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
bst r18,0
bld r23,0
bst r18,1
bld r5,0
bst r18,2
bld r9,0
bst r18,3
bld r13,0
bst r18,4
bld r23,1
bst r18,5
bld r5,1
bst r18,6
bld r9,1
bst r18,7
bld r13,1
bst r19,0
bld r23,2
bst r19,1
bld r5,2
bst r19,2
bld r9,2
bst r19,3
bld r13,2
bst r19,4
bld r23,3
bst r19,5
bld r5,3
bst r19,6
bld r9,3
bst r19,7
bld r13,3
bst r20,0
bld r23,4
bst r20,1
bld r5,4
bst r20,2
bld r9,4
bst r20,3
bld r13,4
bst r20,4
bld r23,5
bst r20,5
bld r5,5
bst r20,6
bld r9,5
bst r20,7
bld r13,5
bst r21,0
bld r23,6
bst r21,1
bld r5,6
bst r21,2
bld r9,6
bst r21,3
bld r13,6
bst r21,4
bld r23,7
bst r21,5
bld r5,7
bst r21,6
bld r9,7
bst r21,7
bld r13,7
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
bst r18,0
bld r2,0
bst r18,1
bld r6,0
bst r18,2
bld r10,0
bst r18,3
bld r14,0
bst r18,4
bld r2,1
bst r18,5
bld r6,1
bst r18,6
bld r10,1
bst r18,7
bld r14,1
bst r19,0
bld r2,2
bst r19,1
bld r6,2
bst r19,2
bld r10,2
bst r19,3
bld r14,2
bst r19,4
bld r2,3
bst r19,5
bld r6,3
bst r19,6
bld r10,3
bst r19,7
bld r14,3
bst r20,0
bld r2,4
bst r20,1
bld r6,4
bst r20,2
bld r10,4
bst r20,3
bld r14,4
bst r20,4
bld r2,5
bst r20,5
bld r6,5
bst r20,6
bld r10,5
bst r20,7
bld r14,5
bst r21,0
bld r2,6
bst r21,1
bld r6,6
bst r21,2
bld r10,6
bst r21,3
bld r14,6
bst r21,4
bld r2,7
bst r21,5
bld r6,7
bst r21,6
bld r10,7
bst r21,7
bld r14,7
ld r18,X+
ld r19,X+
ld r20,X+
ld r21,X+
bst r18,0
bld r3,0
bst r18,1
bld r7,0
bst r18,2
bld r11,0
bst r18,3
bld r15,0
bst r18,4
bld r3,1
bst r18,5
bld r7,1
bst r18,6
bld r11,1
bst r18,7
bld r15,1
bst r19,0
bld r3,2
bst r19,1
bld r7,2
bst r19,2
bld r11,2
bst r19,3
bld r15,2
bst r19,4
bld r3,3
bst r19,5
bld r7,3
bst r19,6
bld r11,3
bst r19,7
bld r15,3
bst r20,0
bld r3,4
bst r20,1
bld r7,4
bst r20,2
bld r11,4
bst r20,3
bld r15,4
bst r20,4
bld r3,5
bst r20,5
bld r7,5
bst r20,6
bld r11,5
bst r20,7
bld r15,5
bst r21,0
bld r3,6
bst r21,1
bld r7,6
bst r21,2
bld r11,6
bst r21,3
bld r15,6
bst r21,4
bld r3,7
bst r21,5
bld r7,7
bst r21,6
bld r11,7
bst r21,7
bld r15,7
movw r26,r30
subi r26,192
sbci r27,254
ldi r30,lo8(table_0)
ldi r31,hi8(table_0)
#if defined(RAMPZ)
ldi r24,hh8(table_0)
in r0,_SFR_IO_ADDR(RAMPZ)
push r0
out _SFR_IO_ADDR(RAMPZ),r24
#endif
ldi r30,160
rcall 286f
rcall 286f
rcall 286f
rcall 286f
rcall 286f
rcall 286f
rcall 286f
rcall 286f
rjmp 1024f
286:
eor r22,r12
eor r23,r13
eor r2,r14
eor r3,r15
eor r12,r22
eor r13,r23
eor r14,r2
eor r15,r3
eor r22,r12
eor r23,r13
eor r2,r14
eor r3,r15
dec r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r19,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r19,Z
#elif defined(__AVR_TINY__)
ld r19,Z
#else
lpm
mov r19,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r18,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r18,Z
#elif defined(__AVR_TINY__)
ld r18,Z
#else
lpm
mov r18,r0
#endif
eor r22,r18
eor r23,r19
eor r2,r20
eor r3,r21
ld r21,-X
ld r20,-X
ld r19,-X
ld r18,-X
eor r8,r18
eor r9,r19
eor r10,r20
eor r11,r21
ld r21,-X
ld r20,-X
ld r19,-X
ld r18,-X
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
mov r0,r6
mov r6,r4
mov r4,r0
mov r0,r7
mov r7,r5
mov r5,r0
mov r0,r11
mov r11,r10
mov r10,r9
mov r9,r8
mov r8,r0
mov r0,r12
mov r12,r13
mov r13,r14
mov r14,r15
mov r15,r0
mov r0,r22
and r0,r4
eor r8,r0
mov r0,r23
and r0,r5
eor r9,r0
mov r0,r2
and r0,r6
eor r10,r0
mov r0,r3
and r0,r7
eor r11,r0
com r12
com r13
com r14
com r15
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r12,r8
eor r13,r9
eor r14,r10
eor r15,r11
mov r0,r22
or r0,r4
eor r8,r0
mov r0,r23
or r0,r5
eor r9,r0
mov r0,r2
or r0,r6
eor r10,r0
mov r0,r3
or r0,r7
eor r11,r0
mov r0,r4
and r0,r12
eor r22,r0
mov r0,r5
and r0,r13
eor r23,r0
mov r0,r6
and r0,r14
eor r2,r0
mov r0,r7
and r0,r15
eor r3,r0
mov r0,r22
and r0,r8
eor r4,r0
mov r0,r23
and r0,r9
eor r5,r0
mov r0,r2
and r0,r10
eor r6,r0
mov r0,r3
and r0,r11
eor r7,r0
dec r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r19,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r19,Z
#elif defined(__AVR_TINY__)
ld r19,Z
#else
lpm
mov r19,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r18,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r18,Z
#elif defined(__AVR_TINY__)
ld r18,Z
#else
lpm
mov r18,r0
#endif
eor r12,r18
eor r13,r19
eor r14,r20
eor r15,r21
ld r21,-X
ld r20,-X
ld r19,-X
ld r18,-X
eor r8,r18
eor r9,r19
eor r10,r20
eor r11,r21
ld r21,-X
ld r20,-X
ld r19,-X
ld r18,-X
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
mov r0,r1
lsr r22
ror r0
lsr r22
ror r0
or r22,r0
mov r0,r1
lsr r23
ror r0
lsr r23
ror r0
or r23,r0
mov r0,r1
lsr r2
ror r0
lsr r2
ror r0
or r2,r0
mov r0,r1
lsr r3
ror r0
lsr r3
ror r0
or r3,r0
swap r4
swap r5
swap r6
swap r7
lsl r8
adc r8,r1
lsl r8
adc r8,r1
lsl r9
adc r9,r1
lsl r9
adc r9,r1
lsl r10
adc r10,r1
lsl r10
adc r10,r1
lsl r11
adc r11,r1
lsl r11
adc r11,r1
mov r0,r12
and r0,r4
eor r8,r0
mov r0,r13
and r0,r5
eor r9,r0
mov r0,r14
and r0,r6
eor r10,r0
mov r0,r15
and r0,r7
eor r11,r0
com r22
com r23
com r2
com r3
eor r4,r22
eor r5,r23
eor r6,r2
eor r7,r3
eor r22,r8
eor r23,r9
eor r2,r10
eor r3,r11
mov r0,r12
or r0,r4
eor r8,r0
mov r0,r13
or r0,r5
eor r9,r0
mov r0,r14
or r0,r6
eor r10,r0
mov r0,r15
or r0,r7
eor r11,r0
mov r0,r4
and r0,r22
eor r12,r0
mov r0,r5
and r0,r23
eor r13,r0
mov r0,r6
and r0,r2
eor r14,r0
mov r0,r7
and r0,r3
eor r15,r0
mov r0,r12
and r0,r8
eor r4,r0
mov r0,r13
and r0,r9
eor r5,r0
mov r0,r14
and r0,r10
eor r6,r0
mov r0,r15
and r0,r11
eor r7,r0
dec r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r19,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r19,Z
#elif defined(__AVR_TINY__)
ld r19,Z
#else
lpm
mov r19,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r18,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r18,Z
#elif defined(__AVR_TINY__)
ld r18,Z
#else
lpm
mov r18,r0
#endif
eor r22,r18
eor r23,r19
eor r2,r20
eor r3,r21
ld r21,-X
ld r20,-X
ld r19,-X
ld r18,-X
eor r8,r18
eor r9,r19
eor r10,r20
eor r11,r21
ld r21,-X
ld r20,-X
ld r19,-X
ld r18,-X
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
movw r18,r4
movw r20,r6
lsr r21
ror r20
ror r19
ror r18
eor r18,r4
eor r19,r5
eor r20,r6
eor r21,r7
andi r18,85
andi r19,85
andi r20,85
andi r21,85
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
lsl r18
rol r19
rol r20
rol r21
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
movw r18,r8
movw r20,r10
lsr r21
ror r20
ror r19
ror r18
eor r18,r8
eor r19,r9
andi r18,85
andi r19,85
eor r8,r18
eor r9,r19
mov r20,r1
mov r21,r1
lsl r18
rol r19
rol r20
rol r21
eor r8,r18
eor r9,r19
eor r10,r20
eor r11,r21
mov r0,r10
mov r10,r8
mov r8,r0
mov r0,r11
mov r11,r9
mov r9,r0
movw r18,r14
lsr r19
ror r18
eor r18,r14
eor r19,r15
andi r18,85
andi r19,85
eor r14,r18
eor r15,r19
lsl r18
rol r19
eor r14,r18
eor r15,r19
mov r0,r14
mov r14,r12
mov r12,r0
mov r0,r15
mov r15,r13
mov r13,r0
mov r0,r22
and r0,r4
eor r8,r0
mov r0,r23
and r0,r5
eor r9,r0
mov r0,r2
and r0,r6
eor r10,r0
mov r0,r3
and r0,r7
eor r11,r0
com r12
com r13
com r14
com r15
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r12,r8
eor r13,r9
eor r14,r10
eor r15,r11
mov r0,r22
or r0,r4
eor r8,r0
mov r0,r23
or r0,r5
eor r9,r0
mov r0,r2
or r0,r6
eor r10,r0
mov r0,r3
or r0,r7
eor r11,r0
mov r0,r4
and r0,r12
eor r22,r0
mov r0,r5
and r0,r13
eor r23,r0
mov r0,r6
and r0,r14
eor r2,r0
mov r0,r7
and r0,r15
eor r3,r0
mov r0,r22
and r0,r8
eor r4,r0
mov r0,r23
and r0,r9
eor r5,r0
mov r0,r2
and r0,r10
eor r6,r0
mov r0,r3
and r0,r11
eor r7,r0
dec r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r19,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r19,Z
#elif defined(__AVR_TINY__)
ld r19,Z
#else
lpm
mov r19,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r18,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r18,Z
#elif defined(__AVR_TINY__)
ld r18,Z
#else
lpm
mov r18,r0
#endif
eor r12,r18
eor r13,r19
eor r14,r20
eor r15,r21
ld r21,-X
ld r20,-X
ld r19,-X
ld r18,-X
eor r8,r18
eor r9,r19
eor r10,r20
eor r11,r21
ld r21,-X
ld r20,-X
ld r19,-X
ld r18,-X
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
lsl r22
rol r23
adc r22,r1
lsl r22
rol r23
adc r22,r1
lsl r22
rol r23
adc r22,r1
lsl r22
rol r23
adc r22,r1
lsl r2
rol r3
adc r2,r1
lsl r2
rol r3
adc r2,r1
lsl r2
rol r3
adc r2,r1
lsl r2
rol r3
adc r2,r1
mov r0,r5
mov r5,r4
mov r4,r0
mov r0,r7
mov r7,r6
mov r6,r0
mov r0,r1
lsr r9
ror r8
ror r0
lsr r9
ror r8
ror r0
lsr r9
ror r8
ror r0
lsr r9
ror r8
ror r0
or r9,r0
mov r0,r1
lsr r11
ror r10
ror r0
lsr r11
ror r10
ror r0
lsr r11
ror r10
ror r0
lsr r11
ror r10
ror r0
or r11,r0
mov r0,r12
and r0,r4
eor r8,r0
mov r0,r13
and r0,r5
eor r9,r0
mov r0,r14
and r0,r6
eor r10,r0
mov r0,r15
and r0,r7
eor r11,r0
com r22
com r23
com r2
com r3
eor r4,r22
eor r5,r23
eor r6,r2
eor r7,r3
eor r22,r8
eor r23,r9
eor r2,r10
eor r3,r11
mov r0,r12
or r0,r4
eor r8,r0
mov r0,r13
or r0,r5
eor r9,r0
mov r0,r14
or r0,r6
eor r10,r0
mov r0,r15
or r0,r7
eor r11,r0
mov r0,r4
and r0,r22
eor r12,r0
mov r0,r5
and r0,r23
eor r13,r0
mov r0,r6
and r0,r2
eor r14,r0
mov r0,r7
and r0,r3
eor r15,r0
mov r0,r12
and r0,r8
eor r4,r0
mov r0,r13
and r0,r9
eor r5,r0
mov r0,r14
and r0,r10
eor r6,r0
mov r0,r15
and r0,r11
eor r7,r0
dec r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r19,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r19,Z
#elif defined(__AVR_TINY__)
ld r19,Z
#else
lpm
mov r19,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r18,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r18,Z
#elif defined(__AVR_TINY__)
ld r18,Z
#else
lpm
mov r18,r0
#endif
eor r22,r18
eor r23,r19
eor r2,r20
eor r3,r21
ld r21,-X
ld r20,-X
ld r19,-X
ld r18,-X
eor r8,r18
eor r9,r19
eor r10,r20
eor r11,r21
ld r21,-X
ld r20,-X
ld r19,-X
ld r18,-X
eor r4,r18
eor r5,r19
eor r6,r20
eor r7,r21
movw r18,r4
movw r20,r6
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
andi r18,204
andi r19,204
andi r20,204
andi r21,204
lsr r7
ror r6
ror r5
ror r4
lsr r7
ror r6
ror r5
ror r4
ldi r25,51
and r4,r25
and r5,r25
and r6,r25
and r7,r25
or r4,r18
or r5,r19
or r6,r20
or r7,r21
movw r18,r8
movw r20,r10
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
lsl r18
rol r19
rol r20
rol r21
andi r18,136
andi r19,136
andi r20,136
andi r21,136
lsr r11
ror r10
ror r9
ror r8
ldi r24,119
and r8,r24
and r9,r24
and r10,r24
and r11,r24
or r8,r18
or r9,r19
or r10,r20
or r11,r21
movw r18,r12
movw r20,r14
lsl r18
rol r19
rol r20
rol r21
andi r18,238
andi r19,238
andi r20,238
andi r21,238
lsr r15
ror r14
ror r13
ror r12
lsr r15
ror r14
ror r13
ror r12
lsr r15
ror r14
ror r13
ror r12
ldi r17,17
and r12,r17
and r13,r17
and r14,r17
and r15,r17
or r12,r18
or r13,r19
or r14,r20
or r15,r21
mov r0,r22
and r0,r4
eor r8,r0
mov r0,r23
and r0,r5
eor r9,r0
mov r0,r2
and r0,r6
eor r10,r0
mov r0,r3
and r0,r7
eor r11,r0
com r12
com r13
com r14
com r15
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r12,r8
eor r13,r9
eor r14,r10
eor r15,r11
mov r0,r22
or r0,r4
eor r8,r0
mov r0,r23
or r0,r5
eor r9,r0
mov r0,r2
or r0,r6
eor r10,r0
mov r0,r3
or r0,r7
eor r11,r0
mov r0,r4
and r0,r12
eor r22,r0
mov r0,r5
and r0,r13
eor r23,r0
mov r0,r6
and r0,r14
eor r2,r0
mov r0,r7
and r0,r15
eor r3,r0
mov r0,r22
and r0,r8
eor r4,r0
mov r0,r23
and r0,r9
eor r5,r0
mov r0,r2
and r0,r10
eor r6,r0
mov r0,r3
and r0,r11
eor r7,r0
ret
1024:
#if defined(RAMPZ)
pop r0
out _SFR_IO_ADDR(RAMPZ),r0
#endif
ldd r26,Y+1
ldd r27,Y+2
bst r22,0
bld r18,0
bst r4,0
bld r18,1
bst r8,0
bld r18,2
bst r12,0
bld r18,3
bst r22,1
bld r18,4
bst r4,1
bld r18,5
bst r8,1
bld r18,6
bst r12,1
bld r18,7
bst r22,2
bld r19,0
bst r4,2
bld r19,1
bst r8,2
bld r19,2
bst r12,2
bld r19,3
bst r22,3
bld r19,4
bst r4,3
bld r19,5
bst r8,3
bld r19,6
bst r12,3
bld r19,7
bst r22,4
bld r20,0
bst r4,4
bld r20,1
bst r8,4
bld r20,2
bst r12,4
bld r20,3
bst r22,5
bld r20,4
bst r4,5
bld r20,5
bst r8,5
bld r20,6
bst r12,5
bld r20,7
bst r22,6
bld r21,0
bst r4,6
bld r21,1
bst r8,6
bld r21,2
bst r12,6
bld r21,3
bst r22,7
bld r21,4
bst r4,7
bld r21,5
bst r8,7
bld r21,6
bst r12,7
bld r21,7
st X+,r18
st X+,r19
st X+,r20
st X+,r21
bst r23,0
bld r18,0
bst r5,0
bld r18,1
bst r9,0
bld r18,2
bst r13,0
bld r18,3
bst r23,1
bld r18,4
bst r5,1
bld r18,5
bst r9,1
bld r18,6
bst r13,1
bld r18,7
bst r23,2
bld r19,0
bst r5,2
bld r19,1
bst r9,2
bld r19,2
bst r13,2
bld r19,3
bst r23,3
bld r19,4
bst r5,3
bld r19,5
bst r9,3
bld r19,6
bst r13,3
bld r19,7
bst r23,4
bld r20,0
bst r5,4
bld r20,1
bst r9,4
bld r20,2
bst r13,4
bld r20,3
bst r23,5
bld r20,4
bst r5,5
bld r20,5
bst r9,5
bld r20,6
bst r13,5
bld r20,7
bst r23,6
bld r21,0
bst r5,6
bld r21,1
bst r9,6
bld r21,2
bst r13,6
bld r21,3
bst r23,7
bld r21,4
bst r5,7
bld r21,5
bst r9,7
bld r21,6
bst r13,7
bld r21,7
st X+,r18
st X+,r19
st X+,r20
st X+,r21
bst r2,0
bld r18,0
bst r6,0
bld r18,1
bst r10,0
bld r18,2
bst r14,0
bld r18,3
bst r2,1
bld r18,4
bst r6,1
bld r18,5
bst r10,1
bld r18,6
bst r14,1
bld r18,7
bst r2,2
bld r19,0
bst r6,2
bld r19,1
bst r10,2
bld r19,2
bst r14,2
bld r19,3
bst r2,3
bld r19,4
bst r6,3
bld r19,5
bst r10,3
bld r19,6
bst r14,3
bld r19,7
bst r2,4
bld r20,0
bst r6,4
bld r20,1
bst r10,4
bld r20,2
bst r14,4
bld r20,3
bst r2,5
bld r20,4
bst r6,5
bld r20,5
bst r10,5
bld r20,6
bst r14,5
bld r20,7
bst r2,6
bld r21,0
bst r6,6
bld r21,1
bst r10,6
bld r21,2
bst r14,6
bld r21,3
bst r2,7
bld r21,4
bst r6,7
bld r21,5
bst r10,7
bld r21,6
bst r14,7
bld r21,7
st X+,r18
st X+,r19
st X+,r20
st X+,r21
bst r3,0
bld r18,0
bst r7,0
bld r18,1
bst r11,0
bld r18,2
bst r15,0
bld r18,3
bst r3,1
bld r18,4
bst r7,1
bld r18,5
bst r11,1
bld r18,6
bst r15,1
bld r18,7
bst r3,2
bld r19,0
bst r7,2
bld r19,1
bst r11,2
bld r19,2
bst r15,2
bld r19,3
bst r3,3
bld r19,4
bst r7,3
bld r19,5
bst r11,3
bld r19,6
bst r15,3
bld r19,7
bst r3,4
bld r20,0
bst r7,4
bld r20,1
bst r11,4
bld r20,2
bst r15,4
bld r20,3
bst r3,5
bld r20,4
bst r7,5
bld r20,5
bst r11,5
bld r20,6
bst r15,5
bld r20,7
bst r3,6
bld r21,0
bst r7,6
bld r21,1
bst r11,6
bld r21,2
bst r15,6
bld r21,3
bst r3,7
bld r21,4
bst r7,7
bld r21,5
bst r11,7
bld r21,6
bst r15,7
bld r21,7
st X+,r18
st X+,r19
st X+,r20
st X+,r21
pop r0
pop r0
pop r17
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
pop r3
pop r2
pop r29
pop r28
ret
.size gift128n_decrypt, .-gift128n_decrypt
.text
.global gift128t_encrypt
.type gift128t_encrypt, @function
gift128t_encrypt:
push r28
push r29
push r2
push r3
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push r16
push r17
push r23
push r22
movw r30,r24
movw r26,r20
in r28,0x3d
in r29,0x3e
.L__stack_usage = 20
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
bst r20,0
bld r2,0
bst r20,1
bld r6,0
bst r20,2
bld r10,0
bst r20,3
bld r14,0
bst r20,4
bld r2,1
bst r20,5
bld r6,1
bst r20,6
bld r10,1
bst r20,7
bld r14,1
bst r21,0
bld r2,2
bst r21,1
bld r6,2
bst r21,2
bld r10,2
bst r21,3
bld r14,2
bst r21,4
bld r2,3
bst r21,5
bld r6,3
bst r21,6
bld r10,3
bst r21,7
bld r14,3
bst r22,0
bld r2,4
bst r22,1
bld r6,4
bst r22,2
bld r10,4
bst r22,3
bld r14,4
bst r22,4
bld r2,5
bst r22,5
bld r6,5
bst r22,6
bld r10,5
bst r22,7
bld r14,5
bst r23,0
bld r2,6
bst r23,1
bld r6,6
bst r23,2
bld r10,6
bst r23,3
bld r14,6
bst r23,4
bld r2,7
bst r23,5
bld r6,7
bst r23,6
bld r10,7
bst r23,7
bld r14,7
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
bst r20,0
bld r3,0
bst r20,1
bld r7,0
bst r20,2
bld r11,0
bst r20,3
bld r15,0
bst r20,4
bld r3,1
bst r20,5
bld r7,1
bst r20,6
bld r11,1
bst r20,7
bld r15,1
bst r21,0
bld r3,2
bst r21,1
bld r7,2
bst r21,2
bld r11,2
bst r21,3
bld r15,2
bst r21,4
bld r3,3
bst r21,5
bld r7,3
bst r21,6
bld r11,3
bst r21,7
bld r15,3
bst r22,0
bld r3,4
bst r22,1
bld r7,4
bst r22,2
bld r11,4
bst r22,3
bld r15,4
bst r22,4
bld r3,5
bst r22,5
bld r7,5
bst r22,6
bld r11,5
bst r22,7
bld r15,5
bst r23,0
bld r3,6
bst r23,1
bld r7,6
bst r23,2
bld r11,6
bst r23,3
bld r15,6
bst r23,4
bld r3,7
bst r23,5
bld r7,7
bst r23,6
bld r11,7
bst r23,7
bld r15,7
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
bst r20,0
bld r4,0
bst r20,1
bld r8,0
bst r20,2
bld r12,0
bst r20,3
bld r24,0
bst r20,4
bld r4,1
bst r20,5
bld r8,1
bst r20,6
bld r12,1
bst r20,7
bld r24,1
bst r21,0
bld r4,2
bst r21,1
bld r8,2
bst r21,2
bld r12,2
bst r21,3
bld r24,2
bst r21,4
bld r4,3
bst r21,5
bld r8,3
bst r21,6
bld r12,3
bst r21,7
bld r24,3
bst r22,0
bld r4,4
bst r22,1
bld r8,4
bst r22,2
bld r12,4
bst r22,3
bld r24,4
bst r22,4
bld r4,5
bst r22,5
bld r8,5
bst r22,6
bld r12,5
bst r22,7
bld r24,5
bst r23,0
bld r4,6
bst r23,1
bld r8,6
bst r23,2
bld r12,6
bst r23,3
bld r24,6
bst r23,4
bld r4,7
bst r23,5
bld r8,7
bst r23,6
bld r12,7
bst r23,7
bld r24,7
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
bst r20,0
bld r5,0
bst r20,1
bld r9,0
bst r20,2
bld r13,0
bst r20,3
bld r25,0
bst r20,4
bld r5,1
bst r20,5
bld r9,1
bst r20,6
bld r13,1
bst r20,7
bld r25,1
bst r21,0
bld r5,2
bst r21,1
bld r9,2
bst r21,2
bld r13,2
bst r21,3
bld r25,2
bst r21,4
bld r5,3
bst r21,5
bld r9,3
bst r21,6
bld r13,3
bst r21,7
bld r25,3
bst r22,0
bld r5,4
bst r22,1
bld r9,4
bst r22,2
bld r13,4
bst r22,3
bld r25,4
bst r22,4
bld r5,5
bst r22,5
bld r9,5
bst r22,6
bld r13,5
bst r22,7
bld r25,5
bst r23,0
bld r5,6
bst r23,1
bld r9,6
bst r23,2
bld r13,6
bst r23,3
bld r25,6
bst r23,4
bld r5,7
bst r23,5
bld r9,7
bst r23,6
bld r13,7
bst r23,7
bld r25,7
movw r26,r30
ldi r30,lo8(table_0)
ldi r31,hi8(table_0)
#if defined(RAMPZ)
ldi r19,hh8(table_0)
in r0,_SFR_IO_ADDR(RAMPZ)
push r0
out _SFR_IO_ADDR(RAMPZ),r19
#endif
rcall 311f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 311f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 311f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 311f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 311f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 311f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 311f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 311f
rjmp 1049f
311:
mov r0,r2
and r0,r10
eor r6,r0
mov r0,r3
and r0,r11
eor r7,r0
mov r0,r4
and r0,r12
eor r8,r0
mov r0,r5
and r0,r13
eor r9,r0
mov r0,r6
and r0,r14
eor r2,r0
mov r0,r7
and r0,r15
eor r3,r0
mov r0,r8
and r0,r24
eor r4,r0
mov r0,r9
and r0,r25
eor r5,r0
mov r0,r2
or r0,r6
eor r10,r0
mov r0,r3
or r0,r7
eor r11,r0
mov r0,r4
or r0,r8
eor r12,r0
mov r0,r5
or r0,r9
eor r13,r0
eor r14,r10
eor r15,r11
eor r24,r12
eor r25,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
com r14
com r15
com r24
com r25
mov r0,r2
and r0,r6
eor r10,r0
mov r0,r3
and r0,r7
eor r11,r0
mov r0,r4
and r0,r8
eor r12,r0
mov r0,r5
and r0,r9
eor r13,r0
movw r20,r6
movw r22,r8
lsl r20
rol r21
rol r22
rol r23
lsl r20
rol r21
rol r22
rol r23
andi r20,204
andi r21,204
andi r22,204
andi r23,204
lsr r9
ror r8
ror r7
ror r6
lsr r9
ror r8
ror r7
ror r6
ldi r19,51
and r6,r19
and r7,r19
and r8,r19
and r9,r19
or r6,r20
or r7,r21
or r8,r22
or r9,r23
movw r20,r10
movw r22,r12
lsl r20
rol r21
rol r22
rol r23
andi r20,238
andi r21,238
andi r22,238
andi r23,238
lsr r13
ror r12
ror r11
ror r10
lsr r13
ror r12
ror r11
ror r10
lsr r13
ror r12
ror r11
ror r10
ldi r17,17
and r10,r17
and r11,r17
and r12,r17
and r13,r17
or r10,r20
or r11,r21
or r12,r22
or r13,r23
movw r20,r14
movw r22,r24
lsl r20
rol r21
rol r22
rol r23
lsl r20
rol r21
rol r22
rol r23
lsl r20
rol r21
rol r22
rol r23
andi r20,136
andi r21,136
andi r22,136
andi r23,136
lsr r25
ror r24
ror r15
ror r14
ldi r16,119
and r14,r16
and r15,r16
andi r24,119
andi r25,119
or r14,r20
or r15,r21
or r24,r22
or r25,r23
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
eor r10,r20
eor r11,r21
eor r12,r22
eor r13,r23
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r22,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r22,Z
#elif defined(__AVR_TINY__)
ld r22,Z
#else
lpm
mov r22,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r23,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r23,Z
#elif defined(__AVR_TINY__)
ld r23,Z
#else
lpm
mov r23,r0
#endif
inc r30
eor r2,r20
eor r3,r21
eor r4,r22
eor r5,r23
mov r0,r14
and r0,r10
eor r6,r0
mov r0,r15
and r0,r11
eor r7,r0
mov r0,r24
and r0,r12
eor r8,r0
mov r0,r25
and r0,r13
eor r9,r0
mov r0,r6
and r0,r2
eor r14,r0
mov r0,r7
and r0,r3
eor r15,r0
mov r0,r8
and r0,r4
eor r24,r0
mov r0,r9
and r0,r5
eor r25,r0
mov r0,r14
or r0,r6
eor r10,r0
mov r0,r15
or r0,r7
eor r11,r0
mov r0,r24
or r0,r8
eor r12,r0
mov r0,r25
or r0,r9
eor r13,r0
eor r2,r10
eor r3,r11
eor r4,r12
eor r5,r13
eor r6,r2
eor r7,r3
eor r8,r4
eor r9,r5
com r2
com r3
com r4
com r5
mov r0,r14
and r0,r6
eor r10,r0
mov r0,r15
and r0,r7
eor r11,r0
mov r0,r24
and r0,r8
eor r12,r0
mov r0,r25
and r0,r9
eor r13,r0
mov r0,r1
lsr r3
ror r2
ror r0
lsr r3
ror r2
ror r0
lsr r3
ror r2
ror r0
lsr r3
ror r2
ror r0
or r3,r0
mov r0,r1
lsr r5
ror r4
ror r0
lsr r5
ror r4
ror r0
lsr r5
ror r4
ror r0
lsr r5
ror r4
ror r0
or r5,r0
mov r0,r7
mov r7,r6
mov r6,r0
mov r0,r9
mov r9,r8
mov r8,r0
lsl r10
rol r11
adc r10,r1
lsl r10
rol r11
adc r10,r1
lsl r10
rol r11
adc r10,r1
lsl r10
rol r11
adc r10,r1
lsl r12
rol r13
adc r12,r1
lsl r12
rol r13
adc r12,r1
lsl r12
rol r13
adc r12,r1
lsl r12
rol r13
adc r12,r1
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
eor r10,r20
eor r11,r21
eor r12,r22
eor r13,r23
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r22,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r22,Z
#elif defined(__AVR_TINY__)
ld r22,Z
#else
lpm
mov r22,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r23,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r23,Z
#elif defined(__AVR_TINY__)
ld r23,Z
#else
lpm
mov r23,r0
#endif
inc r30
eor r14,r20
eor r15,r21
eor r24,r22
eor r25,r23
mov r0,r2
and r0,r10
eor r6,r0
mov r0,r3
and r0,r11
eor r7,r0
mov r0,r4
and r0,r12
eor r8,r0
mov r0,r5
and r0,r13
eor r9,r0
mov r0,r6
and r0,r14
eor r2,r0
mov r0,r7
and r0,r15
eor r3,r0
mov r0,r8
and r0,r24
eor r4,r0
mov r0,r9
and r0,r25
eor r5,r0
mov r0,r2
or r0,r6
eor r10,r0
mov r0,r3
or r0,r7
eor r11,r0
mov r0,r4
or r0,r8
eor r12,r0
mov r0,r5
or r0,r9
eor r13,r0
eor r14,r10
eor r15,r11
eor r24,r12
eor r25,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
com r14
com r15
com r24
com r25
mov r0,r2
and r0,r6
eor r10,r0
mov r0,r3
and r0,r7
eor r11,r0
mov r0,r4
and r0,r8
eor r12,r0
mov r0,r5
and r0,r9
eor r13,r0
movw r20,r6
movw r22,r8
lsr r23
ror r22
ror r21
ror r20
eor r20,r6
eor r21,r7
eor r22,r8
eor r23,r9
andi r20,85
andi r21,85
andi r22,85
andi r23,85
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
lsl r20
rol r21
rol r22
rol r23
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
mov r0,r12
mov r12,r10
mov r10,r0
mov r0,r13
mov r13,r11
mov r11,r0
movw r20,r10
movw r22,r12
lsr r23
ror r22
ror r21
ror r20
eor r20,r10
eor r21,r11
andi r20,85
andi r21,85
eor r10,r20
eor r11,r21
mov r22,r1
mov r23,r1
lsl r20
rol r21
rol r22
rol r23
eor r10,r20
eor r11,r21
eor r12,r22
eor r13,r23
mov r0,r24
mov r24,r14
mov r14,r0
mov r0,r25
mov r25,r15
mov r15,r0
movw r20,r24
lsr r21
ror r20
eor r20,r24
eor r21,r25
andi r20,85
andi r21,85
eor r24,r20
eor r25,r21
lsl r20
rol r21
eor r24,r20
eor r25,r21
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
eor r10,r20
eor r11,r21
eor r12,r22
eor r13,r23
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r22,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r22,Z
#elif defined(__AVR_TINY__)
ld r22,Z
#else
lpm
mov r22,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r23,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r23,Z
#elif defined(__AVR_TINY__)
ld r23,Z
#else
lpm
mov r23,r0
#endif
inc r30
eor r2,r20
eor r3,r21
eor r4,r22
eor r5,r23
mov r0,r14
and r0,r10
eor r6,r0
mov r0,r15
and r0,r11
eor r7,r0
mov r0,r24
and r0,r12
eor r8,r0
mov r0,r25
and r0,r13
eor r9,r0
mov r0,r6
and r0,r2
eor r14,r0
mov r0,r7
and r0,r3
eor r15,r0
mov r0,r8
and r0,r4
eor r24,r0
mov r0,r9
and r0,r5
eor r25,r0
mov r0,r14
or r0,r6
eor r10,r0
mov r0,r15
or r0,r7
eor r11,r0
mov r0,r24
or r0,r8
eor r12,r0
mov r0,r25
or r0,r9
eor r13,r0
eor r2,r10
eor r3,r11
eor r4,r12
eor r5,r13
eor r6,r2
eor r7,r3
eor r8,r4
eor r9,r5
com r2
com r3
com r4
com r5
mov r0,r14
and r0,r6
eor r10,r0
mov r0,r15
and r0,r7
eor r11,r0
mov r0,r24
and r0,r8
eor r12,r0
mov r0,r25
and r0,r9
eor r13,r0
lsl r2
adc r2,r1
lsl r2
adc r2,r1
lsl r3
adc r3,r1
lsl r3
adc r3,r1
lsl r4
adc r4,r1
lsl r4
adc r4,r1
lsl r5
adc r5,r1
lsl r5
adc r5,r1
swap r6
swap r7
swap r8
swap r9
mov r0,r1
lsr r10
ror r0
lsr r10
ror r0
or r10,r0
mov r0,r1
lsr r11
ror r0
lsr r11
ror r0
or r11,r0
mov r0,r1
lsr r12
ror r0
lsr r12
ror r0
or r12,r0
mov r0,r1
lsr r13
ror r0
lsr r13
ror r0
or r13,r0
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
eor r10,r20
eor r11,r21
eor r12,r22
eor r13,r23
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r22,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r22,Z
#elif defined(__AVR_TINY__)
ld r22,Z
#else
lpm
mov r22,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r23,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r23,Z
#elif defined(__AVR_TINY__)
ld r23,Z
#else
lpm
mov r23,r0
#endif
inc r30
eor r14,r20
eor r15,r21
eor r24,r22
eor r25,r23
mov r0,r2
and r0,r10
eor r6,r0
mov r0,r3
and r0,r11
eor r7,r0
mov r0,r4
and r0,r12
eor r8,r0
mov r0,r5
and r0,r13
eor r9,r0
mov r0,r6
and r0,r14
eor r2,r0
mov r0,r7
and r0,r15
eor r3,r0
mov r0,r8
and r0,r24
eor r4,r0
mov r0,r9
and r0,r25
eor r5,r0
mov r0,r2
or r0,r6
eor r10,r0
mov r0,r3
or r0,r7
eor r11,r0
mov r0,r4
or r0,r8
eor r12,r0
mov r0,r5
or r0,r9
eor r13,r0
eor r14,r10
eor r15,r11
eor r24,r12
eor r25,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
com r14
com r15
com r24
com r25
mov r0,r2
and r0,r6
eor r10,r0
mov r0,r3
and r0,r7
eor r11,r0
mov r0,r4
and r0,r8
eor r12,r0
mov r0,r5
and r0,r9
eor r13,r0
mov r0,r8
mov r8,r6
mov r6,r0
mov r0,r9
mov r9,r7
mov r7,r0
mov r0,r10
mov r10,r11
mov r11,r12
mov r12,r13
mov r13,r0
mov r0,r25
mov r25,r24
mov r24,r15
mov r15,r14
mov r14,r0
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
eor r10,r20
eor r11,r21
eor r12,r22
eor r13,r23
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r22,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r22,Z
#elif defined(__AVR_TINY__)
ld r22,Z
#else
lpm
mov r22,r0
#endif
inc r30
#if defined(RAMPZ)
elpm r23,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r23,Z
#elif defined(__AVR_TINY__)
ld r23,Z
#else
lpm
mov r23,r0
#endif
inc r30
eor r2,r20
eor r3,r21
eor r4,r22
eor r5,r23
eor r2,r14
eor r3,r15
eor r4,r24
eor r5,r25
eor r14,r2
eor r15,r3
eor r24,r4
eor r25,r5
eor r2,r14
eor r3,r15
eor r4,r24
eor r5,r25
ret
1049:
#if defined(RAMPZ)
pop r0
out _SFR_IO_ADDR(RAMPZ),r0
#endif
ldd r26,Y+1
ldd r27,Y+2
bst r2,0
bld r20,0
bst r6,0
bld r20,1
bst r10,0
bld r20,2
bst r14,0
bld r20,3
bst r2,1
bld r20,4
bst r6,1
bld r20,5
bst r10,1
bld r20,6
bst r14,1
bld r20,7
bst r2,2
bld r21,0
bst r6,2
bld r21,1
bst r10,2
bld r21,2
bst r14,2
bld r21,3
bst r2,3
bld r21,4
bst r6,3
bld r21,5
bst r10,3
bld r21,6
bst r14,3
bld r21,7
bst r2,4
bld r22,0
bst r6,4
bld r22,1
bst r10,4
bld r22,2
bst r14,4
bld r22,3
bst r2,5
bld r22,4
bst r6,5
bld r22,5
bst r10,5
bld r22,6
bst r14,5
bld r22,7
bst r2,6
bld r23,0
bst r6,6
bld r23,1
bst r10,6
bld r23,2
bst r14,6
bld r23,3
bst r2,7
bld r23,4
bst r6,7
bld r23,5
bst r10,7
bld r23,6
bst r14,7
bld r23,7
st X+,r20
st X+,r21
st X+,r22
st X+,r23
bst r3,0
bld r20,0
bst r7,0
bld r20,1
bst r11,0
bld r20,2
bst r15,0
bld r20,3
bst r3,1
bld r20,4
bst r7,1
bld r20,5
bst r11,1
bld r20,6
bst r15,1
bld r20,7
bst r3,2
bld r21,0
bst r7,2
bld r21,1
bst r11,2
bld r21,2
bst r15,2
bld r21,3
bst r3,3
bld r21,4
bst r7,3
bld r21,5
bst r11,3
bld r21,6
bst r15,3
bld r21,7
bst r3,4
bld r22,0
bst r7,4
bld r22,1
bst r11,4
bld r22,2
bst r15,4
bld r22,3
bst r3,5
bld r22,4
bst r7,5
bld r22,5
bst r11,5
bld r22,6
bst r15,5
bld r22,7
bst r3,6
bld r23,0
bst r7,6
bld r23,1
bst r11,6
bld r23,2
bst r15,6
bld r23,3
bst r3,7
bld r23,4
bst r7,7
bld r23,5
bst r11,7
bld r23,6
bst r15,7
bld r23,7
st X+,r20
st X+,r21
st X+,r22
st X+,r23
bst r4,0
bld r20,0
bst r8,0
bld r20,1
bst r12,0
bld r20,2
bst r24,0
bld r20,3
bst r4,1
bld r20,4
bst r8,1
bld r20,5
bst r12,1
bld r20,6
bst r24,1
bld r20,7
bst r4,2
bld r21,0
bst r8,2
bld r21,1
bst r12,2
bld r21,2
bst r24,2
bld r21,3
bst r4,3
bld r21,4
bst r8,3
bld r21,5
bst r12,3
bld r21,6
bst r24,3
bld r21,7
bst r4,4
bld r22,0
bst r8,4
bld r22,1
bst r12,4
bld r22,2
bst r24,4
bld r22,3
bst r4,5
bld r22,4
bst r8,5
bld r22,5
bst r12,5
bld r22,6
bst r24,5
bld r22,7
bst r4,6
bld r23,0
bst r8,6
bld r23,1
bst r12,6
bld r23,2
bst r24,6
bld r23,3
bst r4,7
bld r23,4
bst r8,7
bld r23,5
bst r12,7
bld r23,6
bst r24,7
bld r23,7
st X+,r20
st X+,r21
st X+,r22
st X+,r23
bst r5,0
bld r20,0
bst r9,0
bld r20,1
bst r13,0
bld r20,2
bst r25,0
bld r20,3
bst r5,1
bld r20,4
bst r9,1
bld r20,5
bst r13,1
bld r20,6
bst r25,1
bld r20,7
bst r5,2
bld r21,0
bst r9,2
bld r21,1
bst r13,2
bld r21,2
bst r25,2
bld r21,3
bst r5,3
bld r21,4
bst r9,3
bld r21,5
bst r13,3
bld r21,6
bst r25,3
bld r21,7
bst r5,4
bld r22,0
bst r9,4
bld r22,1
bst r13,4
bld r22,2
bst r25,4
bld r22,3
bst r5,5
bld r22,4
bst r9,5
bld r22,5
bst r13,5
bld r22,6
bst r25,5
bld r22,7
bst r5,6
bld r23,0
bst r9,6
bld r23,1
bst r13,6
bld r23,2
bst r25,6
bld r23,3
bst r5,7
bld r23,4
bst r9,7
bld r23,5
bst r13,7
bld r23,6
bst r25,7
bld r23,7
st X+,r20
st X+,r21
st X+,r22
st X+,r23
pop r0
pop r0
pop r17
pop r16
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
pop r3
pop r2
pop r29
pop r28
ret
.size gift128t_encrypt, .-gift128t_encrypt
.text
.global gift128t_decrypt
.type gift128t_decrypt, @function
gift128t_decrypt:
push r28
push r29
push r2
push r3
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push r16
push r17
push r23
push r22
movw r30,r24
movw r26,r20
in r28,0x3d
in r29,0x3e
.L__stack_usage = 20
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
bst r20,0
bld r2,0
bst r20,1
bld r6,0
bst r20,2
bld r10,0
bst r20,3
bld r14,0
bst r20,4
bld r2,1
bst r20,5
bld r6,1
bst r20,6
bld r10,1
bst r20,7
bld r14,1
bst r21,0
bld r2,2
bst r21,1
bld r6,2
bst r21,2
bld r10,2
bst r21,3
bld r14,2
bst r21,4
bld r2,3
bst r21,5
bld r6,3
bst r21,6
bld r10,3
bst r21,7
bld r14,3
bst r22,0
bld r2,4
bst r22,1
bld r6,4
bst r22,2
bld r10,4
bst r22,3
bld r14,4
bst r22,4
bld r2,5
bst r22,5
bld r6,5
bst r22,6
bld r10,5
bst r22,7
bld r14,5
bst r23,0
bld r2,6
bst r23,1
bld r6,6
bst r23,2
bld r10,6
bst r23,3
bld r14,6
bst r23,4
bld r2,7
bst r23,5
bld r6,7
bst r23,6
bld r10,7
bst r23,7
bld r14,7
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
bst r20,0
bld r3,0
bst r20,1
bld r7,0
bst r20,2
bld r11,0
bst r20,3
bld r15,0
bst r20,4
bld r3,1
bst r20,5
bld r7,1
bst r20,6
bld r11,1
bst r20,7
bld r15,1
bst r21,0
bld r3,2
bst r21,1
bld r7,2
bst r21,2
bld r11,2
bst r21,3
bld r15,2
bst r21,4
bld r3,3
bst r21,5
bld r7,3
bst r21,6
bld r11,3
bst r21,7
bld r15,3
bst r22,0
bld r3,4
bst r22,1
bld r7,4
bst r22,2
bld r11,4
bst r22,3
bld r15,4
bst r22,4
bld r3,5
bst r22,5
bld r7,5
bst r22,6
bld r11,5
bst r22,7
bld r15,5
bst r23,0
bld r3,6
bst r23,1
bld r7,6
bst r23,2
bld r11,6
bst r23,3
bld r15,6
bst r23,4
bld r3,7
bst r23,5
bld r7,7
bst r23,6
bld r11,7
bst r23,7
bld r15,7
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
bst r20,0
bld r4,0
bst r20,1
bld r8,0
bst r20,2
bld r12,0
bst r20,3
bld r24,0
bst r20,4
bld r4,1
bst r20,5
bld r8,1
bst r20,6
bld r12,1
bst r20,7
bld r24,1
bst r21,0
bld r4,2
bst r21,1
bld r8,2
bst r21,2
bld r12,2
bst r21,3
bld r24,2
bst r21,4
bld r4,3
bst r21,5
bld r8,3
bst r21,6
bld r12,3
bst r21,7
bld r24,3
bst r22,0
bld r4,4
bst r22,1
bld r8,4
bst r22,2
bld r12,4
bst r22,3
bld r24,4
bst r22,4
bld r4,5
bst r22,5
bld r8,5
bst r22,6
bld r12,5
bst r22,7
bld r24,5
bst r23,0
bld r4,6
bst r23,1
bld r8,6
bst r23,2
bld r12,6
bst r23,3
bld r24,6
bst r23,4
bld r4,7
bst r23,5
bld r8,7
bst r23,6
bld r12,7
bst r23,7
bld r24,7
ld r20,X+
ld r21,X+
ld r22,X+
ld r23,X+
bst r20,0
bld r5,0
bst r20,1
bld r9,0
bst r20,2
bld r13,0
bst r20,3
bld r25,0
bst r20,4
bld r5,1
bst r20,5
bld r9,1
bst r20,6
bld r13,1
bst r20,7
bld r25,1
bst r21,0
bld r5,2
bst r21,1
bld r9,2
bst r21,2
bld r13,2
bst r21,3
bld r25,2
bst r21,4
bld r5,3
bst r21,5
bld r9,3
bst r21,6
bld r13,3
bst r21,7
bld r25,3
bst r22,0
bld r5,4
bst r22,1
bld r9,4
bst r22,2
bld r13,4
bst r22,3
bld r25,4
bst r22,4
bld r5,5
bst r22,5
bld r9,5
bst r22,6
bld r13,5
bst r22,7
bld r25,5
bst r23,0
bld r5,6
bst r23,1
bld r9,6
bst r23,2
bld r13,6
bst r23,3
bld r25,6
bst r23,4
bld r5,7
bst r23,5
bld r9,7
bst r23,6
bld r13,7
bst r23,7
bld r25,7
movw r26,r30
subi r26,192
sbci r27,254
ldi r30,lo8(table_0)
ldi r31,hi8(table_0)
#if defined(RAMPZ)
ldi r19,hh8(table_0)
in r0,_SFR_IO_ADDR(RAMPZ)
push r0
out _SFR_IO_ADDR(RAMPZ),r19
#endif
ldi r30,160
rcall 314f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 314f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 314f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 314f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 314f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 314f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 314f
eor r2,r18
eor r3,r18
eor r4,r18
eor r5,r18
rcall 314f
rjmp 1052f
314:
eor r2,r14
eor r3,r15
eor r4,r24
eor r5,r25
eor r14,r2
eor r15,r3
eor r24,r4
eor r25,r5
eor r2,r14
eor r3,r15
eor r4,r24
eor r5,r25
dec r30
#if defined(RAMPZ)
elpm r23,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r23,Z
#elif defined(__AVR_TINY__)
ld r23,Z
#else
lpm
mov r23,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r22,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r22,Z
#elif defined(__AVR_TINY__)
ld r22,Z
#else
lpm
mov r22,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
eor r2,r20
eor r3,r21
eor r4,r22
eor r5,r23
ld r23,-X
ld r22,-X
ld r21,-X
ld r20,-X
eor r10,r20
eor r11,r21
eor r12,r22
eor r13,r23
ld r23,-X
ld r22,-X
ld r21,-X
ld r20,-X
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
mov r0,r8
mov r8,r6
mov r6,r0
mov r0,r9
mov r9,r7
mov r7,r0
mov r0,r13
mov r13,r12
mov r12,r11
mov r11,r10
mov r10,r0
mov r0,r14
mov r14,r15
mov r15,r24
mov r24,r25
mov r25,r0
mov r0,r2
and r0,r6
eor r10,r0
mov r0,r3
and r0,r7
eor r11,r0
mov r0,r4
and r0,r8
eor r12,r0
mov r0,r5
and r0,r9
eor r13,r0
com r14
com r15
com r24
com r25
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r14,r10
eor r15,r11
eor r24,r12
eor r25,r13
mov r0,r2
or r0,r6
eor r10,r0
mov r0,r3
or r0,r7
eor r11,r0
mov r0,r4
or r0,r8
eor r12,r0
mov r0,r5
or r0,r9
eor r13,r0
mov r0,r6
and r0,r14
eor r2,r0
mov r0,r7
and r0,r15
eor r3,r0
mov r0,r8
and r0,r24
eor r4,r0
mov r0,r9
and r0,r25
eor r5,r0
mov r0,r2
and r0,r10
eor r6,r0
mov r0,r3
and r0,r11
eor r7,r0
mov r0,r4
and r0,r12
eor r8,r0
mov r0,r5
and r0,r13
eor r9,r0
dec r30
#if defined(RAMPZ)
elpm r23,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r23,Z
#elif defined(__AVR_TINY__)
ld r23,Z
#else
lpm
mov r23,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r22,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r22,Z
#elif defined(__AVR_TINY__)
ld r22,Z
#else
lpm
mov r22,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
eor r14,r20
eor r15,r21
eor r24,r22
eor r25,r23
ld r23,-X
ld r22,-X
ld r21,-X
ld r20,-X
eor r10,r20
eor r11,r21
eor r12,r22
eor r13,r23
ld r23,-X
ld r22,-X
ld r21,-X
ld r20,-X
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
mov r0,r1
lsr r2
ror r0
lsr r2
ror r0
or r2,r0
mov r0,r1
lsr r3
ror r0
lsr r3
ror r0
or r3,r0
mov r0,r1
lsr r4
ror r0
lsr r4
ror r0
or r4,r0
mov r0,r1
lsr r5
ror r0
lsr r5
ror r0
or r5,r0
swap r6
swap r7
swap r8
swap r9
lsl r10
adc r10,r1
lsl r10
adc r10,r1
lsl r11
adc r11,r1
lsl r11
adc r11,r1
lsl r12
adc r12,r1
lsl r12
adc r12,r1
lsl r13
adc r13,r1
lsl r13
adc r13,r1
mov r0,r14
and r0,r6
eor r10,r0
mov r0,r15
and r0,r7
eor r11,r0
mov r0,r24
and r0,r8
eor r12,r0
mov r0,r25
and r0,r9
eor r13,r0
com r2
com r3
com r4
com r5
eor r6,r2
eor r7,r3
eor r8,r4
eor r9,r5
eor r2,r10
eor r3,r11
eor r4,r12
eor r5,r13
mov r0,r14
or r0,r6
eor r10,r0
mov r0,r15
or r0,r7
eor r11,r0
mov r0,r24
or r0,r8
eor r12,r0
mov r0,r25
or r0,r9
eor r13,r0
mov r0,r6
and r0,r2
eor r14,r0
mov r0,r7
and r0,r3
eor r15,r0
mov r0,r8
and r0,r4
eor r24,r0
mov r0,r9
and r0,r5
eor r25,r0
mov r0,r14
and r0,r10
eor r6,r0
mov r0,r15
and r0,r11
eor r7,r0
mov r0,r24
and r0,r12
eor r8,r0
mov r0,r25
and r0,r13
eor r9,r0
dec r30
#if defined(RAMPZ)
elpm r23,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r23,Z
#elif defined(__AVR_TINY__)
ld r23,Z
#else
lpm
mov r23,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r22,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r22,Z
#elif defined(__AVR_TINY__)
ld r22,Z
#else
lpm
mov r22,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
eor r2,r20
eor r3,r21
eor r4,r22
eor r5,r23
ld r23,-X
ld r22,-X
ld r21,-X
ld r20,-X
eor r10,r20
eor r11,r21
eor r12,r22
eor r13,r23
ld r23,-X
ld r22,-X
ld r21,-X
ld r20,-X
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
movw r20,r6
movw r22,r8
lsr r23
ror r22
ror r21
ror r20
eor r20,r6
eor r21,r7
eor r22,r8
eor r23,r9
andi r20,85
andi r21,85
andi r22,85
andi r23,85
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
lsl r20
rol r21
rol r22
rol r23
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
movw r20,r10
movw r22,r12
lsr r23
ror r22
ror r21
ror r20
eor r20,r10
eor r21,r11
andi r20,85
andi r21,85
eor r10,r20
eor r11,r21
mov r22,r1
mov r23,r1
lsl r20
rol r21
rol r22
rol r23
eor r10,r20
eor r11,r21
eor r12,r22
eor r13,r23
mov r0,r12
mov r12,r10
mov r10,r0
mov r0,r13
mov r13,r11
mov r11,r0
movw r20,r24
lsr r21
ror r20
eor r20,r24
eor r21,r25
andi r20,85
andi r21,85
eor r24,r20
eor r25,r21
lsl r20
rol r21
eor r24,r20
eor r25,r21
mov r0,r24
mov r24,r14
mov r14,r0
mov r0,r25
mov r25,r15
mov r15,r0
mov r0,r2
and r0,r6
eor r10,r0
mov r0,r3
and r0,r7
eor r11,r0
mov r0,r4
and r0,r8
eor r12,r0
mov r0,r5
and r0,r9
eor r13,r0
com r14
com r15
com r24
com r25
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r14,r10
eor r15,r11
eor r24,r12
eor r25,r13
mov r0,r2
or r0,r6
eor r10,r0
mov r0,r3
or r0,r7
eor r11,r0
mov r0,r4
or r0,r8
eor r12,r0
mov r0,r5
or r0,r9
eor r13,r0
mov r0,r6
and r0,r14
eor r2,r0
mov r0,r7
and r0,r15
eor r3,r0
mov r0,r8
and r0,r24
eor r4,r0
mov r0,r9
and r0,r25
eor r5,r0
mov r0,r2
and r0,r10
eor r6,r0
mov r0,r3
and r0,r11
eor r7,r0
mov r0,r4
and r0,r12
eor r8,r0
mov r0,r5
and r0,r13
eor r9,r0
dec r30
#if defined(RAMPZ)
elpm r23,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r23,Z
#elif defined(__AVR_TINY__)
ld r23,Z
#else
lpm
mov r23,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r22,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r22,Z
#elif defined(__AVR_TINY__)
ld r22,Z
#else
lpm
mov r22,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
eor r14,r20
eor r15,r21
eor r24,r22
eor r25,r23
ld r23,-X
ld r22,-X
ld r21,-X
ld r20,-X
eor r10,r20
eor r11,r21
eor r12,r22
eor r13,r23
ld r23,-X
ld r22,-X
ld r21,-X
ld r20,-X
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
lsl r2
rol r3
adc r2,r1
lsl r2
rol r3
adc r2,r1
lsl r2
rol r3
adc r2,r1
lsl r2
rol r3
adc r2,r1
lsl r4
rol r5
adc r4,r1
lsl r4
rol r5
adc r4,r1
lsl r4
rol r5
adc r4,r1
lsl r4
rol r5
adc r4,r1
mov r0,r7
mov r7,r6
mov r6,r0
mov r0,r9
mov r9,r8
mov r8,r0
mov r0,r1
lsr r11
ror r10
ror r0
lsr r11
ror r10
ror r0
lsr r11
ror r10
ror r0
lsr r11
ror r10
ror r0
or r11,r0
mov r0,r1
lsr r13
ror r12
ror r0
lsr r13
ror r12
ror r0
lsr r13
ror r12
ror r0
lsr r13
ror r12
ror r0
or r13,r0
mov r0,r14
and r0,r6
eor r10,r0
mov r0,r15
and r0,r7
eor r11,r0
mov r0,r24
and r0,r8
eor r12,r0
mov r0,r25
and r0,r9
eor r13,r0
com r2
com r3
com r4
com r5
eor r6,r2
eor r7,r3
eor r8,r4
eor r9,r5
eor r2,r10
eor r3,r11
eor r4,r12
eor r5,r13
mov r0,r14
or r0,r6
eor r10,r0
mov r0,r15
or r0,r7
eor r11,r0
mov r0,r24
or r0,r8
eor r12,r0
mov r0,r25
or r0,r9
eor r13,r0
mov r0,r6
and r0,r2
eor r14,r0
mov r0,r7
and r0,r3
eor r15,r0
mov r0,r8
and r0,r4
eor r24,r0
mov r0,r9
and r0,r5
eor r25,r0
mov r0,r14
and r0,r10
eor r6,r0
mov r0,r15
and r0,r11
eor r7,r0
mov r0,r24
and r0,r12
eor r8,r0
mov r0,r25
and r0,r13
eor r9,r0
dec r30
#if defined(RAMPZ)
elpm r23,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r23,Z
#elif defined(__AVR_TINY__)
ld r23,Z
#else
lpm
mov r23,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r22,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r22,Z
#elif defined(__AVR_TINY__)
ld r22,Z
#else
lpm
mov r22,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r21,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r21,Z
#elif defined(__AVR_TINY__)
ld r21,Z
#else
lpm
mov r21,r0
#endif
dec r30
#if defined(RAMPZ)
elpm r20,Z
#elif defined(__AVR_HAVE_LPMX__)
lpm r20,Z
#elif defined(__AVR_TINY__)
ld r20,Z
#else
lpm
mov r20,r0
#endif
eor r2,r20
eor r3,r21
eor r4,r22
eor r5,r23
ld r23,-X
ld r22,-X
ld r21,-X
ld r20,-X
eor r10,r20
eor r11,r21
eor r12,r22
eor r13,r23
ld r23,-X
ld r22,-X
ld r21,-X
ld r20,-X
eor r6,r20
eor r7,r21
eor r8,r22
eor r9,r23
movw r20,r6
movw r22,r8
lsl r20
rol r21
rol r22
rol r23
lsl r20
rol r21
rol r22
rol r23
andi r20,204
andi r21,204
andi r22,204
andi r23,204
lsr r9
ror r8
ror r7
ror r6
lsr r9
ror r8
ror r7
ror r6
ldi r19,51
and r6,r19
and r7,r19
and r8,r19
and r9,r19
or r6,r20
or r7,r21
or r8,r22
or r9,r23
movw r20,r10
movw r22,r12
lsl r20
rol r21
rol r22
rol r23
lsl r20
rol r21
rol r22
rol r23
lsl r20
rol r21
rol r22
rol r23
andi r20,136
andi r21,136
andi r22,136
andi r23,136
lsr r13
ror r12
ror r11
ror r10
ldi r17,119
and r10,r17
and r11,r17
and r12,r17
and r13,r17
or r10,r20
or r11,r21
or r12,r22
or r13,r23
movw r20,r14
movw r22,r24
lsl r20
rol r21
rol r22
rol r23
andi r20,238
andi r21,238
andi r22,238
andi r23,238
lsr r25
ror r24
ror r15
ror r14
lsr r25
ror r24
ror r15
ror r14
lsr r25
ror r24
ror r15
ror r14
ldi r16,17
and r14,r16
and r15,r16
andi r24,17
andi r25,17
or r14,r20
or r15,r21
or r24,r22
or r25,r23
mov r0,r2
and r0,r6
eor r10,r0
mov r0,r3
and r0,r7
eor r11,r0
mov r0,r4
and r0,r8
eor r12,r0
mov r0,r5
and r0,r9
eor r13,r0
com r14
com r15
com r24
com r25
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r14,r10
eor r15,r11
eor r24,r12
eor r25,r13
mov r0,r2
or r0,r6
eor r10,r0
mov r0,r3
or r0,r7
eor r11,r0
mov r0,r4
or r0,r8
eor r12,r0
mov r0,r5
or r0,r9
eor r13,r0
mov r0,r6
and r0,r14
eor r2,r0
mov r0,r7
and r0,r15
eor r3,r0
mov r0,r8
and r0,r24
eor r4,r0
mov r0,r9
and r0,r25
eor r5,r0
mov r0,r2
and r0,r10
eor r6,r0
mov r0,r3
and r0,r11
eor r7,r0
mov r0,r4
and r0,r12
eor r8,r0
mov r0,r5
and r0,r13
eor r9,r0
ret
1052:
#if defined(RAMPZ)
pop r0
out _SFR_IO_ADDR(RAMPZ),r0
#endif
ldd r26,Y+1
ldd r27,Y+2
bst r2,0
bld r20,0
bst r6,0
bld r20,1
bst r10,0
bld r20,2
bst r14,0
bld r20,3
bst r2,1
bld r20,4
bst r6,1
bld r20,5
bst r10,1
bld r20,6
bst r14,1
bld r20,7
bst r2,2
bld r21,0
bst r6,2
bld r21,1
bst r10,2
bld r21,2
bst r14,2
bld r21,3
bst r2,3
bld r21,4
bst r6,3
bld r21,5
bst r10,3
bld r21,6
bst r14,3
bld r21,7
bst r2,4
bld r22,0
bst r6,4
bld r22,1
bst r10,4
bld r22,2
bst r14,4
bld r22,3
bst r2,5
bld r22,4
bst r6,5
bld r22,5
bst r10,5
bld r22,6
bst r14,5
bld r22,7
bst r2,6
bld r23,0
bst r6,6
bld r23,1
bst r10,6
bld r23,2
bst r14,6
bld r23,3
bst r2,7
bld r23,4
bst r6,7
bld r23,5
bst r10,7
bld r23,6
bst r14,7
bld r23,7
st X+,r20
st X+,r21
st X+,r22
st X+,r23
bst r3,0
bld r20,0
bst r7,0
bld r20,1
bst r11,0
bld r20,2
bst r15,0
bld r20,3
bst r3,1
bld r20,4
bst r7,1
bld r20,5
bst r11,1
bld r20,6
bst r15,1
bld r20,7
bst r3,2
bld r21,0
bst r7,2
bld r21,1
bst r11,2
bld r21,2
bst r15,2
bld r21,3
bst r3,3
bld r21,4
bst r7,3
bld r21,5
bst r11,3
bld r21,6
bst r15,3
bld r21,7
bst r3,4
bld r22,0
bst r7,4
bld r22,1
bst r11,4
bld r22,2
bst r15,4
bld r22,3
bst r3,5
bld r22,4
bst r7,5
bld r22,5
bst r11,5
bld r22,6
bst r15,5
bld r22,7
bst r3,6
bld r23,0
bst r7,6
bld r23,1
bst r11,6
bld r23,2
bst r15,6
bld r23,3
bst r3,7
bld r23,4
bst r7,7
bld r23,5
bst r11,7
bld r23,6
bst r15,7
bld r23,7
st X+,r20
st X+,r21
st X+,r22
st X+,r23
bst r4,0
bld r20,0
bst r8,0
bld r20,1
bst r12,0
bld r20,2
bst r24,0
bld r20,3
bst r4,1
bld r20,4
bst r8,1
bld r20,5
bst r12,1
bld r20,6
bst r24,1
bld r20,7
bst r4,2
bld r21,0
bst r8,2
bld r21,1
bst r12,2
bld r21,2
bst r24,2
bld r21,3
bst r4,3
bld r21,4
bst r8,3
bld r21,5
bst r12,3
bld r21,6
bst r24,3
bld r21,7
bst r4,4
bld r22,0
bst r8,4
bld r22,1
bst r12,4
bld r22,2
bst r24,4
bld r22,3
bst r4,5
bld r22,4
bst r8,5
bld r22,5
bst r12,5
bld r22,6
bst r24,5
bld r22,7
bst r4,6
bld r23,0
bst r8,6
bld r23,1
bst r12,6
bld r23,2
bst r24,6
bld r23,3
bst r4,7
bld r23,4
bst r8,7
bld r23,5
bst r12,7
bld r23,6
bst r24,7
bld r23,7
st X+,r20
st X+,r21
st X+,r22
st X+,r23
bst r5,0
bld r20,0
bst r9,0
bld r20,1
bst r13,0
bld r20,2
bst r25,0
bld r20,3
bst r5,1
bld r20,4
bst r9,1
bld r20,5
bst r13,1
bld r20,6
bst r25,1
bld r20,7
bst r5,2
bld r21,0
bst r9,2
bld r21,1
bst r13,2
bld r21,2
bst r25,2
bld r21,3
bst r5,3
bld r21,4
bst r9,3
bld r21,5
bst r13,3
bld r21,6
bst r25,3
bld r21,7
bst r5,4
bld r22,0
bst r9,4
bld r22,1
bst r13,4
bld r22,2
bst r25,4
bld r22,3
bst r5,5
bld r22,4
bst r9,5
bld r22,5
bst r13,5
bld r22,6
bst r25,5
bld r22,7
bst r5,6
bld r23,0
bst r9,6
bld r23,1
bst r13,6
bld r23,2
bst r25,6
bld r23,3
bst r5,7
bld r23,4
bst r9,7
bld r23,5
bst r13,7
bld r23,6
bst r25,7
bld r23,7
st X+,r20
st X+,r21
st X+,r22
st X+,r23
pop r0
pop r0
pop r17
pop r16
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
pop r3
pop r2
pop r29
pop r28
ret
.size gift128t_decrypt, .-gift128t_decrypt
#endif
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef LW_INTERNAL_UTIL_H
#define LW_INTERNAL_UTIL_H
#include <stdint.h>
/* Figure out how to inline functions using this C compiler */
#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
#define STATIC_INLINE static inline
#elif defined(__GNUC__) || defined(__clang__)
#define STATIC_INLINE static __inline__
#else
#define STATIC_INLINE static
#endif
/* Try to figure out whether the CPU is little-endian or big-endian.
* May need to modify this to include new compiler-specific defines.
* Alternatively, define __LITTLE_ENDIAN__ or __BIG_ENDIAN__ in your
* compiler flags when you compile this library */
#if defined(__x86_64) || defined(__x86_64__) || \
defined(__i386) || defined(__i386__) || \
defined(__AVR__) || defined(__arm) || defined(__arm__) || \
defined(_M_AMD64) || defined(_M_X64) || defined(_M_IX86) || \
defined(_M_IA64) || defined(_M_ARM) || defined(_M_ARM_FP) || \
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == 1234) || \
defined(__LITTLE_ENDIAN__)
#define LW_UTIL_LITTLE_ENDIAN 1
#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == 4321) || \
defined(__BIG_ENDIAN__)
/* Big endian */
#else
#error "Cannot determine the endianess of this platform"
#endif
/* Helper macros to load and store values while converting endian-ness */
/* Load a big-endian 32-bit word from a byte buffer */
#define be_load_word32(ptr) \
((((uint32_t)((ptr)[0])) << 24) | \
(((uint32_t)((ptr)[1])) << 16) | \
(((uint32_t)((ptr)[2])) << 8) | \
((uint32_t)((ptr)[3])))
/* Store a big-endian 32-bit word into a byte buffer */
#define be_store_word32(ptr, x) \
do { \
uint32_t _x = (x); \
(ptr)[0] = (uint8_t)(_x >> 24); \
(ptr)[1] = (uint8_t)(_x >> 16); \
(ptr)[2] = (uint8_t)(_x >> 8); \
(ptr)[3] = (uint8_t)_x; \
} while (0)
/* Load a little-endian 32-bit word from a byte buffer */
#define le_load_word32(ptr) \
((((uint32_t)((ptr)[3])) << 24) | \
(((uint32_t)((ptr)[2])) << 16) | \
(((uint32_t)((ptr)[1])) << 8) | \
((uint32_t)((ptr)[0])))
/* Store a little-endian 32-bit word into a byte buffer */
#define le_store_word32(ptr, x) \
do { \
uint32_t _x = (x); \
(ptr)[0] = (uint8_t)_x; \
(ptr)[1] = (uint8_t)(_x >> 8); \
(ptr)[2] = (uint8_t)(_x >> 16); \
(ptr)[3] = (uint8_t)(_x >> 24); \
} while (0)
/* Load a big-endian 64-bit word from a byte buffer */
#define be_load_word64(ptr) \
((((uint64_t)((ptr)[0])) << 56) | \
(((uint64_t)((ptr)[1])) << 48) | \
(((uint64_t)((ptr)[2])) << 40) | \
(((uint64_t)((ptr)[3])) << 32) | \
(((uint64_t)((ptr)[4])) << 24) | \
(((uint64_t)((ptr)[5])) << 16) | \
(((uint64_t)((ptr)[6])) << 8) | \
((uint64_t)((ptr)[7])))
/* Store a big-endian 64-bit word into a byte buffer */
#define be_store_word64(ptr, x) \
do { \
uint64_t _x = (x); \
(ptr)[0] = (uint8_t)(_x >> 56); \
(ptr)[1] = (uint8_t)(_x >> 48); \
(ptr)[2] = (uint8_t)(_x >> 40); \
(ptr)[3] = (uint8_t)(_x >> 32); \
(ptr)[4] = (uint8_t)(_x >> 24); \
(ptr)[5] = (uint8_t)(_x >> 16); \
(ptr)[6] = (uint8_t)(_x >> 8); \
(ptr)[7] = (uint8_t)_x; \
} while (0)
/* Load a little-endian 64-bit word from a byte buffer */
#define le_load_word64(ptr) \
((((uint64_t)((ptr)[7])) << 56) | \
(((uint64_t)((ptr)[6])) << 48) | \
(((uint64_t)((ptr)[5])) << 40) | \
(((uint64_t)((ptr)[4])) << 32) | \
(((uint64_t)((ptr)[3])) << 24) | \
(((uint64_t)((ptr)[2])) << 16) | \
(((uint64_t)((ptr)[1])) << 8) | \
((uint64_t)((ptr)[0])))
/* Store a little-endian 64-bit word into a byte buffer */
#define le_store_word64(ptr, x) \
do { \
uint64_t _x = (x); \
(ptr)[0] = (uint8_t)_x; \
(ptr)[1] = (uint8_t)(_x >> 8); \
(ptr)[2] = (uint8_t)(_x >> 16); \
(ptr)[3] = (uint8_t)(_x >> 24); \
(ptr)[4] = (uint8_t)(_x >> 32); \
(ptr)[5] = (uint8_t)(_x >> 40); \
(ptr)[6] = (uint8_t)(_x >> 48); \
(ptr)[7] = (uint8_t)(_x >> 56); \
} while (0)
/* Load a big-endian 16-bit word from a byte buffer */
#define be_load_word16(ptr) \
((((uint16_t)((ptr)[0])) << 8) | \
((uint16_t)((ptr)[1])))
/* Store a big-endian 16-bit word into a byte buffer */
#define be_store_word16(ptr, x) \
do { \
uint16_t _x = (x); \
(ptr)[0] = (uint8_t)(_x >> 8); \
(ptr)[1] = (uint8_t)_x; \
} while (0)
/* Load a little-endian 16-bit word from a byte buffer */
#define le_load_word16(ptr) \
((((uint16_t)((ptr)[1])) << 8) | \
((uint16_t)((ptr)[0])))
/* Store a little-endian 16-bit word into a byte buffer */
#define le_store_word16(ptr, x) \
do { \
uint16_t _x = (x); \
(ptr)[0] = (uint8_t)_x; \
(ptr)[1] = (uint8_t)(_x >> 8); \
} while (0)
/* XOR a source byte buffer against a destination */
#define lw_xor_block(dest, src, len) \
do { \
unsigned char *_dest = (dest); \
const unsigned char *_src = (src); \
unsigned _len = (len); \
while (_len > 0) { \
*_dest++ ^= *_src++; \
--_len; \
} \
} while (0)
/* XOR two source byte buffers and put the result in a destination buffer */
#define lw_xor_block_2_src(dest, src1, src2, len) \
do { \
unsigned char *_dest = (dest); \
const unsigned char *_src1 = (src1); \
const unsigned char *_src2 = (src2); \
unsigned _len = (len); \
while (_len > 0) { \
*_dest++ = *_src1++ ^ *_src2++; \
--_len; \
} \
} while (0)
/* XOR a source byte buffer against a destination and write to another
* destination at the same time */
#define lw_xor_block_2_dest(dest2, dest, src, len) \
do { \
unsigned char *_dest2 = (dest2); \
unsigned char *_dest = (dest); \
const unsigned char *_src = (src); \
unsigned _len = (len); \
while (_len > 0) { \
*_dest2++ = (*_dest++ ^= *_src++); \
--_len; \
} \
} while (0)
/* XOR two byte buffers and write to a destination which at the same
* time copying the contents of src2 to dest2 */
#define lw_xor_block_copy_src(dest2, dest, src1, src2, len) \
do { \
unsigned char *_dest2 = (dest2); \
unsigned char *_dest = (dest); \
const unsigned char *_src1 = (src1); \
const unsigned char *_src2 = (src2); \
unsigned _len = (len); \
while (_len > 0) { \
unsigned char _temp = *_src2++; \
*_dest2++ = _temp; \
*_dest++ = *_src1++ ^ _temp; \
--_len; \
} \
} while (0)
/* XOR a source byte buffer against a destination and write to another
* destination at the same time. This version swaps the source value
* into the "dest" buffer */
#define lw_xor_block_swap(dest2, dest, src, len) \
do { \
unsigned char *_dest2 = (dest2); \
unsigned char *_dest = (dest); \
const unsigned char *_src = (src); \
unsigned _len = (len); \
while (_len > 0) { \
unsigned char _temp = *_src++; \
*_dest2++ = *_dest ^ _temp; \
*_dest++ = _temp; \
--_len; \
} \
} while (0)
/* Rotation functions need to be optimised for best performance on AVR.
* The most efficient rotations are where the number of bits is 1 or a
* multiple of 8, so we compose the efficient rotations to produce all
* other rotation counts of interest. */
#if defined(__AVR__)
#define LW_CRYPTO_ROTATE32_COMPOSED 1
#else
#define LW_CRYPTO_ROTATE32_COMPOSED 0
#endif
/* Rotation macros for 32-bit arguments */
/* Generic left rotate */
#define leftRotate(a, bits) \
(__extension__ ({ \
uint32_t _temp = (a); \
(_temp << (bits)) | (_temp >> (32 - (bits))); \
}))
/* Generic right rotate */
#define rightRotate(a, bits) \
(__extension__ ({ \
uint32_t _temp = (a); \
(_temp >> (bits)) | (_temp << (32 - (bits))); \
}))
#if !LW_CRYPTO_ROTATE32_COMPOSED
/* Left rotate by a specific number of bits. These macros may be replaced
* with more efficient ones on platforms that lack a barrel shifter */
#define leftRotate1(a) (leftRotate((a), 1))
#define leftRotate2(a) (leftRotate((a), 2))
#define leftRotate3(a) (leftRotate((a), 3))
#define leftRotate4(a) (leftRotate((a), 4))
#define leftRotate5(a) (leftRotate((a), 5))
#define leftRotate6(a) (leftRotate((a), 6))
#define leftRotate7(a) (leftRotate((a), 7))
#define leftRotate8(a) (leftRotate((a), 8))
#define leftRotate9(a) (leftRotate((a), 9))
#define leftRotate10(a) (leftRotate((a), 10))
#define leftRotate11(a) (leftRotate((a), 11))
#define leftRotate12(a) (leftRotate((a), 12))
#define leftRotate13(a) (leftRotate((a), 13))
#define leftRotate14(a) (leftRotate((a), 14))
#define leftRotate15(a) (leftRotate((a), 15))
#define leftRotate16(a) (leftRotate((a), 16))
#define leftRotate17(a) (leftRotate((a), 17))
#define leftRotate18(a) (leftRotate((a), 18))
#define leftRotate19(a) (leftRotate((a), 19))
#define leftRotate20(a) (leftRotate((a), 20))
#define leftRotate21(a) (leftRotate((a), 21))
#define leftRotate22(a) (leftRotate((a), 22))
#define leftRotate23(a) (leftRotate((a), 23))
#define leftRotate24(a) (leftRotate((a), 24))
#define leftRotate25(a) (leftRotate((a), 25))
#define leftRotate26(a) (leftRotate((a), 26))
#define leftRotate27(a) (leftRotate((a), 27))
#define leftRotate28(a) (leftRotate((a), 28))
#define leftRotate29(a) (leftRotate((a), 29))
#define leftRotate30(a) (leftRotate((a), 30))
#define leftRotate31(a) (leftRotate((a), 31))
/* Right rotate by a specific number of bits. These macros may be replaced
* with more efficient ones on platforms that lack a barrel shifter */
#define rightRotate1(a) (rightRotate((a), 1))
#define rightRotate2(a) (rightRotate((a), 2))
#define rightRotate3(a) (rightRotate((a), 3))
#define rightRotate4(a) (rightRotate((a), 4))
#define rightRotate5(a) (rightRotate((a), 5))
#define rightRotate6(a) (rightRotate((a), 6))
#define rightRotate7(a) (rightRotate((a), 7))
#define rightRotate8(a) (rightRotate((a), 8))
#define rightRotate9(a) (rightRotate((a), 9))
#define rightRotate10(a) (rightRotate((a), 10))
#define rightRotate11(a) (rightRotate((a), 11))
#define rightRotate12(a) (rightRotate((a), 12))
#define rightRotate13(a) (rightRotate((a), 13))
#define rightRotate14(a) (rightRotate((a), 14))
#define rightRotate15(a) (rightRotate((a), 15))
#define rightRotate16(a) (rightRotate((a), 16))
#define rightRotate17(a) (rightRotate((a), 17))
#define rightRotate18(a) (rightRotate((a), 18))
#define rightRotate19(a) (rightRotate((a), 19))
#define rightRotate20(a) (rightRotate((a), 20))
#define rightRotate21(a) (rightRotate((a), 21))
#define rightRotate22(a) (rightRotate((a), 22))
#define rightRotate23(a) (rightRotate((a), 23))
#define rightRotate24(a) (rightRotate((a), 24))
#define rightRotate25(a) (rightRotate((a), 25))
#define rightRotate26(a) (rightRotate((a), 26))
#define rightRotate27(a) (rightRotate((a), 27))
#define rightRotate28(a) (rightRotate((a), 28))
#define rightRotate29(a) (rightRotate((a), 29))
#define rightRotate30(a) (rightRotate((a), 30))
#define rightRotate31(a) (rightRotate((a), 31))
#else /* LW_CRYPTO_ROTATE32_COMPOSED */
/* Composed rotation macros where 1 and 8 are fast, but others are slow */
/* Left rotate by 1 */
#define leftRotate1(a) (leftRotate((a), 1))
/* Left rotate by 2 */
#define leftRotate2(a) (leftRotate(leftRotate((a), 1), 1))
/* Left rotate by 3 */
#define leftRotate3(a) (leftRotate(leftRotate(leftRotate((a), 1), 1), 1))
/* Left rotate by 4 */
#define leftRotate4(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 1), 1), 1), 1))
/* Left rotate by 5: Rotate left by 8, then right by 3 */
#define leftRotate5(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 8), 1), 1), 1))
/* Left rotate by 6: Rotate left by 8, then right by 2 */
#define leftRotate6(a) (rightRotate(rightRotate(leftRotate((a), 8), 1), 1))
/* Left rotate by 7: Rotate left by 8, then right by 1 */
#define leftRotate7(a) (rightRotate(leftRotate((a), 8), 1))
/* Left rotate by 8 */
#define leftRotate8(a) (leftRotate((a), 8))
/* Left rotate by 9: Rotate left by 8, then left by 1 */
#define leftRotate9(a) (leftRotate(leftRotate((a), 8), 1))
/* Left rotate by 10: Rotate left by 8, then left by 2 */
#define leftRotate10(a) (leftRotate(leftRotate(leftRotate((a), 8), 1), 1))
/* Left rotate by 11: Rotate left by 8, then left by 3 */
#define leftRotate11(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 8), 1), 1), 1))
/* Left rotate by 12: Rotate left by 16, then right by 4 */
#define leftRotate12(a) (rightRotate(rightRotate(rightRotate(rightRotate(leftRotate((a), 16), 1), 1), 1), 1))
/* Left rotate by 13: Rotate left by 16, then right by 3 */
#define leftRotate13(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 16), 1), 1), 1))
/* Left rotate by 14: Rotate left by 16, then right by 2 */
#define leftRotate14(a) (rightRotate(rightRotate(leftRotate((a), 16), 1), 1))
/* Left rotate by 15: Rotate left by 16, then right by 1 */
#define leftRotate15(a) (rightRotate(leftRotate((a), 16), 1))
/* Left rotate by 16 */
#define leftRotate16(a) (leftRotate((a), 16))
/* Left rotate by 17: Rotate left by 16, then left by 1 */
#define leftRotate17(a) (leftRotate(leftRotate((a), 16), 1))
/* Left rotate by 18: Rotate left by 16, then left by 2 */
#define leftRotate18(a) (leftRotate(leftRotate(leftRotate((a), 16), 1), 1))
/* Left rotate by 19: Rotate left by 16, then left by 3 */
#define leftRotate19(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 16), 1), 1), 1))
/* Left rotate by 20: Rotate left by 16, then left by 4 */
#define leftRotate20(a) (leftRotate(leftRotate(leftRotate(leftRotate(leftRotate((a), 16), 1), 1), 1), 1))
/* Left rotate by 21: Rotate left by 24, then right by 3 */
#define leftRotate21(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 24), 1), 1), 1))
/* Left rotate by 22: Rotate left by 24, then right by 2 */
#define leftRotate22(a) (rightRotate(rightRotate(leftRotate((a), 24), 1), 1))
/* Left rotate by 23: Rotate left by 24, then right by 1 */
#define leftRotate23(a) (rightRotate(leftRotate((a), 24), 1))
/* Left rotate by 24 */
#define leftRotate24(a) (leftRotate((a), 24))
/* Left rotate by 25: Rotate left by 24, then left by 1 */
#define leftRotate25(a) (leftRotate(leftRotate((a), 24), 1))
/* Left rotate by 26: Rotate left by 24, then left by 2 */
#define leftRotate26(a) (leftRotate(leftRotate(leftRotate((a), 24), 1), 1))
/* Left rotate by 27: Rotate left by 24, then left by 3 */
#define leftRotate27(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 24), 1), 1), 1))
/* Left rotate by 28: Rotate right by 4 */
#define leftRotate28(a) (rightRotate(rightRotate(rightRotate(rightRotate((a), 1), 1), 1), 1))
/* Left rotate by 29: Rotate right by 3 */
#define leftRotate29(a) (rightRotate(rightRotate(rightRotate((a), 1), 1), 1))
/* Left rotate by 30: Rotate right by 2 */
#define leftRotate30(a) (rightRotate(rightRotate((a), 1), 1))
/* Left rotate by 31: Rotate right by 1 */
#define leftRotate31(a) (rightRotate((a), 1))
/* Define the 32-bit right rotations in terms of left rotations */
#define rightRotate1(a) (leftRotate31((a)))
#define rightRotate2(a) (leftRotate30((a)))
#define rightRotate3(a) (leftRotate29((a)))
#define rightRotate4(a) (leftRotate28((a)))
#define rightRotate5(a) (leftRotate27((a)))
#define rightRotate6(a) (leftRotate26((a)))
#define rightRotate7(a) (leftRotate25((a)))
#define rightRotate8(a) (leftRotate24((a)))
#define rightRotate9(a) (leftRotate23((a)))
#define rightRotate10(a) (leftRotate22((a)))
#define rightRotate11(a) (leftRotate21((a)))
#define rightRotate12(a) (leftRotate20((a)))
#define rightRotate13(a) (leftRotate19((a)))
#define rightRotate14(a) (leftRotate18((a)))
#define rightRotate15(a) (leftRotate17((a)))
#define rightRotate16(a) (leftRotate16((a)))
#define rightRotate17(a) (leftRotate15((a)))
#define rightRotate18(a) (leftRotate14((a)))
#define rightRotate19(a) (leftRotate13((a)))
#define rightRotate20(a) (leftRotate12((a)))
#define rightRotate21(a) (leftRotate11((a)))
#define rightRotate22(a) (leftRotate10((a)))
#define rightRotate23(a) (leftRotate9((a)))
#define rightRotate24(a) (leftRotate8((a)))
#define rightRotate25(a) (leftRotate7((a)))
#define rightRotate26(a) (leftRotate6((a)))
#define rightRotate27(a) (leftRotate5((a)))
#define rightRotate28(a) (leftRotate4((a)))
#define rightRotate29(a) (leftRotate3((a)))
#define rightRotate30(a) (leftRotate2((a)))
#define rightRotate31(a) (leftRotate1((a)))
#endif /* LW_CRYPTO_ROTATE32_COMPOSED */
/* Rotation macros for 64-bit arguments */
/* Generic left rotate */
#define leftRotate_64(a, bits) \
(__extension__ ({ \
uint64_t _temp = (a); \
(_temp << (bits)) | (_temp >> (64 - (bits))); \
}))
/* Generic right rotate */
#define rightRotate_64(a, bits) \
(__extension__ ({ \
uint64_t _temp = (a); \
(_temp >> (bits)) | (_temp << (64 - (bits))); \
}))
/* Left rotate by a specific number of bits. These macros may be replaced
* with more efficient ones on platforms that lack a barrel shifter */
#define leftRotate1_64(a) (leftRotate_64((a), 1))
#define leftRotate2_64(a) (leftRotate_64((a), 2))
#define leftRotate3_64(a) (leftRotate_64((a), 3))
#define leftRotate4_64(a) (leftRotate_64((a), 4))
#define leftRotate5_64(a) (leftRotate_64((a), 5))
#define leftRotate6_64(a) (leftRotate_64((a), 6))
#define leftRotate7_64(a) (leftRotate_64((a), 7))
#define leftRotate8_64(a) (leftRotate_64((a), 8))
#define leftRotate9_64(a) (leftRotate_64((a), 9))
#define leftRotate10_64(a) (leftRotate_64((a), 10))
#define leftRotate11_64(a) (leftRotate_64((a), 11))
#define leftRotate12_64(a) (leftRotate_64((a), 12))
#define leftRotate13_64(a) (leftRotate_64((a), 13))
#define leftRotate14_64(a) (leftRotate_64((a), 14))
#define leftRotate15_64(a) (leftRotate_64((a), 15))
#define leftRotate16_64(a) (leftRotate_64((a), 16))
#define leftRotate17_64(a) (leftRotate_64((a), 17))
#define leftRotate18_64(a) (leftRotate_64((a), 18))
#define leftRotate19_64(a) (leftRotate_64((a), 19))
#define leftRotate20_64(a) (leftRotate_64((a), 20))
#define leftRotate21_64(a) (leftRotate_64((a), 21))
#define leftRotate22_64(a) (leftRotate_64((a), 22))
#define leftRotate23_64(a) (leftRotate_64((a), 23))
#define leftRotate24_64(a) (leftRotate_64((a), 24))
#define leftRotate25_64(a) (leftRotate_64((a), 25))
#define leftRotate26_64(a) (leftRotate_64((a), 26))
#define leftRotate27_64(a) (leftRotate_64((a), 27))
#define leftRotate28_64(a) (leftRotate_64((a), 28))
#define leftRotate29_64(a) (leftRotate_64((a), 29))
#define leftRotate30_64(a) (leftRotate_64((a), 30))
#define leftRotate31_64(a) (leftRotate_64((a), 31))
#define leftRotate32_64(a) (leftRotate_64((a), 32))
#define leftRotate33_64(a) (leftRotate_64((a), 33))
#define leftRotate34_64(a) (leftRotate_64((a), 34))
#define leftRotate35_64(a) (leftRotate_64((a), 35))
#define leftRotate36_64(a) (leftRotate_64((a), 36))
#define leftRotate37_64(a) (leftRotate_64((a), 37))
#define leftRotate38_64(a) (leftRotate_64((a), 38))
#define leftRotate39_64(a) (leftRotate_64((a), 39))
#define leftRotate40_64(a) (leftRotate_64((a), 40))
#define leftRotate41_64(a) (leftRotate_64((a), 41))
#define leftRotate42_64(a) (leftRotate_64((a), 42))
#define leftRotate43_64(a) (leftRotate_64((a), 43))
#define leftRotate44_64(a) (leftRotate_64((a), 44))
#define leftRotate45_64(a) (leftRotate_64((a), 45))
#define leftRotate46_64(a) (leftRotate_64((a), 46))
#define leftRotate47_64(a) (leftRotate_64((a), 47))
#define leftRotate48_64(a) (leftRotate_64((a), 48))
#define leftRotate49_64(a) (leftRotate_64((a), 49))
#define leftRotate50_64(a) (leftRotate_64((a), 50))
#define leftRotate51_64(a) (leftRotate_64((a), 51))
#define leftRotate52_64(a) (leftRotate_64((a), 52))
#define leftRotate53_64(a) (leftRotate_64((a), 53))
#define leftRotate54_64(a) (leftRotate_64((a), 54))
#define leftRotate55_64(a) (leftRotate_64((a), 55))
#define leftRotate56_64(a) (leftRotate_64((a), 56))
#define leftRotate57_64(a) (leftRotate_64((a), 57))
#define leftRotate58_64(a) (leftRotate_64((a), 58))
#define leftRotate59_64(a) (leftRotate_64((a), 59))
#define leftRotate60_64(a) (leftRotate_64((a), 60))
#define leftRotate61_64(a) (leftRotate_64((a), 61))
#define leftRotate62_64(a) (leftRotate_64((a), 62))
#define leftRotate63_64(a) (leftRotate_64((a), 63))
/* Right rotate by a specific number of bits. These macros may be replaced
* with more efficient ones on platforms that lack a barrel shifter */
#define rightRotate1_64(a) (rightRotate_64((a), 1))
#define rightRotate2_64(a) (rightRotate_64((a), 2))
#define rightRotate3_64(a) (rightRotate_64((a), 3))
#define rightRotate4_64(a) (rightRotate_64((a), 4))
#define rightRotate5_64(a) (rightRotate_64((a), 5))
#define rightRotate6_64(a) (rightRotate_64((a), 6))
#define rightRotate7_64(a) (rightRotate_64((a), 7))
#define rightRotate8_64(a) (rightRotate_64((a), 8))
#define rightRotate9_64(a) (rightRotate_64((a), 9))
#define rightRotate10_64(a) (rightRotate_64((a), 10))
#define rightRotate11_64(a) (rightRotate_64((a), 11))
#define rightRotate12_64(a) (rightRotate_64((a), 12))
#define rightRotate13_64(a) (rightRotate_64((a), 13))
#define rightRotate14_64(a) (rightRotate_64((a), 14))
#define rightRotate15_64(a) (rightRotate_64((a), 15))
#define rightRotate16_64(a) (rightRotate_64((a), 16))
#define rightRotate17_64(a) (rightRotate_64((a), 17))
#define rightRotate18_64(a) (rightRotate_64((a), 18))
#define rightRotate19_64(a) (rightRotate_64((a), 19))
#define rightRotate20_64(a) (rightRotate_64((a), 20))
#define rightRotate21_64(a) (rightRotate_64((a), 21))
#define rightRotate22_64(a) (rightRotate_64((a), 22))
#define rightRotate23_64(a) (rightRotate_64((a), 23))
#define rightRotate24_64(a) (rightRotate_64((a), 24))
#define rightRotate25_64(a) (rightRotate_64((a), 25))
#define rightRotate26_64(a) (rightRotate_64((a), 26))
#define rightRotate27_64(a) (rightRotate_64((a), 27))
#define rightRotate28_64(a) (rightRotate_64((a), 28))
#define rightRotate29_64(a) (rightRotate_64((a), 29))
#define rightRotate30_64(a) (rightRotate_64((a), 30))
#define rightRotate31_64(a) (rightRotate_64((a), 31))
#define rightRotate32_64(a) (rightRotate_64((a), 32))
#define rightRotate33_64(a) (rightRotate_64((a), 33))
#define rightRotate34_64(a) (rightRotate_64((a), 34))
#define rightRotate35_64(a) (rightRotate_64((a), 35))
#define rightRotate36_64(a) (rightRotate_64((a), 36))
#define rightRotate37_64(a) (rightRotate_64((a), 37))
#define rightRotate38_64(a) (rightRotate_64((a), 38))
#define rightRotate39_64(a) (rightRotate_64((a), 39))
#define rightRotate40_64(a) (rightRotate_64((a), 40))
#define rightRotate41_64(a) (rightRotate_64((a), 41))
#define rightRotate42_64(a) (rightRotate_64((a), 42))
#define rightRotate43_64(a) (rightRotate_64((a), 43))
#define rightRotate44_64(a) (rightRotate_64((a), 44))
#define rightRotate45_64(a) (rightRotate_64((a), 45))
#define rightRotate46_64(a) (rightRotate_64((a), 46))
#define rightRotate47_64(a) (rightRotate_64((a), 47))
#define rightRotate48_64(a) (rightRotate_64((a), 48))
#define rightRotate49_64(a) (rightRotate_64((a), 49))
#define rightRotate50_64(a) (rightRotate_64((a), 50))
#define rightRotate51_64(a) (rightRotate_64((a), 51))
#define rightRotate52_64(a) (rightRotate_64((a), 52))
#define rightRotate53_64(a) (rightRotate_64((a), 53))
#define rightRotate54_64(a) (rightRotate_64((a), 54))
#define rightRotate55_64(a) (rightRotate_64((a), 55))
#define rightRotate56_64(a) (rightRotate_64((a), 56))
#define rightRotate57_64(a) (rightRotate_64((a), 57))
#define rightRotate58_64(a) (rightRotate_64((a), 58))
#define rightRotate59_64(a) (rightRotate_64((a), 59))
#define rightRotate60_64(a) (rightRotate_64((a), 60))
#define rightRotate61_64(a) (rightRotate_64((a), 61))
#define rightRotate62_64(a) (rightRotate_64((a), 62))
#define rightRotate63_64(a) (rightRotate_64((a), 63))
/* Rotate a 16-bit value left by a number of bits */
#define leftRotate_16(a, bits) \
(__extension__ ({ \
uint16_t _temp = (a); \
(_temp << (bits)) | (_temp >> (16 - (bits))); \
}))
/* Rotate a 16-bit value right by a number of bits */
#define rightRotate_16(a, bits) \
(__extension__ ({ \
uint16_t _temp = (a); \
(_temp >> (bits)) | (_temp << (16 - (bits))); \
}))
/* Left rotate by a specific number of bits. These macros may be replaced
* with more efficient ones on platforms that lack a barrel shifter */
#define leftRotate1_16(a) (leftRotate_16((a), 1))
#define leftRotate2_16(a) (leftRotate_16((a), 2))
#define leftRotate3_16(a) (leftRotate_16((a), 3))
#define leftRotate4_16(a) (leftRotate_16((a), 4))
#define leftRotate5_16(a) (leftRotate_16((a), 5))
#define leftRotate6_16(a) (leftRotate_16((a), 6))
#define leftRotate7_16(a) (leftRotate_16((a), 7))
#define leftRotate8_16(a) (leftRotate_16((a), 8))
#define leftRotate9_16(a) (leftRotate_16((a), 9))
#define leftRotate10_16(a) (leftRotate_16((a), 10))
#define leftRotate11_16(a) (leftRotate_16((a), 11))
#define leftRotate12_16(a) (leftRotate_16((a), 12))
#define leftRotate13_16(a) (leftRotate_16((a), 13))
#define leftRotate14_16(a) (leftRotate_16((a), 14))
#define leftRotate15_16(a) (leftRotate_16((a), 15))
/* Right rotate by a specific number of bits. These macros may be replaced
* with more efficient ones on platforms that lack a barrel shifter */
#define rightRotate1_16(a) (rightRotate_16((a), 1))
#define rightRotate2_16(a) (rightRotate_16((a), 2))
#define rightRotate3_16(a) (rightRotate_16((a), 3))
#define rightRotate4_16(a) (rightRotate_16((a), 4))
#define rightRotate5_16(a) (rightRotate_16((a), 5))
#define rightRotate6_16(a) (rightRotate_16((a), 6))
#define rightRotate7_16(a) (rightRotate_16((a), 7))
#define rightRotate8_16(a) (rightRotate_16((a), 8))
#define rightRotate9_16(a) (rightRotate_16((a), 9))
#define rightRotate10_16(a) (rightRotate_16((a), 10))
#define rightRotate11_16(a) (rightRotate_16((a), 11))
#define rightRotate12_16(a) (rightRotate_16((a), 12))
#define rightRotate13_16(a) (rightRotate_16((a), 13))
#define rightRotate14_16(a) (rightRotate_16((a), 14))
#define rightRotate15_16(a) (rightRotate_16((a), 15))
/* Rotate an 8-bit value left by a number of bits */
#define leftRotate_8(a, bits) \
(__extension__ ({ \
uint8_t _temp = (a); \
(_temp << (bits)) | (_temp >> (8 - (bits))); \
}))
/* Rotate an 8-bit value right by a number of bits */
#define rightRotate_8(a, bits) \
(__extension__ ({ \
uint8_t _temp = (a); \
(_temp >> (bits)) | (_temp << (8 - (bits))); \
}))
/* Left rotate by a specific number of bits. These macros may be replaced
* with more efficient ones on platforms that lack a barrel shifter */
#define leftRotate1_8(a) (leftRotate_8((a), 1))
#define leftRotate2_8(a) (leftRotate_8((a), 2))
#define leftRotate3_8(a) (leftRotate_8((a), 3))
#define leftRotate4_8(a) (leftRotate_8((a), 4))
#define leftRotate5_8(a) (leftRotate_8((a), 5))
#define leftRotate6_8(a) (leftRotate_8((a), 6))
#define leftRotate7_8(a) (leftRotate_8((a), 7))
/* Right rotate by a specific number of bits. These macros may be replaced
* with more efficient ones on platforms that lack a barrel shifter */
#define rightRotate1_8(a) (rightRotate_8((a), 1))
#define rightRotate2_8(a) (rightRotate_8((a), 2))
#define rightRotate3_8(a) (rightRotate_8((a), 3))
#define rightRotate4_8(a) (rightRotate_8((a), 4))
#define rightRotate5_8(a) (rightRotate_8((a), 5))
#define rightRotate6_8(a) (rightRotate_8((a), 6))
#define rightRotate7_8(a) (rightRotate_8((a), 7))
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment