Commit e3e8b784 by Alexandre Adomnicai Committed by Enrico Pozzobon

giftcofb128v1.armcortexm

parent a28aa8ad
#ifndef GIFT_COFB_H_
#define GIFT_COFB_H_
#define TAG_SIZE 16
#define COFB_ENCRYPT 1
#define COFB_DECRYPT 0
#define XOR_BLOCK(x, y, z) ({ \
(x)[0] = (y)[0] ^ (z)[0]; \
(x)[1] = (y)[1] ^ (z)[1]; \
(x)[2] = (y)[2] ^ (z)[2]; \
(x)[3] = (y)[3] ^ (z)[3]; \
})
#define XOR_TOP_BAR_BLOCK(x, y) ({ \
(x)[0] ^= (y)[0]; \
(x)[1] ^= (y)[1]; \
})
#endif // GIFT_COFB_H_
\ No newline at end of file
#include <string.h>
#include "api.h"
#include "cofb.h"
#include "giftb128.h"
static inline void padding(u32* d, const u32* s, const u32 no_of_bytes){
u32 i;
if (no_of_bytes == 0) {
d[0] = 0x00000080; // little-endian
d[1] = 0x00000000;
d[2] = 0x00000000;
d[3] = 0x00000000;
}
else if (no_of_bytes < GIFT128_BLOCK_SIZE) {
for (i = 0; i < no_of_bytes/4+1; i++)
d[i] = s[i];
d[i-1] &= ~(0xffffffffL << (no_of_bytes % 4)*8);
d[i-1] |= 0x00000080L << (no_of_bytes % 4)*8;
for (; i < 4; i++)
d[i] = 0x00000000;
}
else {
d[0] = s[0];
d[1] = s[1];
d[2] = s[2];
d[3] = s[3];
}
}
static inline void double_half_block(u32* x) {
u32 tmp0;
tmp0 = (x)[0];
(x)[0] = (((x)[0] & 0x7f7f7f7f) << 1) | (((x)[0] & 0x80808080) >> 15);
(x)[0] |= ((x)[1] & 0x80808080) << 17;
(x)[1] = (((x)[1] & 0x7f7f7f7f) << 1) | (((x)[1] & 0x80808080) >> 15);
(x)[1] ^= (((tmp0 >> 7) & 1) * 27) << 24;
}
static inline void triple_half_block(u32* x) {
u32 tmp0, tmp1;
tmp0 = (x)[0];
tmp1 = (x)[1];
(x)[0] = (((x)[0] & 0x7f7f7f7f) << 1) | (((x)[0] & 0x80808080) >> 15);
(x)[0] |= ((x)[1] & 0x80808080) << 17;
(x)[1] = (((x)[1] & 0x7f7f7f7f) << 1) | (((x)[1] & 0x80808080) >> 15);
(x)[1] ^= (((tmp0 >> 7) & 1) * 27) << 24;
(x)[0] ^= tmp0;
(x)[1] ^= tmp1;
}
static inline void g(u32 *x) {
u32 tmp0, tmp1;
tmp0 = (x)[0];
tmp1 = (x)[1];
(x)[0] = (x)[2];
(x)[1] = (x)[3];
(x)[2] = ((tmp0 & 0x7f7f7f7f) << 1) | ((tmp0 & 0x80808080) >> 15);
(x)[2] |= ((tmp1 & 0x80808080) << 17);
(x)[3] = ((tmp1 & 0x7f7f7f7f) << 1) | ((tmp1 & 0x80808080) >> 15);
(x)[3] |= ((tmp0 & 0x80808080) << 17);
}
static inline void rho1(u32* d, u32* y, u32* m, u32 n) {
g(y);
padding(d,m,n);
XOR_BLOCK(d, d, y);
}
static inline void rho(u32* y, u32* m, u32* x, u32* c, u32 n) {
XOR_BLOCK(c, y, m);
rho1(x, y, m, n);
}
static inline void rho_prime(u32* y, u32*c, u32* m, u32* x, u32 n) {
XOR_BLOCK(m, y, c);
rho1(x, y, m, n);
}
/****************************************************************************
* Constant-time implementation of the GIFT-COFB authenticated cipher based on
* fixsliced GIFTb-128. Encryption/decryption is handled by the same function,
* depending on the 'mode' parameter (1/0).
****************************************************************************/
int giftcofb_crypt(u8* out, const u8* key, const u8* nonce, const u8* ad,
u32 ad_len, const u8* in, u32 in_len, const int encrypting) {
u32 tmp0, tmp1, emptyA, emptyM, offset[2];
u32 input[4], rkey[80];
u8 Y[GIFT128_BLOCK_SIZE];
if (!encrypting) {
if (in_len < TAG_SIZE)
return -1;
in_len -= TAG_SIZE;
}
if(ad_len == 0)
emptyA = 1;
else
emptyA = 0;
if(in_len == 0)
emptyM =1;
else
emptyM = 0;
gift128_keyschedule(key, rkey);
giftb128_encrypt_block(Y, rkey, nonce);
offset[0] = ((u32*)Y)[0];
offset[1] = ((u32*)Y)[1];
while(ad_len > GIFT128_BLOCK_SIZE){
rho1(input, (u32*)Y, (u32*)ad, GIFT128_BLOCK_SIZE);
double_half_block(offset);
XOR_TOP_BAR_BLOCK(input, offset);
giftb128_encrypt_block(Y, rkey, (u8*)input);
ad += GIFT128_BLOCK_SIZE;
ad_len -= GIFT128_BLOCK_SIZE;
}
triple_half_block(offset);
if((ad_len % GIFT128_BLOCK_SIZE != 0) || (emptyA))
triple_half_block(offset);
if(emptyM) {
triple_half_block(offset);
triple_half_block(offset);
}
rho1(input, (u32*)Y, (u32*)ad, ad_len);
XOR_TOP_BAR_BLOCK(input, offset);
giftb128_encrypt_block(Y, rkey, (u8*)input);
while (in_len > GIFT128_BLOCK_SIZE){
double_half_block(offset);
if (encrypting)
rho((u32*)Y, (u32*)in, input, (u32*)out, GIFT128_BLOCK_SIZE);
else
rho_prime((u32*)Y, (u32*)in, input, (u32*)out, GIFT128_BLOCK_SIZE);
XOR_TOP_BAR_BLOCK(input, offset);
giftb128_encrypt_block(Y, rkey, (u8*)input);
in += GIFT128_BLOCK_SIZE;
out += GIFT128_BLOCK_SIZE;
in_len -= GIFT128_BLOCK_SIZE;
}
if(!emptyM){
triple_half_block(offset);
if(in_len % GIFT128_BLOCK_SIZE != 0)
triple_half_block(offset);
if (encrypting) {
rho((u32*)Y, (u32*)in, input, (u32*)out, in_len);
out += in_len;
}
else {
rho_prime((u32*)Y, (u32*)in, input, (u32*)out, in_len);
in += in_len;
}
XOR_TOP_BAR_BLOCK(input, offset);
giftb128_encrypt_block(Y, rkey, (u8*)input);
}
if (encrypting) { // encryption mode
memcpy(out, Y, TAG_SIZE);
return 0;
}
// decrypting
tmp0 = 0;
for(tmp1 = 0; tmp1 < TAG_SIZE; tmp1++)
tmp0 |= in[tmp1] ^ Y[tmp1];
return tmp0;
}
int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen,
const unsigned char* m, unsigned long long mlen,
const unsigned char* ad, unsigned long long adlen,
const unsigned char* nsec, const unsigned char* npub,
const unsigned char* k) {
(void)nsec;
*clen = mlen + TAG_SIZE;
return giftcofb_crypt(c, k, npub, ad, adlen, m, mlen, COFB_ENCRYPT);
}
int crypto_aead_decrypt(unsigned char* m, unsigned long long *mlen,
unsigned char* nsec, const unsigned char* c,
unsigned long long clen, const unsigned char* ad,
unsigned long long adlen, const unsigned char* npub,
const unsigned char *k) {
(void)nsec;
*mlen = clen - TAG_SIZE;
return giftcofb_crypt(m, k, npub, ad, adlen, c, clen, COFB_DECRYPT);
}
\ No newline at end of file
#ifndef GIFT128_H_
#define GIFT128_H_
#define KEY_SIZE 16
#define GIFT128_BLOCK_SIZE 16
typedef unsigned char u8;
typedef unsigned int u32;
extern void gift128_keyschedule(const u8* key, u32* rkey);
extern void giftb128_encrypt_block(u8* out_block, const u32* rkey, const u8* in_block);
#endif // GIFT128_H_
\ No newline at end of file
#define CRYPTO_KEYBYTES 16
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 16
#define CRYPTO_ABYTES 16
#define CRYPTO_NOOVERLAP 1
#ifndef GIFT_COFB_H_
#define GIFT_COFB_H_
#define TAG_SIZE 16
#define COFB_ENCRYPT 1
#define COFB_DECRYPT 0
#define XOR_BLOCK(x, y, z) ({ \
(x)[0] = (y)[0] ^ (z)[0]; \
(x)[1] = (y)[1] ^ (z)[1]; \
(x)[2] = (y)[2] ^ (z)[2]; \
(x)[3] = (y)[3] ^ (z)[3]; \
})
#define XOR_TOP_BAR_BLOCK(x, y) ({ \
(x)[0] ^= (y)[0]; \
(x)[1] ^= (y)[1]; \
})
#endif // GIFT_COFB_H_
\ No newline at end of file
#include <string.h>
#include "api.h"
#include "cofb.h"
#include "giftb128.h"
static inline void padding(u32* d, const u32* s, const u32 no_of_bytes){
u32 i;
if (no_of_bytes == 0) {
d[0] = 0x00000080; // little-endian
d[1] = 0x00000000;
d[2] = 0x00000000;
d[3] = 0x00000000;
}
else if (no_of_bytes < GIFT128_BLOCK_SIZE) {
for (i = 0; i < no_of_bytes/4+1; i++)
d[i] = s[i];
d[i-1] &= ~(0xffffffffL << (no_of_bytes % 4)*8);
d[i-1] |= 0x00000080L << (no_of_bytes % 4)*8;
for (; i < 4; i++)
d[i] = 0x00000000;
}
else {
d[0] = s[0];
d[1] = s[1];
d[2] = s[2];
d[3] = s[3];
}
}
static inline void double_half_block(u32* x) {
u32 tmp0;
tmp0 = (x)[0];
(x)[0] = (((x)[0] & 0x7f7f7f7f) << 1) | (((x)[0] & 0x80808080) >> 15);
(x)[0] |= ((x)[1] & 0x80808080) << 17;
(x)[1] = (((x)[1] & 0x7f7f7f7f) << 1) | (((x)[1] & 0x80808080) >> 15);
(x)[1] ^= (((tmp0 >> 7) & 1) * 27) << 24;
}
static inline void triple_half_block(u32* x) {
u32 tmp0, tmp1;
tmp0 = (x)[0];
tmp1 = (x)[1];
(x)[0] = (((x)[0] & 0x7f7f7f7f) << 1) | (((x)[0] & 0x80808080) >> 15);
(x)[0] |= ((x)[1] & 0x80808080) << 17;
(x)[1] = (((x)[1] & 0x7f7f7f7f) << 1) | (((x)[1] & 0x80808080) >> 15);
(x)[1] ^= (((tmp0 >> 7) & 1) * 27) << 24;
(x)[0] ^= tmp0;
(x)[1] ^= tmp1;
}
static inline void g(u32 *x) {
u32 tmp0, tmp1;
tmp0 = (x)[0];
tmp1 = (x)[1];
(x)[0] = (x)[2];
(x)[1] = (x)[3];
(x)[2] = ((tmp0 & 0x7f7f7f7f) << 1) | ((tmp0 & 0x80808080) >> 15);
(x)[2] |= ((tmp1 & 0x80808080) << 17);
(x)[3] = ((tmp1 & 0x7f7f7f7f) << 1) | ((tmp1 & 0x80808080) >> 15);
(x)[3] |= ((tmp0 & 0x80808080) << 17);
}
static inline void rho1(u32* d, u32* y, u32* m, u32 n) {
g(y);
padding(d,m,n);
XOR_BLOCK(d, d, y);
}
static inline void rho(u32* y, u32* m, u32* x, u32* c, u32 n) {
XOR_BLOCK(c, y, m);
rho1(x, y, m, n);
}
static inline void rho_prime(u32* y, u32*c, u32* m, u32* x, u32 n) {
XOR_BLOCK(m, y, c);
rho1(x, y, m, n);
}
/****************************************************************************
* Constant-time implementation of the GIFT-COFB authenticated cipher based on
* fixsliced GIFTb-128. Encryption/decryption is handled by the same function,
* depending on the 'mode' parameter (1/0).
****************************************************************************/
int giftcofb_crypt(u8* out, const u8* key, const u8* nonce, const u8* ad,
u32 ad_len, const u8* in, u32 in_len, const int encrypting) {
u32 tmp0, tmp1, emptyA, emptyM, offset[2];
u32 input[4], rkey[80];
u8 Y[GIFT128_BLOCK_SIZE];
if (!encrypting) {
if (in_len < TAG_SIZE)
return -1;
in_len -= TAG_SIZE;
}
if(ad_len == 0)
emptyA = 1;
else
emptyA = 0;
if(in_len == 0)
emptyM =1;
else
emptyM = 0;
gift128_keyschedule(key, rkey);
giftb128_encrypt_block(Y, rkey, nonce);
offset[0] = ((u32*)Y)[0];
offset[1] = ((u32*)Y)[1];
while(ad_len > GIFT128_BLOCK_SIZE){
rho1(input, (u32*)Y, (u32*)ad, GIFT128_BLOCK_SIZE);
double_half_block(offset);
XOR_TOP_BAR_BLOCK(input, offset);
giftb128_encrypt_block(Y, rkey, (u8*)input);
ad += GIFT128_BLOCK_SIZE;
ad_len -= GIFT128_BLOCK_SIZE;
}
triple_half_block(offset);
if((ad_len % GIFT128_BLOCK_SIZE != 0) || (emptyA))
triple_half_block(offset);
if(emptyM) {
triple_half_block(offset);
triple_half_block(offset);
}
rho1(input, (u32*)Y, (u32*)ad, ad_len);
XOR_TOP_BAR_BLOCK(input, offset);
giftb128_encrypt_block(Y, rkey, (u8*)input);
while (in_len > GIFT128_BLOCK_SIZE){
double_half_block(offset);
if (encrypting)
rho((u32*)Y, (u32*)in, input, (u32*)out, GIFT128_BLOCK_SIZE);
else
rho_prime((u32*)Y, (u32*)in, input, (u32*)out, GIFT128_BLOCK_SIZE);
XOR_TOP_BAR_BLOCK(input, offset);
giftb128_encrypt_block(Y, rkey, (u8*)input);
in += GIFT128_BLOCK_SIZE;
out += GIFT128_BLOCK_SIZE;
in_len -= GIFT128_BLOCK_SIZE;
}
if(!emptyM){
triple_half_block(offset);
if(in_len % GIFT128_BLOCK_SIZE != 0)
triple_half_block(offset);
if (encrypting) {
rho((u32*)Y, (u32*)in, input, (u32*)out, in_len);
out += in_len;
}
else {
rho_prime((u32*)Y, (u32*)in, input, (u32*)out, in_len);
in += in_len;
}
XOR_TOP_BAR_BLOCK(input, offset);
giftb128_encrypt_block(Y, rkey, (u8*)input);
}
if (encrypting) { // encryption mode
memcpy(out, Y, TAG_SIZE);
return 0;
}
// decrypting
tmp0 = 0;
for(tmp1 = 0; tmp1 < TAG_SIZE; tmp1++)
tmp0 |= in[tmp1] ^ Y[tmp1];
return tmp0;
}
int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen,
const unsigned char* m, unsigned long long mlen,
const unsigned char* ad, unsigned long long adlen,
const unsigned char* nsec, const unsigned char* npub,
const unsigned char* k) {
(void)nsec;
*clen = mlen + TAG_SIZE;
return giftcofb_crypt(c, k, npub, ad, adlen, m, mlen, COFB_ENCRYPT);
}
int crypto_aead_decrypt(unsigned char* m, unsigned long long *mlen,
unsigned char* nsec, const unsigned char* c,
unsigned long long clen, const unsigned char* ad,
unsigned long long adlen, const unsigned char* npub,
const unsigned char *k) {
(void)nsec;
*mlen = clen - TAG_SIZE;
return giftcofb_crypt(m, k, npub, ad, adlen, c, clen, COFB_DECRYPT);
}
#ifndef GIFT128_H_
#define GIFT128_H_
#define KEY_SIZE 16
#define GIFT128_BLOCK_SIZE 16
typedef unsigned char u8;
typedef unsigned int u32;
extern void gift128_keyschedule(const u8* key, u32* rkey);
extern void giftb128_encrypt_block(u8* out_block, const u32* rkey, const u8* in_block);
#endif // GIFT128_H_
\ No newline at end of file
#define CRYPTO_KEYBYTES 16
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 16
#define CRYPTO_ABYTES 16
#define CRYPTO_NOOVERLAP 1
......@@ -5,21 +5,6 @@
#define COFB_ENCRYPT 1
#define COFB_DECRYPT 0
typedef unsigned char u8;
typedef unsigned int u32;
int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen,
const unsigned char* m, unsigned long long mlen,
const unsigned char* ad, unsigned long long adlen,
const unsigned char* nsec, const unsigned char* npub,
const unsigned char* k);
int crypto_aead_decrypt(unsigned char* m, unsigned long long *mlen,
unsigned char* nsec, const unsigned char* c,
unsigned long long clen, const unsigned char* ad,
unsigned long long adlen, const unsigned char* npub,
const unsigned char *k);
#define DOUBLE_HALF_BLOCK(x) ({ \
tmp0 = (x)[0]; \
(x)[0] = (((x)[0] & 0x7f7f7f7f) << 1) | (((x)[0] & 0x80808080) >> 15); \
......@@ -78,4 +63,4 @@ int crypto_aead_decrypt(unsigned char* m, unsigned long long *mlen,
RHO1(x, y, m, n); \
})
#endif // GIFT_COFB_H_
#endif // GIFT_COFB_H_
\ No newline at end of file
/*******************************************************************************
* Constant-time 32-bit implementation of the GIFT-COFB authenticated cipher.
*
* @author Alexandre Adomnicai, Nanyang Technological University,
* alexandre.adomnicai@ntu.edu.sg
* @date January 2020
*******************************************************************************/
#include <string.h>
#include "cofb.h"
#include "giftb128.h"
#include "giftcofb128v1.h"
static inline void padding(u32* dest, const u32* src, const u32 no_of_bytes) {
static inline void padding(u32* d, const u32* s, const u32 no_of_bytes){
u32 i;
if (no_of_bytes == 0) {
dest[0] = 0x00000080; // little-endian
dest[1] = 0x00000000;
dest[2] = 0x00000000;
dest[3] = 0x00000000;
d[0] = 0x00000080; // little-endian
d[1] = 0x00000000;
d[2] = 0x00000000;
d[3] = 0x00000000;
}
else if (no_of_bytes < GIFT128_BLOCK_SIZE) {
for (i = 0; i < no_of_bytes/4+1; i++)
dest[i] = src[i];
dest[i-1] &= ~(0xffffffffL << (no_of_bytes % 4)*8);
dest[i-1] |= 0x00000080L << (no_of_bytes % 4)*8;
d[i] = s[i];
d[i-1] &= ~(0xffffffffL << (no_of_bytes % 4)*8);
d[i-1] |= 0x00000080L << (no_of_bytes % 4)*8;
for (; i < 4; i++)
dest[i] = 0x00000000;
d[i] = 0x00000000;
}
else {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
dest[3] = src[3];
d[0] = s[0];
d[1] = s[1];
d[2] = s[2];
d[3] = s[3];
}
}
......@@ -37,7 +30,7 @@ static inline void padding(u32* dest, const u32* src, const u32 no_of_bytes) {
* Constant-time implementation of the GIFT-COFB authenticated cipher based on
* fixsliced GIFTb-128. Encryption/decryption is handled by the same function,
* depending on the 'mode' parameter (1/0).
****************************************************************************/
***************************************************************************/
int giftcofb_crypt(u8* out, const u8* key, const u8* nonce, const u8* ad,
u32 ad_len, const u8* in, u32 in_len, const int encrypting) {
......@@ -127,9 +120,6 @@ int giftcofb_crypt(u8* out, const u8* key, const u8* nonce, const u8* ad,
return tmp0;
}
/****************************************************************************
* API required by the NIST for the LWC competition.
****************************************************************************/
int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen,
const unsigned char* m, unsigned long long mlen,
const unsigned char* ad, unsigned long long adlen,
......@@ -140,9 +130,6 @@ int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen,
return giftcofb_crypt(c, k, npub, ad, adlen, m, mlen, COFB_ENCRYPT);
}
/****************************************************************************
* API required by the NIST for the LWC competition.
****************************************************************************/
int crypto_aead_decrypt(unsigned char* m, unsigned long long *mlen,
unsigned char* nsec, const unsigned char* c,
unsigned long long clen, const unsigned char* ad,
......
......@@ -7,12 +7,6 @@
typedef unsigned char u8;
typedef unsigned int u32;
typedef struct param_128 {
u32 ctr;
u8 nonce[12];
u32 rkey[80];
} param_128;
extern void gift128_keyschedule(const u8* key, u32* rkey);
extern void giftb128_encrypt_block(u8* out_block, const u32* rkey, const u8* in_block);
......
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