openbsd-misc
[Top] [All Lists]

Safer+ encryption

To: misc@openbsd.org
Subject: Safer+ encryption
From: "vipin mehta" <vipin_mehta@hotmail.com>
Date: Wed, 28 Feb 2001 16:40:54
Sender: owner-misc@openbsd.org
Hi,
I implemented the SAFER+ algorithm on my own but I'm facing some problem in getting the correct results. Can you guys please help me to trace out as to where I'm committing the error. I'm attaching the code for your reference or if anyone can give me one complete test vector with the output at every step at every round, I'll be highly obliged.

Regards,
Vipin Mehta


Code Starts here ==>

/* The implementation is not optimized at all, so forgive me if I have freaked out with the code size. I just wanted to get the correct results. Later on I would have done the optimization but here am
  I, stuck up at the first position itself */
# include <stdio.h>

/* BIAS Vector Table */
unsigned char SAFER_PLUS_BTable[17][16]={
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x46, 0x97, 0xb1, 0xba, 0xa3, 0xb7, 0x10, 0x0a, 0xc5, 0x37, 0xb3, 0xc9, 0x5a, 0x28, 0xac, 0x64}, {0xec, 0xab, 0xaa, 0xc6, 0x67, 0x95, 0x58, 0x0d, 0xf8, 0x9a, 0xf6, 0x6e, 0x66, 0xdc, 0x05, 0x3d}, {0x8a, 0xc3, 0xd8, 0x89, 0x6a, 0xe9, 0x36, 0x49, 0x43, 0xbf, 0xeb, 0xd4, 0x96, 0x9b, 0x68, 0xa0}, {0x5d, 0x57, 0x92, 0x1f, 0xd5, 0x71, 0x5c, 0xbb, 0x22, 0xc1, 0xbe, 0x7b, 0xbc, 0x99, 0x63, 0x94}, {0x2a, 0x61, 0xb8, 0x34, 0x32, 0x19, 0xfd, 0xfb, 0x17, 0x40, 0xe6, 0x51, 0x1d, 0x41, 0x44, 0x8f}, {0xdd, 0x04, 0x80, 0xde, 0xe7, 0x31, 0xd6, 0x7f, 0x01, 0xa2, 0xf7, 0x39, 0xda, 0x6f, 0x23, 0xca}, {0x3a, 0xd0, 0x1c, 0xd1, 0x30, 0x3e, 0x12, 0xa1, 0xcd, 0x0f, 0xe0, 0xa8, 0xaf, 0x82, 0x59, 0x2c}, {0x7d, 0xad, 0xb2, 0xef, 0xc2, 0x87, 0xce, 0x75, 0x06, 0x13, 0x02, 0x90, 0x4f, 0x2e, 0x72, 0x33}, {0xc0, 0x8d, 0xcf, 0xa9, 0x81, 0xe2, 0xc4, 0x27, 0x2f, 0x6c, 0x7a, 0x9f, 0x52, 0xe1, 0x15, 0x38}, {0xfc, 0x20, 0x42, 0xc7, 0x08, 0xe4, 0x09, 0x55, 0x5e, 0x8c, 0x14, 0x76, 0x60, 0xff, 0xdf, 0xd7}, {0xfa, 0x0b, 0x21, 0x00, 0x1a, 0xf9, 0xa6, 0xb9, 0xe8, 0x9e, 0x62, 0x4c, 0xd9, 0x91, 0x50, 0xd2}, {0x18, 0xb4, 0x07, 0x84, 0xea, 0x5b, 0xa4, 0xc8, 0x0e, 0xcb, 0x48, 0x69, 0x4b, 0x4e, 0x9c, 0x35}, {0x45, 0x4d, 0x54, 0xe5, 0x25, 0x3c, 0x0c, 0x4a, 0x8b, 0x3f, 0xcc, 0xa7, 0xdb, 0x6b, 0xae, 0xf4}, {0x2d, 0xf3, 0x7c, 0x6d, 0x9d, 0xb5, 0x26, 0x74, 0xf2, 0x93, 0x53, 0xb0, 0xf0, 0x11, 0xed, 0x83}, {0xb6, 0x03, 0x16, 0x73, 0x3b, 0x1e, 0x8e, 0x70, 0xbd, 0x86, 0x1b, 0x47, 0x7e, 0x24, 0x56, 0xf1}, {0x88, 0x46, 0x97, 0xb1, 0xba, 0xa3, 0xb7, 0x10, 0x0a, 0xc5, 0x37, 0xb3, 0xc9, 0x5a, 0x28, 0xac}
};

/* Exptab Matrix */
unsigned char expf[256] =
{
1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40
};

/* Logtab Matrix */
unsigned char logf[256] =
{
128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, 192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, 112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, 201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, 175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, 121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, 189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, 208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, 210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, 164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, 122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, 109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, 184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48
};

/* The input test key */
unsigned char input_key[17] =
{
        0x29, 0x23, 0xbe, 0x84, 0xe1, 0x6c, 0xd6, 0xae,
        0x52, 0x90, 0x49, 0xf1, 0xf1, 0xbb, 0xe9, 0xeb,
        0x00
};

/* The input Vector on which I'll do all the operations and finally get the result
  in this vector itself */
unsigned char input_vector[16] =
{
        0xb3, 0xa6, 0xdb, 0x3c, 0x87, 0x0c, 0x3e, 0x99,
        0x24, 0x5e, 0x0d, 0x1c, 0x06, 0xb7, 0x47, 0xde
};

/* The output_keys, 2-D array, contains all the 17 keys for the 8 rounds. Fortunately I've been able to get the key scheduling correct in my first attempt itself. So value in the
  output_keys matrix should be fine */
unsigned char output_keys[17][16];
unsigned char tmp[16];

/* Key scheduling algorithm */
void generate_key(unsigned char round)
{
        unsigned char count;
        unsigned char tmp;

        for (count=round; count<round+16; count++)
        {
output_keys[round][count-round] = (input_key[count%17]+SAFER_PLUS_BTable[round][count-round])%256;

                tmp = (input_key[count%17] & 0xe0) >> 5;
                input_key[count%17] = ((input_key[count%17] << 3) & 0xf8)| tmp;
        }
        tmp = (input_key[count%17] & 0xe0) >> 5;
        input_key[count%17] = ((input_key[count%17] << 3) & 0xf8) | tmp;
}

/* I call filter 1 as the first set operation to be performed in each round and is nothing but
  xor add add xor xor add add xor xor add add xor xor add add xor */
void filter1(unsigned char round)
{
        input_vector[0] ^= output_keys[2*round][0];
        input_vector[3] ^= output_keys[2*round][3];
        input_vector[4] ^= output_keys[2*round][4];
        input_vector[7] ^= output_keys[2*round][7];
        input_vector[8] ^= output_keys[2*round][8];
        input_vector[11] ^= output_keys[2*round][11];
        input_vector[12] ^= output_keys[2*round][12];
        input_vector[15] ^= output_keys[2*round][15];

        input_vector[1] = (input_vector[1] + output_keys[2*round][1])%256;
        input_vector[2] = (input_vector[2] + output_keys[2*round][2])%256;
        input_vector[5] = (input_vector[5] + output_keys[2*round][5])%256;
        input_vector[6] = (input_vector[6] + output_keys[2*round][6])%256;
        input_vector[9] = (input_vector[9] + output_keys[2*round][9])%256;
        input_vector[10] = (input_vector[10] + output_keys[2*round][10])%256;
        input_vector[13] = (input_vector[13] + output_keys[2*round][13])%256;
        input_vector[14] = (input_vector[14] + output_keys[2*round][14])%256;
}

/* I call filter 2 as the second set operation to be performed in each round and is nothing but
  exp log log exp exp log log exp exp log log exp exp log log exp */
void filter2(void)
{
        input_vector[0] = expf[input_vector[0]];
        input_vector[3] = expf[input_vector[3]];
        input_vector[4] = expf[input_vector[4]];
        input_vector[7] = expf[input_vector[7]];
        input_vector[8] = expf[input_vector[8]];
        input_vector[11] = expf[input_vector[11]];
        input_vector[12] = expf[input_vector[12]];
        input_vector[15] = expf[input_vector[15]];

        input_vector[1] = logf[input_vector[1]];
        input_vector[2] = logf[input_vector[2]];
        input_vector[5] = logf[input_vector[5]];
        input_vector[6] = logf[input_vector[6]];
        input_vector[9] = logf[input_vector[9]];
        input_vector[10] = logf[input_vector[10]];
        input_vector[13] = logf[input_vector[13]];
        input_vector[14] = logf[input_vector[14]];
}

/* I call filter 3 as the third set operation to be performed in each round and is nothing but
  add xor xor add add xor xor add add xor xor add add xor xor add */
void filter3(unsigned char round)
{
        input_vector[1] ^= output_keys[2*round+1][1];
        input_vector[2] ^= output_keys[2*round+1][2];
        input_vector[5] ^= output_keys[2*round+1][5];
        input_vector[6] ^= output_keys[2*round+1][6];
        input_vector[9] ^= output_keys[2*round+1][9];
        input_vector[10] ^= output_keys[2*round+1][10];
        input_vector[13] ^= output_keys[2*round+1][13];
        input_vector[14] ^= output_keys[2*round+1][14];

        input_vector[0] = (input_vector[0] + output_keys[2*round+1][0])%256;
        input_vector[3] = (input_vector[3] + output_keys[2*round+1][3])%256;
        input_vector[4] = (input_vector[4] + output_keys[2*round+1][4])%256;
        input_vector[7] = (input_vector[7] + output_keys[2*round+1][7])%256;
        input_vector[8] = (input_vector[8] + output_keys[2*round+1][8])%256;
        input_vector[11] = (input_vector[11] + output_keys[2*round+1][11])%256;
        input_vector[12] = (input_vector[12] + output_keys[2*round+1][12])%256;
        input_vector[15] = (input_vector[15] + output_keys[2*round+1][15])%256;
}

/* This will calculate the pht for the 16 octets */
void pht(void)
{
        unsigned char count;

        for (count=0; count<8; count++)
        {
input_vector[2*count] = (2*input_vector[2*count] + input_vector[2*count+1])%256; input_vector[2*count+1] = (input_vector[2*count] + input_vector[2*count+1])%256;
        }
}

/* This will do the Armenian Shuffling */
void shuffle(void)
{
        unsigned char count = 0;

        /* Armenian Shuffling */
        tmp[0] = input_vector[8];
        tmp[1] = input_vector[11];
        tmp[2] = input_vector[12];
        tmp[3] = input_vector[15];
        tmp[4] = input_vector[2];
        tmp[5] = input_vector[1];
        tmp[6] = input_vector[6];
        tmp[7] = input_vector[5];
        tmp[8] = input_vector[10];
        tmp[9] = input_vector[9];
        tmp[10] = input_vector[14];
        tmp[11] = input_vector[13];
        tmp[12] = input_vector[0];
        tmp[13] = input_vector[7];
        tmp[14] = input_vector[4];
        tmp[15] = input_vector[3];

        for (count=0; count<16; count++)
        {
                input_vector[count] = tmp[count];
        }
}

/* Main */
int main(void)
{
        unsigned char parity_byte = 0;
        unsigned char count = 0;

/* Generating the Scheduling keys and it works correctly. I've checked it against one of the test
           vectors I had */
        for (count=0; count<16; count++)
        {
                parity_byte ^= input_key[count];
        }
        input_key[16] = parity_byte;

        for (count=0; count<17; count++)
        {
                generate_key(count);
        }

        /* Starting the 8 rounds */
        for (count=0; count<8; count++)
        {
                filter1(count);
                filter2();
                filter3(count);

                /* Invertible linear transformation */
                pht();
                shuffle();
                pht();
                shuffle();
                pht();
                shuffle();
                pht();
        }

/* Calling the filter1 with value 8 to use the last sub-key to be used for the output
           transformation */
        filter1(8);

        /* Printing the output */
        for (count=0; count<16; count++)
        {
                printf("%d ", input_vector[count]);
        }
        printf("\n");

        return 0;
}



_________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com.


<Prev in Thread] Current Thread [Next in Thread>
  • Safer+ encryption, vipin mehta <=