package ro.pub.cs.pp.a51hadoop.algorithm.a51; import ro.pub.cs.pp.a51hadoop.algorithm.Hashfn; import ro.pub.cs.pp.a51hadoop.algorithm.a51.A51Bitops; import ro.pub.cs.pp.a51hadoop.algorithm.a51.A51Constants; public class A51KeySetup { public final int[] R; /* * Clock all three of R1,R2,R3, ignoring their middle bits. * This is only used for key setup. */ private static int[] clockallthree(final int[] R) { int ret[] = new int[R.length]; for(int i = 0; i < R.length; i++) ret[i] = A51Bitops.clockone(R[i], A51Constants.R_mask[i], A51Constants.R_feedback_taps[i]); return ret; } /* Do the A5/1 key setup. This routine accepts a 64-bit key * and a 22-bit frame number. */ public static int[] keysetup(int[] key, int frame) { int i; int[] R = new int[3]; /* Zero out the shift registers. */ for(i = 0; i < R.length; i++) R[i] = 0; /* Load the key into the shift registers, LSB of first * byte of key array first, clocking each register * once for every key bit loaded. (The usual clock * control rule is temporarily disabled.) */ for (i = 0; i < 64; i++) { R = clockallthree(R); /* always clock */ int keybit = (key[i/8] >> (i & 7)) & 1; /* The i-th bit of the key */ for(int j = 0; j < R.length; j++) R[j] ^= keybit; } /* Load the frame number into the shift * registers, LSB first, * clocking each register once for every * key bit loaded. (The usual clock * control rule is still disabled.) */ for (i = 0; i < 22; i++) { R = clockallthree(R); /* always clock */ int framebit = (frame >> i) & 1; /* The i-th bit of the frame # */ for(int j = 0; j < R.length; j++) R[j] ^= framebit; } /* Run the shift registers for 100 clocks * to mix the keying material and frame number * together with output generation disabled, * so that there is sufficient avalanche. * We re-enable the majority-based clock control * rule from now on. */ for (i=0; i<100; i++) { R = A51Hashfn.clock(R); } /* Now the key is properly set up. */ return R; } public A51KeySetup(int[] key, int frame) { this.R = keysetup(key, frame); } }