Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The output sha256 hash value does not meet expectations #22

Open
TealerLinkGuo opened this issue Jul 25, 2024 · 3 comments
Open

The output sha256 hash value does not meet expectations #22

TealerLinkGuo opened this issue Jul 25, 2024 · 3 comments

Comments

@TealerLinkGuo
Copy link

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
@secworks
Copy link
Owner

secworks commented Jul 26, 2024

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.

@secworks
Copy link
Owner

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.

@secworks
Copy link
Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants