/* * Copyright 2000 David Chess; Copyright 2005 Sam Trenholme * * Slump 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 2, or (at your option) any later * version. * * Slump 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 Slump; see the file GPL. If not, write to the Free * Software Foundation, 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * * Additionally, while not required for redistribution of this program, * the following requests are made when making a derived version of * this program: * * - Slump's code is partly derived from the Doom map generator * called SLIGE, by David Chess. Please inform David Chess of * any derived version that you make. His email address is at * the domain "theogeny.com" with the name "chess" placed before * the at symbol. * * - Please do not call any derivative of this program SLIGE. */ /* This is a program which calculates and makes the tables used by the RNG core Written by Sam Trenholme */ /* 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,0x11b); } /* 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); } /* sbox: calculate, on the fly, the 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: four multiply constants Output: Displays table on stdout */ void one_en_table(int m1, int m2, int m3, int m4) { int counter; unsigned char s; for(counter = 0; counter < 256; counter++) { if(counter % 4 == 0) printf("\n"); s = sbox(counter); printf("0x%02x%02x%02x%02xU, ", mul(s,m1),mul(s,m2),mul(s,m3),mul(s,m4)); } printf("\n};\n"); } main() { int a[4] = {19,77,6,16}; printf("/* This file is automatically generated by the program "); printf("make_32bit_tables.c */\n\n"); printf("static const u32 Te0[256] = {"); one_en_table(a[0],a[1],a[2],a[3]); printf("static const u32 Te1[256] = {"); one_en_table(a[3],a[0],a[1],a[2]); printf("static const u32 Te2[256] = {"); one_en_table(a[2],a[3],a[0],a[1]); printf("static const u32 Te3[256] = {"); one_en_table(a[1],a[2],a[3],a[0]); printf("static const u32 Te4[256] = {"); one_en_table(1,1,1,1); exit(0); }