// This file is part of the Advanced Encryption Standard (AES) Tutorial.
// Copyright (C) 2005 - 2008 CodePlanet http://www.codeplanet.eu/
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// It is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
#include
#include // for uint8_t
/**
* Galois field GF(2^8): Print log and exponentiation table.
*/
void write_tables(uint8_t* logtable, uint8_t* exptable, FILE *fp)
{
unsigned int i, c;
fprintf(fp, "Generator: %2.2x\n\n", exptable[1]);
fprintf(fp, "Log table:\n");
fprintf(fp, " | 0 1 2 3 4 5 6 7 8 9 a b c d e f\n");
fprintf(fp, "---|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|");
for(i = 0, c = 0; i < 256; i++) {
if(!(i % 16)) {
fprintf(fp, "\n%x0 |", c);
++c;
}
fprintf(fp, "%2.2x ", logtable[i]);
}
fprintf(fp, "\n\nExponentiation table:\n");
fprintf(fp, " | 0 1 2 3 4 5 6 7 8 9 a b c d e f\n");
fprintf(fp, "---|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|");
for(i = 0, c = 0; i < 256; i++) {
if(!(i % 16)) {
fprintf(fp, "\n%x0 |", c);
++c;
}
fprintf(fp, "%2.2x ", exptable[i]);
}
fprintf(fp, "\n\n");
}
/**
* Multiply two numbers in the GF(2^8) finite field defined
* by the polynomial x^8 + x^4 + x^3 + x + 1
*/
uint8_t galois_multiplication(uint8_t a, uint8_t b)
{
uint8_t p = 0;
uint8_t counter;
uint8_t hi_bit_set;
for (counter = 0; counter < 8; counter++) {
if ((b & 1) == 1)
p ^= a;
hi_bit_set = (a & 0x80); // xtime()
a <<= 1;
if (hi_bit_set == 0x80)
a ^= 0x1b;
b >>= 1;
}
return p;
}
int main(int argc, char **argv)
{
static char filename[] = "rijndael-tables.txt";
FILE *fp = NULL;
uint8_t logtable[256]; // Log table
uint8_t exptable[256]; // Exp table
unsigned int i, j;
uint8_t generators[128] = {
3, 5, 6, 9, 11, 14, 17, 18, 19, 20, 23, 24,
25, 26, 28, 30, 31, 33, 34, 35, 39, 40, 42, 44,
48, 49, 60, 62, 63, 65, 69, 70, 71, 72, 73, 75,
76, 78, 79, 82, 84, 86, 87, 88, 89, 90, 91, 95,
100, 101, 104, 105, 109, 110, 112, 113, 118, 119, 121, 122,
123, 126, 129, 132, 134, 135, 136, 138, 142, 143, 144, 147,
152, 153, 155, 157, 160, 164, 165, 166, 149, 150, 167, 169,
170, 172, 173, 178, 180, 183, 184, 185, 186, 190, 191, 192,
193, 196, 200, 201, 206, 207, 208, 214, 215, 218, 220, 221,
222, 226, 227, 229, 230, 231, 233, 234, 235, 238, 240, 241,
244, 245, 246, 248, 251, 253, 254, 255 };
// Open file
if((fp = fopen(filename, "w")) == NULL) {
printf("Error opening %s", filename);
return 1;
}
for (i = 0; i < 128; i++) {
exptable[0] = 0x01;
logtable[0] = 0x00;
// Calculate tables
for (j = 1; j < 256; j++) {
exptable[j] = galois_multiplication(exptable[j-1], generators[i]);
logtable[exptable[j]] = j; // The value in exptable[j] is the actual offset
}
write_tables(logtable, exptable, fp); // Write the 2 tables
}
fclose(fp); // Close file
return 0;
}