AES加密算法(一)

POPLAR 2022-05-06 06:00:40 3090

AES(Advanced Encryption Standard)是由NIST标准化的对称分组密码,AES为分组密码,所谓分组密码,也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。而常见的非对称加密算法有RSA、ECC和EIGamal。由于上一代的DES算法密钥长度小(56bits),容易被破解而被AES取代。在AES标准规范中,分组长度只能是128位,每个分组为16个字节。密钥的长度有三种,分别是128位、192位、256位。密钥的长度不同,推荐加密轮数也不同,如下表所示:

芯片中设计中,AES加密算法随处可见。本文以AES-128bits为例讲解。一般地,明文分组用字节为单位的正方形矩阵描述,称为状态矩阵。在算法的每一轮中,状态矩阵的内容不断发生变化,最后的结果作为密文输出。- 字节替换SubBytes

字节替换(SubBytes)是AES算法中惟一的非线性运算,使用替换表(S-Box)对矩阵中的每一个字节元素进行独立运算。且s-box是可逆的。verilog中使用查找表实现。把该字节的高4位作为行值,低4位作为列值,取出S盒或者逆S盒中对应的行的元素作为输出。例如,加密时,输出的字节S1为0x12,则查S盒的第0x01行和0x02列,得到值0xc9,然后替换S1原有的0x12为0xc9。  
![](https://ebaina.oss-cn-hangzhou.aliyuncs.com/wechat-official-crawl/2022-05/165223083974323.jpg)
  • 行移位

    行移位的逆变换是将状态矩阵中的每一行执行相反的移位操作,例如AES-128中,状态矩阵的第0行右移0字节,第1行右移1字节,第2行右移2字节,第3行右移3字节。

  • 列混合

    列混合变换是通过矩阵相乘来实现的,矩阵如下:

矩阵元素的乘法和加法都是定义在基于GF(2^8)上的二元运算,并不是通常意义上的乘法和加法。

  • 二元运算的加法:等价于两个字节的异或;

  • 二元运算的乘法:对于一个8位的二进制数,使用域上的乘法乘以(00000010)等价于左移1位(低位补0)后,再根据情况同(0001_1011)进行异或运算。

<pre class="code-snippet__js" data-lang="typescript">```
<span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">function</span> [7:0] <span class="code-snippet__title">x2time</span></span>;</span>

input [7:0] b;

<span class="code-snippet_outer">    x2time={b[<span class="code-snippet__number">6</span>:<span class="code-snippet__number">0</span>],<span class="code-snippet__number">1</span><span class="code-snippet__string">'b0}^(8'</span>h1b&{<span class="code-snippet__number">8</span>{b[<span class="code-snippet__number">7</span>]}});</span>

endfunction

假设数据为a7a6a5a4a3a2a1a0,

乘以00000010,左移1位,得a6a5a4a3a2a1a0 0,

若a7为1,则乘以00000010的结果为:a6a5a4a3a2a1a0 0 ^ 0001_1011;

若a7为0,则乘以00000010的结果为:a6a5a4a3a2a1a0 0;

矩阵算子仅有1、2、3,那么乘以3怎么算呢?

乘以(0000_0011)可以拆分成:

设定函数function:mix_col,其输入值为矩阵的一列:

可以计算得到:

<pre class="code-snippet__js" data-lang="makefile">```
<span class="code-snippet_outer">function [31:0] mix_col;</span>

    input    [7:0]   s0  ,s1  ,s2 ,s3 ;

<span class="code-snippet_outer">    reg      [7:0]   s0_o,s1_o,s2_o,s3_o;</span>

begin

<span class="code-snippet_outer">        mix_col[31:24]=x2time(s0)^x2time(s1)^s1^s2^s3;</span>

        mix_col[23:16]=s0^x2time(s1)^x2time(s2)^s2^s3;

<span class="code-snippet_outer">        mix_col[15:08]=s0^s1^x2time(s2)^x2time(s3)^s3;</span>

mix_col[07:00]=x2time(s0)^s0^s1^s2^x2time(s3);

<span class="code-snippet_outer">    end</span>

endfunction

  • 轮密钥加AddRoundKey

轮密钥加是将128位轮密钥Ki同状态矩阵中的数据进行逐位异或操作,其中,密钥Ki中每个字W[4i],W[4i+1],W[4i+2],W[4i+3]为128bit,包含4个字,轮密钥加过程可以看成是逐位异或的结果。- 密钥扩展

AES首先将初始密钥128bit分成4个字(W[0]、W[1]、W[2]、W[3])
比如,设初始的128位密钥为:3C A1 0B 21 57 F0 19 16 90 2E 13 80 AC C1 07 BD 即,4个初始值为:W[0] = 3C A1 0B 21W[1] = 57 F0 19 16W[2] = 90 2E 13 80W[3] = AC C1 07 BDAES-128加密轮数10轮,即需对W数组扩充40个新列,构成总共44列的扩展密钥数组。

新列以如下的递归方式产生:

1.如果i不是4的倍数,那么第i列由如下等式确定:

W[i]=W[i-4]⨁W[i-1]2.如果i是4的倍数,那么第i列由如下等式确定:

W[i]=W[i-4]⨁T(W[i-1])其中,函数T由3部分组成:

  • 字循环

将1个字中的4个字节循环左移1个字节。即将输入字[b0, b1, b2, b3]变换成[b1,b2,b3,b0]。- 字节代换

对字循环的结果使用S盒进行字节代换。- 轮常量异或

将前两步的结果同轮常量Rcon\[j\]进行异或,其中j表示轮数。

轮常量Rcon[j]是一个字,其值见下表。

下面求扩展的第1轮的子密钥(W[4],W[5],W[6],W[7])。

(一)首先计算W[4]: 由于4是4的倍数,所以:

W[4] = W[0] ⨁ T(W[3])T(W[3])的计算步骤如下:- 字循环

AC C1 07 BD变成C1 07 BD AC;- 字节代换

将 C1 07 BD AC 作为S盒的输入,输出为78 C5 7A 91;- 轮常量异或

将78 C5 7A 91与第一轮轮常量Rcon[1]进行异或,得到79 C5 7A 91;
因此,T(W[3])=79 C5 7A 91;所以,W[4] = 3C A1 0B 21 ⨁ 79 C5 7A 91 = 45 64 71 B0;(二)然后计算W[5],W[6],W[7]子密钥段,i不是4的倍数,计算则如下:

W[5] = W[1] ⨁ W[4] =57 F0 19 16 ⨁ 45 64 71 B0 = 12 94 68 A6

W[6] = W[2] ⨁ W[5] =90 2E 13 80 ⨁ 12 94 68 A6 = 82 BA 7B 26

W[7] = W[3] ⨁ W[6] =AC C1 07 BD ⨁ 82 BA 7B 26 = 2E 7B 7C 9B

所以,第一轮密钥为45 64 71 B0 12 94 68 A6 82 BA 7B 26 2E 7B 7C 9B。

参考链接:https://blog.csdn.net/qq\_28205153/article/details/55798628

感谢阅读文章,如果文章有用,麻烦点个“在看”或转发分享。

转载:全栈芯片工程师

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
POPLAR
红包 点赞 收藏 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
更多相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
POPLAR
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区