Mickey序列密码算法的c语言实现

Mickey 密码算法简介

MICKEY(Mutual Irregular Clocking KEYstream generator)
由 Steve Babbage 和 Matthew Dodd 设计, 最初版本是 MICKEY1.0,
但该版本受到了 TMDTO 攻击,设计者又将其发展为 MICKEY 2.0 和
MICKEY-128 2.0。MICKEY 设计结构简洁,硬件实现效率很高,并且
采用互控结构使得 MICKEY 具有很高的安全性,至今没有有效的分析
结果出现。

组成:

  • 100 级线性寄存器 R
  • 100 级非线性寄存器 S
  • 80bit 密钥
  • 可变长度(0-80bit)的初始向量 IV 4 组
  • 序列控制方式:互控

原理图:
原理图

刷新变换

寄存器R动作

寄存器S动作

表

寄存器S动作

算法初始化

算法实现

/**************************************************
************Mickey2.0密码算法***********************
***************************************************/
#include <stdio.h>
#include<iostream>
#include"time.h"
using namespace std;
typedef unsigned char uchar;
uchar rtaps[13] = {0xde, 0x4c, 0x9e, 0x48, 0x6, 0x66, 0x2a, 0xad, 0xf1, 0x81, 0xe1,
                   0xfb, 0xc0 };
uchar comp0[13] = {0xc, 0x5e, 0x95, 0x56, 0x90, 0x15, 0x42, 0x9e, 0x57, 0xfd, 0x7e,
                   0xa0, 0x60 };
uchar comp1[13] = {0x59, 0x79, 0x46, 0xbb, 0xc6, 0xb8, 0x45, 0xc7, 0xeb, 0xbc,
                   0x43, 0x89, 0x80};
uchar fb0[13] = {0xf5, 0xfe, 0x5f, 0xf9, 0x81, 0xc9, 0x52, 0xf5, 0x40, 0x1a, 0x37,
                 0x39, 0x80};
uchar fb1[13] = {0xee, 0x1d, 0x31, 0x32, 0xc6, 0xd, 0x88, 0x92, 0xd4, 0xa3, 0xdf,
                 0x2, 0x10};
uchar Key[10] = {0xfe, 0x1f, 0x3e, 0x78, 0x4a, 0xac, 0x2e, 0xf0, 0x15, 0x7b};
uchar IV[4] = {0xe1, 0x4f, 0xc4, 0xb7};
uchar IVlength = 4;

struct mickey_registers {//寄存器
    uchar R[13];//定义了104bit只使用一百比特
    uchar S[13];
};
typedef struct mickey_registers mickey;

//移位寄存器R的动作方式
void clock_r(mickey *m, uchar Input_Bit_R, uchar Control_Bit_R) {
    uchar Feedback_Bit, i;
    uchar carry_bits[13];
    Feedback_Bit = ((m->R[12] &0x10)>>4) ^ Input_Bit_R;// 取出第100bit后异或
    carry_bits[0] = 0;
    for (i=0 ; i<12 ; i++)
        carry_bits[i+1] = (m->R[i] & 1)<<7;//存储需要跨字节移动的比特:最低比特要移到下一个字节的最高比特
    if (Control_Bit_R)
        for (i=0 ; i<13 ; i++)
            m->R[i] ^= (m->R[i]>>1) ^ carry_bits[i];//右移一位并异或上自身
    else
        for (i=0 ; i<13 ; i++)
            m->R[i] = (m->R[i]>>1) ^ carry_bits[i];//右移一位
    if (Feedback_Bit)//只对Feedback_Bit为一时进行操作0对于对于模2加是单位元
        for (i=0 ; i<13 ; i++)
            m->R[i] ^= rtaps[i];
}
//移位寄存器S的动作方式
void clock_s(mickey *m, uchar Input_Bit_S, uchar Control_Bit_S) {
    uchar Feedback_Bit, i;
    uchar carry_bits_right[13];
    uchar carry_bits_left[13];
    uchar temp;
    Feedback_Bit = ((m->S[12] & 16)>>4) ^ Input_Bit_S;//取出第100比特计算Feedback_Bit

    carry_bits_right[0] = 0;
    for (i=0 ; i<12; i++)
        carry_bits_right[i+1] = (m->S[i] & 1)<<7;//存储需要跨字节移动的比特:最低比特
    carry_bits_left[12] = 0;
    for (i=1 ; i<13 ; i++)
        carry_bits_left[i-1] = (m->S[i] & 0x80)>>7;//存储需要跨字节移动的比特
    temp = (m->S[12]>>1) & 0x10;//取出第99bit放在第100比特的位置放在temp中
    for (i=0 ; i<13 ; i++)
        m->S[i] = ((m->S[i]>>1) ^ carry_bits_right[i]) ^ ((m->S[i] ^comp0[i]) & (m->S[i]<<1 ^ carry_bits_left[i] ^ comp1[i]));
    m->S[0] &= 0x7f;//将第1比特设置为0
    m->S[12] &= 0xef;//将最高比特设置为0
    m->S[12] ^= temp;
    if (Feedback_Bit) {//Feedback_Bit=0时后面的步骤实际可省
        if (Control_Bit_S) {
            for (i=0 ; i<13 ; i++)
                m->S[i] ^= fb1[i];
        } else {
            for (i=0 ; i<13 ; i++)
                m->S[i] ^= fb0[i];
        }
    }
}
//刷新变换
void clock_kg(mickey *m, uchar Mixing, uchar Input_Bit) {
    uchar Control_Bit_R, Control_Bit_S, Input_Bit_R, Input_Bit_S;
    Control_Bit_R = ((m->S[4] & 32)>>5) ^ ((m->R[8] & 16)>>4);//s34^r67
    Control_Bit_S = ((m->S[8] & 16)>>4) ^ ((m->R[4] & 64)>>6);//s67^r33
    if (Mixing)
        Input_Bit_R = Input_Bit ^ ((m->S[6] & 32)>>5);//Input_Bit^s55
    else
        Input_Bit_R = Input_Bit;
    Input_Bit_S = Input_Bit;
    clock_r(m, Input_Bit_R, Control_Bit_R);
    clock_s(m, Input_Bit_S, Control_Bit_S);
}
//输出密钥流or密文流
void print_stream(uchar Stream[]) {
    int i;
    for (i=0 ; i<16 ; i++)
        printf("%2x ",Stream[i]);
    printf("\n");
}
int main() {
    uchar KeyStream[16];
    uchar mstream[16]={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
    mickey m;
    uchar i, j, Input_Bit;
    clock_t start,end;
    for (i=0 ; i<13 ; i++) {
        m.S[i] = 0;//两个寄存器初始状态设置为全零
        m.R[i] = 0;
    }
    int counter = 0;
    //装载IV
    for (i=0 ; i<IVlength ; i++) {
        for (j=0 ; j<8 ; j++) {
            Input_Bit = (IV[i]>>(7-j)) & 1;
            clock_kg(&m, 1, Input_Bit);
            counter++;
        }
    }
  //装载密钥
    for (i=0 ; i<10 ; i++) {
        for (j=0 ; j<8 ; j++) {
            Input_Bit = (Key[i]>>(7-j)) & 1;
            clock_kg(&m, 1, Input_Bit);
        }
    }
    //空转100次
    for (i=0 ; i<100 ; i++)
        clock_kg(&m , 1, 0);
    //输出明文
    printf("明文流为:\n");
   print_stream(mstream);
    //加密1000次
   start=clock();
    for(int k=0;k<10000;k++){
        for (i=0 ; i<16 ; i++) {//生成16个字节的密钥流
                KeyStream[i] = 0;
                for (j=0 ; j<8 ; j++) {//生成一个字节的密钥流
                    KeyStream[i] ^= ((m.R[0] ^ m.S[0]) & 128)>>j;
                    clock_kg(&m, 0, 0);
            }
        }
        for (i=0 ; i<16 ; i++)
            mstream[i]^=KeyStream[i];
    }
    end=clock();
//输出密文流
        printf("密文流为:\n");
    print_stream(mstream);
    double encodetime;
    encodetime=(double)(end-start)/CLOCKS_PER_SEC;
    printf("加密1.28mb时间为%f秒\n",encodetime);
}

文章原创 转载请注明出处!!!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值