2 * In writing this program, I've had to guess a few pices of information:
4 * 1. Which bits of the key are loaded into which bits of the shift register
5 * 2. Which order the frame sequence number is shifted into the SR (MSB
7 * 3. The position of the feedback taps on R2 and R3 (R1 is known).
8 * 4. The position of the clock control taps. These are on the `middle' one,
9 * I've assumed to be 9 on R1, 11 on R2, 11 on R3.
13 * Look at the `middle' stage of each of the 3 shift registers.
14 * Either 0, 1, 2 or 3 of these 3 taps will be set high.
15 * If 0 or 1 or one of them are high, return true. This will cause each of
16 * the middle taps to be inverted before being used as a clock control. In
17 * all cases either 2 or 3 of the clock enable lines will be active. Thus,
18 * at least two shift registers change on every clock-tick and the system
19 * never becomes stuck.
22 static int threshold(r1, r2, r3)
29 total = (((r1 >> 9) & 0x1) == 1) +
30 (((r2 >> 11) & 0x1) == 1) +
31 (((r3 >> 11) & 0x1) == 1);
39 unsigned long clock_r1(ctl, r1)
43 unsigned long feedback;
46 * Primitive polynomial x**19 + x**5 + x**2 + x + 1
49 ctl ^= ((r1 >> 9) & 0x1);
52 feedback = (r1 >> 18) ^ (r1 >> 17) ^ (r1 >> 16) ^ (r1 >> 13);
53 r1 = (r1 << 1) & 0x7ffff;
60 unsigned long clock_r2(ctl, r2)
64 unsigned long feedback;
68 * Primitive polynomial x**22 + x**9 + x**5 + x + 1
71 ctl ^= ((r2 >> 11) & 0x1);
74 feedback = (r2 >> 21) ^ (r2 >> 20) ^ (r2 >> 16) ^ (r2 >> 12);
75 r2 = (r2 << 1) & 0x3fffff;
82 unsigned long clock_r3(ctl, r3)
86 unsigned long feedback;
89 * Primitive polynomial x**23 + x**5 + x**4 + x + 1
92 ctl ^= ((r3 >> 11) & 0x1);
95 feedback = (r3 >> 22) ^ (r3 >> 21) ^ (r3 >> 18) ^ (r3 >> 17);
96 r3 = (r3 << 1) & 0x7fffff;
103 int keystream(key, frame, alice, bob)
104 unsigned char *key; /* 64 bit session key */
105 unsigned long frame; /* 22 bit frame sequence number */
106 unsigned char *alice; /* 114 bit Alice to Bob key stream */
107 unsigned char *bob; /* 114 bit Bob to Alice key stream */
109 unsigned long r1; /* 19 bit shift register */
110 unsigned long r2; /* 22 bit shift register */
111 unsigned long r3; /* 23 bit shift register */
112 int i; /* counter for loops */
113 int clock_ctl; /* xored with clock enable on each shift register */
114 unsigned char *ptr; /* current position in keystream */
115 unsigned char byte; /* byte of keystream being assembled */
116 unsigned int bits; /* number of bits of keystream in byte */
117 unsigned int bit; /* bit output from keystream generator */
119 /* Initialise shift registers from session key */
121 r1 = (key[0] | (key[1] << 8) | (key[2] << 16) ) & 0x7ffff;
122 r2 = ((key[2] >> 3) | (key[3] << 5) | (key[4] << 13) | (key[5] << 21)) & 0x3fffff;
123 r3 = ((key[5] >> 1) | (key[6] << 7) | (key[7] << 15) ) & 0x7fffff;
126 /* Merge frame sequence number into shift register state, by xor'ing it
127 * into the feedback path
132 clock_ctl = threshold(r1, r2, r2);
133 r1 = clock_r1(clock_ctl, r1);
134 r2 = clock_r2(clock_ctl, r2);
135 r3 = clock_r3(clock_ctl, r3);
145 /* Run shift registers for 100 clock ticks to allow frame number to
146 * be diffused into all the bits of the shift registers
151 clock_ctl = threshold(r1, r2, r2);
152 r1 = clock_r1(clock_ctl, r1);
153 r2 = clock_r2(clock_ctl, r2);
154 r3 = clock_r3(clock_ctl, r3);
157 /* Produce 114 bits of Alice->Bob key stream */
164 clock_ctl = threshold(r1, r2, r2);
165 r1 = clock_r1(clock_ctl, r1);
166 r2 = clock_r2(clock_ctl, r2);
167 r3 = clock_r3(clock_ctl, r3);
169 bit = ((r1 >> 18) ^ (r2 >> 21) ^ (r3 >> 22)) & 0x01;
170 byte = (byte << 1) | bit;
183 /* Run shift registers for another 100 bits to hide relationship between
184 * Alice->Bob key stream and Bob->Alice key stream.
189 clock_ctl = threshold(r1, r2, r2);
190 r1 = clock_r1(clock_ctl, r1);
191 r2 = clock_r2(clock_ctl, r2);
192 r3 = clock_r3(clock_ctl, r3);
195 /* Produce 114 bits of Bob->Alice key stream */
202 clock_ctl = threshold(r1, r2, r2);
203 r1 = clock_r1(clock_ctl, r1);
204 r2 = clock_r2(clock_ctl, r2);
205 r3 = clock_r3(clock_ctl, r3);
207 bit = ((r1 >> 18) ^ (r2 >> 21) ^ (r3 >> 22)) & 0x01;
208 byte = (byte << 1) | bit;