speck_64-128_and_128-128.c 2.27 KB
Newer Older
lwc-tester committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
#include "options.h" //options.h to define BLOCKSIZE

#if BLOCKSIZE == 64
#	define ROUNDS 27

	//size of a word in bytes
	//(pt and ct size = 2 words = 1 block)
#	define WSZ 4

	//number of words for key
#	define M 4

#elif BLOCKSIZE == 128
#	define ROUNDS 32

	//size of a word in bytes
	//(pt and ct size = 2 words = 1 block)
#	define WSZ 8

	//number of words for key
#	define M 2

#endif

#define CARRY(r, a, b) ( ((a>>7)&(b>>7)) | ((a>>7)&(!(r>>7))) | ((!(r>>7))&(b>>7)) )

typedef unsigned char u8;
typedef unsigned int u32;

void blockcipher_encrypt (u8 *ct, const u8 *pt, const u8 *K)
{
    u8 L[(ROUNDS+M-2)*WSZ] = { 0 };
    u8 RK[ROUNDS*WSZ] = { 0 };
	u8 carry;
	u8 ct_temp[2*WSZ] = { 0 };

	//RK0 = K0	
	for(u8 j=0; j<WSZ; j++){
		RK[j] = K[j];
	}
	
	//initial Ls
	for(u8 i=0; i<M-1; i++){
		for(u8 j=0; j<WSZ; j++){
			L[i*WSZ+j] = K[(i+1)*WSZ+j];
		}
	}
	
	//Key Schedule
    for (u8 i=0; i<ROUNDS-1; i++){
		carry = 0;
		
		//L[i+m-1] = (ROR(L[i], 8) + RK[i]) ^ i
		for(u8 j=0; j<WSZ; j++){
			L[(i+M-1)*WSZ+j] = L[i*WSZ+((j+1)%WSZ)] + RK[i*WSZ+j];
			
			//add carry
			L[(i+M-1)*WSZ+j] += carry;
			
			//set next carry
			carry = CARRY(L[(i+M-1)*WSZ+j], L[i*WSZ+((j+1)%WSZ)], RK[i*WSZ+j]);
			
			if(j==0){
				L[(i+M-1)*WSZ+j] ^= i;
			}
		}
		
        //RK[i+1] = ROL(RK[i], 3) ^ L[i+m-1]
		for(u8 j=0; j<WSZ; j++){
			RK[(i+1)*WSZ+j] = (RK[i*WSZ+j]<<3 | RK[i*WSZ+((j+WSZ-1)%WSZ)]>>5) ^ L[(i+M-1)*WSZ+j];
		}
    }
	
	//Encryption 
	for(u8 j=0; j<2*WSZ; j++){
		ct[j] = pt[j]; //copy pt to ct
	}

    for(u8 i=0; i<ROUNDS; i++){
		carry = 0;
		
		//ct[1] = (ROR(ct[1], 8) + ct[0]) ^ RK[i]
		for(u8 j=0; j<WSZ; j++){
			ct_temp[WSZ+j] = (ct[WSZ+((j+1)%WSZ)] + ct[j]);
			
			//add carry
			ct_temp[WSZ+j] += carry;
			
			//set next carry
90 91 92 93 94
			if (carry)
				carry = (ct_temp[WSZ+j] <= ct[WSZ+((j+1)%WSZ)]) || (ct_temp[WSZ+j] <= ct[j]);
			else
				carry = (ct_temp[WSZ+j] < ct[WSZ+((j+1)%WSZ)]) || (ct_temp[WSZ+j] < ct[j]);

lwc-tester committed
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
			
			
			ct_temp[WSZ+j] ^= RK[i*WSZ+j];
		}
		
		//ct[0] = ROL(ct[0], 3) ^ ct[1]
		for(u8 j=0; j<WSZ; j++){
			ct_temp[j] = ( ct[j]<<3 | ct[(j+WSZ-1)%WSZ]>>5) ^ ct_temp[WSZ+j];
		}
		
		//copy ct from temp
		for(u8 j=0; j<2*WSZ; j++){
			ct[j] = ct_temp[j];
		}
    }
110
}