标题:
FPGA实现MD5算法 Quartus II 13.0 Verilog HDL 模块源码 (最大计算55字节)
[打印本页]
作者:
npn
时间:
2022-3-9 10:20
标题:
FPGA实现MD5算法 Quartus II 13.0 Verilog HDL 模块源码 (最大计算55字节)
main.png
(12.05 KB, 下载次数: 98)
下载附件
2022-3-9 10:19 上传
module md5_while( //进行一轮MD5计算
input [511:0] dat, //MD5块数据 512位
input [127:0] in, //MD5输入
output [127:0] out //MD5输出
);
function [31:0] ReverseIntBytes; //反转整数字节序(32位大小端转换)
input [31:0] in;
begin
ReverseIntBytes[31:24] = in[7:0];
ReverseIntBytes[23:16] = in[15:8];
ReverseIntBytes[15:8] = in[23:16];
ReverseIntBytes[7:0] = in[31:24];
end
endfunction
function [31:0] rol32; //32位循环左移
input [31:0] a; //数字 范围:0~4294967295
input [4:0] b; //位数 范围:0~31
begin
rol32 = a << b | a >> 6'd32-b;
end
endfunction
function [31:0] md5_F;
input [31:0] x;
input [31:0] y;
input [31:0] z;
begin
md5_F = (x & y) | ((~x) & z);
end
endfunction
function [31:0] md5_G;
input [31:0] x;
input [31:0] y;
input [31:0] z;
begin
md5_G = (x & z) | (y & (~z));
end
endfunction
function [31:0] md5_H;
input [31:0] x;
input [31:0] y;
input [31:0] z;
begin
md5_H = (x ^ y ^ z);
end
endfunction
function [31:0] md5_I;
input [31:0] x;
input [31:0] y;
input [31:0] z;
begin
md5_I = (y ^ (x | (~z)));
end
endfunction
function [31:0] md5_FF;
input [31:0] a;
input [31:0] b;
input [31:0] c;
input [31:0] d;
input [31:0] Mj;
input [4:0] s;
input [31:0] ti;
begin
md5_FF = b + rol32 (a + md5_F(b,c,d) + Mj + ti, s);
end
endfunction
function [31:0] md5_GG;
input [31:0] a;
input [31:0] b;
input [31:0] c;
input [31:0] d;
input [31:0] Mj;
input [4:0] s;
input [31:0] ti;
begin
md5_GG = b + rol32 (a + md5_G(b,c,d) + Mj + ti, s);
end
endfunction
function [31:0] md5_HH;
input [31:0] a;
input [31:0] b;
input [31:0] c;
input [31:0] d;
input [31:0] Mj;
input [4:0] s;
input [31:0] ti;
begin
md5_HH = b + rol32 (a + md5_H(b,c,d) + Mj + ti, s);
end
endfunction
function [31:0] md5_II;
input [31:0] a;
input [31:0] b;
input [31:0] c;
input [31:0] d;
input [31:0] Mj;
input [4:0] s;
input [31:0] ti;
begin
md5_II = b + rol32 (a + md5_I(b,c,d) + Mj + ti, s);
end
endfunction
assign out = {
ReverseIntBytes(AA),
ReverseIntBytes(BB),
ReverseIntBytes(CC),
ReverseIntBytes(DD)
};
reg [31:0] AA;
reg [31:0] BB;
reg [31:0] CC;
reg [31:0] DD;
reg [31:0] A;
reg [31:0] B;
reg [31:0] C;
reg [31:0] D;
wire [31:0] x [15:0];
generate
genvar y;
for(y = 0;y < 16;y = y + 1) begin:gen
assign x[y] = ReverseIntBytes(dat[32*(16-y)-1:32*(16-y)-32]);
end
endgenerate
always @(*) begin
{AA,BB,CC,DD} = {
ReverseIntBytes(in[127:96]),
ReverseIntBytes(in[95:64]),
ReverseIntBytes(in[63:32]),
ReverseIntBytes(in[31:0])
};
{A,B,C,D} = {AA,BB,CC,DD};
A = md5_FF(A, B, C, D, x[00], 5'd07, 32'hD76AA478);
D = md5_FF(D, A, B, C, x[01], 5'd12, 32'hE8C7B756);
C = md5_FF(C, D, A, B, x[02], 5'd17, 32'h242070DB);
B = md5_FF(B, C, D, A, x[03], 5'd22, 32'hC1BDCEEE);
A = md5_FF(A, B, C, D, x[04], 5'd07, 32'hF57C0FAF);
D = md5_FF(D, A, B, C, x[05], 5'd12, 32'h4787C62A);
C = md5_FF(C, D, A, B, x[06], 5'd17, 32'hA8304613);
B = md5_FF(B, C, D, A, x[07], 5'd22, 32'hFD469501);
A = md5_FF(A, B, C, D, x[08], 5'd07, 32'h698098D8);
D = md5_FF(D, A, B, C, x[09], 5'd12, 32'h8B44F7AF);
C = md5_FF(C, D, A, B, x[10], 5'd17, 32'hFFFF5BB1);
B = md5_FF(B, C, D, A, x[11], 5'd22, 32'h895CD7BE);
A = md5_FF(A, B, C, D, x[12], 5'd07, 32'h6B901122);
D = md5_FF(D, A, B, C, x[13], 5'd12, 32'hFD987193);
C = md5_FF(C, D, A, B, x[14], 5'd17, 32'hA679438E);
B = md5_FF(B, C, D, A, x[15], 5'd22, 32'h49B40821);
A = md5_GG(A, B, C, D, x[01], 5'd05, 32'hF61E2562);
D = md5_GG(D, A, B, C, x[06], 5'd09, 32'hC040B340);
C = md5_GG(C, D, A, B, x[11], 5'd14, 32'h265E5A51);
B = md5_GG(B, C, D, A, x[00], 5'd20, 32'hE9B6C7AA);
A = md5_GG(A, B, C, D, x[05], 5'd05, 32'hD62F105D);
D = md5_GG(D, A, B, C, x[10], 5'd09, 32'h02441453);
C = md5_GG(C, D, A, B, x[15], 5'd14, 32'hD8A1E681);
B = md5_GG(B, C, D, A, x[04], 5'd20, 32'hE7D3FBC8);
A = md5_GG(A, B, C, D, x[09], 5'd05, 32'h21E1CDE6);
D = md5_GG(D, A, B, C, x[14], 5'd09, 32'hC33707D6);
C = md5_GG(C, D, A, B, x[03], 5'd14, 32'hF4D50D87);
B = md5_GG(B, C, D, A, x[08], 5'd20, 32'h455A14ED);
A = md5_GG(A, B, C, D, x[13], 5'd05, 32'hA9E3E905);
D = md5_GG(D, A, B, C, x[02], 5'd09, 32'hFCEFA3F8);
C = md5_GG(C, D, A, B, x[07], 5'd14, 32'h676F02D9);
B = md5_GG(B, C, D, A, x[12], 5'd20, 32'h8D2A4C8A);
A = md5_HH(A, B, C, D, x[05], 5'd04, 32'hFFFA3942);
D = md5_HH(D, A, B, C, x[08], 5'd11, 32'h8771F681);
C = md5_HH(C, D, A, B, x[11], 5'd16, 32'h6D9D6122);
B = md5_HH(B, C, D, A, x[14], 5'd23, 32'hFDE5380C);
A = md5_HH(A, B, C, D, x[01], 5'd04, 32'hA4BEEA44);
D = md5_HH(D, A, B, C, x[04], 5'd11, 32'h4BDECFA9);
C = md5_HH(C, D, A, B, x[07], 5'd16, 32'hF6BB4B60);
B = md5_HH(B, C, D, A, x[10], 5'd23, 32'hBEBFBC70);
A = md5_HH(A, B, C, D, x[13], 5'd04, 32'h289B7EC6);
D = md5_HH(D, A, B, C, x[00], 5'd11, 32'hEAA127FA);
C = md5_HH(C, D, A, B, x[03], 5'd16, 32'hD4EF3085);
B = md5_HH(B, C, D, A, x[06], 5'd23, 32'h04881D05);
A = md5_HH(A, B, C, D, x[09], 5'd04, 32'hD9D4D039);
D = md5_HH(D, A, B, C, x[12], 5'd11, 32'hE6DB99E5);
C = md5_HH(C, D, A, B, x[15], 5'd16, 32'h1FA27CF8);
B = md5_HH(B, C, D, A, x[02], 5'd23, 32'hC4AC5665);
A = md5_II(A, B, C, D, x[00], 5'd06, 32'hF4292244);
D = md5_II(D, A, B, C, x[07], 5'd10, 32'h432AFF97);
C = md5_II(C, D, A, B, x[14], 5'd15, 32'hAB9423A7);
B = md5_II(B, C, D, A, x[05], 5'd21, 32'hFC93A039);
A = md5_II(A, B, C, D, x[12], 5'd06, 32'h655B59C3);
D = md5_II(D, A, B, C, x[03], 5'd10, 32'h8F0CCC92);
C = md5_II(C, D, A, B, x[10], 5'd15, 32'hFFEFF47D);
B = md5_II(B, C, D, A, x[01], 5'd21, 32'h85845DD1);
A = md5_II(A, B, C, D, x[08], 5'd06, 32'h6FA87E4F);
D = md5_II(D, A, B, C, x[15], 5'd10, 32'hFE2CE6E0);
C = md5_II(C, D, A, B, x[06], 5'd15, 32'hA3014314);
B = md5_II(B, C, D, A, x[13], 5'd21, 32'h4E0811A1);
A = md5_II(A, B, C, D, x[04], 5'd06, 32'hF7537E82);
D = md5_II(D, A, B, C, x[11], 5'd10, 32'hBD3AF235);
C = md5_II(C, D, A, B, x[02], 5'd15, 32'h2AD7D2BB);
B = md5_II(B, C, D, A, x[09], 5'd21, 32'hEB86D391);
{AA,BB,CC,DD} = {AA + A,BB + B,CC + C,DD + D};
end
endmodule
module md5( //计算MD5 最大55字节
input [439:0] dat, //MD5明文数据 55*8=440位 (位宽必须一致 数据靠左对齐 末尾填0 否则会出错)
input [5:0] len, //数据字节数 范围:0~55
output [127:0] ret, //MD5计算结果 128位
output ok //计算成功置1 失败清0
);
function [63:0] ReverseLongBytes; //反转长整数字节序(64位大小端转换)
input [63:0] in;
begin
ReverseLongBytes[63:56] = in[7:0];
ReverseLongBytes[55:48] = in[15:8];
ReverseLongBytes[47:40] = in[23:16];
ReverseLongBytes[39:32] = in[31:24];
ReverseLongBytes[31:24] = in[39:32];
ReverseLongBytes[23:16] = in[47:40];
ReverseLongBytes[15:8] = in[55:48];
ReverseLongBytes[7:0] = in[63:56];
end
endfunction
reg [511:0] md5_block = 512'b0;
assign ok = (len <= 55);
generate
genvar y;
for(y = 0; y <= 55;y = y + 1) begin:gen2
parameter i = 440 - y * 8 - 1;
parameter j = i < 0 ? 7 : i;
parameter k = 72 + i;
always @(*) begin
if(y < len) begin
md5_block[k:k-7] = dat[j:j-7];
end else if(y == len) begin
md5_block[k:k-7] = 8'h80;
end else begin
md5_block[k:k-7] = 8'h0;
end
end
end
endgenerate
always @(*) begin
md5_block[63:0] = ReverseLongBytes(len << 3);
end
md5_while md5_while(
.dat(md5_block),
.in(128'h0123456789ABCDEFFEDCBA9876543210), //严禁修改
.out(ret)
);
endmodule
module main(
input clk, //50Mhz 时钟输入 Pin17
output reg led //LED Pin3 (低电平点亮)
);
wire [127:0] ret;
wire ok;
md5 md5(
.dat({"Hello World!0123456789",{33{8'h0}}}),
.len(6'd22), //22字节
.ret(ret),
.ok(ok)
);
always @(posedge clk) begin
if(ret == 128'hEF8D236D359B2B0907ADAA4A26D3AFE6 && ok == 1) begin //计算正确点亮
led <= 0;
end else begin //错误熄灭
led <= 1;
end
end
endmodule
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1