AES加密算法(一)

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

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)
  • 1
  • 2
  • 行移位

    行移位的逆变换是将状态矩阵中的每一行执行相反的移位操作,例如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>
  • 1
  • 2

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>
  • 1

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>
    • 1
    • 2

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

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

    begin

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

            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>
    • 1

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

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

    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表示轮数。
      • 1

      轮常量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元 红包规则

        易百纳技术社区