The output sha256 hash value does not meet expectations
hello sir, I am trying to directly test sha256_core.v without using sha256.v as the top-level module. I have written a testbench for it, but when I input the hexadecimal block value, I did not get the expected hash value output.
Here is my input block data
10a548fa958c10d2d11435456176bc6a555cb3f463a8bd23a7bb29283781f2a71123c60c6ef0923a2ec4c9f75e0e0f9042509594865b46691f962c4dd4642c28
Here is the correct hash value of input block calculated by the online sha256 tool
1b20aa312f1c48723c3e0e17396b01b03926267cacd7d50221379be90ef24ced
Here is the online tool website I use to verify sha256 hash values
https://emn178.github.io/online-tools/sha256.html?input=10a548fa958c10d2d11435456176bc6a555cb3f463a8bd23a7bb29283781f2a71123c60c6ef0923a2ec4c9f75e0e0f9042509594865b46691f962c4dd4642c28&input_type=hex&output_type=hex&hmac_enabled=0&hmac_input_type=hex
This is the output digest value I obtained when running testbench
086a42b3642eddf7623eb021d4e496e756a3cd632638fc1b1c75e2c45e0d5302
This is clearly inconsistent with expectations
Here is my testbench
`timescale 1ns/1ps
module sha256_core_tb;
parameter CLK_HALF_PERIOD = 5;
parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
reg clk;
reg reset;
reg init;
reg mode;
reg next;
reg [511:0] input_block;
wire ready;
wire [255:0] out_hash;
wire out_valid;
sha256_core dut (
.clk(clk),
.reset_n(reset),
.init(init),
.next(mode),
.mode(next),
.block(input_block),
.ready(ready),
.digest(out_hash),
.digest_valid(out_valid)
);
initial begin
clk = 0;
forever begin
#(CLK_HALF_PERIOD);
clk = ~clk;
#(CLK_HALF_PERIOD);
end
end
task wait_ready;
begin
while(!ready) begin
#(CLK_PERIOD);
end
end
endtask // wait_ready
task init_sim;
begin
clk = 0;
reset = 1;
init = 0;
next = 0;
mode = 1;
input_block = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
end
endtask // init_dut
task reset_dut;
begin
reset = 0;
#(4 * CLK_HALF_PERIOD);
reset = 1;
end
endtask // reset_dut
reg [511:0] block;
initial begin
$dumpfile("sha256.vcd");
$dumpvars(0, sha256_core_tb);
init_sim();
#(CLK_PERIOD);
reset_dut();
#(CLK_PERIOD);
// block = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018;
block = 512'h10a548fa958c10d2d11435456176bc6a555cb3f463a8bd23a7bb29283781f2a71123c60c6ef0923a2ec4c9f75e0e0f9042509594865b46691f962c4dd4642c28;
input_block = block;
init = 1;
#(CLK_PERIOD*500)
$finish;
end
endmodule
Hello, First off, you are not padding the message. As stated in the README:
Note that the core does **NOT** implement padding of final block. The caller is expected to handle padding."
The sha256 tool you use to verify adds a second complete padding block. See the NIST SHA256 specification on padding. In your case the padding block should be:
512'h80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200;
Secondly I can't replicate the results you get. I suggest that you look at the tb_sha256_core.v testbench. If I modify the sha256_core_test task double block test like this:
// TC2: Double block message.
tc2_1 = 512'h10a548fa958c10d2d11435456176bc6a555cb3f463a8bd23a7bb29283781f2a71123c60c6ef0923a2ec4c9f75e0e0f9042509594865b46691f962c4dd4642c28;
res2_1 = 256'h60944998deef165a47f60568c95c5f987fc63dd70361564fa7219be824484884;
tc2_2 = 512'h80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200;
res2_2 = 256'h1b20aa312f1c48723c3e0e17396b01b03926267cacd7d50221379be90ef24ced;
double_block_test(2, tc2_1, res2_1, tc2_2, res2_2);
The test goes through, i.e. it matches the expected behavior.
There probably will be a new top level module that adds padding. But it isn't done yet.
Padding is easy for a CPU to do while the final message block is being processed, but somewhat cumbersome in HW to do.
And your issue makes me realize that the README isn't very helpful unless you actually knows hos the SHA-256 hash function works. I will update the documentation.
Closing this since no response in more than six months.