Lightweight cryptographic algorithm GFIT C code

Introduction of lightweight cryptography GFIT and its C implementation

GIFT algorithm:
n={64,128}, k=128, r={28,40} are {GIFT-64, GIFT-128} respectively.
(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));
    }
    void addkeys(byte*k, byte*s)
    {
    	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;
    
    }
    void addLFSR(byte*s, byte*c)
    {
    	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);
            addkeys(k, s);
    		UpdateConstant(Constants);
    		addLFSR(s, 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