Commit ff91180d by Arne Deprez Committed by Sebastian Renner

forkae update

parent 5ecb20e1
......@@ -154,7 +154,7 @@ typedef void (*aead_xof_squeeze_t)
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
......@@ -166,7 +166,18 @@ typedef void (*aead_xof_squeeze_t)
* 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
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief The AEAD mode provides side-channel protection for the key.
*/
#define AEAD_FLAG_SC_PROTECT_KEY 0x0002
/**
* \brief The AEAD mode provides side-channel protection for all block
* operations.
*/
#define AEAD_FLAG_SC_PROTECT_ALL 0x0004
/**
* \brief Meta-information about an AEAD cipher.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,6 +23,8 @@
#ifndef LW_INTERNAL_FORKSKINNY_H
#define LW_INTERNAL_FORKSKINNY_H
#include "internal-util.h"
/**
* \file internal-forkskinny.h
* \brief ForkSkinny block cipher family.
......@@ -39,6 +41,172 @@ extern "C" {
#endif
/**
* \brief Number of rounds of ForkSkinny-128-256 before forking.
*/
#define FORKSKINNY_128_256_ROUNDS_BEFORE 21
/**
* \brief Number of rounds of ForkSkinny-128-256 after forking.
*/
#define FORKSKINNY_128_256_ROUNDS_AFTER 27
/**
* \brief State information for ForkSkinny-128-256.
*/
typedef struct
{
// uint32_t TK1[4]; /**< First part of the tweakey */
// uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_256_state_t;
typedef struct
{
/** Words of the full key schedule */
uint32_t row0[(FORKSKINNY_128_256_ROUNDS_BEFORE + 2*FORKSKINNY_128_256_ROUNDS_AFTER)];
uint32_t row1[(FORKSKINNY_128_256_ROUNDS_BEFORE + 2*FORKSKINNY_128_256_ROUNDS_AFTER)];
} forkskinny_128_256_tweakey_schedule_t;
/**
* \brief Number of rounds of ForkSkinny-128-384 before forking.
*/
#define FORKSKINNY_128_384_ROUNDS_BEFORE 25
/**
* \brief Number of rounds of ForkSkinny-128-384 after forking.
*/
#define FORKSKINNY_128_384_ROUNDS_AFTER 31
/**
* \brief State information for ForkSkinny-128-384.
*/
typedef struct
{
// uint32_t TK1[4]; /**< First part of the tweakey */
// uint32_t TK2[4]; /**< Second part of the tweakey */
// uint32_t TK3[4]; /**< Third part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_384_state_t;
typedef struct
{
/** Words of the full key schedule */
uint32_t row0[(FORKSKINNY_128_384_ROUNDS_BEFORE + 2*FORKSKINNY_128_384_ROUNDS_AFTER)];
uint32_t row1[(FORKSKINNY_128_384_ROUNDS_BEFORE + 2*FORKSKINNY_128_384_ROUNDS_AFTER)];
} forkskinny_128_384_tweakey_schedule_t;
/**
* \brief Number of rounds of ForkSkinny-64-192 before forking.
*/
#define FORKSKINNY_64_192_ROUNDS_BEFORE 17
/**
* \brief Number of rounds of ForkSkinny-64-192 after forking.
*/
#define FORKSKINNY_64_192_ROUNDS_AFTER 23
/**
* \brief State information for ForkSkinny-64-192.
*/
typedef struct
{
uint16_t TK1[4]; /**< First part of the tweakey */
uint16_t TK2[4]; /**< Second part of the tweakey */
uint16_t TK3[4]; /**< Third part of the tweakey */
uint16_t S[4]; /**< Current block state */
} forkskinny_64_192_state_t;
typedef struct
{
/** Words of the full key schedule */
uint16_t row0[(FORKSKINNY_64_192_ROUNDS_BEFORE + 2*FORKSKINNY_64_192_ROUNDS_AFTER)];
uint16_t row1[(FORKSKINNY_64_192_ROUNDS_BEFORE + 2*FORKSKINNY_64_192_ROUNDS_AFTER)];
} forkskinny_64_192_tweakey_schedule_t;
void forkskinny_128_256_init_tks(forkskinny_128_256_tweakey_schedule_t *tks, const unsigned char key[32], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-256.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_256_rounds
(forkskinny_128_256_state_t *state, forkskinny_128_256_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-256 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_256_inv_rounds
(forkskinny_128_256_state_t *state, forkskinny_128_256_tweakey_schedule_t *tks, unsigned first, unsigned last);
void forkskinny_128_384_init_tks(forkskinny_128_384_tweakey_schedule_t *tks, const unsigned char key[48], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-384.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_384_rounds
(forkskinny_128_384_state_t *state, forkskinny_128_384_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-384 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_384_inv_rounds
(forkskinny_128_384_state_t *state, forkskinny_128_384_tweakey_schedule_t *tks, unsigned first, unsigned last);
void forkskinny_64_192_init_tks(forkskinny_64_192_tweakey_schedule_t *tks, const unsigned char key[24], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-64-192.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*
* Note: The cells of each row are ordered in big-endian nibble order
* so it is simplest to manage the rows in big-endian byte order.
*/
void forkskinny_64_192_rounds
(forkskinny_64_192_state_t *state, forkskinny_64_192_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-64-192 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_64_192_inv_rounds
(forkskinny_64_192_state_t *state, forkskinny_64_192_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Encrypts a block of plaintext with ForkSkinny-128-256.
*
* \param key 256-bit tweakey for ForkSkinny-128-256.
......
......@@ -74,6 +74,21 @@ extern "C" {
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_permute_tk_half(tk2, tk3) \
do { \
/* Permute the bottom half of the tweakey state in place, no swap */ \
uint32_t row2 = tk2; \
uint32_t row3 = tk3; \
row3 = (row3 << 16) | (row3 >> 16); \
tk2 = ((row2 >> 8) & 0x000000FFU) | \
((row2 << 16) & 0x00FF0000U) | \
( row3 & 0xFF00FF00U); \
tk3 = ((row2 >> 16) & 0x000000FFU) | \
(row2 & 0xFF000000U) | \
((row3 << 8) & 0x0000FF00U) | \
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk(tk) \
do { \
/* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \
......@@ -91,6 +106,21 @@ extern "C" {
((row1 << 8) & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk_half(tk0, tk1) \
do { \
/* Permute the top half of the tweakey state in place, no swap */ \
uint32_t row0 = tk0; \
uint32_t row1 = tk1; \
tk0 = ((row0 >> 16) & 0x000000FFU) | \
((row0 << 8) & 0x0000FF00U) | \
((row1 << 16) & 0x00FF0000U) | \
( row1 & 0xFF000000U); \
tk1 = ((row0 >> 16) & 0x0000FF00U) | \
((row0 << 16) & 0xFF000000U) | \
((row1 >> 16) & 0x000000FFU) | \
((row1 << 8) & 0x00FF0000U); \
} while (0)
/*
* Apply the SKINNY sbox. The original version from the specification is
* equivalent to:
......
......@@ -154,7 +154,7 @@ typedef void (*aead_xof_squeeze_t)
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
......@@ -166,7 +166,18 @@ typedef void (*aead_xof_squeeze_t)
* 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
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief The AEAD mode provides side-channel protection for the key.
*/
#define AEAD_FLAG_SC_PROTECT_KEY 0x0002
/**
* \brief The AEAD mode provides side-channel protection for all block
* operations.
*/
#define AEAD_FLAG_SC_PROTECT_ALL 0x0004
/**
* \brief Meta-information about an AEAD cipher.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,6 +23,8 @@
#ifndef LW_INTERNAL_FORKSKINNY_H
#define LW_INTERNAL_FORKSKINNY_H
#include "internal-util.h"
/**
* \file internal-forkskinny.h
* \brief ForkSkinny block cipher family.
......@@ -39,6 +41,158 @@ extern "C" {
#endif
/**
* \brief State information for ForkSkinny-128-256.
*/
typedef struct
{
uint32_t TK1[4]; /**< First part of the tweakey */
uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_256_state_t;
/**
* \brief State information for ForkSkinny-128-384.
*/
typedef struct
{
uint32_t TK1[4]; /**< First part of the tweakey */
uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t TK3[4]; /**< Third part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_384_state_t;
/**
* \brief State information for ForkSkinny-64-192.
*/
typedef struct
{
uint16_t TK1[4]; /**< First part of the tweakey */
uint16_t TK2[4]; /**< Second part of the tweakey */
uint16_t TK3[4]; /**< Third part of the tweakey */
uint16_t S[4]; /**< Current block state */
} forkskinny_64_192_state_t;
/**
* \brief Applies several rounds of ForkSkinny-128-256.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_256_rounds
(forkskinny_128_256_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-256 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_256_inv_rounds
(forkskinny_128_256_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-128-256.
*
* \param state Points to the ForkSkinny-128-256 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_128_256_forward_tk
(forkskinny_128_256_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-128-256.
*
* \param state Points to the ForkSkinny-128-256 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_128_256_reverse_tk
(forkskinny_128_256_state_t *state, unsigned rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-384.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_384_rounds
(forkskinny_128_384_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-384 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_384_inv_rounds
(forkskinny_128_384_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-128-384.
*
* \param state Points to the ForkSkinny-128-384 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_128_384_forward_tk
(forkskinny_128_384_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-128-384.
*
* \param state Points to the ForkSkinny-128-384 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_128_384_reverse_tk
(forkskinny_128_384_state_t *state, unsigned rounds);
/**
* \brief Applies several rounds of ForkSkinny-64-192.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*
* Note: The cells of each row are ordered in big-endian nibble order
* so it is simplest to manage the rows in big-endian byte order.
*/
void forkskinny_64_192_rounds
(forkskinny_64_192_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-64-192 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_64_192_inv_rounds
(forkskinny_64_192_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-64-192.
*
* \param state Points to the ForkSkinny-64-192 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_64_192_forward_tk
(forkskinny_64_192_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-64-192.
*
* \param state Points to the ForkSkinny-64-192 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_64_192_reverse_tk
(forkskinny_64_192_state_t *state, unsigned rounds);
/**
* \brief Encrypts a block of plaintext with ForkSkinny-128-256.
*
* \param key 256-bit tweakey for ForkSkinny-128-256.
......
......@@ -74,6 +74,21 @@ extern "C" {
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_permute_tk_half(tk2, tk3) \
do { \
/* Permute the bottom half of the tweakey state in place, no swap */ \
uint32_t row2 = tk2; \
uint32_t row3 = tk3; \
row3 = (row3 << 16) | (row3 >> 16); \
tk2 = ((row2 >> 8) & 0x000000FFU) | \
((row2 << 16) & 0x00FF0000U) | \
( row3 & 0xFF00FF00U); \
tk3 = ((row2 >> 16) & 0x000000FFU) | \
(row2 & 0xFF000000U) | \
((row3 << 8) & 0x0000FF00U) | \
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk(tk) \
do { \
/* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \
......@@ -91,6 +106,21 @@ extern "C" {
((row1 << 8) & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk_half(tk0, tk1) \
do { \
/* Permute the top half of the tweakey state in place, no swap */ \
uint32_t row0 = tk0; \
uint32_t row1 = tk1; \
tk0 = ((row0 >> 16) & 0x000000FFU) | \
((row0 << 8) & 0x0000FF00U) | \
((row1 << 16) & 0x00FF0000U) | \
( row1 & 0xFF000000U); \
tk1 = ((row0 >> 16) & 0x0000FF00U) | \
((row0 << 16) & 0xFF000000U) | \
((row1 >> 16) & 0x000000FFU) | \
((row1 << 8) & 0x00FF0000U); \
} while (0)
/*
* Apply the SKINNY sbox. The original version from the specification is
* equivalent to:
......@@ -319,6 +349,61 @@ do { \
x = ((x << 1) & 0xEEEEU) | ((x >> 3) & 0x1111U); \
} while (0)
#define rows_to_columns_32(column0, column1, column2, column3, row0, row1, row2, row3) \
do { \
column0 = (row3 & 0xFF) << 24|(row2 & 0xFF) << 16|(row1 & 0xFF) << 8 | (row0 & 0xFF);\
column1 = (row3 & 0xFF00) << 16|(row2 & 0xFF00) << 8 |(row1 & 0xFF00) | (row0>>8 & 0xFF);\
column2 = (row3 & 0xFF0000) << 8 |(row2 & 0xFF0000) |(row1 & 0xFF0000) >> 8 | (row0>>16 & 0xFF);\
column3 = (row3 & 0xFF000000) |(row2 & 0xFF000000) >> 8 |(row1 & 0xFF000000) >> 16| (row0>>24 & 0xFF);\
} while(0)
#define columns_to_rows_32(row0, row1, row2, row3, column0, column1, column2, column3) rows_to_columns_32(row0, row1, row2, row3, column0, column1, column2, column3)
#define load_column_8(dest, src) \
do { \
dest[0] = (src[12]) << 24 | (src[8]) << 16 | (src[4]) << 8 | (src[0]); \
dest[1] = (src[13]) << 24 | (src[9]) << 16 | (src[5]) << 8 | (src[1]); \
dest[2] = (src[14]) << 24 | (src[10]) << 16 | (src[6]) << 8 | (src[2]); \
dest[3] = (src[15]) << 24 | (src[11]) << 16 | (src[7]) << 8 | (src[3]); \
} while(0)
#define store_column_8(dest, src) \
do { \
dest[0] = (uint8_t) (src[0]); dest[1] = (uint8_t) (src[1]); dest[2] = (uint8_t) (src[2]); dest[3] = (uint8_t) (src[3]); \
dest[4] = (uint8_t) (src[0]>>8); dest[5] = (uint8_t) (src[1]>>8); dest[6] = (uint8_t) (src[2]>>8); dest[7] = (uint8_t) (src[3]>>8); \
dest[8] = (uint8_t) (src[0]>>16);dest[9] = (uint8_t) (src[1]>>16);dest[10]= (uint8_t) (src[2]>>16);dest[11]= (uint8_t)(src[3]>>16); \
dest[12]= (uint8_t) (src[0]>>24);dest[13]= (uint8_t) (src[1]>>24);dest[14]= (uint8_t) (src[2]>>24);dest[15]= (uint8_t)(src[3]>>24); \
} while(0)
#define TK_to_column_256(columns, state) \
do { \
uint32_t TK0 = state->TK1[0] ^ state->TK2[0];\
uint32_t TK1 = state->TK1[1] ^ state->TK2[1]; \
uint32_t tk00 = TK0 & 0xFF; \
uint32_t tk01 = TK0 & 0xFF00;\
uint32_t tk02 = TK0 & 0xFF0000;\
uint32_t tk03 = TK0 & 0xFF000000;\
columns[0] = tk00 << 24 | (TK1 & 0xFF000000) >> 8 | tk00 << 8 | tk00; \
columns[1] = tk01 << 16 | (TK1 & 0xFF) << 16 | tk01 | tk01 >> 8; \
columns[2] = tk02 << 8 | (TK1 & 0xFF00) << 8 | tk02 >> 8 | tk02 >> 16; \
columns[3] = tk03 | (TK1 & 0xFF0000) | tk03 >> 16 | tk03 >> 24; \
} while(0)
#define TK_to_column_384(columns, state) \
do { \
uint32_t TK0 = state->TK1[0] ^ state->TK2[0] ^ state->TK3[0];\
uint32_t TK1 = state->TK1[1] ^ state->TK2[1] ^ state->TK3[1];\
uint32_t tk00 = TK0 & 0xFF; \
uint32_t tk01 = TK0 & 0xFF00;\
uint32_t tk02 = TK0 & 0xFF0000;\
uint32_t tk03 = TK0 & 0xFF000000;\
columns[0] = tk00 << 24 | (TK1 & 0xFF000000) >> 8 | tk00 << 8 | tk00; \
columns[1] = tk01 << 16 | (TK1 & 0xFF) << 16 | tk01 | tk01 >> 8; \
columns[2] = tk02 << 8 | (TK1 & 0xFF00) << 8 | tk02 >> 8 | tk02 >> 16; \
columns[3] = tk03 | (TK1 & 0xFF0000) | tk03 >> 16 | tk03 >> 24; \
} while(0)
/** @endcond */
#ifdef __cplusplus
......
......@@ -154,7 +154,7 @@ typedef void (*aead_xof_squeeze_t)
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
......@@ -166,7 +166,18 @@ typedef void (*aead_xof_squeeze_t)
* 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
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief The AEAD mode provides side-channel protection for the key.
*/
#define AEAD_FLAG_SC_PROTECT_KEY 0x0002
/**
* \brief The AEAD mode provides side-channel protection for all block
* operations.
*/
#define AEAD_FLAG_SC_PROTECT_ALL 0x0004
/**
* \brief Meta-information about an AEAD cipher.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,6 +23,8 @@
#ifndef LW_INTERNAL_FORKSKINNY_H
#define LW_INTERNAL_FORKSKINNY_H
#include "internal-util.h"
/**
* \file internal-forkskinny.h
* \brief ForkSkinny block cipher family.
......@@ -39,6 +41,172 @@ extern "C" {
#endif
/**
* \brief Number of rounds of ForkSkinny-128-256 before forking.
*/
#define FORKSKINNY_128_256_ROUNDS_BEFORE 21
/**
* \brief Number of rounds of ForkSkinny-128-256 after forking.
*/
#define FORKSKINNY_128_256_ROUNDS_AFTER 27
/**
* \brief State information for ForkSkinny-128-256.
*/
typedef struct
{
// uint32_t TK1[4]; /**< First part of the tweakey */
// uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_256_state_t;
typedef struct
{
/** Words of the full key schedule */
uint32_t row0[(FORKSKINNY_128_256_ROUNDS_BEFORE + 2*FORKSKINNY_128_256_ROUNDS_AFTER)];
uint32_t row1[(FORKSKINNY_128_256_ROUNDS_BEFORE + 2*FORKSKINNY_128_256_ROUNDS_AFTER)];
} forkskinny_128_256_tweakey_schedule_t;
/**
* \brief Number of rounds of ForkSkinny-128-384 before forking.
*/
#define FORKSKINNY_128_384_ROUNDS_BEFORE 25
/**
* \brief Number of rounds of ForkSkinny-128-384 after forking.
*/
#define FORKSKINNY_128_384_ROUNDS_AFTER 31
/**
* \brief State information for ForkSkinny-128-384.
*/
typedef struct
{
// uint32_t TK1[4]; /**< First part of the tweakey */
// uint32_t TK2[4]; /**< Second part of the tweakey */
// uint32_t TK3[4]; /**< Third part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_384_state_t;
typedef struct
{
/** Words of the full key schedule */
uint32_t row0[(FORKSKINNY_128_384_ROUNDS_BEFORE + 2*FORKSKINNY_128_384_ROUNDS_AFTER)];
uint32_t row1[(FORKSKINNY_128_384_ROUNDS_BEFORE + 2*FORKSKINNY_128_384_ROUNDS_AFTER)];
} forkskinny_128_384_tweakey_schedule_t;
/**
* \brief Number of rounds of ForkSkinny-64-192 before forking.
*/
#define FORKSKINNY_64_192_ROUNDS_BEFORE 17
/**
* \brief Number of rounds of ForkSkinny-64-192 after forking.
*/
#define FORKSKINNY_64_192_ROUNDS_AFTER 23
/**
* \brief State information for ForkSkinny-64-192.
*/
typedef struct
{
uint16_t TK1[4]; /**< First part of the tweakey */
uint16_t TK2[4]; /**< Second part of the tweakey */
uint16_t TK3[4]; /**< Third part of the tweakey */
uint16_t S[4]; /**< Current block state */
} forkskinny_64_192_state_t;
typedef struct
{
/** Words of the full key schedule */
uint16_t row0[(FORKSKINNY_64_192_ROUNDS_BEFORE + 2*FORKSKINNY_64_192_ROUNDS_AFTER)];
uint16_t row1[(FORKSKINNY_64_192_ROUNDS_BEFORE + 2*FORKSKINNY_64_192_ROUNDS_AFTER)];
} forkskinny_64_192_tweakey_schedule_t;
void forkskinny_128_256_init_tks(forkskinny_128_256_tweakey_schedule_t *tks, const unsigned char key[32], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-256.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_256_rounds
(forkskinny_128_256_state_t *state, forkskinny_128_256_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-256 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_256_inv_rounds
(forkskinny_128_256_state_t *state, forkskinny_128_256_tweakey_schedule_t *tks, unsigned first, unsigned last);
void forkskinny_128_384_init_tks(forkskinny_128_384_tweakey_schedule_t *tks, const unsigned char key[48], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-384.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_384_rounds
(forkskinny_128_384_state_t *state, forkskinny_128_384_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-384 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_384_inv_rounds
(forkskinny_128_384_state_t *state, forkskinny_128_384_tweakey_schedule_t *tks, unsigned first, unsigned last);
void forkskinny_64_192_init_tks(forkskinny_64_192_tweakey_schedule_t *tks, const unsigned char key[24], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-64-192.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*
* Note: The cells of each row are ordered in big-endian nibble order
* so it is simplest to manage the rows in big-endian byte order.
*/
void forkskinny_64_192_rounds
(forkskinny_64_192_state_t *state, forkskinny_64_192_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-64-192 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_64_192_inv_rounds
(forkskinny_64_192_state_t *state, forkskinny_64_192_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Encrypts a block of plaintext with ForkSkinny-128-256.
*
* \param key 256-bit tweakey for ForkSkinny-128-256.
......
......@@ -74,6 +74,21 @@ extern "C" {
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_permute_tk_half(tk2, tk3) \
do { \
/* Permute the bottom half of the tweakey state in place, no swap */ \
uint32_t row2 = tk2; \
uint32_t row3 = tk3; \
row3 = (row3 << 16) | (row3 >> 16); \
tk2 = ((row2 >> 8) & 0x000000FFU) | \
((row2 << 16) & 0x00FF0000U) | \
( row3 & 0xFF00FF00U); \
tk3 = ((row2 >> 16) & 0x000000FFU) | \
(row2 & 0xFF000000U) | \
((row3 << 8) & 0x0000FF00U) | \
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk(tk) \
do { \
/* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \
......@@ -91,6 +106,21 @@ extern "C" {
((row1 << 8) & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk_half(tk0, tk1) \
do { \
/* Permute the top half of the tweakey state in place, no swap */ \
uint32_t row0 = tk0; \
uint32_t row1 = tk1; \
tk0 = ((row0 >> 16) & 0x000000FFU) | \
((row0 << 8) & 0x0000FF00U) | \
((row1 << 16) & 0x00FF0000U) | \
( row1 & 0xFF000000U); \
tk1 = ((row0 >> 16) & 0x0000FF00U) | \
((row0 << 16) & 0xFF000000U) | \
((row1 >> 16) & 0x000000FFU) | \
((row1 << 8) & 0x00FF0000U); \
} while (0)
/*
* Apply the SKINNY sbox. The original version from the specification is
* equivalent to:
......
......@@ -154,7 +154,7 @@ typedef void (*aead_xof_squeeze_t)
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
......@@ -166,7 +166,18 @@ typedef void (*aead_xof_squeeze_t)
* 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
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief The AEAD mode provides side-channel protection for the key.
*/
#define AEAD_FLAG_SC_PROTECT_KEY 0x0002
/**
* \brief The AEAD mode provides side-channel protection for all block
* operations.
*/
#define AEAD_FLAG_SC_PROTECT_ALL 0x0004
/**
* \brief Meta-information about an AEAD cipher.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,6 +23,8 @@
#ifndef LW_INTERNAL_FORKSKINNY_H
#define LW_INTERNAL_FORKSKINNY_H
#include "internal-util.h"
/**
* \file internal-forkskinny.h
* \brief ForkSkinny block cipher family.
......@@ -39,6 +41,158 @@ extern "C" {
#endif
/**
* \brief State information for ForkSkinny-128-256.
*/
typedef struct
{
uint32_t TK1[4]; /**< First part of the tweakey */
uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_256_state_t;
/**
* \brief State information for ForkSkinny-128-384.
*/
typedef struct
{
uint32_t TK1[4]; /**< First part of the tweakey */
uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t TK3[4]; /**< Third part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_384_state_t;
/**
* \brief State information for ForkSkinny-64-192.
*/
typedef struct
{
uint16_t TK1[4]; /**< First part of the tweakey */
uint16_t TK2[4]; /**< Second part of the tweakey */
uint16_t TK3[4]; /**< Third part of the tweakey */
uint16_t S[4]; /**< Current block state */
} forkskinny_64_192_state_t;
/**
* \brief Applies several rounds of ForkSkinny-128-256.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_256_rounds
(forkskinny_128_256_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-256 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_256_inv_rounds
(forkskinny_128_256_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-128-256.
*
* \param state Points to the ForkSkinny-128-256 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_128_256_forward_tk
(forkskinny_128_256_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-128-256.
*
* \param state Points to the ForkSkinny-128-256 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_128_256_reverse_tk
(forkskinny_128_256_state_t *state, unsigned rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-384.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_384_rounds
(forkskinny_128_384_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-384 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_384_inv_rounds
(forkskinny_128_384_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-128-384.
*
* \param state Points to the ForkSkinny-128-384 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_128_384_forward_tk
(forkskinny_128_384_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-128-384.
*
* \param state Points to the ForkSkinny-128-384 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_128_384_reverse_tk
(forkskinny_128_384_state_t *state, unsigned rounds);
/**
* \brief Applies several rounds of ForkSkinny-64-192.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*
* Note: The cells of each row are ordered in big-endian nibble order
* so it is simplest to manage the rows in big-endian byte order.
*/
void forkskinny_64_192_rounds
(forkskinny_64_192_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-64-192 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_64_192_inv_rounds
(forkskinny_64_192_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-64-192.
*
* \param state Points to the ForkSkinny-64-192 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_64_192_forward_tk
(forkskinny_64_192_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-64-192.
*
* \param state Points to the ForkSkinny-64-192 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_64_192_reverse_tk
(forkskinny_64_192_state_t *state, unsigned rounds);
/**
* \brief Encrypts a block of plaintext with ForkSkinny-128-256.
*
* \param key 256-bit tweakey for ForkSkinny-128-256.
......
......@@ -74,6 +74,21 @@ extern "C" {
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_permute_tk_half(tk2, tk3) \
do { \
/* Permute the bottom half of the tweakey state in place, no swap */ \
uint32_t row2 = tk2; \
uint32_t row3 = tk3; \
row3 = (row3 << 16) | (row3 >> 16); \
tk2 = ((row2 >> 8) & 0x000000FFU) | \
((row2 << 16) & 0x00FF0000U) | \
( row3 & 0xFF00FF00U); \
tk3 = ((row2 >> 16) & 0x000000FFU) | \
(row2 & 0xFF000000U) | \
((row3 << 8) & 0x0000FF00U) | \
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk(tk) \
do { \
/* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \
......@@ -91,6 +106,21 @@ extern "C" {
((row1 << 8) & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk_half(tk0, tk1) \
do { \
/* Permute the top half of the tweakey state in place, no swap */ \
uint32_t row0 = tk0; \
uint32_t row1 = tk1; \
tk0 = ((row0 >> 16) & 0x000000FFU) | \
((row0 << 8) & 0x0000FF00U) | \
((row1 << 16) & 0x00FF0000U) | \
( row1 & 0xFF000000U); \
tk1 = ((row0 >> 16) & 0x0000FF00U) | \
((row0 << 16) & 0xFF000000U) | \
((row1 >> 16) & 0x000000FFU) | \
((row1 << 8) & 0x00FF0000U); \
} while (0)
/*
* Apply the SKINNY sbox. The original version from the specification is
* equivalent to:
......@@ -319,6 +349,61 @@ do { \
x = ((x << 1) & 0xEEEEU) | ((x >> 3) & 0x1111U); \
} while (0)
#define rows_to_columns_32(column0, column1, column2, column3, row0, row1, row2, row3) \
do { \
column0 = (row3 & 0xFF) << 24|(row2 & 0xFF) << 16|(row1 & 0xFF) << 8 | (row0 & 0xFF);\
column1 = (row3 & 0xFF00) << 16|(row2 & 0xFF00) << 8 |(row1 & 0xFF00) | (row0>>8 & 0xFF);\
column2 = (row3 & 0xFF0000) << 8 |(row2 & 0xFF0000) |(row1 & 0xFF0000) >> 8 | (row0>>16 & 0xFF);\
column3 = (row3 & 0xFF000000) |(row2 & 0xFF000000) >> 8 |(row1 & 0xFF000000) >> 16| (row0>>24 & 0xFF);\
} while(0)
#define columns_to_rows_32(row0, row1, row2, row3, column0, column1, column2, column3) rows_to_columns_32(row0, row1, row2, row3, column0, column1, column2, column3)
#define load_column_8(dest, src) \
do { \
dest[0] = (src[12]) << 24 | (src[8]) << 16 | (src[4]) << 8 | (src[0]); \
dest[1] = (src[13]) << 24 | (src[9]) << 16 | (src[5]) << 8 | (src[1]); \
dest[2] = (src[14]) << 24 | (src[10]) << 16 | (src[6]) << 8 | (src[2]); \
dest[3] = (src[15]) << 24 | (src[11]) << 16 | (src[7]) << 8 | (src[3]); \
} while(0)
#define store_column_8(dest, src) \
do { \
dest[0] = (uint8_t) (src[0]); dest[1] = (uint8_t) (src[1]); dest[2] = (uint8_t) (src[2]); dest[3] = (uint8_t) (src[3]); \
dest[4] = (uint8_t) (src[0]>>8); dest[5] = (uint8_t) (src[1]>>8); dest[6] = (uint8_t) (src[2]>>8); dest[7] = (uint8_t) (src[3]>>8); \
dest[8] = (uint8_t) (src[0]>>16);dest[9] = (uint8_t) (src[1]>>16);dest[10]= (uint8_t) (src[2]>>16);dest[11]= (uint8_t)(src[3]>>16); \
dest[12]= (uint8_t) (src[0]>>24);dest[13]= (uint8_t) (src[1]>>24);dest[14]= (uint8_t) (src[2]>>24);dest[15]= (uint8_t)(src[3]>>24); \
} while(0)
#define TK_to_column_256(columns, state) \
do { \
uint32_t TK0 = state->TK1[0] ^ state->TK2[0];\
uint32_t TK1 = state->TK1[1] ^ state->TK2[1]; \
uint32_t tk00 = TK0 & 0xFF; \
uint32_t tk01 = TK0 & 0xFF00;\
uint32_t tk02 = TK0 & 0xFF0000;\
uint32_t tk03 = TK0 & 0xFF000000;\
columns[0] = tk00 << 24 | (TK1 & 0xFF000000) >> 8 | tk00 << 8 | tk00; \
columns[1] = tk01 << 16 | (TK1 & 0xFF) << 16 | tk01 | tk01 >> 8; \
columns[2] = tk02 << 8 | (TK1 & 0xFF00) << 8 | tk02 >> 8 | tk02 >> 16; \
columns[3] = tk03 | (TK1 & 0xFF0000) | tk03 >> 16 | tk03 >> 24; \
} while(0)
#define TK_to_column_384(columns, state) \
do { \
uint32_t TK0 = state->TK1[0] ^ state->TK2[0] ^ state->TK3[0];\
uint32_t TK1 = state->TK1[1] ^ state->TK2[1] ^ state->TK3[1];\
uint32_t tk00 = TK0 & 0xFF; \
uint32_t tk01 = TK0 & 0xFF00;\
uint32_t tk02 = TK0 & 0xFF0000;\
uint32_t tk03 = TK0 & 0xFF000000;\
columns[0] = tk00 << 24 | (TK1 & 0xFF000000) >> 8 | tk00 << 8 | tk00; \
columns[1] = tk01 << 16 | (TK1 & 0xFF) << 16 | tk01 | tk01 >> 8; \
columns[2] = tk02 << 8 | (TK1 & 0xFF00) << 8 | tk02 >> 8 | tk02 >> 16; \
columns[3] = tk03 | (TK1 & 0xFF0000) | tk03 >> 16 | tk03 >> 24; \
} while(0)
/** @endcond */
#ifdef __cplusplus
......
......@@ -154,7 +154,7 @@ typedef void (*aead_xof_squeeze_t)
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
......@@ -166,7 +166,18 @@ typedef void (*aead_xof_squeeze_t)
* 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
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief The AEAD mode provides side-channel protection for the key.
*/
#define AEAD_FLAG_SC_PROTECT_KEY 0x0002
/**
* \brief The AEAD mode provides side-channel protection for all block
* operations.
*/
#define AEAD_FLAG_SC_PROTECT_ALL 0x0004
/**
* \brief Meta-information about an AEAD cipher.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,6 +23,8 @@
#ifndef LW_INTERNAL_FORKSKINNY_H
#define LW_INTERNAL_FORKSKINNY_H
#include "internal-util.h"
/**
* \file internal-forkskinny.h
* \brief ForkSkinny block cipher family.
......@@ -39,6 +41,172 @@ extern "C" {
#endif
/**
* \brief Number of rounds of ForkSkinny-128-256 before forking.
*/
#define FORKSKINNY_128_256_ROUNDS_BEFORE 21
/**
* \brief Number of rounds of ForkSkinny-128-256 after forking.
*/
#define FORKSKINNY_128_256_ROUNDS_AFTER 27
/**
* \brief State information for ForkSkinny-128-256.
*/
typedef struct
{
// uint32_t TK1[4]; /**< First part of the tweakey */
// uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_256_state_t;
typedef struct
{
/** Words of the full key schedule */
uint32_t row0[(FORKSKINNY_128_256_ROUNDS_BEFORE + 2*FORKSKINNY_128_256_ROUNDS_AFTER)];
uint32_t row1[(FORKSKINNY_128_256_ROUNDS_BEFORE + 2*FORKSKINNY_128_256_ROUNDS_AFTER)];
} forkskinny_128_256_tweakey_schedule_t;
/**
* \brief Number of rounds of ForkSkinny-128-384 before forking.
*/
#define FORKSKINNY_128_384_ROUNDS_BEFORE 25
/**
* \brief Number of rounds of ForkSkinny-128-384 after forking.
*/
#define FORKSKINNY_128_384_ROUNDS_AFTER 31
/**
* \brief State information for ForkSkinny-128-384.
*/
typedef struct
{
// uint32_t TK1[4]; /**< First part of the tweakey */
// uint32_t TK2[4]; /**< Second part of the tweakey */
// uint32_t TK3[4]; /**< Third part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_384_state_t;
typedef struct
{
/** Words of the full key schedule */
uint32_t row0[(FORKSKINNY_128_384_ROUNDS_BEFORE + 2*FORKSKINNY_128_384_ROUNDS_AFTER)];
uint32_t row1[(FORKSKINNY_128_384_ROUNDS_BEFORE + 2*FORKSKINNY_128_384_ROUNDS_AFTER)];
} forkskinny_128_384_tweakey_schedule_t;
/**
* \brief Number of rounds of ForkSkinny-64-192 before forking.
*/
#define FORKSKINNY_64_192_ROUNDS_BEFORE 17
/**
* \brief Number of rounds of ForkSkinny-64-192 after forking.
*/
#define FORKSKINNY_64_192_ROUNDS_AFTER 23
/**
* \brief State information for ForkSkinny-64-192.
*/
typedef struct
{
uint16_t TK1[4]; /**< First part of the tweakey */
uint16_t TK2[4]; /**< Second part of the tweakey */
uint16_t TK3[4]; /**< Third part of the tweakey */
uint16_t S[4]; /**< Current block state */
} forkskinny_64_192_state_t;
typedef struct
{
/** Words of the full key schedule */
uint16_t row0[(FORKSKINNY_64_192_ROUNDS_BEFORE + 2*FORKSKINNY_64_192_ROUNDS_AFTER)];
uint16_t row1[(FORKSKINNY_64_192_ROUNDS_BEFORE + 2*FORKSKINNY_64_192_ROUNDS_AFTER)];
} forkskinny_64_192_tweakey_schedule_t;
void forkskinny_128_256_init_tks(forkskinny_128_256_tweakey_schedule_t *tks, const unsigned char key[32], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-256.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_256_rounds
(forkskinny_128_256_state_t *state, forkskinny_128_256_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-256 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_256_inv_rounds
(forkskinny_128_256_state_t *state, forkskinny_128_256_tweakey_schedule_t *tks, unsigned first, unsigned last);
void forkskinny_128_384_init_tks(forkskinny_128_384_tweakey_schedule_t *tks, const unsigned char key[48], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-384.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_384_rounds
(forkskinny_128_384_state_t *state, forkskinny_128_384_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-384 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_384_inv_rounds
(forkskinny_128_384_state_t *state, forkskinny_128_384_tweakey_schedule_t *tks, unsigned first, unsigned last);
void forkskinny_64_192_init_tks(forkskinny_64_192_tweakey_schedule_t *tks, const unsigned char key[24], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-64-192.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*
* Note: The cells of each row are ordered in big-endian nibble order
* so it is simplest to manage the rows in big-endian byte order.
*/
void forkskinny_64_192_rounds
(forkskinny_64_192_state_t *state, forkskinny_64_192_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-64-192 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_64_192_inv_rounds
(forkskinny_64_192_state_t *state, forkskinny_64_192_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Encrypts a block of plaintext with ForkSkinny-128-256.
*
* \param key 256-bit tweakey for ForkSkinny-128-256.
......
......@@ -74,6 +74,21 @@ extern "C" {
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_permute_tk_half(tk2, tk3) \
do { \
/* Permute the bottom half of the tweakey state in place, no swap */ \
uint32_t row2 = tk2; \
uint32_t row3 = tk3; \
row3 = (row3 << 16) | (row3 >> 16); \
tk2 = ((row2 >> 8) & 0x000000FFU) | \
((row2 << 16) & 0x00FF0000U) | \
( row3 & 0xFF00FF00U); \
tk3 = ((row2 >> 16) & 0x000000FFU) | \
(row2 & 0xFF000000U) | \
((row3 << 8) & 0x0000FF00U) | \
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk(tk) \
do { \
/* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \
......@@ -91,6 +106,21 @@ extern "C" {
((row1 << 8) & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk_half(tk0, tk1) \
do { \
/* Permute the top half of the tweakey state in place, no swap */ \
uint32_t row0 = tk0; \
uint32_t row1 = tk1; \
tk0 = ((row0 >> 16) & 0x000000FFU) | \
((row0 << 8) & 0x0000FF00U) | \
((row1 << 16) & 0x00FF0000U) | \
( row1 & 0xFF000000U); \
tk1 = ((row0 >> 16) & 0x0000FF00U) | \
((row0 << 16) & 0xFF000000U) | \
((row1 >> 16) & 0x000000FFU) | \
((row1 << 8) & 0x00FF0000U); \
} while (0)
/*
* Apply the SKINNY sbox. The original version from the specification is
* equivalent to:
......
......@@ -154,7 +154,7 @@ typedef void (*aead_xof_squeeze_t)
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
......@@ -166,7 +166,18 @@ typedef void (*aead_xof_squeeze_t)
* 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
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief The AEAD mode provides side-channel protection for the key.
*/
#define AEAD_FLAG_SC_PROTECT_KEY 0x0002
/**
* \brief The AEAD mode provides side-channel protection for all block
* operations.
*/
#define AEAD_FLAG_SC_PROTECT_ALL 0x0004
/**
* \brief Meta-information about an AEAD cipher.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,6 +23,8 @@
#ifndef LW_INTERNAL_FORKSKINNY_H
#define LW_INTERNAL_FORKSKINNY_H
#include "internal-util.h"
/**
* \file internal-forkskinny.h
* \brief ForkSkinny block cipher family.
......@@ -39,6 +41,158 @@ extern "C" {
#endif
/**
* \brief State information for ForkSkinny-128-256.
*/
typedef struct
{
uint32_t TK1[4]; /**< First part of the tweakey */
uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_256_state_t;
/**
* \brief State information for ForkSkinny-128-384.
*/
typedef struct
{
uint32_t TK1[4]; /**< First part of the tweakey */
uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t TK3[4]; /**< Third part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_384_state_t;
/**
* \brief State information for ForkSkinny-64-192.
*/
typedef struct
{
uint16_t TK1[4]; /**< First part of the tweakey */
uint16_t TK2[4]; /**< Second part of the tweakey */
uint16_t TK3[4]; /**< Third part of the tweakey */
uint16_t S[4]; /**< Current block state */
} forkskinny_64_192_state_t;
/**
* \brief Applies several rounds of ForkSkinny-128-256.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_256_rounds
(forkskinny_128_256_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-256 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_256_inv_rounds
(forkskinny_128_256_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-128-256.
*
* \param state Points to the ForkSkinny-128-256 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_128_256_forward_tk
(forkskinny_128_256_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-128-256.
*
* \param state Points to the ForkSkinny-128-256 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_128_256_reverse_tk
(forkskinny_128_256_state_t *state, unsigned rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-384.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_384_rounds
(forkskinny_128_384_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-384 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_384_inv_rounds
(forkskinny_128_384_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-128-384.
*
* \param state Points to the ForkSkinny-128-384 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_128_384_forward_tk
(forkskinny_128_384_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-128-384.
*
* \param state Points to the ForkSkinny-128-384 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_128_384_reverse_tk
(forkskinny_128_384_state_t *state, unsigned rounds);
/**
* \brief Applies several rounds of ForkSkinny-64-192.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*
* Note: The cells of each row are ordered in big-endian nibble order
* so it is simplest to manage the rows in big-endian byte order.
*/
void forkskinny_64_192_rounds
(forkskinny_64_192_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-64-192 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_64_192_inv_rounds
(forkskinny_64_192_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-64-192.
*
* \param state Points to the ForkSkinny-64-192 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_64_192_forward_tk
(forkskinny_64_192_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-64-192.
*
* \param state Points to the ForkSkinny-64-192 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_64_192_reverse_tk
(forkskinny_64_192_state_t *state, unsigned rounds);
/**
* \brief Encrypts a block of plaintext with ForkSkinny-128-256.
*
* \param key 256-bit tweakey for ForkSkinny-128-256.
......
......@@ -74,6 +74,21 @@ extern "C" {
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_permute_tk_half(tk2, tk3) \
do { \
/* Permute the bottom half of the tweakey state in place, no swap */ \
uint32_t row2 = tk2; \
uint32_t row3 = tk3; \
row3 = (row3 << 16) | (row3 >> 16); \
tk2 = ((row2 >> 8) & 0x000000FFU) | \
((row2 << 16) & 0x00FF0000U) | \
( row3 & 0xFF00FF00U); \
tk3 = ((row2 >> 16) & 0x000000FFU) | \
(row2 & 0xFF000000U) | \
((row3 << 8) & 0x0000FF00U) | \
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk(tk) \
do { \
/* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \
......@@ -91,6 +106,21 @@ extern "C" {
((row1 << 8) & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk_half(tk0, tk1) \
do { \
/* Permute the top half of the tweakey state in place, no swap */ \
uint32_t row0 = tk0; \
uint32_t row1 = tk1; \
tk0 = ((row0 >> 16) & 0x000000FFU) | \
((row0 << 8) & 0x0000FF00U) | \
((row1 << 16) & 0x00FF0000U) | \
( row1 & 0xFF000000U); \
tk1 = ((row0 >> 16) & 0x0000FF00U) | \
((row0 << 16) & 0xFF000000U) | \
((row1 >> 16) & 0x000000FFU) | \
((row1 << 8) & 0x00FF0000U); \
} while (0)
/*
* Apply the SKINNY sbox. The original version from the specification is
* equivalent to:
......@@ -319,6 +349,61 @@ do { \
x = ((x << 1) & 0xEEEEU) | ((x >> 3) & 0x1111U); \
} while (0)
#define rows_to_columns_32(column0, column1, column2, column3, row0, row1, row2, row3) \
do { \
column0 = (row3 & 0xFF) << 24|(row2 & 0xFF) << 16|(row1 & 0xFF) << 8 | (row0 & 0xFF);\
column1 = (row3 & 0xFF00) << 16|(row2 & 0xFF00) << 8 |(row1 & 0xFF00) | (row0>>8 & 0xFF);\
column2 = (row3 & 0xFF0000) << 8 |(row2 & 0xFF0000) |(row1 & 0xFF0000) >> 8 | (row0>>16 & 0xFF);\
column3 = (row3 & 0xFF000000) |(row2 & 0xFF000000) >> 8 |(row1 & 0xFF000000) >> 16| (row0>>24 & 0xFF);\
} while(0)
#define columns_to_rows_32(row0, row1, row2, row3, column0, column1, column2, column3) rows_to_columns_32(row0, row1, row2, row3, column0, column1, column2, column3)
#define load_column_8(dest, src) \
do { \
dest[0] = (src[12]) << 24 | (src[8]) << 16 | (src[4]) << 8 | (src[0]); \
dest[1] = (src[13]) << 24 | (src[9]) << 16 | (src[5]) << 8 | (src[1]); \
dest[2] = (src[14]) << 24 | (src[10]) << 16 | (src[6]) << 8 | (src[2]); \
dest[3] = (src[15]) << 24 | (src[11]) << 16 | (src[7]) << 8 | (src[3]); \
} while(0)
#define store_column_8(dest, src) \
do { \
dest[0] = (uint8_t) (src[0]); dest[1] = (uint8_t) (src[1]); dest[2] = (uint8_t) (src[2]); dest[3] = (uint8_t) (src[3]); \
dest[4] = (uint8_t) (src[0]>>8); dest[5] = (uint8_t) (src[1]>>8); dest[6] = (uint8_t) (src[2]>>8); dest[7] = (uint8_t) (src[3]>>8); \
dest[8] = (uint8_t) (src[0]>>16);dest[9] = (uint8_t) (src[1]>>16);dest[10]= (uint8_t) (src[2]>>16);dest[11]= (uint8_t)(src[3]>>16); \
dest[12]= (uint8_t) (src[0]>>24);dest[13]= (uint8_t) (src[1]>>24);dest[14]= (uint8_t) (src[2]>>24);dest[15]= (uint8_t)(src[3]>>24); \
} while(0)
#define TK_to_column_256(columns, state) \
do { \
uint32_t TK0 = state->TK1[0] ^ state->TK2[0];\
uint32_t TK1 = state->TK1[1] ^ state->TK2[1]; \
uint32_t tk00 = TK0 & 0xFF; \
uint32_t tk01 = TK0 & 0xFF00;\
uint32_t tk02 = TK0 & 0xFF0000;\
uint32_t tk03 = TK0 & 0xFF000000;\
columns[0] = tk00 << 24 | (TK1 & 0xFF000000) >> 8 | tk00 << 8 | tk00; \
columns[1] = tk01 << 16 | (TK1 & 0xFF) << 16 | tk01 | tk01 >> 8; \
columns[2] = tk02 << 8 | (TK1 & 0xFF00) << 8 | tk02 >> 8 | tk02 >> 16; \
columns[3] = tk03 | (TK1 & 0xFF0000) | tk03 >> 16 | tk03 >> 24; \
} while(0)
#define TK_to_column_384(columns, state) \
do { \
uint32_t TK0 = state->TK1[0] ^ state->TK2[0] ^ state->TK3[0];\
uint32_t TK1 = state->TK1[1] ^ state->TK2[1] ^ state->TK3[1];\
uint32_t tk00 = TK0 & 0xFF; \
uint32_t tk01 = TK0 & 0xFF00;\
uint32_t tk02 = TK0 & 0xFF0000;\
uint32_t tk03 = TK0 & 0xFF000000;\
columns[0] = tk00 << 24 | (TK1 & 0xFF000000) >> 8 | tk00 << 8 | tk00; \
columns[1] = tk01 << 16 | (TK1 & 0xFF) << 16 | tk01 | tk01 >> 8; \
columns[2] = tk02 << 8 | (TK1 & 0xFF00) << 8 | tk02 >> 8 | tk02 >> 16; \
columns[3] = tk03 | (TK1 & 0xFF0000) | tk03 >> 16 | tk03 >> 24; \
} while(0)
/** @endcond */
#ifdef __cplusplus
......
......@@ -154,7 +154,7 @@ typedef void (*aead_xof_squeeze_t)
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
......@@ -166,7 +166,18 @@ typedef void (*aead_xof_squeeze_t)
* 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
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief The AEAD mode provides side-channel protection for the key.
*/
#define AEAD_FLAG_SC_PROTECT_KEY 0x0002
/**
* \brief The AEAD mode provides side-channel protection for all block
* operations.
*/
#define AEAD_FLAG_SC_PROTECT_ALL 0x0004
/**
* \brief Meta-information about an AEAD cipher.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,6 +23,8 @@
#ifndef LW_INTERNAL_FORKSKINNY_H
#define LW_INTERNAL_FORKSKINNY_H
#include "internal-util.h"
/**
* \file internal-forkskinny.h
* \brief ForkSkinny block cipher family.
......@@ -39,6 +41,172 @@ extern "C" {
#endif
/**
* \brief Number of rounds of ForkSkinny-128-256 before forking.
*/
#define FORKSKINNY_128_256_ROUNDS_BEFORE 21
/**
* \brief Number of rounds of ForkSkinny-128-256 after forking.
*/
#define FORKSKINNY_128_256_ROUNDS_AFTER 27
/**
* \brief State information for ForkSkinny-128-256.
*/
typedef struct
{
// uint32_t TK1[4]; /**< First part of the tweakey */
// uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_256_state_t;
typedef struct
{
/** Words of the full key schedule */
uint32_t row0[(FORKSKINNY_128_256_ROUNDS_BEFORE + 2*FORKSKINNY_128_256_ROUNDS_AFTER)];
uint32_t row1[(FORKSKINNY_128_256_ROUNDS_BEFORE + 2*FORKSKINNY_128_256_ROUNDS_AFTER)];
} forkskinny_128_256_tweakey_schedule_t;
/**
* \brief Number of rounds of ForkSkinny-128-384 before forking.
*/
#define FORKSKINNY_128_384_ROUNDS_BEFORE 25
/**
* \brief Number of rounds of ForkSkinny-128-384 after forking.
*/
#define FORKSKINNY_128_384_ROUNDS_AFTER 31
/**
* \brief State information for ForkSkinny-128-384.
*/
typedef struct
{
// uint32_t TK1[4]; /**< First part of the tweakey */
// uint32_t TK2[4]; /**< Second part of the tweakey */
// uint32_t TK3[4]; /**< Third part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_384_state_t;
typedef struct
{
/** Words of the full key schedule */
uint32_t row0[(FORKSKINNY_128_384_ROUNDS_BEFORE + 2*FORKSKINNY_128_384_ROUNDS_AFTER)];
uint32_t row1[(FORKSKINNY_128_384_ROUNDS_BEFORE + 2*FORKSKINNY_128_384_ROUNDS_AFTER)];
} forkskinny_128_384_tweakey_schedule_t;
/**
* \brief Number of rounds of ForkSkinny-64-192 before forking.
*/
#define FORKSKINNY_64_192_ROUNDS_BEFORE 17
/**
* \brief Number of rounds of ForkSkinny-64-192 after forking.
*/
#define FORKSKINNY_64_192_ROUNDS_AFTER 23
/**
* \brief State information for ForkSkinny-64-192.
*/
typedef struct
{
uint16_t TK1[4]; /**< First part of the tweakey */
uint16_t TK2[4]; /**< Second part of the tweakey */
uint16_t TK3[4]; /**< Third part of the tweakey */
uint16_t S[4]; /**< Current block state */
} forkskinny_64_192_state_t;
typedef struct
{
/** Words of the full key schedule */
uint16_t row0[(FORKSKINNY_64_192_ROUNDS_BEFORE + 2*FORKSKINNY_64_192_ROUNDS_AFTER)];
uint16_t row1[(FORKSKINNY_64_192_ROUNDS_BEFORE + 2*FORKSKINNY_64_192_ROUNDS_AFTER)];
} forkskinny_64_192_tweakey_schedule_t;
void forkskinny_128_256_init_tks(forkskinny_128_256_tweakey_schedule_t *tks, const unsigned char key[32], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-256.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_256_rounds
(forkskinny_128_256_state_t *state, forkskinny_128_256_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-256 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_256_inv_rounds
(forkskinny_128_256_state_t *state, forkskinny_128_256_tweakey_schedule_t *tks, unsigned first, unsigned last);
void forkskinny_128_384_init_tks(forkskinny_128_384_tweakey_schedule_t *tks, const unsigned char key[48], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-384.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_384_rounds
(forkskinny_128_384_state_t *state, forkskinny_128_384_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-384 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_384_inv_rounds
(forkskinny_128_384_state_t *state, forkskinny_128_384_tweakey_schedule_t *tks, unsigned first, unsigned last);
void forkskinny_64_192_init_tks(forkskinny_64_192_tweakey_schedule_t *tks, const unsigned char key[24], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-64-192.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*
* Note: The cells of each row are ordered in big-endian nibble order
* so it is simplest to manage the rows in big-endian byte order.
*/
void forkskinny_64_192_rounds
(forkskinny_64_192_state_t *state, forkskinny_64_192_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-64-192 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_64_192_inv_rounds
(forkskinny_64_192_state_t *state, forkskinny_64_192_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Encrypts a block of plaintext with ForkSkinny-128-256.
*
* \param key 256-bit tweakey for ForkSkinny-128-256.
......
......@@ -74,6 +74,21 @@ extern "C" {
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_permute_tk_half(tk2, tk3) \
do { \
/* Permute the bottom half of the tweakey state in place, no swap */ \
uint32_t row2 = tk2; \
uint32_t row3 = tk3; \
row3 = (row3 << 16) | (row3 >> 16); \
tk2 = ((row2 >> 8) & 0x000000FFU) | \
((row2 << 16) & 0x00FF0000U) | \
( row3 & 0xFF00FF00U); \
tk3 = ((row2 >> 16) & 0x000000FFU) | \
(row2 & 0xFF000000U) | \
((row3 << 8) & 0x0000FF00U) | \
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk(tk) \
do { \
/* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \
......@@ -91,6 +106,21 @@ extern "C" {
((row1 << 8) & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk_half(tk0, tk1) \
do { \
/* Permute the top half of the tweakey state in place, no swap */ \
uint32_t row0 = tk0; \
uint32_t row1 = tk1; \
tk0 = ((row0 >> 16) & 0x000000FFU) | \
((row0 << 8) & 0x0000FF00U) | \
((row1 << 16) & 0x00FF0000U) | \
( row1 & 0xFF000000U); \
tk1 = ((row0 >> 16) & 0x0000FF00U) | \
((row0 << 16) & 0xFF000000U) | \
((row1 >> 16) & 0x000000FFU) | \
((row1 << 8) & 0x00FF0000U); \
} while (0)
/*
* Apply the SKINNY sbox. The original version from the specification is
* equivalent to:
......
......@@ -154,7 +154,7 @@ typedef void (*aead_xof_squeeze_t)
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
......@@ -166,7 +166,18 @@ typedef void (*aead_xof_squeeze_t)
* 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
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief The AEAD mode provides side-channel protection for the key.
*/
#define AEAD_FLAG_SC_PROTECT_KEY 0x0002
/**
* \brief The AEAD mode provides side-channel protection for all block
* operations.
*/
#define AEAD_FLAG_SC_PROTECT_ALL 0x0004
/**
* \brief Meta-information about an AEAD cipher.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,6 +23,8 @@
#ifndef LW_INTERNAL_FORKSKINNY_H
#define LW_INTERNAL_FORKSKINNY_H
#include "internal-util.h"
/**
* \file internal-forkskinny.h
* \brief ForkSkinny block cipher family.
......@@ -39,6 +41,158 @@ extern "C" {
#endif
/**
* \brief State information for ForkSkinny-128-256.
*/
typedef struct
{
uint32_t TK1[4]; /**< First part of the tweakey */
uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_256_state_t;
/**
* \brief State information for ForkSkinny-128-384.
*/
typedef struct
{
uint32_t TK1[4]; /**< First part of the tweakey */
uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t TK3[4]; /**< Third part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_384_state_t;
/**
* \brief State information for ForkSkinny-64-192.
*/
typedef struct
{
uint16_t TK1[4]; /**< First part of the tweakey */
uint16_t TK2[4]; /**< Second part of the tweakey */
uint16_t TK3[4]; /**< Third part of the tweakey */
uint16_t S[4]; /**< Current block state */
} forkskinny_64_192_state_t;
/**
* \brief Applies several rounds of ForkSkinny-128-256.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_256_rounds
(forkskinny_128_256_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-256 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_256_inv_rounds
(forkskinny_128_256_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-128-256.
*
* \param state Points to the ForkSkinny-128-256 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_128_256_forward_tk
(forkskinny_128_256_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-128-256.
*
* \param state Points to the ForkSkinny-128-256 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_128_256_reverse_tk
(forkskinny_128_256_state_t *state, unsigned rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-384.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_384_rounds
(forkskinny_128_384_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-384 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_384_inv_rounds
(forkskinny_128_384_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-128-384.
*
* \param state Points to the ForkSkinny-128-384 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_128_384_forward_tk
(forkskinny_128_384_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-128-384.
*
* \param state Points to the ForkSkinny-128-384 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_128_384_reverse_tk
(forkskinny_128_384_state_t *state, unsigned rounds);
/**
* \brief Applies several rounds of ForkSkinny-64-192.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*
* Note: The cells of each row are ordered in big-endian nibble order
* so it is simplest to manage the rows in big-endian byte order.
*/
void forkskinny_64_192_rounds
(forkskinny_64_192_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-64-192 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_64_192_inv_rounds
(forkskinny_64_192_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-64-192.
*
* \param state Points to the ForkSkinny-64-192 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_64_192_forward_tk
(forkskinny_64_192_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-64-192.
*
* \param state Points to the ForkSkinny-64-192 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_64_192_reverse_tk
(forkskinny_64_192_state_t *state, unsigned rounds);
/**
* \brief Encrypts a block of plaintext with ForkSkinny-128-256.
*
* \param key 256-bit tweakey for ForkSkinny-128-256.
......
......@@ -74,6 +74,21 @@ extern "C" {
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_permute_tk_half(tk2, tk3) \
do { \
/* Permute the bottom half of the tweakey state in place, no swap */ \
uint32_t row2 = tk2; \
uint32_t row3 = tk3; \
row3 = (row3 << 16) | (row3 >> 16); \
tk2 = ((row2 >> 8) & 0x000000FFU) | \
((row2 << 16) & 0x00FF0000U) | \
( row3 & 0xFF00FF00U); \
tk3 = ((row2 >> 16) & 0x000000FFU) | \
(row2 & 0xFF000000U) | \
((row3 << 8) & 0x0000FF00U) | \
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk(tk) \
do { \
/* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \
......@@ -91,6 +106,21 @@ extern "C" {
((row1 << 8) & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk_half(tk0, tk1) \
do { \
/* Permute the top half of the tweakey state in place, no swap */ \
uint32_t row0 = tk0; \
uint32_t row1 = tk1; \
tk0 = ((row0 >> 16) & 0x000000FFU) | \
((row0 << 8) & 0x0000FF00U) | \
((row1 << 16) & 0x00FF0000U) | \
( row1 & 0xFF000000U); \
tk1 = ((row0 >> 16) & 0x0000FF00U) | \
((row0 << 16) & 0xFF000000U) | \
((row1 >> 16) & 0x000000FFU) | \
((row1 << 8) & 0x00FF0000U); \
} while (0)
/*
* Apply the SKINNY sbox. The original version from the specification is
* equivalent to:
......@@ -319,6 +349,61 @@ do { \
x = ((x << 1) & 0xEEEEU) | ((x >> 3) & 0x1111U); \
} while (0)
#define rows_to_columns_32(column0, column1, column2, column3, row0, row1, row2, row3) \
do { \
column0 = (row3 & 0xFF) << 24|(row2 & 0xFF) << 16|(row1 & 0xFF) << 8 | (row0 & 0xFF);\
column1 = (row3 & 0xFF00) << 16|(row2 & 0xFF00) << 8 |(row1 & 0xFF00) | (row0>>8 & 0xFF);\
column2 = (row3 & 0xFF0000) << 8 |(row2 & 0xFF0000) |(row1 & 0xFF0000) >> 8 | (row0>>16 & 0xFF);\
column3 = (row3 & 0xFF000000) |(row2 & 0xFF000000) >> 8 |(row1 & 0xFF000000) >> 16| (row0>>24 & 0xFF);\
} while(0)
#define columns_to_rows_32(row0, row1, row2, row3, column0, column1, column2, column3) rows_to_columns_32(row0, row1, row2, row3, column0, column1, column2, column3)
#define load_column_8(dest, src) \
do { \
dest[0] = (src[12]) << 24 | (src[8]) << 16 | (src[4]) << 8 | (src[0]); \
dest[1] = (src[13]) << 24 | (src[9]) << 16 | (src[5]) << 8 | (src[1]); \
dest[2] = (src[14]) << 24 | (src[10]) << 16 | (src[6]) << 8 | (src[2]); \
dest[3] = (src[15]) << 24 | (src[11]) << 16 | (src[7]) << 8 | (src[3]); \
} while(0)
#define store_column_8(dest, src) \
do { \
dest[0] = (uint8_t) (src[0]); dest[1] = (uint8_t) (src[1]); dest[2] = (uint8_t) (src[2]); dest[3] = (uint8_t) (src[3]); \
dest[4] = (uint8_t) (src[0]>>8); dest[5] = (uint8_t) (src[1]>>8); dest[6] = (uint8_t) (src[2]>>8); dest[7] = (uint8_t) (src[3]>>8); \
dest[8] = (uint8_t) (src[0]>>16);dest[9] = (uint8_t) (src[1]>>16);dest[10]= (uint8_t) (src[2]>>16);dest[11]= (uint8_t)(src[3]>>16); \
dest[12]= (uint8_t) (src[0]>>24);dest[13]= (uint8_t) (src[1]>>24);dest[14]= (uint8_t) (src[2]>>24);dest[15]= (uint8_t)(src[3]>>24); \
} while(0)
#define TK_to_column_256(columns, state) \
do { \
uint32_t TK0 = state->TK1[0] ^ state->TK2[0];\
uint32_t TK1 = state->TK1[1] ^ state->TK2[1]; \
uint32_t tk00 = TK0 & 0xFF; \
uint32_t tk01 = TK0 & 0xFF00;\
uint32_t tk02 = TK0 & 0xFF0000;\
uint32_t tk03 = TK0 & 0xFF000000;\
columns[0] = tk00 << 24 | (TK1 & 0xFF000000) >> 8 | tk00 << 8 | tk00; \
columns[1] = tk01 << 16 | (TK1 & 0xFF) << 16 | tk01 | tk01 >> 8; \
columns[2] = tk02 << 8 | (TK1 & 0xFF00) << 8 | tk02 >> 8 | tk02 >> 16; \
columns[3] = tk03 | (TK1 & 0xFF0000) | tk03 >> 16 | tk03 >> 24; \
} while(0)
#define TK_to_column_384(columns, state) \
do { \
uint32_t TK0 = state->TK1[0] ^ state->TK2[0] ^ state->TK3[0];\
uint32_t TK1 = state->TK1[1] ^ state->TK2[1] ^ state->TK3[1];\
uint32_t tk00 = TK0 & 0xFF; \
uint32_t tk01 = TK0 & 0xFF00;\
uint32_t tk02 = TK0 & 0xFF0000;\
uint32_t tk03 = TK0 & 0xFF000000;\
columns[0] = tk00 << 24 | (TK1 & 0xFF000000) >> 8 | tk00 << 8 | tk00; \
columns[1] = tk01 << 16 | (TK1 & 0xFF) << 16 | tk01 | tk01 >> 8; \
columns[2] = tk02 << 8 | (TK1 & 0xFF00) << 8 | tk02 >> 8 | tk02 >> 16; \
columns[3] = tk03 | (TK1 & 0xFF0000) | tk03 >> 16 | tk03 >> 24; \
} while(0)
/** @endcond */
#ifdef __cplusplus
......
......@@ -154,7 +154,7 @@ typedef void (*aead_xof_squeeze_t)
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
......@@ -166,7 +166,18 @@ typedef void (*aead_xof_squeeze_t)
* 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
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief The AEAD mode provides side-channel protection for the key.
*/
#define AEAD_FLAG_SC_PROTECT_KEY 0x0002
/**
* \brief The AEAD mode provides side-channel protection for all block
* operations.
*/
#define AEAD_FLAG_SC_PROTECT_ALL 0x0004
/**
* \brief Meta-information about an AEAD cipher.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,6 +23,8 @@
#ifndef LW_INTERNAL_FORKSKINNY_H
#define LW_INTERNAL_FORKSKINNY_H
#include "internal-util.h"
/**
* \file internal-forkskinny.h
* \brief ForkSkinny block cipher family.
......@@ -39,6 +41,172 @@ extern "C" {
#endif
/**
* \brief Number of rounds of ForkSkinny-128-256 before forking.
*/
#define FORKSKINNY_128_256_ROUNDS_BEFORE 21
/**
* \brief Number of rounds of ForkSkinny-128-256 after forking.
*/
#define FORKSKINNY_128_256_ROUNDS_AFTER 27
/**
* \brief State information for ForkSkinny-128-256.
*/
typedef struct
{
// uint32_t TK1[4]; /**< First part of the tweakey */
// uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_256_state_t;
typedef struct
{
/** Words of the full key schedule */
uint32_t row0[(FORKSKINNY_128_256_ROUNDS_BEFORE + 2*FORKSKINNY_128_256_ROUNDS_AFTER)];
uint32_t row1[(FORKSKINNY_128_256_ROUNDS_BEFORE + 2*FORKSKINNY_128_256_ROUNDS_AFTER)];
} forkskinny_128_256_tweakey_schedule_t;
/**
* \brief Number of rounds of ForkSkinny-128-384 before forking.
*/
#define FORKSKINNY_128_384_ROUNDS_BEFORE 25
/**
* \brief Number of rounds of ForkSkinny-128-384 after forking.
*/
#define FORKSKINNY_128_384_ROUNDS_AFTER 31
/**
* \brief State information for ForkSkinny-128-384.
*/
typedef struct
{
// uint32_t TK1[4]; /**< First part of the tweakey */
// uint32_t TK2[4]; /**< Second part of the tweakey */
// uint32_t TK3[4]; /**< Third part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_384_state_t;
typedef struct
{
/** Words of the full key schedule */
uint32_t row0[(FORKSKINNY_128_384_ROUNDS_BEFORE + 2*FORKSKINNY_128_384_ROUNDS_AFTER)];
uint32_t row1[(FORKSKINNY_128_384_ROUNDS_BEFORE + 2*FORKSKINNY_128_384_ROUNDS_AFTER)];
} forkskinny_128_384_tweakey_schedule_t;
/**
* \brief Number of rounds of ForkSkinny-64-192 before forking.
*/
#define FORKSKINNY_64_192_ROUNDS_BEFORE 17
/**
* \brief Number of rounds of ForkSkinny-64-192 after forking.
*/
#define FORKSKINNY_64_192_ROUNDS_AFTER 23
/**
* \brief State information for ForkSkinny-64-192.
*/
typedef struct
{
uint16_t TK1[4]; /**< First part of the tweakey */
uint16_t TK2[4]; /**< Second part of the tweakey */
uint16_t TK3[4]; /**< Third part of the tweakey */
uint16_t S[4]; /**< Current block state */
} forkskinny_64_192_state_t;
typedef struct
{
/** Words of the full key schedule */
uint16_t row0[(FORKSKINNY_64_192_ROUNDS_BEFORE + 2*FORKSKINNY_64_192_ROUNDS_AFTER)];
uint16_t row1[(FORKSKINNY_64_192_ROUNDS_BEFORE + 2*FORKSKINNY_64_192_ROUNDS_AFTER)];
} forkskinny_64_192_tweakey_schedule_t;
void forkskinny_128_256_init_tks(forkskinny_128_256_tweakey_schedule_t *tks, const unsigned char key[32], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-256.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_256_rounds
(forkskinny_128_256_state_t *state, forkskinny_128_256_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-256 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_256_inv_rounds
(forkskinny_128_256_state_t *state, forkskinny_128_256_tweakey_schedule_t *tks, unsigned first, unsigned last);
void forkskinny_128_384_init_tks(forkskinny_128_384_tweakey_schedule_t *tks, const unsigned char key[48], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-384.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_384_rounds
(forkskinny_128_384_state_t *state, forkskinny_128_384_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-384 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_384_inv_rounds
(forkskinny_128_384_state_t *state, forkskinny_128_384_tweakey_schedule_t *tks, unsigned first, unsigned last);
void forkskinny_64_192_init_tks(forkskinny_64_192_tweakey_schedule_t *tks, const unsigned char key[24], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-64-192.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*
* Note: The cells of each row are ordered in big-endian nibble order
* so it is simplest to manage the rows in big-endian byte order.
*/
void forkskinny_64_192_rounds
(forkskinny_64_192_state_t *state, forkskinny_64_192_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-64-192 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_64_192_inv_rounds
(forkskinny_64_192_state_t *state, forkskinny_64_192_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Encrypts a block of plaintext with ForkSkinny-128-256.
*
* \param key 256-bit tweakey for ForkSkinny-128-256.
......
......@@ -74,6 +74,21 @@ extern "C" {
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_permute_tk_half(tk2, tk3) \
do { \
/* Permute the bottom half of the tweakey state in place, no swap */ \
uint32_t row2 = tk2; \
uint32_t row3 = tk3; \
row3 = (row3 << 16) | (row3 >> 16); \
tk2 = ((row2 >> 8) & 0x000000FFU) | \
((row2 << 16) & 0x00FF0000U) | \
( row3 & 0xFF00FF00U); \
tk3 = ((row2 >> 16) & 0x000000FFU) | \
(row2 & 0xFF000000U) | \
((row3 << 8) & 0x0000FF00U) | \
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk(tk) \
do { \
/* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \
......@@ -91,6 +106,21 @@ extern "C" {
((row1 << 8) & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk_half(tk0, tk1) \
do { \
/* Permute the top half of the tweakey state in place, no swap */ \
uint32_t row0 = tk0; \
uint32_t row1 = tk1; \
tk0 = ((row0 >> 16) & 0x000000FFU) | \
((row0 << 8) & 0x0000FF00U) | \
((row1 << 16) & 0x00FF0000U) | \
( row1 & 0xFF000000U); \
tk1 = ((row0 >> 16) & 0x0000FF00U) | \
((row0 << 16) & 0xFF000000U) | \
((row1 >> 16) & 0x000000FFU) | \
((row1 << 8) & 0x00FF0000U); \
} while (0)
/*
* Apply the SKINNY sbox. The original version from the specification is
* equivalent to:
......
......@@ -154,7 +154,7 @@ typedef void (*aead_xof_squeeze_t)
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
......@@ -166,7 +166,18 @@ typedef void (*aead_xof_squeeze_t)
* 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
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief The AEAD mode provides side-channel protection for the key.
*/
#define AEAD_FLAG_SC_PROTECT_KEY 0x0002
/**
* \brief The AEAD mode provides side-channel protection for all block
* operations.
*/
#define AEAD_FLAG_SC_PROTECT_ALL 0x0004
/**
* \brief Meta-information about an AEAD cipher.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,6 +23,8 @@
#ifndef LW_INTERNAL_FORKSKINNY_H
#define LW_INTERNAL_FORKSKINNY_H
#include "internal-util.h"
/**
* \file internal-forkskinny.h
* \brief ForkSkinny block cipher family.
......@@ -39,6 +41,158 @@ extern "C" {
#endif
/**
* \brief State information for ForkSkinny-128-256.
*/
typedef struct
{
uint32_t TK1[4]; /**< First part of the tweakey */
uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_256_state_t;
/**
* \brief State information for ForkSkinny-128-384.
*/
typedef struct
{
uint32_t TK1[4]; /**< First part of the tweakey */
uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t TK3[4]; /**< Third part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_384_state_t;
/**
* \brief State information for ForkSkinny-64-192.
*/
typedef struct
{
uint16_t TK1[4]; /**< First part of the tweakey */
uint16_t TK2[4]; /**< Second part of the tweakey */
uint16_t TK3[4]; /**< Third part of the tweakey */
uint16_t S[4]; /**< Current block state */
} forkskinny_64_192_state_t;
/**
* \brief Applies several rounds of ForkSkinny-128-256.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_256_rounds
(forkskinny_128_256_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-256 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_256_inv_rounds
(forkskinny_128_256_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-128-256.
*
* \param state Points to the ForkSkinny-128-256 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_128_256_forward_tk
(forkskinny_128_256_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-128-256.
*
* \param state Points to the ForkSkinny-128-256 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_128_256_reverse_tk
(forkskinny_128_256_state_t *state, unsigned rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-384.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_384_rounds
(forkskinny_128_384_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-384 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_384_inv_rounds
(forkskinny_128_384_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-128-384.
*
* \param state Points to the ForkSkinny-128-384 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_128_384_forward_tk
(forkskinny_128_384_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-128-384.
*
* \param state Points to the ForkSkinny-128-384 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_128_384_reverse_tk
(forkskinny_128_384_state_t *state, unsigned rounds);
/**
* \brief Applies several rounds of ForkSkinny-64-192.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*
* Note: The cells of each row are ordered in big-endian nibble order
* so it is simplest to manage the rows in big-endian byte order.
*/
void forkskinny_64_192_rounds
(forkskinny_64_192_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-64-192 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_64_192_inv_rounds
(forkskinny_64_192_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-64-192.
*
* \param state Points to the ForkSkinny-64-192 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_64_192_forward_tk
(forkskinny_64_192_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-64-192.
*
* \param state Points to the ForkSkinny-64-192 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_64_192_reverse_tk
(forkskinny_64_192_state_t *state, unsigned rounds);
/**
* \brief Encrypts a block of plaintext with ForkSkinny-128-256.
*
* \param key 256-bit tweakey for ForkSkinny-128-256.
......
......@@ -74,6 +74,21 @@ extern "C" {
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_permute_tk_half(tk2, tk3) \
do { \
/* Permute the bottom half of the tweakey state in place, no swap */ \
uint32_t row2 = tk2; \
uint32_t row3 = tk3; \
row3 = (row3 << 16) | (row3 >> 16); \
tk2 = ((row2 >> 8) & 0x000000FFU) | \
((row2 << 16) & 0x00FF0000U) | \
( row3 & 0xFF00FF00U); \
tk3 = ((row2 >> 16) & 0x000000FFU) | \
(row2 & 0xFF000000U) | \
((row3 << 8) & 0x0000FF00U) | \
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk(tk) \
do { \
/* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \
......@@ -91,6 +106,21 @@ extern "C" {
((row1 << 8) & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk_half(tk0, tk1) \
do { \
/* Permute the top half of the tweakey state in place, no swap */ \
uint32_t row0 = tk0; \
uint32_t row1 = tk1; \
tk0 = ((row0 >> 16) & 0x000000FFU) | \
((row0 << 8) & 0x0000FF00U) | \
((row1 << 16) & 0x00FF0000U) | \
( row1 & 0xFF000000U); \
tk1 = ((row0 >> 16) & 0x0000FF00U) | \
((row0 << 16) & 0xFF000000U) | \
((row1 >> 16) & 0x000000FFU) | \
((row1 << 8) & 0x00FF0000U); \
} while (0)
/*
* Apply the SKINNY sbox. The original version from the specification is
* equivalent to:
......@@ -319,6 +349,61 @@ do { \
x = ((x << 1) & 0xEEEEU) | ((x >> 3) & 0x1111U); \
} while (0)
#define rows_to_columns_32(column0, column1, column2, column3, row0, row1, row2, row3) \
do { \
column0 = (row3 & 0xFF) << 24|(row2 & 0xFF) << 16|(row1 & 0xFF) << 8 | (row0 & 0xFF);\
column1 = (row3 & 0xFF00) << 16|(row2 & 0xFF00) << 8 |(row1 & 0xFF00) | (row0>>8 & 0xFF);\
column2 = (row3 & 0xFF0000) << 8 |(row2 & 0xFF0000) |(row1 & 0xFF0000) >> 8 | (row0>>16 & 0xFF);\
column3 = (row3 & 0xFF000000) |(row2 & 0xFF000000) >> 8 |(row1 & 0xFF000000) >> 16| (row0>>24 & 0xFF);\
} while(0)
#define columns_to_rows_32(row0, row1, row2, row3, column0, column1, column2, column3) rows_to_columns_32(row0, row1, row2, row3, column0, column1, column2, column3)
#define load_column_8(dest, src) \
do { \
dest[0] = (src[12]) << 24 | (src[8]) << 16 | (src[4]) << 8 | (src[0]); \
dest[1] = (src[13]) << 24 | (src[9]) << 16 | (src[5]) << 8 | (src[1]); \
dest[2] = (src[14]) << 24 | (src[10]) << 16 | (src[6]) << 8 | (src[2]); \
dest[3] = (src[15]) << 24 | (src[11]) << 16 | (src[7]) << 8 | (src[3]); \
} while(0)
#define store_column_8(dest, src) \
do { \
dest[0] = (uint8_t) (src[0]); dest[1] = (uint8_t) (src[1]); dest[2] = (uint8_t) (src[2]); dest[3] = (uint8_t) (src[3]); \
dest[4] = (uint8_t) (src[0]>>8); dest[5] = (uint8_t) (src[1]>>8); dest[6] = (uint8_t) (src[2]>>8); dest[7] = (uint8_t) (src[3]>>8); \
dest[8] = (uint8_t) (src[0]>>16);dest[9] = (uint8_t) (src[1]>>16);dest[10]= (uint8_t) (src[2]>>16);dest[11]= (uint8_t)(src[3]>>16); \
dest[12]= (uint8_t) (src[0]>>24);dest[13]= (uint8_t) (src[1]>>24);dest[14]= (uint8_t) (src[2]>>24);dest[15]= (uint8_t)(src[3]>>24); \
} while(0)
#define TK_to_column_256(columns, state) \
do { \
uint32_t TK0 = state->TK1[0] ^ state->TK2[0];\
uint32_t TK1 = state->TK1[1] ^ state->TK2[1]; \
uint32_t tk00 = TK0 & 0xFF; \
uint32_t tk01 = TK0 & 0xFF00;\
uint32_t tk02 = TK0 & 0xFF0000;\
uint32_t tk03 = TK0 & 0xFF000000;\
columns[0] = tk00 << 24 | (TK1 & 0xFF000000) >> 8 | tk00 << 8 | tk00; \
columns[1] = tk01 << 16 | (TK1 & 0xFF) << 16 | tk01 | tk01 >> 8; \
columns[2] = tk02 << 8 | (TK1 & 0xFF00) << 8 | tk02 >> 8 | tk02 >> 16; \
columns[3] = tk03 | (TK1 & 0xFF0000) | tk03 >> 16 | tk03 >> 24; \
} while(0)
#define TK_to_column_384(columns, state) \
do { \
uint32_t TK0 = state->TK1[0] ^ state->TK2[0] ^ state->TK3[0];\
uint32_t TK1 = state->TK1[1] ^ state->TK2[1] ^ state->TK3[1];\
uint32_t tk00 = TK0 & 0xFF; \
uint32_t tk01 = TK0 & 0xFF00;\
uint32_t tk02 = TK0 & 0xFF0000;\
uint32_t tk03 = TK0 & 0xFF000000;\
columns[0] = tk00 << 24 | (TK1 & 0xFF000000) >> 8 | tk00 << 8 | tk00; \
columns[1] = tk01 << 16 | (TK1 & 0xFF) << 16 | tk01 | tk01 >> 8; \
columns[2] = tk02 << 8 | (TK1 & 0xFF00) << 8 | tk02 >> 8 | tk02 >> 16; \
columns[3] = tk03 | (TK1 & 0xFF0000) | tk03 >> 16 | tk03 >> 24; \
} while(0)
/** @endcond */
#ifdef __cplusplus
......
......@@ -154,7 +154,7 @@ typedef void (*aead_xof_squeeze_t)
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
......@@ -166,7 +166,18 @@ typedef void (*aead_xof_squeeze_t)
* 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
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief The AEAD mode provides side-channel protection for the key.
*/
#define AEAD_FLAG_SC_PROTECT_KEY 0x0002
/**
* \brief The AEAD mode provides side-channel protection for all block
* operations.
*/
#define AEAD_FLAG_SC_PROTECT_ALL 0x0004
/**
* \brief Meta-information about an AEAD cipher.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,6 +23,8 @@
#ifndef LW_INTERNAL_FORKSKINNY_H
#define LW_INTERNAL_FORKSKINNY_H
#include "internal-util.h"
/**
* \file internal-forkskinny.h
* \brief ForkSkinny block cipher family.
......@@ -39,6 +41,172 @@ extern "C" {
#endif
/**
* \brief Number of rounds of ForkSkinny-128-256 before forking.
*/
#define FORKSKINNY_128_256_ROUNDS_BEFORE 21
/**
* \brief Number of rounds of ForkSkinny-128-256 after forking.
*/
#define FORKSKINNY_128_256_ROUNDS_AFTER 27
/**
* \brief State information for ForkSkinny-128-256.
*/
typedef struct
{
// uint32_t TK1[4]; /**< First part of the tweakey */
// uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_256_state_t;
typedef struct
{
/** Words of the full key schedule */
uint32_t row0[(FORKSKINNY_128_256_ROUNDS_BEFORE + 2*FORKSKINNY_128_256_ROUNDS_AFTER)];
uint32_t row1[(FORKSKINNY_128_256_ROUNDS_BEFORE + 2*FORKSKINNY_128_256_ROUNDS_AFTER)];
} forkskinny_128_256_tweakey_schedule_t;
/**
* \brief Number of rounds of ForkSkinny-128-384 before forking.
*/
#define FORKSKINNY_128_384_ROUNDS_BEFORE 25
/**
* \brief Number of rounds of ForkSkinny-128-384 after forking.
*/
#define FORKSKINNY_128_384_ROUNDS_AFTER 31
/**
* \brief State information for ForkSkinny-128-384.
*/
typedef struct
{
// uint32_t TK1[4]; /**< First part of the tweakey */
// uint32_t TK2[4]; /**< Second part of the tweakey */
// uint32_t TK3[4]; /**< Third part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_384_state_t;
typedef struct
{
/** Words of the full key schedule */
uint32_t row0[(FORKSKINNY_128_384_ROUNDS_BEFORE + 2*FORKSKINNY_128_384_ROUNDS_AFTER)];
uint32_t row1[(FORKSKINNY_128_384_ROUNDS_BEFORE + 2*FORKSKINNY_128_384_ROUNDS_AFTER)];
} forkskinny_128_384_tweakey_schedule_t;
/**
* \brief Number of rounds of ForkSkinny-64-192 before forking.
*/
#define FORKSKINNY_64_192_ROUNDS_BEFORE 17
/**
* \brief Number of rounds of ForkSkinny-64-192 after forking.
*/
#define FORKSKINNY_64_192_ROUNDS_AFTER 23
/**
* \brief State information for ForkSkinny-64-192.
*/
typedef struct
{
uint16_t TK1[4]; /**< First part of the tweakey */
uint16_t TK2[4]; /**< Second part of the tweakey */
uint16_t TK3[4]; /**< Third part of the tweakey */
uint16_t S[4]; /**< Current block state */
} forkskinny_64_192_state_t;
typedef struct
{
/** Words of the full key schedule */
uint16_t row0[(FORKSKINNY_64_192_ROUNDS_BEFORE + 2*FORKSKINNY_64_192_ROUNDS_AFTER)];
uint16_t row1[(FORKSKINNY_64_192_ROUNDS_BEFORE + 2*FORKSKINNY_64_192_ROUNDS_AFTER)];
} forkskinny_64_192_tweakey_schedule_t;
void forkskinny_128_256_init_tks(forkskinny_128_256_tweakey_schedule_t *tks, const unsigned char key[32], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-256.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_256_rounds
(forkskinny_128_256_state_t *state, forkskinny_128_256_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-256 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_256_inv_rounds
(forkskinny_128_256_state_t *state, forkskinny_128_256_tweakey_schedule_t *tks, unsigned first, unsigned last);
void forkskinny_128_384_init_tks(forkskinny_128_384_tweakey_schedule_t *tks, const unsigned char key[48], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-384.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_384_rounds
(forkskinny_128_384_state_t *state, forkskinny_128_384_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-384 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_384_inv_rounds
(forkskinny_128_384_state_t *state, forkskinny_128_384_tweakey_schedule_t *tks, unsigned first, unsigned last);
void forkskinny_64_192_init_tks(forkskinny_64_192_tweakey_schedule_t *tks, const unsigned char key[24], uint8_t nb_rounds);
/**
* \brief Applies several rounds of ForkSkinny-64-192.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*
* Note: The cells of each row are ordered in big-endian nibble order
* so it is simplest to manage the rows in big-endian byte order.
*/
void forkskinny_64_192_rounds
(forkskinny_64_192_state_t *state, forkskinny_64_192_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-64-192 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_64_192_inv_rounds
(forkskinny_64_192_state_t *state, forkskinny_64_192_tweakey_schedule_t *tks, unsigned first, unsigned last);
/**
* \brief Encrypts a block of plaintext with ForkSkinny-128-256.
*
* \param key 256-bit tweakey for ForkSkinny-128-256.
......
......@@ -74,6 +74,21 @@ extern "C" {
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_permute_tk_half(tk2, tk3) \
do { \
/* Permute the bottom half of the tweakey state in place, no swap */ \
uint32_t row2 = tk2; \
uint32_t row3 = tk3; \
row3 = (row3 << 16) | (row3 >> 16); \
tk2 = ((row2 >> 8) & 0x000000FFU) | \
((row2 << 16) & 0x00FF0000U) | \
( row3 & 0xFF00FF00U); \
tk3 = ((row2 >> 16) & 0x000000FFU) | \
(row2 & 0xFF000000U) | \
((row3 << 8) & 0x0000FF00U) | \
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk(tk) \
do { \
/* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \
......@@ -91,6 +106,21 @@ extern "C" {
((row1 << 8) & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk_half(tk0, tk1) \
do { \
/* Permute the top half of the tweakey state in place, no swap */ \
uint32_t row0 = tk0; \
uint32_t row1 = tk1; \
tk0 = ((row0 >> 16) & 0x000000FFU) | \
((row0 << 8) & 0x0000FF00U) | \
((row1 << 16) & 0x00FF0000U) | \
( row1 & 0xFF000000U); \
tk1 = ((row0 >> 16) & 0x0000FF00U) | \
((row0 << 16) & 0xFF000000U) | \
((row1 >> 16) & 0x000000FFU) | \
((row1 << 8) & 0x00FF0000U); \
} while (0)
/*
* Apply the SKINNY sbox. The original version from the specification is
* equivalent to:
......
......@@ -154,7 +154,7 @@ typedef void (*aead_xof_squeeze_t)
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
......@@ -166,7 +166,18 @@ typedef void (*aead_xof_squeeze_t)
* 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
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief The AEAD mode provides side-channel protection for the key.
*/
#define AEAD_FLAG_SC_PROTECT_KEY 0x0002
/**
* \brief The AEAD mode provides side-channel protection for all block
* operations.
*/
#define AEAD_FLAG_SC_PROTECT_ALL 0x0004
/**
* \brief Meta-information about an AEAD cipher.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,6 +23,8 @@
#ifndef LW_INTERNAL_FORKSKINNY_H
#define LW_INTERNAL_FORKSKINNY_H
#include "internal-util.h"
/**
* \file internal-forkskinny.h
* \brief ForkSkinny block cipher family.
......@@ -39,6 +41,158 @@ extern "C" {
#endif
/**
* \brief State information for ForkSkinny-128-256.
*/
typedef struct
{
uint32_t TK1[4]; /**< First part of the tweakey */
uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_256_state_t;
/**
* \brief State information for ForkSkinny-128-384.
*/
typedef struct
{
uint32_t TK1[4]; /**< First part of the tweakey */
uint32_t TK2[4]; /**< Second part of the tweakey */
uint32_t TK3[4]; /**< Third part of the tweakey */
uint32_t S[4]; /**< Current block state */
} forkskinny_128_384_state_t;
/**
* \brief State information for ForkSkinny-64-192.
*/
typedef struct
{
uint16_t TK1[4]; /**< First part of the tweakey */
uint16_t TK2[4]; /**< Second part of the tweakey */
uint16_t TK3[4]; /**< Third part of the tweakey */
uint16_t S[4]; /**< Current block state */
} forkskinny_64_192_state_t;
/**
* \brief Applies several rounds of ForkSkinny-128-256.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_256_rounds
(forkskinny_128_256_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-256 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_256_inv_rounds
(forkskinny_128_256_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-128-256.
*
* \param state Points to the ForkSkinny-128-256 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_128_256_forward_tk
(forkskinny_128_256_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-128-256.
*
* \param state Points to the ForkSkinny-128-256 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_128_256_reverse_tk
(forkskinny_128_256_state_t *state, unsigned rounds);
/**
* \brief Applies several rounds of ForkSkinny-128-384.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*/
void forkskinny_128_384_rounds
(forkskinny_128_384_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-128-384 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_128_384_inv_rounds
(forkskinny_128_384_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-128-384.
*
* \param state Points to the ForkSkinny-128-384 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_128_384_forward_tk
(forkskinny_128_384_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-128-384.
*
* \param state Points to the ForkSkinny-128-384 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_128_384_reverse_tk
(forkskinny_128_384_state_t *state, unsigned rounds);
/**
* \brief Applies several rounds of ForkSkinny-64-192.
*
* \param state State to apply the rounds to.
* \param first First round to apply.
* \param last Last round to apply plus 1.
*
* Note: The cells of each row are ordered in big-endian nibble order
* so it is simplest to manage the rows in big-endian byte order.
*/
void forkskinny_64_192_rounds
(forkskinny_64_192_state_t *state, unsigned first, unsigned last);
/**
* \brief Applies several rounds of ForkSkinny-64-192 in reverse.
*
* \param state State to apply the rounds to.
* \param first First round to apply plus 1.
* \param last Last round to apply.
*/
void forkskinny_64_192_inv_rounds
(forkskinny_64_192_state_t *state, unsigned first, unsigned last);
/**
* \brief Forwards the tweakey for ForkSkinny-64-192.
*
* \param state Points to the ForkSkinny-64-192 state.
* \param rounds Number of rounds to forward by.
*/
void forkskinny_64_192_forward_tk
(forkskinny_64_192_state_t *state, unsigned rounds);
/**
* \brief Reverses the tweakey for ForkSkinny-64-192.
*
* \param state Points to the ForkSkinny-64-192 state.
* \param rounds Number of rounds to reverse by.
*/
void forkskinny_64_192_reverse_tk
(forkskinny_64_192_state_t *state, unsigned rounds);
/**
* \brief Encrypts a block of plaintext with ForkSkinny-128-256.
*
* \param key 256-bit tweakey for ForkSkinny-128-256.
......
......@@ -74,6 +74,21 @@ extern "C" {
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_permute_tk_half(tk2, tk3) \
do { \
/* Permute the bottom half of the tweakey state in place, no swap */ \
uint32_t row2 = tk2; \
uint32_t row3 = tk3; \
row3 = (row3 << 16) | (row3 >> 16); \
tk2 = ((row2 >> 8) & 0x000000FFU) | \
((row2 << 16) & 0x00FF0000U) | \
( row3 & 0xFF00FF00U); \
tk3 = ((row2 >> 16) & 0x000000FFU) | \
(row2 & 0xFF000000U) | \
((row3 << 8) & 0x0000FF00U) | \
( row3 & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk(tk) \
do { \
/* PT' = [8, 9, 10, 11, 12, 13, 14, 15, 2, 0, 4, 7, 6, 3, 5, 1] */ \
......@@ -91,6 +106,21 @@ extern "C" {
((row1 << 8) & 0x00FF0000U); \
} while (0)
#define skinny128_inv_permute_tk_half(tk0, tk1) \
do { \
/* Permute the top half of the tweakey state in place, no swap */ \
uint32_t row0 = tk0; \
uint32_t row1 = tk1; \
tk0 = ((row0 >> 16) & 0x000000FFU) | \
((row0 << 8) & 0x0000FF00U) | \
((row1 << 16) & 0x00FF0000U) | \
( row1 & 0xFF000000U); \
tk1 = ((row0 >> 16) & 0x0000FF00U) | \
((row0 << 16) & 0xFF000000U) | \
((row1 >> 16) & 0x000000FFU) | \
((row1 << 8) & 0x00FF0000U); \
} while (0)
/*
* Apply the SKINNY sbox. The original version from the specification is
* equivalent to:
......@@ -319,6 +349,61 @@ do { \
x = ((x << 1) & 0xEEEEU) | ((x >> 3) & 0x1111U); \
} while (0)
#define rows_to_columns_32(column0, column1, column2, column3, row0, row1, row2, row3) \
do { \
column0 = (row3 & 0xFF) << 24|(row2 & 0xFF) << 16|(row1 & 0xFF) << 8 | (row0 & 0xFF);\
column1 = (row3 & 0xFF00) << 16|(row2 & 0xFF00) << 8 |(row1 & 0xFF00) | (row0>>8 & 0xFF);\
column2 = (row3 & 0xFF0000) << 8 |(row2 & 0xFF0000) |(row1 & 0xFF0000) >> 8 | (row0>>16 & 0xFF);\
column3 = (row3 & 0xFF000000) |(row2 & 0xFF000000) >> 8 |(row1 & 0xFF000000) >> 16| (row0>>24 & 0xFF);\
} while(0)
#define columns_to_rows_32(row0, row1, row2, row3, column0, column1, column2, column3) rows_to_columns_32(row0, row1, row2, row3, column0, column1, column2, column3)
#define load_column_8(dest, src) \
do { \
dest[0] = (src[12]) << 24 | (src[8]) << 16 | (src[4]) << 8 | (src[0]); \
dest[1] = (src[13]) << 24 | (src[9]) << 16 | (src[5]) << 8 | (src[1]); \
dest[2] = (src[14]) << 24 | (src[10]) << 16 | (src[6]) << 8 | (src[2]); \
dest[3] = (src[15]) << 24 | (src[11]) << 16 | (src[7]) << 8 | (src[3]); \
} while(0)
#define store_column_8(dest, src) \
do { \
dest[0] = (uint8_t) (src[0]); dest[1] = (uint8_t) (src[1]); dest[2] = (uint8_t) (src[2]); dest[3] = (uint8_t) (src[3]); \
dest[4] = (uint8_t) (src[0]>>8); dest[5] = (uint8_t) (src[1]>>8); dest[6] = (uint8_t) (src[2]>>8); dest[7] = (uint8_t) (src[3]>>8); \
dest[8] = (uint8_t) (src[0]>>16);dest[9] = (uint8_t) (src[1]>>16);dest[10]= (uint8_t) (src[2]>>16);dest[11]= (uint8_t)(src[3]>>16); \
dest[12]= (uint8_t) (src[0]>>24);dest[13]= (uint8_t) (src[1]>>24);dest[14]= (uint8_t) (src[2]>>24);dest[15]= (uint8_t)(src[3]>>24); \
} while(0)
#define TK_to_column_256(columns, state) \
do { \
uint32_t TK0 = state->TK1[0] ^ state->TK2[0];\
uint32_t TK1 = state->TK1[1] ^ state->TK2[1]; \
uint32_t tk00 = TK0 & 0xFF; \
uint32_t tk01 = TK0 & 0xFF00;\
uint32_t tk02 = TK0 & 0xFF0000;\
uint32_t tk03 = TK0 & 0xFF000000;\
columns[0] = tk00 << 24 | (TK1 & 0xFF000000) >> 8 | tk00 << 8 | tk00; \
columns[1] = tk01 << 16 | (TK1 & 0xFF) << 16 | tk01 | tk01 >> 8; \
columns[2] = tk02 << 8 | (TK1 & 0xFF00) << 8 | tk02 >> 8 | tk02 >> 16; \
columns[3] = tk03 | (TK1 & 0xFF0000) | tk03 >> 16 | tk03 >> 24; \
} while(0)
#define TK_to_column_384(columns, state) \
do { \
uint32_t TK0 = state->TK1[0] ^ state->TK2[0] ^ state->TK3[0];\
uint32_t TK1 = state->TK1[1] ^ state->TK2[1] ^ state->TK3[1];\
uint32_t tk00 = TK0 & 0xFF; \
uint32_t tk01 = TK0 & 0xFF00;\
uint32_t tk02 = TK0 & 0xFF0000;\
uint32_t tk03 = TK0 & 0xFF000000;\
columns[0] = tk00 << 24 | (TK1 & 0xFF000000) >> 8 | tk00 << 8 | tk00; \
columns[1] = tk01 << 16 | (TK1 & 0xFF) << 16 | tk01 | tk01 >> 8; \
columns[2] = tk02 << 8 | (TK1 & 0xFF00) << 8 | tk02 >> 8 | tk02 >> 16; \
columns[3] = tk03 | (TK1 & 0xFF0000) | tk03 >> 16 | tk03 >> 24; \
} while(0)
/** @endcond */
#ifdef __cplusplus
......
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