A5算法的C语言,C语言程序,流密码,序列密码
/*
* In writing this program, I've had to guess a few pices of information:
*
* 1. Which bits of the key are loaded into which bits of the shift register
* 2. Which order the frame sequence number is shifted into the SR (MSB
* first or LSB first)
* 3. The position of the feedback taps on R2 and R3 (R1 is known).
* 4. The position of the clock control taps. These are on the `middle' one,
* I've assumed to be 9 on R1, 11 on R2, 11 on R3.
*/
/*
* Look at the `middle' stage of each of the 3 shift registers.
* Either 0, 1, 2 or 3 of these 3 taps will be set high.
* If 0 or 1 or one of them are high, return true. This will cause each of
* the middle taps to be inverted before being used as a clock control. In
* all cases either 2 or 3 of the clock enable lines will be active. Thus,
* at least two shift registers change on every clock-tick and the system
* never becomes stuck.
*/
typedef struct
{
unsigned long r1, r2, r3;
}a5_ctx
static int threshold(r1, r2, r3)
unsigned int r1;
unsigned int r2;
unsigned int r3;
{
int total;
total = (((r1 >> 9) & 0x1) == 1) +
(((r2 >> 11) & 0x1) == 1) +
(((r3 >> 11) & 0x1) == 1);
if (total > 1)
return (0);
else
return (1);
}
unsigned long clock_r1(ctl, r1)
int ctl;
unsigned long r1;
{
unsigned long feedback;
/*
* Primitive polynomial x**19 + x**5 + x**2 + x + 1
*/
ctl ^= ((r1 >> 9) & 0x1);
if (ctl)
{
feedback = (r1 >> 18) ^ (r1 >> 17) ^ (r1 >> 16) ^ (r1 >> 13);
r1 = (r1 << 1) & 0x7ffff;
if (feedback & 0x01)
r1 ^= 0x01;
}
return (r1);
}
unsigned long clock_r2(ctl, r2)
int ctl;
unsigned long r2;
{
unsigned long feedback;
/*
* Primitive polynomial x**22 + x**9 + x**5 + x + 1
*/
ctl ^= ((r2 >> 11) & 0x1);
if (ctl)
{
feedback = (r2 >> 21) ^ (r2 >> 20) ^ (r2 >> 16) ^ (r2 >> 12);
r2 = (r2 << 1) & 0x3fffff;
if (feedback & 0x01)
r2 ^= 0x01;
}
return (r2);
}
unsigned long clock_r3(ctl, r3)
int ctl;
unsigned long r3;
{
unsigned long feedback;
/*
* Primitive polynomial x**23 + x**5 + x**4 + x + 1
*/
ctl ^= ((r3 >> 11) & 0x1);
if (ctl)
{
feedback = (r3 >> 22) ^ (r3 >> 21) ^ (r3 >> 18) ^ (r3 >> 17);
r3 = (r3 << 1) & 0x7fffff;
if (feedback & 0x01)
r3 ^= 0x01;
}
return (r3);
}
int keystream(key, frame, alice, bob)
unsigned char *key; /* 64 bit session key */
unsigned long frame; /* 22 bit frame sequence number */
unsigned char *alice; /* 114 bit Alice to Bob key stream */
unsigned char *bob; /* 114 bit Bob to Alice key stream */
{
unsigned long r1; /* 19 bit shift register */
unsigned long r2; /* 22 bit shift register */
unsigned long r3; /* 23 bit shift register */
int i;
/* counter for loops */
int clock_ctl; /* xored with clock enable on each shift register */
unsigned char *ptr; /* current posit