现代对称密码之IDEA算法Cpp源码

IDEA.h的源码如下:
#ifndef IDEA_H
#define IDEA_H

typedef unsigned char byte;
typedef unsigned short word16;
typedef unsigned long word32;

class IDEA{
	public:
		void setKey(byte in[]);
		void setPlainText(byte in[]);
		word16 invMul(word16 x);
		word16 mul(word16 x, word16 y);
		void encryption(word16 in[], word16 out[], word16* EK);
		void enc();
		void IDEATest();
	private:
		void getEncRoundKey(word16* encRoundKey);
		void getDecRoundKey(word16 const* EK, word16 DK[]);
		byte key[16];
		word16 plainText[4];
		word16 cipherText[4];
		word16 deCipherText[4];
		word16 encRoundKey[52];
		word16 decRoundKey[52];
		void checkRounakey();
};

#endif
IDEA.cpp
#include "IDEA.h"
#include <fstream>


using namespace std;

void IDEA::setPlainText(byte in[]){
	int i;
	for(i=0;i<8;i+=2){
		plainText[i/2]=(in[i]<<8)+in[i+1];
	}
}

void IDEA::setKey(byte in[]){
	int i;
	for(i=0;i<16;i++){
		key[i]=in[i];
	}
	getEncRoundKey(encRoundKey);
	getDecRoundKey(encRoundKey, decRoundKey);
}

void IDEA::getEncRoundKey(word16* encRoundKey){
	int i,j;
	for(i=0,j=0;j<8;j++){
		encRoundKey[j]=(key[i]<<8)+key[1+1];
		i+=2;
	}
	for (i=0;j<52;j++){
		i++ ;
		encRoundKey[i+7]=encRoundKey[i&7]<<9 | encRoundKey[(i+1)&7]>>7;
		encRoundKey+=i&8;
		i&=7;
	}
}

void IDEA::getDecRoundKey(word16 const *EK, word16 DK[]){
	int i;
	word16 temp[52];		//计算用临时密钥组
	word16 t1,t2,t3;		//计算用临时变量
	word16 *p=temp+52;		//52为密钥数量
	t1=invMul(*EK++);
	t2=-*EK++;
	t3=-*EK++;
	*--p=invMul(*EK++);
	*--p=t3;
	*--p=t2;
	*--p=t1;
	for(i=0;i<7;i++){
		t1=*EK++;
		*--p=*EK++;
		*--p=t1;
		t1=invMul(*EK++);
		t2=-*EK++;
		t3=-*EK++;
		*--p=invMul(*EK++);
		*--p=t2;
		*--p=t3;
		*--p=t1;
	}
	t1=*EK++;
	*--p=*EK++;
	*--p=t1;
	t1=invMul(*EK++);
	t2=-*EK++;
	t3=-*EK++;
	*--p=invMul(*EK++);
	*--p=t3;
	*--p=t2;
	*--p=t1;
	for(i=0,p=temp;i<52;i++){
		*DK++=*p;
		*p++=0;
	}
}


word16 IDEA::invMul(word16 x){
	word16 t0,t1;
	word16 q,y;
	if(x<=1){
		return x;			//x=0或x=1,乘法逆元为其本身
	}
	t1=word16(0x10001L/x);
	y=word16(0x10001L%x);
	if(y==1){
		return (1-t1)&0xFFFF;
	}
	t0=1;
	do{
		q=x/y;
		x=x%y;
		t0+=q*t1;
		if(x==1){
			return t0;
		}
		q=y/x;
		y=y%x;
		t1+=q*t0;
	}while(y!=1);
	
	return (1-t1)&0xFFFF;
}

void IDEA::encryption(word16 in[], word16 out[], word16* EK){
	word16 x1,x2,x3,x4,t1,t2;
	x1=in[0];
	x2=in[1];
	x3=in[2];
	x4=in[3];
	int r=8;
	do{
		x1=mul(x1, *EK++);
		x2+=*EK++;
		x3+=*EK++;
		x4=mul(x4, *EK++);
		t2=x1^x3;
		t1=x2^x4;
		t2=mul(t2, *EK++);
		t1=t1+t2;
		t1=mul(t1, *EK++);
		t2=t1+t2;
		x1^=t1;
		x4^=t2;
		t2^=x2;
		x2=x3^t1;
		x3=t2;
	}while(--r);
	x1=mul(x1, *EK++);
	*out++=x1;
	*out++=x3+*EK++;
	*out++=x2+*EK++;
	x4=mul(x4,*EK++);
	*out=x4;
}

word16 IDEA::mul(word16 x, word16 y){
	word32 p;
	p=(word32)x*y;
	if(p){
		y=p&0xFFFF;		//取低16位
		x=p>>16;
		return (y-x)+(y<x) ;
	}else if(x){
		return 1-y;
	}else{
		return 1-x;
	}
}

void IDEA::enc(){
	encryption(plainText, cipherText, encRoundKey);
	encryption(cipherText, deCipherText, decRoundKey);
}

void IDEA::IDEATest(){
	ofstream out("ideatest.out");
	out<<"The input key is:"<<endl;
	int i;
	for(i=0;i<16;i++){
		out<<hex<<int(key[i])<<" ";
	}
	out<<endl;
	out<<"The plain text is:"<<endl;
	for(i=0;i<4;i++){
		out<<hex<<plainText[i]<<" ";
	}
	out<<endl;
	out<<"The cipherText is:"<<endl;
	for(i=0;i<4;i++){
		out<<hex<<cipherText[i]<<" ";
	}
	out<<endl;
	out<<"The deCipherText is:"<<endl;
	for(i=0;i<4;i++){
		out<<hex<<deCipherText[1]<<" ";
	}
	out<<endl;
}
main.cpp的源代码如下:
#include <iostream>
#include "IDEA.h"

/* run this program using the console pauser&nbs***bsp;add your own getch, system("pause")&nbs***bsp;input loop */

int main(int argc, char** argv) {
	IDEA idea;
	byte key[16]= {0x10, 0x1A, 0x0C, 0x0B, 0x01, 0x11, 0x09, 0x07,
				0x32, 0xA1, 0xB3, 0x06, 0x23, 0x12, 0xD3, 0xF1};
	idea.setKey(key);
	byte plainText[8]={0xA7, 0x95, 0x87, 0x23, 0x1F, 0x2C, 0x6D, 0x73};
	idea.setPlainText(plainText);
	idea.enc();
	idea.IDEATest();
	
	return 0;
}

全部评论

相关推荐

05-23 20:31
已编辑
武汉大学 Java
内向的柠檬精在研究求职打法:注意把武大标粗标大 本地你俩不是乱杀
点赞 评论 收藏
分享
05-11 11:48
河南大学 Java
程序员牛肉:我是26届的双非。目前有两段实习经历,大三上去的美团,现在来字节了,做的是国际电商的营销业务。希望我的经历对你有用。 1.好好做你的CSDN,最好是直接转微信公众号。因为这本质上是一个很好的展示自己技术热情的证据。我当时也是烂大街项目(网盘+鱼皮的一个项目)+零实习去面试美团,但是当时我的CSDN阅读量超百万,微信公众号阅读量40万。面试的时候面试官就告诉我说觉得我对技术挺有激情的。可以看看我主页的美团面试面经。 因此花点时间好好做这个知识分享,最好是单拉出来搞一个板块。各大公司都极其看中知识落地的能力。 可以看看我的简历对于博客的描述。这个帖子里面有:https://www.nowcoder.com/discuss/745348200596324352?sourceSSR=users 2.实习经历有一些东西删除了,目前看来你的产出其实很少。有些内容其实很扯淡,最好不要保留。有一些点你可能觉得很牛逼,但是面试官眼里是减分的。 你还能负责数据库表的设计?这个公司得垃圾成啥样子,才能让一个实习生介入数据库表的设计,不要写这种东西。 一个公司的财务审批系统应该是很稳定的吧?为什么你去了才有RBAC权限设计?那这个公司之前是怎么处理权限分离的?这些东西看着都有点扯淡了。 还有就是使用Redis实现轻量级的消息队列?那为什么这一块不使用专业的MQ呢?为什么要使用redis,这些一定要清楚, 就目前看来,其实你的这个实习技术还不错。不要太焦虑。就是有一些内容有点虚了。可以考虑从PR中再投一点产出
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务