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.
|