/////// Feistel Cipher Algorithm (most common symmetric encyption algorithm) // round function: takes 32bit half xor with key at offset, // which tells it to use the ith version of the key. boolean rev applies // key offsets in reverse order (for decryption) // Max KEYSIZE is 128 because OFFSET array is an array of signed bytes. public class Feistel { public static int ROUNDS = 4; //number of roungs in Feistel Cipher public static int HALFSIZE = 4; // in bytes public static int BLOCKSIZE = HALFSIZE*2; public static int BASESIZE = 124; // number of random bytes public static int KEYSIZE = ROUNDS+BASESIZE; // number of random bytes // actual key consists of BASESIZE + ROUNDS number of bytes // randomize buffer, with each having (byte)max value: public static void setsizes(int r, int h, int ks) { if (r<1 || h<2 || ks<2) return; ROUNDS = r; HALFSIZE =h; BLOCKSIZE = h*2; BASESIZE=ks; KEYSIZE = ROUNDS+BASESIZE; } public static void randomize(byte[] buf, int max) { for (int i=0;i0) { dst[di++] = src[si++]; l--; } return l; // 0 if copy completed } // instance vars and functions byte[] KEY = new byte[BASESIZE]; byte[] KEYI = new byte[ROUNDS]; public Feistel() { randomize(KEY,256); randomize(KEYI,BASESIZE); } public Feistel(byte[] k) { if (k.length!=KEYSIZE) throw new RuntimeException("bad key size"); memcpy(KEY,k,0,0,BASESIZE); memcpy(KEYI,k,0,BASESIZE,ROUNDS); // force the offsets to be compliant for(int i=0;i123) throw new RuntimeException("invalid key"); } public Feistel(byte[] base, byte[] offsets) { if (base.length==BASESIZE && offsets.length==ROUNDS) { KEY=base; KEYI = offsets;} else throw new RuntimeException("bad buffer lengths"); }//constructors // The Feistel "rounding" function void F(int i, byte[] val, byte[] outbuf, boolean rev) { // for the ith key: lookup starting bit index in KEYI, then align i with // KEY[i] and bitwise xor: int si = KEYI[i]; // starting byte index if (rev) si = KEYI[ROUNDS-1-i]; for(int j=0;j