gift128.c 3.12 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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
/*
GIFT-128 (bitslice) implementations
Prepared by: Siang Meng Sim
Email: crypto.s.m.sim@gmail.com
Date: 23 Mar 2019
*/
#include <stdint.h>
#include <stdio.h>

/*Round constants*/
const unsigned char GIFT_RC[40] = {
    0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3E, 0x3D, 0x3B, 0x37, 0x2F,
    0x1E, 0x3C, 0x39, 0x33, 0x27, 0x0E, 0x1D, 0x3A, 0x35, 0x2B,
    0x16, 0x2C, 0x18, 0x30, 0x21, 0x02, 0x05, 0x0B, 0x17, 0x2E,
    0x1C, 0x38, 0x31, 0x23, 0x06, 0x0D, 0x1B, 0x36, 0x2D, 0x1A
};

uint32_t rowperm(uint32_t S, int B0_pos, int B1_pos, int B2_pos, int B3_pos){
    uint32_t T=0;
    int b;
    for(b=0; b<8; b++){
        T |= ((S>>(4*b+0))&0x1)<<(b + 8*B0_pos);
        T |= ((S>>(4*b+1))&0x1)<<(b + 8*B1_pos);
        T |= ((S>>(4*b+2))&0x1)<<(b + 8*B2_pos);
        T |= ((S>>(4*b+3))&0x1)<<(b + 8*B3_pos);
    }
    return T;
}

void giftb128(uint8_t P[16], const uint8_t K[16], uint8_t C[16]){
    int round;
    uint32_t S[4],T;
    uint16_t W[8],T6,T7;

    S[0] = ((uint32_t)P[ 0]<<24) | ((uint32_t)P[ 1]<<16) | ((uint32_t)P[ 2]<<8) | (uint32_t)P[ 3];
    S[1] = ((uint32_t)P[ 4]<<24) | ((uint32_t)P[ 5]<<16) | ((uint32_t)P[ 6]<<8) | (uint32_t)P[ 7];
    S[2] = ((uint32_t)P[ 8]<<24) | ((uint32_t)P[ 9]<<16) | ((uint32_t)P[10]<<8) | (uint32_t)P[11];
    S[3] = ((uint32_t)P[12]<<24) | ((uint32_t)P[13]<<16) | ((uint32_t)P[14]<<8) | (uint32_t)P[15];

    W[0] = ((uint16_t)K[ 0]<<8) | (uint16_t)K[ 1];
    W[1] = ((uint16_t)K[ 2]<<8) | (uint16_t)K[ 3];
    W[2] = ((uint16_t)K[ 4]<<8) | (uint16_t)K[ 5];
    W[3] = ((uint16_t)K[ 6]<<8) | (uint16_t)K[ 7];
    W[4] = ((uint16_t)K[ 8]<<8) | (uint16_t)K[ 9];
    W[5] = ((uint16_t)K[10]<<8) | (uint16_t)K[11];
    W[6] = ((uint16_t)K[12]<<8) | (uint16_t)K[13];
    W[7] = ((uint16_t)K[14]<<8) | (uint16_t)K[15];

    for(round=0; round<40; round++){
        /*===SubCells===*/
        S[1] ^= S[0] & S[2];
        S[0] ^= S[1] & S[3];
        S[2] ^= S[0] | S[1];
        S[3] ^= S[2];
        S[1] ^= S[3];
        S[3] ^= 0xffffffff;
        S[2] ^= S[0] & S[1];

        T = S[0];
        S[0] = S[3];
        S[3] = T;


        /*===PermBits===*/
        S[0] = rowperm(S[0],0,3,2,1);
        S[1] = rowperm(S[1],1,0,3,2);
        S[2] = rowperm(S[2],2,1,0,3);
        S[3] = rowperm(S[3],3,2,1,0);

        /*===AddRoundKey===*/
        S[2] ^= ((uint32_t)W[2]<<16) | (uint32_t)W[3];
        S[1] ^= ((uint32_t)W[6]<<16) | (uint32_t)W[7];

        /*Add round constant*/
        S[3] ^= 0x80000000 ^ GIFT_RC[round];

        /*===Key state update===*/
        T6 = (W[6]>>2) | (W[6]<<14);
        T7 = (W[7]>>12) | (W[7]<<4);
        W[7] = W[5];
        W[6] = W[4];
        W[5] = W[3];
        W[4] = W[2];
        W[3] = W[1];
        W[2] = W[0];
        W[1] = T7;
        W[0] = T6;
    }

    C[ 0] = S[0]>>24;
    C[ 1] = S[0]>>16;
    C[ 2] = S[0]>>8;
    C[ 3] = S[0];
    C[ 4] = S[1]>>24;
    C[ 5] = S[1]>>16;
    C[ 6] = S[1]>>8;
    C[ 7] = S[1];
    C[ 8] = S[2]>>24;
    C[ 9] = S[2]>>16;
    C[10] = S[2]>>8;
    C[11] = S[2];
    C[12] = S[3]>>24;
    C[13] = S[3]>>16;
    C[14] = S[3]>>8;
    C[15] = S[3];

return;}