AES快速实现实验报告

AES快速实现实验报告

AES的快速实现

【实验目的】
  1. 通过本次实验,初步接触常用的加密算法软件快速实现方法。
  2. 鼓励同学们思考与探索新领域,增强编程能力与实践能力。
【实验环境】

​ Windows10 系统;64 位操作系统,基于 x64 的处理器;
​ Java version “13-ea” JYM: -Xms1024m -Xmx2048m 编译器:Eclipse;

【实验内容】
AES加解密软件快速实验
1. 算法原理
  1. 查表法的核心思想是将ByteSub、ShiftRows层和MixColumn层融合为查找表;

  2. 这三层能融合到一起的最本质的原因是都是只涉及到单个字节的操作;

  3. AddRoundKey不能放到表里面的原因是涉及到字节间的操作;

  4. 解密方法需要对密钥进行MixColumn操作,这样才能运动到查表法;

2. 算法流程
  1. 表的构造
Created with Raphaël 2.2.0 表的构造 int i = 0; int[][][] t = new int[4][256][4] 初始化正盒s和逆盒S i<256? 正表? t[0][i] = (2,1,1,3)s[i] t[1][i] = (3,2,1,1)s[i] t[2][i] = (1,3,2,1)s[i] t[3][i] = (1,1,3,2)s[i] i++ t[0][i] = (14,9,13,11)S[i] t[1][i] = (11,14,9,13)S[i] t[2][i] = (13,11,14,9)S[i] t[3][i] = (9,13,11,14)S[i] i++ 输入t表 构造结束 yes no yes no
  1. 整体的流程
Created with Raphaël 2.2.0 快速算法实现 构造s盒和t表; 对消息进行矩阵化 生成轮秘钥 加密? 进行AddRoundKey 进行9轮的轮函数: t查找+AddRoundKey 最后一轮shiftrow,bytesub,addroundkey 输出最后结果 结束 对第二轮到第九轮的轮秘钥进行MixColumn yes no
  1. 源代码
package aes;

import java.util.Scanner;

import gf.Oujilide;

public class AES_FAST {
	//查表法快速实现aes
	static int[][][] t = new int[4][256][4];
	static int[][] mm = new int[4][4];
	static int[][] kk = new int[4][4];
	
	//准备工作:生成s盒;生成t表;把m变形;生成轮密钥
	public static void pre_init(String m,String k,int flag){
		Sbox.create(flag);
		t = T_table.en_t(flag);
		mm = AES.intmat(m);
		kk = KAES.createK(k, 128);
	}
	
	public static int[][] inverse(int[][] k){
		int[][] re =new int[4][4];
		for(int i=0;i<4;i++)
			for(int j=0;j<4;j++)
				re[i][j] = k[j][i];
		return re;
	}
	
	public static int[] add(int[][] t,int[] key) {
		int[] re = new int[4];
		for(int i=0;i<4;i++) {
				re[i] = Oujilide.add(t[0][i], t[1][i]);
				re[i] = Oujilide.add(re[i], t[2][i]);
				re[i] = Oujilide.add(re[i], t[3][i]);
				re[i] = Oujilide.add(re[i], key[i]);
			}
		return re;
	}
	
	static int[] co = new int[] {0,5,10,15};
	static int[] co1 = new int[] {0,13,10,7};
	public static int[][] round(int[][] m,int[][] key){
		int[][] tmp = new int[4][4];
		for(int j=0;j<4;j++) {
				int[][] tt = new int[4][4];
				for(int k=0;k<4;k++) {
					int p  = (j*4+co[k])%16;
					tt[k] = t[k][m[p%4][p/4]];
				}
				tmp[j] = add(tt,key[j]);
			}
		return inverse(tmp);
	}
	public static int[][] roundni(int[][] m,int[][] key){
		int[][] tmp = new int[4][4];
		for(int j=0;j<4;j++) {
				int[][] tt = new int[4][4];
				for(int k=0;k<4;k++) {
					int p  = (j*4+co1[k])%16;
					tt[k] = t[k][m[p%4][p/4]];
				}
				tmp[j] = add(tt,key[j]);
			}
		return inverse(tmp);
	}
	
	public static void aes_fast(String m,int flag) {
		int[][]tmp = new int[4][4];//用来储存每一轮的密钥
		long startTime = System.currentTimeMillis(); //获取开始时间
		if(flag == 0)
		{for(int j=0;j<4;j++) tmp[j] = kk[j];
		mm = AES.AddRoundKey(mm,inverse(tmp));
		/*开始9轮*/
		for(int i=1;i<10;i++) {
			for(int j=0;j<4;j++) tmp[j] = kk[i*4+j];
			mm = round(mm,tmp);
		}	
		/*最后一轮*/
		for(int j=0;j<4;j++) tmp[j] = kk[10*4+j];
		 mm = AES.ByteSub(mm,flag); 
		 mm = AES.ShiftRow(mm, flag);
		 mm = AES.AddRoundKey(mm,inverse(tmp));}
		else {
			for(int j=0;j<4;j++) tmp[j] = kk[10*4+j];
			/*第一轮前*/
			mm = AES.AddRoundKey(mm,inverse(tmp));
			/*开始9轮*/ 
			for(int i=1;i<10;i++) {
				for(int j=0;j<4;j++) tmp[j] = kk[10*4-i*4+j];
				mm = roundni(mm,inverse(AES.MixColumn(inverse(tmp), 1)));}
			/*最后一轮*/
			for(int j=0;j<4;j++) tmp[j] = kk[j];
			 mm = AES.ShiftRow(mm, flag);
			 mm = AES.ByteSub(mm,flag);  
			 mm = AES.AddRoundKey(mm,inverse(tmp));
		}
		 long endTime = System.currentTimeMillis(); //获取结束时间
		 System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
	}
	
	public static void main(String args[]) {
		System.out.println("依次输入m,k,flag");
		Scanner in = new Scanner(System.in);
		String m = in.nextLine();
		String k = in.nextLine();
		int flag = in.nextInt();
		pre_init(m,k,flag);
		aes_fast(m,flag);
		AES.play(mm);
		in.close();
	}
}
  1. 代码分析

​ 本实验最大的优化在于将轮函数里面的三步运算直接合成为一步找表,这是一种典型的用空间换时间的办法,就跟之前aes实现的时候s盒是自己产生还是牺牲一定的空间去计算一样。但是如若把t盒计算的时间加在内,初略地分析只有在每一个t盒的使用次数超过t盒的大小也就是256的时候才会有时间上的优化,或者提前使用t盒的构造函数把t盒直接作为常量写在函数里。

3. 样例截图
  1. 源代码详见 src\aes\AES.java 和 src\aes\AES_FAST.java 测试样例见 readme;

  2. 测试样例截图为:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
数据统计:

普通算法快速算法
181352336ns7397324ns
279875449ns7396879ns
385798552ns7849323ns
平均82342112ns7547842ns
bit/s1.5544*10^41.69584*10^5
4. 实验总结
181352336ns7397324ns
279875449ns7396879ns
385798552ns7849323ns
平均82342112ns7547842ns
bit/s1.5544*10^41.69584*10^5
4. 实验总结

​ 通过本次实验,首先我复习了AES算法的原理,同时学会了优化算法的一种思维—寻找会进行重复运算的地方,将这个重复运算的东西存储到一个表里,利用空间来换取时间。另外,通过本实验可以看出,算法的性能大概提高了10倍左右,这是一个很惊人的数字,由此可见空间换取时间的策略是非常成功的。另外,在我进行了测试之后发现,如果把t表的生成时间计算在内,时间上并不能得到优化,这是因为用到t表的次数小于256,但是当加密的过程变多之后特别是打到千位数量级后,第二种方法的优势便明显的体现了出来。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值