当前位置: 首页 > news >正文

【AES加密专题】3.工具函数的编写(1)

目录

1.兼容 51

2.密钥长度单位的转换

3.定义数据块的大小

4.定义加密轮数

5.有限域

总结一下

拓展:为什么 8 位二进制00011011对应多项式x⁸ + x⁴ + x³ + x + 1?

第一步:二进制与多项式的基础对应

第二步:为什么会多一个x⁸项?

6.子密钥表

(1)static

(2)xdata

(3)unsigned char

(4)g_roundKeyTable

(5)[4*Nb*(Nr+1)]

总结


专题:
【AES加密专题】1.AES的原理详解和加密过程-CSDN博客

【AES加密专题】2.AES头文件详解-CSDN博客

1.兼容 51

/*
* #ifndef __C51__:
__C51__ 是 Keil C51 编译器(专门用于 8051 系列单片机的编译器)在编译时自动定义的宏,
用于标识当前处于 C51 编译环境。#ifndef __C51__ 的意思是:
如果当前不是 C51 编译环境(即未定义__C51__宏),则执行下面的代码。
*/
#ifndef __C51__//在普通 C 编译器(如 PC 端的 GCC、MSVC)中,这些关键字不存在。因此这里将它们定义为 “空宏”#define code#define data#define idata#define xdata#define pdata//在普通 C 环境中,没有专门的 “布尔类型”,因此用unsigned char(无符号字符型,1 字节)//来模拟布尔类型BOOL(通常 0 表示假,非 0 表示真)。typedef unsigned char BOOL;
#elsetypedef bit BOOL;
#endif

  • codedataidataxdatapdata 是 C51 编译器特有的存储类型关键字(用于指定变量在单片机内存中的存储位置,如code表示程序存储区 ROM,data表示内部数据区 RAM 等)。在普通 C 编译器(如 PC 端的 GCC、MSVC)中,这些关键字不存在。因此这里将它们定义为 “空宏”,目的是:当代码中使用这些关键字时(如code unsigned char buf[] = "abc";),在非 C51 环境下编译时会忽略这些关键字,避免编译报错。

  • typedef unsigned char BOOL;:在普通 C 环境中,没有专门的 “布尔类型”,因此用unsigned char(无符号字符型,1 字节)来模拟布尔类型BOOL(通常 0 表示假,非 0 表示真)。

当处于 C51 编译环境时(定义了C51),bit是 C51 特有的位类型(仅占 1 个二进制位,取值 0 或 1),更适合表示布尔值(节省单片机有限的内存)。因此这里将BOOL定义为bit类型。

这段代码通过条件编译,让同一套代码既能在 8051 单片机的 C51 环境下编译(使用特有的bit类型和存储关键字),也能在普通 C 环境下编译(忽略存储关键字,用unsigned char模拟布尔类型),实现了代码的跨环境兼容性。

#define data、#define idata、#define xdata、#define pdata:这些也是宏定义,分别用于标识不同类型的数据存储:

  • data:表示将变量存储在片上 RAM 的直接寻址区,即 8051 的内部 RAM 的前 128 字节(地址范围为 0x00-0x7F)。

  • idata:表示将变量存储在片上 RAM 的间接寻址区,通常是 8051 的内部 RAM 的后 128 字节(地址范围为 0x80-0xFF)。

  • xdata:这个关键字用于指示变量存储在外部数据存储器(如外部 RAM)中。

  • pdata:表示变量存储在 8051 的片外 RAM 的分页区,即外部 RAM 的一个特定分页区域,通常是 256 字节的页内存。

2.密钥长度单位的转换

/*
* Nk表示AES密钥的长度(单位是字,4字节/字)
* 假设AES_KEY_LENGTH 为128,192或256,则Nk分别为4,6,8
*/
#define Nk (AES_KEY_LENGTH /32)

3.定义数据块的大小

/*
*Nb表示数据块的大小(单位是字),固定为4.这是AES的固定标准,AES处理的是4X4的字节块。
*/
#define Nb  4

4.定义加密轮数

// Nr 表示AES的轮数,取决于密钥长度。通过#if 语句确定 AES_KEY_LENGTH 值为128、192或256时的轮数。
#if    AES_KEY_LENGTH == AES_KEY_LENGTH_128#define Nr  10
#elif  AES_KEY_LENGTH == AES_KEY_LENGTH_192#define Nr  12
#elif  AES_KEY_LENGTH == AES_KEY_LENGTH_256#define Nr  14
#else#error AES_KEY_LENGTH must be 128, 192 or 256 BOOLS!
#endif

Nr 不适合直接使用枚举确定的原因主要在于 AES 算法的实现要求 Nr 的值依赖于编译时的宏定义AES_KEY_LENGTH,这使得轮数值在编译时就必须根据密钥长度来确定。

5.有限域

/*
* BPOLY 用于AES中有限域(GF(2^8))运算。其值0x1B 表示GF(2^8)中的不可约多项式
*(x^8+X^4+X^3+X+1)的低8位。
在AES的 MixColumns 操作中,有限域多项式 BPOLY 被用作乘法的模,确保运算在8位内循环。
*/
#define BPOLY 0x1B

我们知道 AES 是一种加密算法,核心是对数据(比如一段文字、一张图片)做各种复杂的数学变换,让明文变成乱码(密文)。这些变换里,有一步很关键:对 8 位二进制数(比如10110011这种 8 位数字)做 “乘法”

但这里的 “乘法” 不是我们平时学的整数乘法,而是一种特殊的 “有限域乘法”。你可以理解为:这些 8 位数字生活在一个 “有限的小圈子” 里(专业名叫GF(2^8)),圈子里的规则是 “任何运算结果都不能超过 8 位”—— 就像钟表上的数字永远在 1-12 之间,超过了就 “绕回去”。

但是问题来了:乘法很容易 “出圈”

比如两个 8 位数字相乘,结果可能变成 9 位、10 位(就像 12 点的钟表上,11 点加 2 点不能是 13 点,得绕回 1 点)。这时候就需要一个 “规矩” 来把超范围的结果 “拉回” 8 位里。

这个 “规矩” 就是不可约多项式,而0x1B就是 AES 里规定的这个 “规矩”。

那0x1B具体是个什么 “规矩”?

0x1B是十六进制,转成二进制是 0001 1011,但因为是 8 位的 “圈子”,完整的规矩其实是一个多项式:x⁸ + x⁴ + x³ + x + 1(可以理解为一种 “减法公式”)。

当两个 8 位数字相乘结果超过 8 位时,就用这个多项式 “减一减”(专业叫 “取模”),直到结果变回 8 位。比如:

  • 假设相乘后得到一个 9 位的数,用0x1B对应的规则一处理,就会变成 8 位,刚好留在 “圈子” 里。

为什么非得是0x1B,而不是其他数?

主要有三个原因:

  1. 大家得统一规矩加密和解密必须用同一个 “规矩”,否则解密时就认不出密文了。AES 是国际标准,必须规定一个唯一的 “规矩” 让全世界遵守,0x1B就是被选中的那个。

  2. 计算起来方便0x1B对应的多项式x⁸ + x⁴ + x³ + x + 1,在硬件(比如芯片)和软件里实现起来特别简单。就像选工具时,肯定选顺手的那一个,0x1B就是那个 “顺手的工具”。

  3. 安全性经过验证密码算法的核心是 “难破解”。0x1B经过大量测试,用它做出来的 AES 加密,破解难度非常高。如果换一个多项式,可能会出现漏洞,让加密变脆弱。

总结一下

0x1B就像 AES 里的一把 “尺子”:

  • 作用是保证 8 位数字相乘后不会 “出圈”,始终在 8 位范围内运算;

  • 选它是因为全世界统一用(标准)、算起来方便(效率高)、加密够安全(难破解)。

如果没有这个 “尺子”,AES 的运算就会乱套,加密解密也无法统一,更谈不上安全了。

拓展:为什么 8 位二进制00011011对应多项式x⁸ + x⁴ + x³ + x + 1

第一步:二进制与多项式的基础对应

在有限域 GF (2⁸) 中,一个 8 位二进制数可以对应一个 “8 次以内的多项式”,规则是:

  • 二进制的每一位(从右到左,即最低位到最高位)对应多项式中x⁰(x 的 0 次方,即 1)、……x⁷的系数。

  • 某一位是 “1”,就表示多项式包含这一项;是 “0” 就不包含。

比如00011011(8 位)的多项式应该是x⁴ + x³ + x + 1

第二步:为什么会多一个x⁸项?

因为0x1B的作用是 “处理乘法溢出”—— 当两个 8 位二进制数相乘时,结果可能超过 8 位(比如变成 9 位),这时候需要用 “模运算” 把结果 “砍回” 8 位。

模运算的本质是:如果结果超过 8 位(即出现了x⁸项,因为 8 位二进制的最高位是x⁷),就用x⁸ + x⁴ + x³ + x + 1这个多项式来 “替换”x⁸项。

具体来说:假设乘法结果里有x⁸,根据多项式规则,x⁸ = x⁴ + x³ + x + 1(因为x⁸ + x⁴ + x³ + x + 1 = 0 → 移项得x⁸ = x⁴ + x³ + x + 1)。这样一来,x⁸就被换成了低次项(最高x⁴),结果自然就变回 8 位以内了。

所以总结:0x1B的 8 位二进制是00011011,它直接对应x⁴ + x³ + x + 1;但因为它的作用是处理 “超过 8 位的x⁸项”,所以完整的不可约多项式要加上x⁸,即x⁸ + x⁴ + x³ + x + 1

6.子密钥表

// AES子密钥表,当密钥长度为128位时,占用176字节空间
static xdata unsigned char g_roundKeyTable[4*Nb*(Nr+1)];

AES 加密的核心过程是对数据进行多轮(“Round”)变换,每一轮都需要一个特定的 “子密钥”(轮密钥)来参与运算。这条语句就是定义一个数组,专门用来存放所有轮的子密钥,相当于一个 “密钥表”。

(1)static

表示这个数组是 “静态变量”,作用域仅限当前 C 文件(不能被其他文件的代码直接访问),避免了变量名冲突,也让代码结构更清晰。保证被多次调用之间维持其值,而不是每次函数调用时重新初始化,对对于需要多个函数调用之间维持状态的变量是有用的。

(2)xdata

这是 8051 单片机(C51 编译器)特有的关键字,指定数组的存储位置 ——外部数据存储器(片外 RAM。AES 的轮密钥表需要较大的空间(比如 128 位密钥时要存 176 字节),而 8051 单片机的内部 RAM(data/idata)通常很小(比如只有 128 字节),放不下,所以用xdata放到外部 RAM 中。

(3)unsigned char

数组的元素类型是 “无符号字符型”,每个元素占 1 字节(8 位)。AES 的子密钥本质上是 8 位的字节数据,用unsigned char刚好能存储,且符合加密中对字节级操作的需求。

(4)g_roundKeyTable

数组名,字面意思是 “轮密钥表”(g_通常表示全局变量,roundKey指轮密钥,Table表示表),直观体现了数组的用途 —— 存放所有轮的子密钥。

(5)[4*Nb*(Nr+1)]

数组的大小,这是最关键的部分,和 AES 的算法参数直接相关:

  • Nb:AES 中 “数据块大小” 的参数(以 “32 位字” 为单位)。AES 的明文 / 密文数据块固定是 128 位(16 字节),128 位 = 4 个 32 位字(32*4=128),所以Nb=4

  • Nr:AES 的 “轮数”,由密钥长度决定:

    • 128 位密钥 → Nr=10轮;

    • 192 位密钥 → Nr=12轮;

    • 256 位密钥 → Nr=14轮。

  • 计算逻辑:每一轮需要4*Nb个字节的子密钥(因为每轮操作对应一个 4×4 的字节矩阵,刚好4*Nb=16字节),而 AES 的轮数是Nr,但初始化时还需要额外 1 轮的密钥(第 0 轮),所以总轮数是Nr+1

  • 例如 128 位密钥时:4*Nb*(Nr+1) = 4*4*(10+1) = 176字节,和注释 “占用 176 字节空间” 完全对应。

总结

这条代码定义了一个 “轮密钥表数组”,专门用来存放 AES 加密中所有轮(包括初始轮)的子密钥。通过xdata指定存储在外部 RAM 以节省内部空间,大小由 AES 的块大小(Nb)和轮数(Nr)动态确定,确保能适配不同密钥长度(128/192/256 位)的需求。

http://www.dtcms.com/a/467461.html

相关文章:

  • 台州企业网站排名优化泰州网站设计咨询
  • 网站怎么做子页宜昌seo
  • 网站建设三剑客wordpress 首页图片
  • 构建AI智能体:五十九、特征工程:数据预处理到特征创造的系统性方法
  • 广州企业建站 网络服务企业网站的网址有哪些
  • AI一周事件(2025年10月1日-10月8日)
  • ArrayList底层的实现原理是什么?
  • 商城网站开发商晋中网站seo
  • 网站建设内容保障制度重庆专业微网站建设
  • string(2),咕咕咕!
  • 哪个网站可以做免费推广wordpress的弊端
  • Octave下载和安装教程(附安装包)
  • 江苏省建设工程交易中心网站网站开发三大流行语言
  • 网站打开有声音是怎么做的网页设计超链接
  • PSDNorm:面向睡眠分期的时间归一化新范式
  • 邵阳网站建设哪家好网站一条龙服务
  • 网站系统建设项目wordpress中文教程
  • 佛山制作网站设计报价新开传奇手游新服网
  • 厦门物流网站建设免费用搭建网站
  • asp个人网站公司简介简短大气
  • C++学习记录(17)红黑树简单实现map和set
  • 2015个人备案网站论坛推广渠道分析
  • 制作微信网站模板wordpress企业模板主题
  • 互联网出版中的网站建设策划网站建设简介淄博
  • 网站百度收录查询提升学历官网
  • 8、C++匿名对象和程序运行内存划分段
  • 并行 Agent:大模型 Scaling 的下一程,从“单打独斗”到“千军万马”
  • 权重域名做网站有用么创意设计团队
  • 南阳做网站公司哪家好企业门户网站模板 下载
  • 吴军-行动指南