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 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
|
/* This is a program which calculates and makes the tables used by
the RNG core
Written by Sam Trenholme
Placed in the public domain 2001.
*/
/* Multiply two elements together for any GF(2^n), where n is less than 30
Input: The two elements to multiply together, the degree to
multiply by, the reducing polynomial for the degree in question
Output: The product of the two elements
*/
int gmul(int i1, int i2, int degree, int field) {
int result = 0;
int counter;
int hibit = 1;
for(counter = 0; counter < degree; counter++)
hibit <<= 1;
for(counter = 0; counter < degree; counter++) {
if((i2 & 1) == 1)
result ^= i1;
i2 >>= 1;
i1 <<= 1;
if((i1 & hibit) == hibit)
i1 ^= field;
}
return result;
}
/* Multiply two elements together in a galois field of 2^8
Input: The two elements to multiply together
Output: The product of the two elements
*/
int mul(int i1, int i2) {
return gmul(i1,i2,8,0x11d);
}
/* Multiply two elements together in the field of 2^4
Input: The two elements to multiply together
Output: The product of the two elements
*/
unsigned char mul_4(unsigned char i1, unsigned char i2) {
return gmul(i1,i2,4,0x13);
}
/* sbox0: give them the value from the original Whirlpool sbox
Input: The byte to calculate the sbox for
Output: The sbox for the byte in question
*/
unsigned char sbox0(unsigned char in) {
unsigned char lsbox[256] = {
0x68, 0xd0, 0xeb, 0x2b, 0x48, 0x9d, 0x6a, 0xe4,
0xe3, 0xa3, 0x56, 0x81, 0x7d, 0xf1, 0x85, 0x9e,
0x2c, 0x8e, 0x78, 0xca, 0x17, 0xa9, 0x61, 0xd5,
0x5d, 0x0b, 0x8c, 0x3c, 0x77, 0x51, 0x22, 0x42,
0x3f, 0x54, 0x41, 0x80, 0xcc, 0x86, 0xb3, 0x18,
0x2e, 0x57, 0x06, 0x62, 0xf4, 0x36, 0xd1, 0x6b,
0x1b, 0x65, 0x75, 0x10, 0xda, 0x49, 0x26, 0xf9,
0xcb, 0x66, 0xe7, 0xba, 0xae, 0x50, 0x52, 0xab,
0x05, 0xf0, 0x0d, 0x73, 0x3b, 0x04, 0x20, 0xfe,
0xdd, 0xf5, 0xb4, 0x5f, 0x0a, 0xb5, 0xc0, 0xa0,
0x71, 0xa5, 0x2d, 0x60, 0x72, 0x93, 0x39, 0x08,
0x83, 0x21, 0x5c, 0x87, 0xb1, 0xe0, 0x00, 0xc3,
0x12, 0x91, 0x8a, 0x02, 0x1c, 0xe6, 0x45, 0xc2,
0xc4, 0xfd, 0xbf, 0x44, 0xa1, 0x4c, 0x33, 0xc5,
0x84, 0x23, 0x7c, 0xb0, 0x25, 0x15, 0x35, 0x69,
0xff, 0x94, 0x4d, 0x70, 0xa2, 0xaf, 0xcd, 0xd6,
0x6c, 0xb7, 0xf8, 0x09, 0xf3, 0x67, 0xa4, 0xea,
0xec, 0xb6, 0xd4, 0xd2, 0x14, 0x1e, 0xe1, 0x24,
0x38, 0xc6, 0xdb, 0x4b, 0x7a, 0x3a, 0xde, 0x5e,
0xdf, 0x95, 0xfc, 0xaa, 0xd7, 0xce, 0x07, 0x0f,
0x3d, 0x58, 0x9a, 0x98, 0x9c, 0xf2, 0xa7, 0x11,
0x7e, 0x8b, 0x43, 0x03, 0xe2, 0xdc, 0xe5, 0xb2,
0x4e, 0xc7, 0x6d, 0xe9, 0x27, 0x40, 0xd8, 0x37,
0x92, 0x8f, 0x01, 0x1d, 0x53, 0x3e, 0x59, 0xc1,
0x4f, 0x32, 0x16, 0xfa, 0x74, 0xfb, 0x63, 0x9f,
0x34, 0x1a, 0x2a, 0x5a, 0x8d, 0xc9, 0xcf, 0xf6,
0x90, 0x28, 0x88, 0x9b, 0x31, 0x0e, 0xbd, 0x4a,
0xe8, 0x96, 0xa6, 0x0c, 0xc8, 0x79, 0xbc, 0xbe,
0xef, 0x6e, 0x46, 0x97, 0x5b, 0xed, 0x19, 0xd9,
0xac, 0x99, 0xa8, 0x29, 0x64, 0x1f, 0xad, 0x55,
0x13, 0xbb, 0xf7, 0x6f, 0xb9, 0x47, 0x2f, 0xee,
0xb8, 0x7b, 0x89, 0x30, 0xd3, 0x7f, 0x76, 0x82
};
return lsbox[in];
}
/* sbox1: Give them the value for the anubis/khazad sbox
Input: The byte to calculate the sbox for
Output: The sbox for the byte in question
*/
unsigned char sbox1(unsigned char in) {
unsigned char lsbox[256] = {
0xa7, 0xd3, 0xe6, 0x71, 0xd0, 0xac, 0x4d, 0x79,
0x3a, 0xc9, 0x91, 0xfc, 0x1e, 0x47, 0x54, 0xbd,
0x8c, 0xa5, 0x7a, 0xfb, 0x63, 0xb8, 0xdd, 0xd4,
0xe5, 0xb3, 0xc5, 0xbe, 0xa9, 0x88, 0x0c, 0xa2,
0x39, 0xdf, 0x29, 0xda, 0x2b, 0xa8, 0xcb, 0x4c,
0x4b, 0x22, 0xaa, 0x24, 0x41, 0x70, 0xa6, 0xf9,
0x5a, 0xe2, 0xb0, 0x36, 0x7d, 0xe4, 0x33, 0xff,
0x60, 0x20, 0x08, 0x8b, 0x5e, 0xab, 0x7f, 0x78,
0x7c, 0x2c, 0x57, 0xd2, 0xdc, 0x6d, 0x7e, 0x0d,
0x53, 0x94, 0xc3, 0x28, 0x27, 0x06, 0x5f, 0xad,
0x67, 0x5c, 0x55, 0x48, 0x0e, 0x52, 0xea, 0x42,
0x5b, 0x5d, 0x30, 0x58, 0x51, 0x59, 0x3c, 0x4e,
0x38, 0x8a, 0x72, 0x14, 0xe7, 0xc6, 0xde, 0x50,
0x8e, 0x92, 0xd1, 0x77, 0x93, 0x45, 0x9a, 0xce,
0x2d, 0x03, 0x62, 0xb6, 0xb9, 0xbf, 0x96, 0x6b,
0x3f, 0x07, 0x12, 0xae, 0x40, 0x34, 0x46, 0x3e,
0xdb, 0xcf, 0xec, 0xcc, 0xc1, 0xa1, 0xc0, 0xd6,
0x1d, 0xf4, 0x61, 0x3b, 0x10, 0xd8, 0x68, 0xa0,
0xb1, 0x0a, 0x69, 0x6c, 0x49, 0xfa, 0x76, 0xc4,
0x9e, 0x9b, 0x6e, 0x99, 0xc2, 0xb7, 0x98, 0xbc,
0x8f, 0x85, 0x1f, 0xb4, 0xf8, 0x11, 0x2e, 0x00,
0x25, 0x1c, 0x2a, 0x3d, 0x05, 0x4f, 0x7b, 0xb2,
0x32, 0x90, 0xaf, 0x19, 0xa3, 0xf7, 0x73, 0x9d,
0x15, 0x74, 0xee, 0xca, 0x9f, 0x0f, 0x1b, 0x75,
0x86, 0x84, 0x9c, 0x4a, 0x97, 0x1a, 0x65, 0xf6,
0xed, 0x09, 0xbb, 0x26, 0x83, 0xeb, 0x6f, 0x81,
0x04, 0x6a, 0x43, 0x01, 0x17, 0xe1, 0x87, 0xf5,
0x8d, 0xe3, 0x23, 0x80, 0x44, 0x16, 0x66, 0x21,
0xfe, 0xd5, 0x31, 0xd9, 0x35, 0x18, 0x02, 0x64,
0xf2, 0xf1, 0x56, 0xcd, 0x82, 0xc8, 0xba, 0xf0,
0xef, 0xe9, 0xe8, 0xfd, 0x89, 0xd7, 0xc7, 0xb5,
0xa4, 0x2f, 0x95, 0x13, 0x0b, 0xf3, 0xe0, 0x37
};
return lsbox[in];
}
/* sbox: calculate, on the fly, the whirlpool tweaked sbox
Input: The byte to calculate the sbox for
Output: The sbox for the byte in question
*/
unsigned char sbox(unsigned char in) {
/* The sboxes */
unsigned char rbox[16] = {0x7,0xc,0xb,0xd,0xe,0x4,0x9,0xf,
0x6,0x3,0x8,0xa,0x2,0x5,0x1,0x0};
unsigned char ebox[16],iebox[16];
/* The two nibbles of this byte */
unsigned char lnib, rnib, ivalue;
int counter;
/* Generate the ebox */
ebox[0] = 1;
for(counter = 1; counter < 15; counter++)
ebox[counter] = mul_4(ebox[counter - 1],0xb) & 0xf;
ebox[0xf] = 0;
/* Generate the inverse ebox */
for(counter = 0; counter < 16; counter++)
iebox[ebox[counter]] = counter;
lnib = (in & 0xf0) >> 4;
rnib = in & 0x0f;
lnib = ebox[lnib];
rnib = iebox[rnib];
ivalue = lnib ^ rnib;
ivalue = rbox[ivalue];
lnib ^= ivalue;
rnib ^= ivalue;
lnib = ebox[lnib];
rnib = iebox[rnib];
return (lnib << 4) | rnib;
}
/* Make one table: Make a single one of the four tables
Input: eight multiply constants, what sbox to use
Output: Displays table on stdout
*/
void one_en_table(int m1, int m2, int m3, int m4,
int m5, int m6, int m7, int m8, int w) {
int counter;
unsigned char s;
for(counter = 0; counter < 256; counter++) {
if(counter % 4 == 0)
printf("\n");
if(w == 1)
s = sbox(counter);
else if(w == 2)
s = sbox0(counter);
else
s = sbox1(counter);
printf("0x%02x%02x%02x%02x%02x%02x%02x%02xLL, ",
mul(s,m1),mul(s,m2),mul(s,m3),mul(s,m4),
mul(s,m5),mul(s,m6),mul(s,m7),mul(s,m8));
}
printf("\n};\n");
}
main(int argc) {
int a[8] = {1,1,3,1,5,8,9,5};
int b,c,t;
printf("/* This file is automatically generated by the program ");
printf("make_64bit_tables.c */\n\n");
/* The s-boxes */
for(c = 0;c < 8; c++) {
printf("static const u64 C%d[256] = {",c);
one_en_table(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],argc);
t = a[7];
for(b = 7; b >= 0; b--)
a[b+1] = a[b];
a[0] = t;
}
/* And the round constants */
printf("static const u64 rc[R + 1] = {\n0x0000000000000000");
for(c = 0; c < 80 ; c++) {
if(c % 8 == 0)
printf("LL,\n0x");
if(argc == 1)
printf("%02x",sbox(c));
else if(argc == 2)
printf("%02x",sbox0(c));
else
printf("%02x",sbox1(c));
}
printf("LL\n};\n");
exit(0);
}
|