基于LFSR的流密钥生成器
利用2个LFSR,输出30位流密码
#include <stdio.h>
#include<stdlib.h>
/*两个寄存器的位数 */
#define R1MASK 0x1F /* 5 bits, numbered 0..4 */
#define R2MASK 0x0F /* 4 bits, numbered 0..3 */
/* 每个寄存器的中间比特 */
#define R1MID 0x02 /* bit 2 */
#define R2MID 0x02 /* bit 2 */
/* 回归标志,用于钟控轮转寄存器*/
/* 特征多项式*/
/*f(x)=x^5+x^4+1;f(x)=x^4+x^3+1. */
#define R1TAPS 0x18 /* bits 4,3 */
#define R2TAPS 0x0C /* bits 3,2 */
/* 输出标记,用于生成输出 */
#define R1OUT 0x10 /* bit 4 (the high bit) */
#define R2OUT 0x08 /* bit 3 (the high bit) */
typedef unsigned char byte;
typedef unsigned int word;
typedef word bit;
/* 计算移位后填入值 */
bit parity(word x) {
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return x & 1;
}
/* 钟控单个寄存器 */
word clockone(word reg, word mask, word taps) {
word t = reg & taps;
reg = (reg << 1) & mask;
reg |= parity(t);
return reg;
}
/* 两个钟控寄存器 */
word R1, R2;
byte m[8] = { 0X01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 };
/* 根据钟控规则进行钟控*/
void clock() {
bit maj = (((R1 & R1MID) >> 1)* ((R2 & R2MID) >> 1)) << 1;
if ((R1 & R1MID) == maj)
R1 = clockone(R1, R1MASK, R1TAPS);
if ((R2 & R2MID) == maj)
R2 = clockone(R2, R2MASK, R2TAPS);
}
/* 对两个都进行钟控,当且仅当用于设置密钥 */
void clockallthree() {
R1 = clockone(R1, R1MASK, R1TAPS);
R2 = clockone(R2, R2MASK, R2TAPS);
}
/* 生成输出值 */
bit getbit() {
return parity(R1 & R1OUT) ^ parity(R2 & R2OUT);
}
/* 进行A5/1密钥设置,这步骤需要64bit密钥和22bit帧数*/
void keysetup(byte key[2], word frame) {
int i;
bit keybit, framebit;
/*对移位寄存器置零. */
R1 = R2 = 0;
/* 将密钥加载入寄存器,
* 优先将每个密钥串的第一个bit作为最低有效位,
*对于每个载入的密钥钟控每个寄存器一次 */
for (i = 0; i < 16; i++) {
clockallthree(); /* always clock */
keybit = (key[i / 8] >> (i & 7)) & 1; /* The i-th bit of the
key */
R1 ^= keybit; R2 ^= keybit;
}
/* 将帧数载入移位寄存器,优先最低有效位,
对每个载入的bit钟控寄存器一次 */
for (i = 0; i < 4; i++) {
clockallthree(); /* always clock */
framebit = (frame >> i) & 1; /* The i-th bit of the frame #
*/
R1 ^= framebit; R2 ^= framebit;;
}
/*进行不产生输出的20次钟控来融合密钥要素与帧数
*/
for (i = 0; i < 20; i++) {
clock();
}
/* 现在密钥已经完全设置完成. */
}
/* 生成30bit的密钥流输出*/
void run(byte S[]) {
int i;
/* 将输出缓存置零. */
for (i = 0; i <= 30 / 8; i++)
S[i] = 0;
/* 生成30bit密钥流用于*/
for (i = 0; i < 30; i++) {
clock();
S[i / 8] |= getbit() << (7 - (i & 7));
}
}
void EnCrypt(byte *p,byte * s,int len)
{
int i = 0, j = 0;
while (p[i] != '\0')
{
j = i * 8 % len; //该块开头对应的密钥bit位
for (int k = j; k < j + 8; k++)
{
p[i] ^= s[k % (len / 8 + 1)] ^ m[(k % len) % 8];
}
i++;
}
}
void test() {
byte key[2] = { 0x01, 0x9C };
word frame = 0x34;
byte S[4] = {0};
int i, failed = 0,j;
keysetup(key, frame);
run(S);
printf("密钥为: 0x");
for (i = 0; i < 2; i++)
printf("%02X", key[i]);
printf("\n");
printf("frame number: 0x%06X\n", (unsigned int)frame);
printf("\n");
printf("observed output:\n");
printf(" 密钥流为: 0x");
for (i = 0; i < 4; i++)
printf("%02X", S[i]);
printf("\n\n\n");
byte p[7] = "朱靖宇";
i = j = 0;
printf("明文为 :%s\n", p);
while (p[i] != '\0')
{
printf("%0x ", p[i++]);
}
printf("\n\n");
i = 0;
printf(">>>>开始加密<<<<\n");
EnCrypt(p, S, 30);
printf("密文为: 0X");
while (p[i] != '\0')
{
printf(" %02X", p[i]);
i++;
}
printf("\n\n\n");
i = 0;
printf(">>>>开始解密<<<<\n");
EnCrypt(p, S, 30);
printf("明文为: ");
while (p[i] != '\0')
{
if (i % 2)
printf("%c%c", p[i - 1], p[i]);
i++;
}
printf("\n");
}
int main(void) {
test();
return 0;
}