# Lightweight cryptographic algorithm GFIT C code

Introduction of lightweight cryptography GFIT and its C implementation

(1) Enter n-bit plaintext and k-bit key.
(2) S_SubCells(S). Replacement of Sbox GS
(3) S_PermBits(S). Mapping from bit position I of cryptographic state to bit position P(i), bP(i) bi, I <{0,... n, 1}.
(4) Ci_f(Ci_1). Wheel constants are generated using 6-bit affine LFSR and their states are expressed as (c5,c4,c3,c2,c1,c0). Its update function is defined as: (c5,c4,c3,c2,c1,c0)(c4,c3,c2,c1,c0,c5_c4 1). Six bits are initialized to zero and updated before being used for a given wheel.
(5) RK_K. K = k7||k6 | | || k0 is the key state, in which ki is 16 bits. Press k7||k6 | |. || k1 | | | k0 k1 2||k0 12 | | ||k3||k2, updating the key state, where >>i is the I bit in the 16 bit right shift.
(6) S_AddRoundKey(S,K,Ci). 1. Intermediate results are different from CI or. bn-1_bn-1_1, b23_b23_c5,b19_b19_c4, b15_b15_c3, b11_b11_c2,b7_b7_c1, b3_c0.2. Intermediate results are different from K or.
(7) Repeated execution (2) (3) (3) r times
(8) Output ciphertext C.

The flow chart of GIFT is as follows:

```   #include "stdafx.h"
#include<stdio.h>
#include<string.h>
#include"inttypes.h"
typedef uint8_t byte;
static const byte sbox[16] = {
0x01, 0x0a, 0x04, 0x0c,
0x06, 0x0f, 0x03, 0x09,
0x02, 0x0d, 0x0b, 0x07,
0x05, 0x00, 0x08, 0x0e
};
static  byte rPx[64] = {
0,17,34,51,48,1,18,35,32,49,2,19,16,33,50,3,
4,21,38,55,52,5,22,39,36,53,6,23,20,37,54,7,
8,25,42,59,56,9,26,43,40,57,10,27,24,41,58,11,
12,29,46,63,60,13,30,47,44,61,14,31,28,45,62,15
};

void printfs(const byte*s, int j = 16)
{
for (int i = 0; i < j; i++)
{
printf("%X ", s[i]);
if (i % 4 == 3) puts("");
}
}
void Subcells(byte*s)
{
for (int i = 0; i < 16; i++)
s[i] = sbox[s[i]];
}
void Exchang(byte*s)
{
int i;
byte rowl, col, shift, rowl1;
byte g[16];
memset(g, 0, sizeof(g));
for (i = 0; i < 64; i++)
{
rowl = i / 4;
col = i % 4;
shift = 0x01;
shift <<=col;
rowl1 = rPx[i] / 4;
if (shift&s[rowl1])
g[rowl] |= shift;
}
memcpy(s, g, sizeof(g));
}
{
int i;
byte p,shift,shift1,q,a,b;
byte tmp;
shift = 0x01;
shift1 = 0x02;
for (i = 0; i < 16; i++)
{
int 	j = i / 8;
int  m = i;
if (i >= 8) m = i - 8;
p = k[j];
a = (p >> m)&shift;
q = k[j + 2];
if ((i == 0) || (i == 8)) b = (q << 1)&shift1;
else  b = (q >> (m - 1)&shift1);

if (a== shift)
{
if ((s[i] & shift) == a)
s[i]  = s[i] & 0x0e;
else
s[i] |= (s[i] & shift) ^ a;
}
if (b == shift1)
{
if ((s[i] & shift1) == b)
s[i] = s[i] & 0x0d;
else
s[i] |= (s[i] & shift1) ^ b ;
}
}

}

void UpdateConstant(byte*c)
{
byte a, c5, c4, c0;
a = *c;
c5 = (a >> 5) & 0x01;
c4 = (a >> 4) & 0x01;
c0 = c5 ^ c4 ^ 1;
*c= ((*c<< 1) & 0x3f) | c0;

}
{
byte a, b;
byte shift = 0x08;
a = *c;
for (int i = 0; i < 6; i++)
{
b = ((a >> i) << 3)&shift;
if (b == shift)
{
if ((s[i] & shift) == b)
s[i] = s[i] & 0x07;
else s[i] |= (s[i] & shift) ^ b;
}
}
if (s[15] & shift)
s[15] = s[15] & 0x07;
else s[15] |= (s[15] & shift) ^ shift;

}
void Ercrypt(byte*s, byte*k)
{
byte *Constants;
byte a = 0x00;
Constants = &a;
int i;
for (i = 0; i < 28; i++)
{
Subcells(s);
Exchang(s);
UpdateConstant(Constants);
Updatekeys(k);

}
}

int main()
{
byte k[16], p[16];
for (int i = 0; i < 16; i++)
p[i] = 0x0f;
for (int i = 0; i < 16; i++)
k[i] = 0xff;

puts("Plaintext:"); printfs(p); puts("");
puts("key:"); printfs(k, 16);    puts("");
puts("Ercrypt:");
Ercrypt(p, k);
printfs(p);
return 0;
}
```

Posted on Mon, 07 Oct 2019 06:23:11 -0700 by amazinggrace1983