设为首页收藏本站帮助中心
查看: 1576|回复: 8
收起左侧

Quartus Verilog HDL/FPGA 实现并行计算数据的MD5哈希校验值算法 (最大输入55字节)

[复制链接]
发表于 2022-1-28 08:31:31 | 显示全部楼层 |阅读模式
main.png
  1. module md5_while(                                //进行一轮MD5计算
  2.         input [511:0] dat,                //MD5块数据 512位
  3.         input [127:0] in,                        //MD5输入
  4.         output [127:0] out                //MD5输出
  5. );

  6. function [31:0] ReverseIntBytes;                //反转整数字节序(32位大小端转换)
  7.         input [31:0] in;
  8.         begin
  9.         ReverseIntBytes[31:24] = in[7:0];
  10.         ReverseIntBytes[23:16] = in[15:8];
  11.         ReverseIntBytes[15:8] = in[23:16];
  12.         ReverseIntBytes[7:0] = in[31:24];       
  13.         end
  14. endfunction

  15. function [31:0] rol32;                //32位循环左移
  16.         input [31:0] a;                        //数字 范围:0~4294967295
  17.         input [4:0] b;                                //位数 范围:0~31
  18.         begin
  19.                 rol32 = a << b | a >> 6'd32-b;
  20.         end
  21. endfunction

  22. function [31:0] md5_F;
  23.         input [31:0] x;
  24.         input [31:0] y;
  25.         input [31:0] z;
  26.         begin
  27.                 md5_F = (x & y) | ((~x) & z);
  28.         end
  29. endfunction

  30. function [31:0] md5_G;
  31.         input [31:0] x;
  32.         input [31:0] y;
  33.         input [31:0] z;
  34.         begin
  35.                 md5_G = (x & z) | (y & (~z));
  36.         end
  37. endfunction

  38. function [31:0] md5_H;
  39.         input [31:0] x;
  40.         input [31:0] y;
  41.         input [31:0] z;
  42.         begin
  43.                 md5_H = (x ^ y ^ z);
  44.         end
  45. endfunction

  46. function [31:0] md5_I;
  47.         input [31:0] x;
  48.         input [31:0] y;
  49.         input [31:0] z;
  50.         begin
  51.                 md5_I = (y ^ (x | (~z)));
  52.         end
  53. endfunction

  54. function [31:0] md5_FF;
  55.         input [31:0] a;
  56.         input [31:0] b;
  57.         input [31:0] c;
  58.         input [31:0] d;
  59.         input [31:0] Mj;
  60.         input [4:0] s;
  61.         input [31:0] ti;
  62.         begin
  63.                 md5_FF = b + rol32 (a + md5_F(b,c,d) + Mj + ti, s);
  64.         end
  65. endfunction

  66. function [31:0] md5_GG;
  67.         input [31:0] a;
  68.         input [31:0] b;
  69.         input [31:0] c;
  70.         input [31:0] d;
  71.         input [31:0] Mj;
  72.         input [4:0] s;
  73.         input [31:0] ti;
  74.         begin
  75.                 md5_GG = b + rol32 (a + md5_G(b,c,d) + Mj + ti, s);       
  76.         end
  77. endfunction

  78. function [31:0] md5_HH;
  79.         input [31:0] a;
  80.         input [31:0] b;
  81.         input [31:0] c;
  82.         input [31:0] d;
  83.         input [31:0] Mj;
  84.         input [4:0] s;
  85.         input [31:0] ti;
  86.         begin
  87.                 md5_HH = b + rol32 (a + md5_H(b,c,d) + Mj + ti, s);       
  88.         end
  89. endfunction

  90. function [31:0] md5_II;
  91.         input [31:0] a;
  92.         input [31:0] b;
  93.         input [31:0] c;
  94.         input [31:0] d;
  95.         input [31:0] Mj;
  96.         input [4:0] s;
  97.         input [31:0] ti;
  98.         begin
  99.                 md5_II = b + rol32 (a + md5_I(b,c,d) + Mj + ti, s);       
  100.         end
  101. endfunction

  102. assign out = {
  103.         ReverseIntBytes(AA),
  104.         ReverseIntBytes(BB),
  105.         ReverseIntBytes(CC),
  106.         ReverseIntBytes(DD)
  107. };

  108. reg [31:0] AA;
  109. reg [31:0] BB;
  110. reg [31:0] CC;
  111. reg [31:0] DD;
  112. reg [31:0] A;
  113. reg [31:0] B;
  114. reg [31:0] C;
  115. reg [31:0] D;
  116. wire [31:0] x [15:0];

  117. generate
  118.                 genvar y;
  119.                 for(y = 0;y < 16;y = y + 1) begin:gen
  120.                         assign x[y] = ReverseIntBytes(dat[32*(16-y)-1:32*(16-y)-32]);
  121.                 end
  122. endgenerate

  123. always @(*) begin
  124.                   {AA,BB,CC,DD} = {
  125.                                 ReverseIntBytes(in[127:96]),
  126.                                 ReverseIntBytes(in[95:64]),
  127.                                 ReverseIntBytes(in[63:32]),
  128.                                 ReverseIntBytes(in[31:0])
  129.                   };
  130.                   {A,B,C,D} = {AA,BB,CC,DD};
  131.         A = md5_FF(A, B, C, D, x[00], 5'd07, 32'hD76AA478);
  132.         D = md5_FF(D, A, B, C, x[01], 5'd12, 32'hE8C7B756);
  133.         C = md5_FF(C, D, A, B, x[02], 5'd17, 32'h242070DB);
  134.         B = md5_FF(B, C, D, A, x[03], 5'd22, 32'hC1BDCEEE);
  135.         A = md5_FF(A, B, C, D, x[04], 5'd07, 32'hF57C0FAF);
  136.         D = md5_FF(D, A, B, C, x[05], 5'd12, 32'h4787C62A);
  137.         C = md5_FF(C, D, A, B, x[06], 5'd17, 32'hA8304613);
  138.         B = md5_FF(B, C, D, A, x[07], 5'd22, 32'hFD469501);
  139.         A = md5_FF(A, B, C, D, x[08], 5'd07, 32'h698098D8);
  140.         D = md5_FF(D, A, B, C, x[09], 5'd12, 32'h8B44F7AF);
  141.         C = md5_FF(C, D, A, B, x[10], 5'd17, 32'hFFFF5BB1);
  142.         B = md5_FF(B, C, D, A, x[11], 5'd22, 32'h895CD7BE);
  143.         A = md5_FF(A, B, C, D, x[12], 5'd07, 32'h6B901122);
  144.         D = md5_FF(D, A, B, C, x[13], 5'd12, 32'hFD987193);
  145.         C = md5_FF(C, D, A, B, x[14], 5'd17, 32'hA679438E);
  146.         B = md5_FF(B, C, D, A, x[15], 5'd22, 32'h49B40821);
  147.         A = md5_GG(A, B, C, D, x[01], 5'd05, 32'hF61E2562);
  148.         D = md5_GG(D, A, B, C, x[06], 5'd09, 32'hC040B340);
  149.         C = md5_GG(C, D, A, B, x[11], 5'd14, 32'h265E5A51);
  150.         B = md5_GG(B, C, D, A, x[00], 5'd20, 32'hE9B6C7AA);
  151.         A = md5_GG(A, B, C, D, x[05], 5'd05, 32'hD62F105D);
  152.         D = md5_GG(D, A, B, C, x[10], 5'd09, 32'h02441453);
  153.         C = md5_GG(C, D, A, B, x[15], 5'd14, 32'hD8A1E681);
  154.         B = md5_GG(B, C, D, A, x[04], 5'd20, 32'hE7D3FBC8);
  155.         A = md5_GG(A, B, C, D, x[09], 5'd05, 32'h21E1CDE6);
  156.         D = md5_GG(D, A, B, C, x[14], 5'd09, 32'hC33707D6);
  157.         C = md5_GG(C, D, A, B, x[03], 5'd14, 32'hF4D50D87);
  158.         B = md5_GG(B, C, D, A, x[08], 5'd20, 32'h455A14ED);
  159.         A = md5_GG(A, B, C, D, x[13], 5'd05, 32'hA9E3E905);
  160.         D = md5_GG(D, A, B, C, x[02], 5'd09, 32'hFCEFA3F8);
  161.         C = md5_GG(C, D, A, B, x[07], 5'd14, 32'h676F02D9);
  162.         B = md5_GG(B, C, D, A, x[12], 5'd20, 32'h8D2A4C8A);
  163.         A = md5_HH(A, B, C, D, x[05], 5'd04, 32'hFFFA3942);
  164.         D = md5_HH(D, A, B, C, x[08], 5'd11, 32'h8771F681);
  165.         C = md5_HH(C, D, A, B, x[11], 5'd16, 32'h6D9D6122);
  166.         B = md5_HH(B, C, D, A, x[14], 5'd23, 32'hFDE5380C);
  167.         A = md5_HH(A, B, C, D, x[01], 5'd04, 32'hA4BEEA44);
  168.         D = md5_HH(D, A, B, C, x[04], 5'd11, 32'h4BDECFA9);
  169.         C = md5_HH(C, D, A, B, x[07], 5'd16, 32'hF6BB4B60);
  170.         B = md5_HH(B, C, D, A, x[10], 5'd23, 32'hBEBFBC70);
  171.         A = md5_HH(A, B, C, D, x[13], 5'd04, 32'h289B7EC6);
  172.         D = md5_HH(D, A, B, C, x[00], 5'd11, 32'hEAA127FA);
  173.         C = md5_HH(C, D, A, B, x[03], 5'd16, 32'hD4EF3085);
  174.         B = md5_HH(B, C, D, A, x[06], 5'd23, 32'h04881D05);
  175.         A = md5_HH(A, B, C, D, x[09], 5'd04, 32'hD9D4D039);
  176.         D = md5_HH(D, A, B, C, x[12], 5'd11, 32'hE6DB99E5);
  177.         C = md5_HH(C, D, A, B, x[15], 5'd16, 32'h1FA27CF8);
  178.         B = md5_HH(B, C, D, A, x[02], 5'd23, 32'hC4AC5665);
  179.         A = md5_II(A, B, C, D, x[00], 5'd06, 32'hF4292244);
  180.         D = md5_II(D, A, B, C, x[07], 5'd10, 32'h432AFF97);
  181.         C = md5_II(C, D, A, B, x[14], 5'd15, 32'hAB9423A7);
  182.         B = md5_II(B, C, D, A, x[05], 5'd21, 32'hFC93A039);
  183.         A = md5_II(A, B, C, D, x[12], 5'd06, 32'h655B59C3);
  184.         D = md5_II(D, A, B, C, x[03], 5'd10, 32'h8F0CCC92);
  185.         C = md5_II(C, D, A, B, x[10], 5'd15, 32'hFFEFF47D);
  186.         B = md5_II(B, C, D, A, x[01], 5'd21, 32'h85845DD1);
  187.         A = md5_II(A, B, C, D, x[08], 5'd06, 32'h6FA87E4F);
  188.         D = md5_II(D, A, B, C, x[15], 5'd10, 32'hFE2CE6E0);
  189.         C = md5_II(C, D, A, B, x[06], 5'd15, 32'hA3014314);
  190.         B = md5_II(B, C, D, A, x[13], 5'd21, 32'h4E0811A1);
  191.         A = md5_II(A, B, C, D, x[04], 5'd06, 32'hF7537E82);
  192.         D = md5_II(D, A, B, C, x[11], 5'd10, 32'hBD3AF235);
  193.         C = md5_II(C, D, A, B, x[02], 5'd15, 32'h2AD7D2BB);
  194.         B = md5_II(B, C, D, A, x[09], 5'd21, 32'hEB86D391);
  195.                   {AA,BB,CC,DD} = {AA + A,BB + B,CC + C,DD + D};
  196. end
  197. endmodule

  198. module md5(                                                //计算MD5 最大55字节
  199.         input [439:0] dat,                //MD5明文数据 55*8=440位 (位宽必须一致 数据靠左对齐 末尾填0 否则会出错)
  200.         input [5:0] len,                        //数据字节数 范围:0~55
  201.         output [127:0] ret,                //MD5计算结果 128位
  202.         output ok                                        //计算成功置1 失败清0
  203. );

  204. function [63:0] ReverseLongBytes;                //反转长整数字节序(64位大小端转换)
  205.         input [63:0] in;
  206.         begin
  207.         ReverseLongBytes[63:56] = in[7:0];
  208.         ReverseLongBytes[55:48] = in[15:8];
  209.         ReverseLongBytes[47:40] = in[23:16];
  210.         ReverseLongBytes[39:32] = in[31:24];
  211.         ReverseLongBytes[31:24] = in[39:32];
  212.         ReverseLongBytes[23:16] = in[47:40];
  213.         ReverseLongBytes[15:8] = in[55:48];
  214.         ReverseLongBytes[7:0] = in[63:56];
  215.         end
  216. endfunction

  217. reg [511:0] md5_block = 512'b0;
  218. assign ok = (len <= 55);
  219. generate
  220.         genvar y;
  221.         for(y = 0; y <= 55;y = y + 1) begin:gen2
  222.                 parameter i = 440 - y * 8 - 1;
  223.                 parameter j = i < 0 ? 7 : i;
  224.                 parameter k = 72 + i;
  225.                 always @(*) begin
  226.                         if(y < len) begin
  227.                                 md5_block[k:k-7] = dat[j:j-7];
  228.                         end else if(y == len) begin
  229.                                 md5_block[k:k-7] = 8'h80;
  230.                         end else begin
  231.                                 md5_block[k:k-7] = 8'h0;
  232.                         end
  233.                 end
  234.         end
  235. endgenerate

  236. always @(*) begin
  237.         md5_block[63:0] = ReverseLongBytes(len << 3);
  238. end

  239. md5_while md5_while(
  240.         .dat(md5_block),
  241.         .in(128'h0123456789ABCDEFFEDCBA9876543210),                //严禁修改
  242.         .out(ret)
  243. );

  244. endmodule

  245. module main(
  246.         input clk,                        //50Mhz 时钟输入 Pin17
  247.         output reg led                //LED Pin3 (低电平点亮)
  248. );
  249.         wire [127:0] ret;
  250.         wire ok;
  251.         md5 md5(
  252.                 .dat({"Hello World!0123456789",{33{8'h0}}}),
  253.                 .len(6'd22),                //22字节
  254.                 .ret(ret),
  255.                 .ok(ok)
  256.         );
  257.         always @(posedge clk) begin
  258.                 if(ret == 128'hEF8D236D359B2B0907ADAA4A26D3AFE6 && ok == 1) begin                //计算正确点亮
  259.                         led <= 0;
  260.                 end else begin                        //错误熄灭
  261.                         led <= 1;
  262.                 end
  263.         end
  264. endmodule

复制代码

相关帖子

回复

使用道具 举报

发表于 2022-1-31 23:01:48 | 显示全部楼层

我也想知道
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入我们

本版积分规则