本仓库存放的是中山大学计算机学院 2024 年秋季学期现代密码学实验课程实验 3-1/3-2 有限域运算的 C 语言实现。详细的代码讲解请移步我的博客:AES-128 实现
实现 AES-128 各个工作模式的加密和解密,包括 ECB、CBC、CFB、OFB、CTR 五种模式。
实验的输入输出均为二进制数据。
输入:
实现 AES-128 各个工作模式的加密和解密。
输入数据由以下部分组成:
- 一个
uint8_t
,表示工作模式和加密/解密。最高位为 0 表示加密,1 表示解密,具体定义如下:0x00
/0x80
表示 ECB 模式加密/解密0x01
/0x81
表示 CBC 模式加密/解密0x02
/0x82
表示 CFB 模式加密/解密0x03
/0x83
表示 OFB 模式加密/解密0x04
/0x84
表示 CTR 模式加密/解密
- 一个
uint8_t[16]
,表示 128 位的密钥。 - 一个
uint8_t[16]
,表示 128 位的 IV。即使当前的工作模式不需要 IV,输入数据仍然会包含这一部分,忽略即可。 - 一个
uint32_t
,表示明文/密文的长度。 uint8_t[]
,表示明文/密文的内容。
例如:
00
2B 7E 15 16 28 AE D2 A6 AB F7 15 88 09 CF 4F 3C
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
40 00 00 00
6B C1 BE E2 2E 40 9F 96 E9 3D 7E 11 73 93 17 2A
AE 2D 8A 57 1E 03 AC 9C 9E B7 6F AC 45 AF 8E 51
30 C8 1C 46 A3 5C E4 11 E5 FB C1 19 1A 0A 52 EF
F6 9F 24 45 DF 4F 9B 17 AD 2B 41 7B E6 6C 37 10
注:为了方便查看,这里以 16 进制书写,且加入了换行。实际输入文件是二进制数据,且除了数据外,不存在换行符等。
输出:
以二进制形式输出加密/解密得到的密文/明文。
上面的样例对应的输出是:
3A D7 7B B4 0D 7A 36 60 A8 9E CA F3 24 66 EF 97
F5 D3 D5 85 03 B9 69 9D E7 85 89 5A 96 FD BA AF
43 B1 CD 7F 59 8E CE 23 88 1B 00 E3 ED 03 06 88
7B 0C 78 5E 27 E8 AD 3F 82 23 20 71 04 72 5D D4
A2 54 BE 88 E0 37 DD D9 D7 9F B6 41 1C 3F 9D F8
所有的样例输入输出都在sample
文件夹下,以二进制文件的形式给出。样例主要来源于 NIST 的文档 Recommendation for Block Cipher Modes of Operation的附录 F,以及 NIST 的 AES 标准文档 FIPS 197。
后一个文档对每个密钥长度给出一个分组的数据,提供了每一轮各步骤的结果,便于调试对照。
特别要说明,CTR 模式的样例,以 IV 作为计数器初始值,而且是以大端序给出的。查看原文档即可发现这一点。
有两份代码:
aes.c
:实现了 AES-128 CBC 模式的加密和解密。里面包含普通版本和 SIMD 加速版本。aes_all.c
:基于 SIMD 加速版本,实现了 AES-128 的全部五种模式的加密和解密。
<stdio.h>
:标准输入输出库,用于文件操作和打印输出。<stdint.h>
:标准整数类型库,定义了固定宽度的整数类型,如本代码中频繁使用的 uint32_t 和 uint8_t。<emmintrin.h>
:包含了 Intel 的 SIMD 指令集(SSE2)的头文件,用于加速计算。<immintrin.h>
:包含了 Intel 的高级 SIMD 指令集(如 AVX)的头文件,用于加速计算。
RCON
:AES 密钥扩展中的轮常量。SBOX
:AES 加密中的 S 盒,用于字节替代。INV_SBOX
:AES 解密中的逆 S 盒,用于字节替代。