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 组
- 序列控制方式:互控
原理图:
算法实现
/**************************************************
************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);
}
文章原创 转载请注明出处!!!