利用LFSR结构设计的流密钥生成器C++实现

基于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;
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值