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

AES加密解密硬件实现详解-完整代码(6):my_bit8_mixcolum.v

本章节为my_bit8_mixcolum.v代码解析(完整代码见文章最后)

在上一篇文章中,我们深入分析了bit1_mixcolum——一个仅处理4个输入字节、输出2个字节的轻量级线性变换单元。这种“比特片”设计展示了如何在有限域上仅用异或和移位实现高效运算。然而,在实际的AES或类AES算法中,我们需要处理32位字甚至128位状态块。如何将基础单元扩展为实用的模块?本文介绍的bit8_mixcolum正是答案:通过模块化复用循环输入重排,将四个bit1_mixcolum并行组合,一次性完成32位数据的双路列混合。

1. 模块功能概览

端口名方向位宽描述
ininput32输入数据,按大端字节序包含四个字节 (a,b,c,d)
outxoutput32第一个输出字,由四组独立变换的结果拼接而成
outyoutput32第二个输出字,对应另一种线性组合的结果

核心功能:将输入的32位视为4个独立的字节,通过四个并行的bit1_mixcolum实例(每个实例的输入顺序经过循环移位),产生两个32位输出。这两个输出分别对应同一输入列混合后的两组不同线性关系。

2. 内部结构与工作原理

2.1 字节拆分

首先将32位输入按大端序拆分为四个字节:

  • a = in[31:24](最高字节)
  • b = in[23:16]
  • c = in[15:8]
  • d = in[7:0](最低字节)

这种拆分方式与AES官方文档及大多数处理器内存布局一致。

2.2 并行实例化的连接方式

模块内部例化了四个bit1_mixcolum子模块,分别记为u1u2u3u4。每个子模块的输入顺序不是固定的(a,b,c,d),而是按照循环右移(或左移)方式重排:

实例in1in2in3in4输出Out1输出Out2
u1abcdx1y1
u2bcdax2y2
u3cdabx3y3
u4dabcx4y4

这种旋转方式的直观理解:

  • 如果把输入四个字节看作一个循环队列,那么每个子模块依次从队列的不同起点开始取四个连续元素。
  • 当所有子模块的Out1按顺序(x1,x2,x3,x4)拼接时,得到的结果相当于对四组不同旋转的输入应用同一个变换F1。同理,(y1,y2,y3,y4)拼接得到F2变换的结果。

2.3 输出拼接

最终输出为:

outx = {x1, x2, x3, x4} outy = {y1, y2, y3, y4}

保持大端字节序,与输入格式一致。

3. 数学形式化描述

bit1_mixcolum定义的变换为:

F1(a,b,c,d) = b ⊕ c ⊕ d ⊕ xtime(a ⊕ b) F2(a,b,c,d) = xtime(xtime( (a⊕c) ⊕ xtime(a⊕b) ⊕ xtime(c⊕d) )) ⊕ F1(a,b,c,d)

bit8_mixcolum的输出为:

outx = { F1(a,b,c,d), F1(b,c,d,a), F1(c,d,a,b), F1(d,a,b,c) } outy = { F2(a,b,c,d), F2(b,c,d,a), F2(c,d,a,b), F2(d,a,b,c) }

可以看出,整个模块实际上对输入向量的四个循环移位版本分别应用相同的非线性‑线性组合,然后将结果向量化输出。这是一种典型的**SIMD(单指令多数据)**风格的硬件设计。

4. 创新点分析

创新维度具体描述
模块化分层设计直接复用bit1_mixcolum作为构建块,避免了在更高层次上重新设计有限域乘法逻辑。这种“乐高式”搭建使得代码简洁、易于验证和维护。
循环输入重排技巧通过简单的接线旋转(无需额外逻辑),实现了对输入字节所有循环排列的覆盖。这比硬编码四个不同的变换函数要优雅得多,且面积几乎为零。
双输出通道并行同时产生outxouty两个32位结果,满足了后续数据处理(例如AES的列混合需要两行同时计算)的需求,提升了吞吐率。
纯组合逻辑,无流水线冲突整个模块没有任何寄存器,所有子模块并行计算,输出延迟等于单个bit1_mixcolum的传播延迟(约4级xtime加若干异或门)。非常适合整合到高性能流水线中。
字节序友好明确采用大端字节序,与AES标准、网络字节序以及多数RISC指令集的内存视图一致,减少了集成的字节交换开销。
可扩展性强以此模块为基础,可以很容易地扩展到完整的128位列混合:只需例化4个bit8_mixcolum(分别处理四列),即可一次完成整个状态矩阵的变换。

5. 比喻

想象你有一个4人小组,每个人都要完成两道计算题(F1和F2),但每个人拿到的题目顺序不同:

  • 第1人:按顺序使用(a,b,c,d)作为输入
  • 第2人:把题目向前滚动一位,使用(b,c,d,a)
  • 第3人:再滚动一位,使用(c,d,a,b)
  • 第4人:再滚动一位,使用(d,a,b,c)

四个人同时独立计算,最后把所有人算出的F1结果按编号收起来就是outx,F2结果收起来就是outy
这个比喻说明了并行(四人同时)和循环移位(每人看到的顺序不同)两个核心思想。

6. 应用场景与扩展

  • AES-128/256的列混合层:将128位状态划分为4个32位列,每个列送入一个bit8_mixcolum,即可在单个时钟周期内完成整个MixColumns操作。
  • 自定义加密算法的混淆层:如果读者需要设计轻量级分组密码,可以调整bit1_mixcolum内部的xtime系数,然后同样用这种“旋转并行”结构实现任意4字节的线性变换。
  • FPGA中作为组合逻辑加速器:由于无寄存器,可放在逻辑路径中而不增加流水线深度,适合对延迟敏感的协议处理。
  • ASIC中的标准单元库模块:面积小、扇出规整,易于布局布线。

7. 总结

bit8_mixcolum是一个教科书级的模块化并行设计范例。它没有创造新的运算,而是通过巧妙的例化方式输入重排,将基础单元的能力放大了四倍。读者可以从中学习到:

  • 如何从底层模块构建上层功能
  • 如何利用循环移位覆盖所有需要的组合
  • 如何保持接口简洁而功能完整

理解了这个模块,也就掌握了构建更大规模密码硬件的基本思路。下一篇我们将继续向上组合,展示完整的128位列混合模块,敬请期待。


my_bit8_mixcolum.v完整代码

`timescale 1ns / 10ps module bit8_mixcolum ( input [31:0] in, output [31:0] outx, output [31:0] outy ); // ==================== 内部线网(w_ 前缀) ==================== wire [7:0] w_a, w_b, w_c, w_d; // 输入字节拆分 wire [7:0] w_x1, w_x2, w_x3, w_x4; // 子模块 outx 输出 wire [7:0] w_y1, w_y2, w_y3, w_y4; // 子模块 outy 输出 // ==================== 输入字节拆分 ==================== assign w_a = in[31:24]; assign w_b = in[23:16]; assign w_c = in[15:8]; assign w_d = in[7:0]; // ==================== 四个 bit1_mixcolum 实例化 ==================== bit1_mixcolum u1 ( .in1 (w_a), .in2 (w_b), .in3 (w_c), .in4 (w_d), .Out1 (w_x1), .Out2 (w_y1) ); bit1_mixcolum u2 ( .in1 (w_b), .in2 (w_c), .in3 (w_d), .in4 (w_a), .Out1 (w_x2), .Out2 (w_y2) ); bit1_mixcolum u3 ( .in1 (w_c), .in2 (w_d), .in3 (w_a), .in4 (w_b), .Out1 (w_x3), .Out2 (w_y3) ); bit1_mixcolum u4 ( .in1 (w_d), .in2 (w_a), .in3 (w_b), .in4 (w_c), .Out1 (w_x4), .Out2 (w_y4) ); // ==================== 输出拼接 ==================== assign outx = {w_x1, w_x2, w_x3, w_x4}; assign outy = {w_y1, w_y2, w_y3, w_y4}; endmodule

tb_my_bit8_mixcolum.v完整代码

`timescale 1ns/10ps module tb_bit8_mixcolum; // ============================================================ // 信号声明(全部放在模块头部,符合 Verilog 2001 要求) // ============================================================ reg [31:0] in; wire [31:0] outx, outy; reg [31:0] expected_outx; reg [31:0] expected_outy; reg [7:0] a, b, c, d; // 输入字节拆分(辅助) integer test_id; reg all_pass; // ============================================================ // 实例化待测模块 // ============================================================ bit8_mixcolum uut ( .in (in), .outx (outx), .outy (outy) ); // ============================================================ // 参考模型函数(GF(2^8) 运算,不可约多项式 x^8+x^4+x^3+x+1) // ============================================================ // xtime(x) = x * {02} in GF(2^8) function [7:0] xtime; input [7:0] x; reg [7:0] tmp; begin tmp = {x[6:0], 1'b0}; if (x[7]) tmp = tmp ^ 8'h1b; xtime = tmp; end endfunction // F1 函数:对应 bit1_mixcolum 的 Out1 function [7:0] F1; input [7:0] a, b, c, d; reg [7:0] t1; begin t1 = a ^ b; F1 = b ^ c ^ d ^ xtime(t1); end endfunction // F2 函数:对应 bit1_mixcolum 的 Out2 function [7:0] F2; input [7:0] a, b, c, d; reg [7:0] t1, t2, t3, t4, t5, t6; begin t1 = a ^ b; t2 = a ^ c; t3 = c ^ d; t4 = xtime(t1); t5 = xtime(t3); t6 = t2 ^ t4 ^ t5; F2 = xtime(xtime(t6)) ^ F1(a, b, c, d); end endfunction // 期望 outx 的计算 function [31:0] exp_outx; input [7:0] a, b, c, d; begin exp_outx = { F1(a,b,c,d), F1(b,c,d,a), F1(c,d,a,b), F1(d,a,b,c) }; end endfunction // 期望 outy 的计算 function [31:0] exp_outy; input [7:0] a, b, c, d; begin exp_outy = { F2(a,b,c,d), F2(b,c,d,a), F2(c,d,a,b), F2(d,a,b,c) }; end endfunction // ============================================================ // 测试主流程 // ============================================================ initial begin $display("=========================================================="); $display("Starting auto-checking testbench for bit8_mixcolum"); $display("==========================================================\n"); all_pass = 1'b1; test_id = 0; // -------------------------------------------------------- // Test 1: 全零输入 // -------------------------------------------------------- test_id = test_id + 1; in = 32'h00000000; a = 8'h00; b = 8'h00; c = 8'h00; d = 8'h00; expected_outx = exp_outx(a, b, c, d); expected_outy = exp_outy(a, b, c, d); #10; run_check(test_id, in, outx, outy, expected_outx, expected_outy); // -------------------------------------------------------- // Test 2: 全 0x01 // -------------------------------------------------------- test_id = test_id + 1; in = 32'h01010101; a = 8'h01; b = 8'h01; c = 8'h01; d = 8'h01; expected_outx = exp_outx(a, b, c, d); expected_outy = exp_outy(a, b, c, d); #10; run_check(test_id, in, outx, outy, expected_outx, expected_outy); // -------------------------------------------------------- // Test 3: 全 0xFF // -------------------------------------------------------- test_id = test_id + 1; in = 32'hFFFFFFFF; a = 8'hFF; b = 8'hFF; c = 8'hFF; d = 8'hFF; expected_outx = exp_outx(a, b, c, d); expected_outy = exp_outy(a, b, c, d); #10; run_check(test_id, in, outx, outy, expected_outx, expected_outy); // -------------------------------------------------------- // Test 4: 递增模式 0x01020304 // -------------------------------------------------------- test_id = test_id + 1; in = 32'h01020304; a = 8'h01; b = 8'h02; c = 8'h03; d = 8'h04; expected_outx = exp_outx(a, b, c, d); expected_outy = exp_outy(a, b, c, d); #10; run_check(test_id, in, outx, outy, expected_outx, expected_outy); // -------------------------------------------------------- // Test 5: 随机模式 1 // -------------------------------------------------------- test_id = test_id + 1; in = 32'h12345678; a = 8'h12; b = 8'h34; c = 8'h56; d = 8'h78; expected_outx = exp_outx(a, b, c, d); expected_outy = exp_outy(a, b, c, d); #10; run_check(test_id, in, outx, outy, expected_outx, expected_outy); // -------------------------------------------------------- // Test 6: 随机模式 2 (边界含 0x80) // -------------------------------------------------------- test_id = test_id + 1; in = 32'h80A5C3F0; a = 8'h80; b = 8'hA5; c = 8'hC3; d = 8'hF0; expected_outx = exp_outx(a, b, c, d); expected_outy = exp_outy(a, b, c, d); #10; run_check(test_id, in, outx, outy, expected_outx, expected_outy); // -------------------------------------------------------- // Test 7: 交替 0x55 / 0xAA // -------------------------------------------------------- test_id = test_id + 1; in = 32'h55AA55AA; a = 8'h55; b = 8'hAA; c = 8'h55; d = 8'hAA; expected_outx = exp_outx(a, b, c, d); expected_outy = exp_outy(a, b, c, d); #10; run_check(test_id, in, outx, outy, expected_outx, expected_outy); // -------------------------------------------------------- // 最终报告 // -------------------------------------------------------- $display("\n=========================================================="); if (all_pass) $display("RESULT: ALL TESTS PASSED"); else $display("RESULT: SOME TESTS FAILED (see above)"); $display("=========================================================="); $finish; end // ============================================================ // 比较任务(自动判断 PASS/FAIL) // ============================================================ task run_check; input integer id; input [31:0] i, ox, oy, exx, exy; reg okx, oky; begin okx = (ox === exx); oky = (oy === exy); $display("Test %0d: in = %h", id, i); $display(" outx = %h (%s) expected = %h", ox, okx ? "OK" : "FAIL", exx); $display(" outy = %h (%s) expected = %h", oy, oky ? "OK" : "FAIL", exy); if (okx && oky) begin $display(" => PASS\n"); end else begin $display(" => FAIL\n"); all_pass = 1'b0; end end endtask endmodule


AES加密解密硬件实现详解:从算法到Verilog设计

AES加密解密硬件实现详解-完整代码(1):my_sbox_tops.v

AES加密解密硬件实现详解-完整代码(2):my_subbytes.v

AES加密解密硬件实现详解-完整代码(3):my_keysecret.v

AES加密解密硬件实现详解-完整代码(4):my_mixcolum.v

AES加密解密硬件实现详解-完整代码(5):my_bit1_mixcolum.v

AES加密解密硬件实现详解-完整代码(6):my_bit8_mixcolum.v

AES加密解密硬件实现详解-完整代码(7):my_aes_top.v
(如果您对模块的数学推导或硬件实现有疑问,欢迎留言讨论!)

http://www.zskr.cn/news/1509225.html

相关文章:

  • 2026年河南专业艺考画室怎么选?——基于师资、成绩、服务与区域覆盖的综合分析 - 优质品牌商家
  • watch mtapi.mt5.MT5API OrderSend ‘{params, returnObj}‘ -x 3 会显示3个返回
  • 通辽市黄金回收白银回收铂金回收彩金回收靠谱门店TOP排行榜及联系方式地址电话+诚信店铺推荐 - 大熊猫898989
  • 从零开始:Python爬虫实战——爬取豆瓣读书评分9.0以上高分图书(完整教程)
  • 2026四川全新料PP打包带选型指南:半自动全自动打包机适配与常见问题分析
  • 基于算法数据拆解墨西哥vs南非:攻防指标多维对比
  • SVG动效制作工具选型报告:轻松实现“Apple风”图片动效的企业级方案 - 小小智慧树~
  • 时间序列分解实战指南:趋势、季节性与残差的业务解读
  • 跑外卖日入七八十,挖漏洞半小时赚500!这就是网安技术红利
  • 别再傻傻分不清了!C51单片机编程里bit和sbit到底怎么用?
  • 揭秘PC版微信QQ防撤回补丁:告别“对方已撤回“的终极解决方案
  • 【TGRS 2026即插即用模块】PSAA并行自感知注意力,适合红外小目标检测、遥感图像处理、医学图像重建、遥感图像分割、目标分割、目标检测、图像增强等CV任务通用,涨点起飞!
  • 终极自托管游戏串流实战指南:5步搭建你的家庭游戏云平台
  • 鸿蒙原生开发——从零构建倒数日追踪器
  • AC7840芯片UART+DMA循环接收工程(IAR/Keil双环境验证)
  • 从S32K1到S32K3:手把手教你迁移汽车MCU项目(基于Arm Cortex-M7实战)
  • 百度网盘直链解析工具:技术侦探带你破解下载速度之谜
  • 从设计到量产:手把手拆解芯片内存测试(MBIST)与修复(BISR)的全流程
  • 为什么你的MOS管在干燥冬天更容易挂?从极间电容和输入电阻角度拆解静电积累
  • 从收音机到Wi-Fi:串联RLC电路如何成为无线通信的“频率守门员”?
  • 生产级多维聚合四大铁律:从pandas groupby到银行风控实战
  • X79双路主板Win10开机卡Logo?富士康/广达平台专用DLL修复包
  • CMake 015:日志级别全解析
  • Vue.js从零到精通系列(六):组合式函数与逻辑复用——打造自己的 Hooks 工具箱
  • 2026年济南中职学校大揭秘:究竟哪个教学质量更胜一筹?
  • STM32F103的TIM定时器到底怎么选?从呼吸灯到舵机控制,聊聊通用定时器的那些事儿
  • H5页面跨环境直连微信小程序:微信内+外部浏览器一键唤起方案
  • 华硕笔记本性能优化神器G-Helper:告别臃肿Armoury Crate的终极指南
  • 用Python和NetworkX做《权游》社会网络分析
  • 零基础入局白帽SRC!3个月从零斩获首个漏洞,新手赏金挖洞全攻略