From f762c8d4e4ae3335c3340ac24ecc9c58606f7163 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Sun, 6 Jun 2021 22:04:55 -0400 Subject: The SHA-3 algorithm really wants everything to be little-endian, which is at odds with everything else in our system (including the register interface to sha3_wrapper). Rather than trying to rewrite Bernd's beautiful code, I'll isolate it in its own little-endian universe by byte-swapping all reads and writes. --- src/rtl/sha3.v | 46 +++++++++++++++++++++++++++++++--------------- src/tb/tb_sha3.v | 24 +++++++++--------------- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/rtl/sha3.v b/src/rtl/sha3.v index ee29ba6..869d142 100644 --- a/src/rtl/sha3.v +++ b/src/rtl/sha3.v @@ -44,14 +44,30 @@ `define SHA3_NUM_ROUNDS 5'd24 module sha3( input wire clk, - input wire nreset, - input wire w, - input wire [ 8:2] addr, - input wire [32-1:0] din, - output reg [32-1:0] dout, - input wire init, - input wire next, - output wire ready); + input wire nreset, + input wire w, + input wire [ 8:2] addr, + input wire [32-1:0] din, + output wire [32-1:0] dout, + input wire init, + input wire next, + output wire ready); + + + /* + * The SHA-3 algorithm really wants everything to be little-endian, + * which is at odds with everything else in our system (including the + * register interface to sha3_wrapper). Rather than trying to rewrite + * Bernd's beautiful code, I'll isolate it in its own little-endian + * universe by byte-swapping all reads and writes. + */ + + reg [31:0] dout_swap; + assign dout = {dout_swap[7:0], dout_swap[15:8], dout_swap[23:16], dout_swap[31:24]}; + + wire [31:0] din_swap; + assign din_swap = {din[7:0], din[15:8], din[23:16], din[31:24]}; + integer i, j; @@ -100,9 +116,9 @@ module sha3( input wire clk, always @* // - dout = addr[8] ? - (~addr[2] ? st [addr[7:3]][31:0] : st [addr[7:3]][63:32]) : - (~addr[2] ? blk[addr[7:3]][31:0] : blk[addr[7:3]][63:32]) ; + dout_swap = addr[8] ? + (~addr[2] ? st [addr[7:3]][31:0] : st [addr[7:3]][63:32]) : + (~addr[2] ? blk[addr[7:3]][31:0] : blk[addr[7:3]][63:32]) ; always @* begin @@ -188,12 +204,12 @@ module sha3( input wire clk, end - if (w && !addr[8]) // only the first half of memory is writeable + if (w) // case (addr[2]) - 1: blk[addr[7:3]][63:32] <= din; - 0: blk[addr[7:3]][31: 0] <= din; - endcase // case (addr[2]) + 1: blk[addr[7:3]][63:32] <= din_swap; + 0: blk[addr[7:3]][31: 0] <= din_swap; + endcase end diff --git a/src/tb/tb_sha3.v b/src/tb/tb_sha3.v index 28d06a3..5dd93c4 100644 --- a/src/tb/tb_sha3.v +++ b/src/tb/tb_sha3.v @@ -239,8 +239,8 @@ module tb_sha3(); for (i=0; i<50; i=i+1) begin case (i) - 0: tb_wr_data = 32'h00000006; // ...0001 | 10 - block_words-1: tb_wr_data = 32'h80000000; // 1000... + 0: tb_wr_data = 32'h06000000; // ...0001 | 10 + block_words-1: tb_wr_data = 32'h00000080; // 1000... default: tb_wr_data = 32'h00000000; endcase tb_addr = {1'b0, i[5:0]}; // increment address @@ -266,9 +266,7 @@ module tb_sha3(); tb_addr = {1'b1, i[5:0]}; #(CLK_PERIOD); - // swap bytes in the read value - for (j=31; j>0; j=j-8) - hash_word[j-:8] = tb_rd_data[31-j+:8]; + hash_word = tb_rd_data; $display(" *** hash_word[%0d]: reference = %08x, calculated = %08x", i, hash_shreg[511-:32], hash_word); @@ -323,8 +321,8 @@ module tb_sha3(); for (i=0; i<50; i=i+1) begin case (i) - 0: tb_wr_data = 32'h06636261; // ...0001 | 10 | 'cba' - block_words-1: tb_wr_data = 32'h80000000; // 1000... + 0: tb_wr_data = 32'h61626306; // ...0001 | 10 | 'cba' + block_words-1: tb_wr_data = 32'h00000080; // 1000... default: tb_wr_data = 32'h00000000; endcase tb_addr = {1'b0, i[5:0]}; // increment address @@ -350,9 +348,7 @@ module tb_sha3(); tb_addr = {1'b1, i[5:0]}; #(CLK_PERIOD); - // swap bytes in the read value - for (j=31; j>0; j=j-8) - hash_word[j-:8] = tb_rd_data[31-j+:8]; + hash_word = tb_rd_data; $display(" *** hash_word[%0d]: reference = %08x, calculated = %08x", i, hash_shreg[511-:32], hash_word); @@ -440,14 +436,14 @@ module tb_sha3(); total_bits = total_bits - 32; end else if (total_bits == 0) begin // padding - tb_wr_data = 32'h00000006; + tb_wr_data = 32'h06000000; tb_addr = {1'b0, i[5:0]}; tb_we = 1; #(CLK_PERIOD); total_bits = total_bits - 32; end else if (i == (block_words-1)) begin // more padding - tb_wr_data = 32'h80000000; + tb_wr_data = 32'h00000080; tb_addr = {1'b0, i[5:0]}; tb_we = 1; #(CLK_PERIOD); @@ -482,9 +478,7 @@ module tb_sha3(); tb_addr = {1'b1, i[5:0]}; #(CLK_PERIOD); - // swap bytes in the read value - for (j=31; j>0; j=j-8) - hash_word[j-:8] = tb_rd_data[31-j+:8]; + hash_word = tb_rd_data; $display(" *** hash_word[%0d]: reference = %08x, calculated = %08x", i, hash_shreg[511-:32], hash_word); -- cgit v1.2.3