aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Selkirk <paul@psgd.org>2021-05-31 17:29:10 -0400
committerPaul Selkirk <paul@psgd.org>2021-06-02 16:02:35 -0400
commit9c5acbbcd7928a2958d370923d9cc0276037f1aa (patch)
tree24d51885febdce59340717dd0f014436aa4feb8f
parent8dcb8eaddb94a46fb72dfc2b1fe84de972c9f243 (diff)
Reformatted
-rw-r--r--src/rtl/sha3.v310
-rw-r--r--src/rtl/sha3_wrapper.v40
-rw-r--r--stm32/sha3_driver_sample.c773
3 files changed, 562 insertions, 561 deletions
diff --git a/src/rtl/sha3.v b/src/rtl/sha3.v
index ab18ca0..b01d50c 100644
--- a/src/rtl/sha3.v
+++ b/src/rtl/sha3.v
@@ -41,161 +41,161 @@
`define pilni(i) ((piln>>((23-i)*5)) & 5'h1f)
`define rndci(i) ((rndc>>((23-i)*64)) & 64'hffffffffffffffff)
-`define SHA3_NUM_ROUNDS 5'd24
-
-module sha3( input wire clk,
- nreset,
- 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);
-
- integer i, j;
-
- reg [64-1:0] blk[0:24], // input block
- st [0:24], // current state
- stn[0:24], // new state
- bc [0: 4], // intermediate values
- t; // temporary variable
-
- reg [ 4:0] round; // counter value
-
-
- localparam [ 4: 0] roundlimit = `SHA3_NUM_ROUNDS - 'b1;
-
-
- localparam [24*6-1:0] rotc =
- { 6'h01, 6'h03, 6'h06, 6'h0A, 6'h0F, 6'h15,
- 6'h1C, 6'h24, 6'h2D, 6'h37, 6'h02, 6'h0E,
- 6'h1B, 6'h29, 6'h38, 6'h08, 6'h19, 6'h2B,
- 6'h3E, 6'h12, 6'h27, 6'h3D, 6'h14, 6'h2C};
-
- localparam [24*5-1:0] piln =
- { 5'h0A, 5'h07, 5'h0B, 5'h11, 5'h12, 5'h03,
- 5'h05, 5'h10, 5'h08, 5'h15, 5'h18, 5'h04,
- 5'h0F, 5'h17, 5'h13, 5'h0D, 5'h0C, 5'h02,
- 5'h14, 5'h0E, 5'h16, 5'h09, 5'h06, 5'h01};
-
- localparam [24*64-1:0] rndc =
- { 64'h0000000000000001, 64'h0000000000008082,
- 64'h800000000000808a, 64'h8000000080008000,
- 64'h000000000000808b, 64'h0000000080000001,
- 64'h8000000080008081, 64'h8000000000008009,
- 64'h000000000000008a, 64'h0000000000000088,
- 64'h0000000080008009, 64'h000000008000000a,
- 64'h000000008000808b, 64'h800000000000008b,
- 64'h8000000000008089, 64'h8000000000008003,
- 64'h8000000000008002, 64'h8000000000000080,
- 64'h000000000000800a, 64'h800000008000000a,
- 64'h8000000080008081, 64'h8000000000008080,
- 64'h0000000080000001, 64'h8000000080008008};
-
- /* input block buffer is mapped to the lower half of the
- address space, sponge state is mapped to the upper one */
-
- /* the lowest address bit determines what part of 64-bit word to return */
-
- always @(posedge clk)
- //
- 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]) ;
-
-
- always @* begin
-
- // theta1
- for (i=0; i<25; i=i+1)
- stn[i] = st[i];
-
- for (i=0; i<5; i=i+1)
- bc[i] = stn[i] ^ stn[i+5] ^ stn[i+10] ^ stn[i+15] ^ stn[i+20];
-
- // theta2
- for (i=0; i<5; i=i+1) begin
-
- t = bc[(i+4)%5] ^ `rotl64(bc[(i+1)%5], 1);
-
- for(j=i; j<25; j=j+5)
- stn[j] = t ^ stn[j];
- end
-
- // rophi
- t = stn[1];
- for(i=0; i<24; i=i+1) begin
- j = `pilni(i);
- { stn[j], t } = { `rotl64(t, `rotci(i)), stn[j] };
- end
-
- // chi
- for (j=0; j<25; j=j+5) begin
-
- for (i=0; i<5; i=i+1)
- bc[i] = stn[j + i];
-
- for (i=0; i<5; i=i+1)
- stn[j+i] = stn[j+i] ^ (~bc[(i+1)%5] & bc[(i+2)%5]);
- end
-
- // iota
- stn[0] = stn[0] ^ `rndci(round);
- end
-
-
- /* ready flag logic */
-
- reg ready_reg = 'b1;
- assign ready = ready_reg;
-
- always @(posedge clk or negedge nreset)
- //
- if (!nreset) ready_reg <= 'b1;
- else begin
- if (ready) ready_reg <= !(init || next);
- else ready_reg <= !(round < roundlimit);
- end
-
- /* state update logic */
- always @(posedge clk or negedge nreset)
- //
- if (!nreset) begin
-
- for (i=0; i<25; i=i+1) begin
- st[i] <= 64'hX; // wipe state
- blk[i] <= 64'h0; // wipe block
- end
-
- round <= `SHA3_NUM_ROUNDS;
-
- end else begin
-
- if (!ready) begin
-
- for (i=0; i<25; i=i+1)
- st[i] <= stn[i];
-
- round <= round + 'd1;
-
- end else if (init || next) begin
-
- for (i=0; i<25; i=i+1)
- st[i] <= init ? blk[i] : st[i] ^ blk[i]; // init has priority over next
-
- round <= 'd0;
-
- end
-
- if (w && !addr[8]) // only the first half of memory is writeable
- //
- case (addr[2])
- 1: blk[addr[7:3]][63:32] <= din;
- 0: blk[addr[7:3]][31: 0] <= din;
- endcase // case (addr[2])
-
- end
+`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);
+
+ integer i, j;
+
+ reg [64-1:0] blk[0:24], // input block
+ st [0:24], // current state
+ stn[0:24], // new state
+ bc [0: 4], // intermediate values
+ t; // temporary variable
+
+ reg [ 4:0] round; // counter value
+
+
+ localparam [ 4: 0] roundlimit = `SHA3_NUM_ROUNDS - 'b1;
+
+
+ localparam [24*6-1:0] rotc =
+ { 6'h01, 6'h03, 6'h06, 6'h0A, 6'h0F, 6'h15,
+ 6'h1C, 6'h24, 6'h2D, 6'h37, 6'h02, 6'h0E,
+ 6'h1B, 6'h29, 6'h38, 6'h08, 6'h19, 6'h2B,
+ 6'h3E, 6'h12, 6'h27, 6'h3D, 6'h14, 6'h2C};
+
+ localparam [24*5-1:0] piln =
+ { 5'h0A, 5'h07, 5'h0B, 5'h11, 5'h12, 5'h03,
+ 5'h05, 5'h10, 5'h08, 5'h15, 5'h18, 5'h04,
+ 5'h0F, 5'h17, 5'h13, 5'h0D, 5'h0C, 5'h02,
+ 5'h14, 5'h0E, 5'h16, 5'h09, 5'h06, 5'h01};
+
+ localparam [24*64-1:0] rndc =
+ { 64'h0000000000000001, 64'h0000000000008082,
+ 64'h800000000000808a, 64'h8000000080008000,
+ 64'h000000000000808b, 64'h0000000080000001,
+ 64'h8000000080008081, 64'h8000000000008009,
+ 64'h000000000000008a, 64'h0000000000000088,
+ 64'h0000000080008009, 64'h000000008000000a,
+ 64'h000000008000808b, 64'h800000000000008b,
+ 64'h8000000000008089, 64'h8000000000008003,
+ 64'h8000000000008002, 64'h8000000000000080,
+ 64'h000000000000800a, 64'h800000008000000a,
+ 64'h8000000080008081, 64'h8000000000008080,
+ 64'h0000000080000001, 64'h8000000080008008};
+
+ /* input block buffer is mapped to the lower half of the
+ address space, sponge state is mapped to the upper one */
+
+ /* the lowest address bit determines what part of 64-bit word to return */
+
+ always @(posedge clk)
+ //
+ 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]) ;
+
+
+ always @* begin
+
+ // theta1
+ for (i=0; i<25; i=i+1)
+ stn[i] = st[i];
+
+ for (i=0; i<5; i=i+1)
+ bc[i] = stn[i] ^ stn[i+5] ^ stn[i+10] ^ stn[i+15] ^ stn[i+20];
+
+ // theta2
+ for (i=0; i<5; i=i+1) begin
+
+ t = bc[(i+4)%5] ^ `rotl64(bc[(i+1)%5], 1);
+
+ for(j=i; j<25; j=j+5)
+ stn[j] = t ^ stn[j];
+ end
+
+ // rophi
+ t = stn[1];
+ for(i=0; i<24; i=i+1) begin
+ j = `pilni(i);
+ { stn[j], t } = { `rotl64(t, `rotci(i)), stn[j] };
+ end
+
+ // chi
+ for (j=0; j<25; j=j+5) begin
+
+ for (i=0; i<5; i=i+1)
+ bc[i] = stn[j + i];
+
+ for (i=0; i<5; i=i+1)
+ stn[j+i] = stn[j+i] ^ (~bc[(i+1)%5] & bc[(i+2)%5]);
+ end
+
+ // iota
+ stn[0] = stn[0] ^ `rndci(round);
+ end
+
+
+ /* ready flag logic */
+
+ reg ready_reg = 'b1;
+ assign ready = ready_reg;
+
+ always @(posedge clk or negedge nreset)
+ //
+ if (!nreset) ready_reg <= 'b1;
+ else begin
+ if (ready) ready_reg <= !(init || next);
+ else ready_reg <= !(round < roundlimit);
+ end
+
+ /* state update logic */
+ always @(posedge clk or negedge nreset)
+ //
+ if (!nreset) begin
+
+ for (i=0; i<25; i=i+1) begin
+ st[i] <= 64'hX; // wipe state
+ blk[i] <= 64'h0; // wipe block
+ end
+
+ round <= `SHA3_NUM_ROUNDS;
+
+ end else begin
+
+ if (!ready) begin
+
+ for (i=0; i<25; i=i+1)
+ st[i] <= stn[i];
+
+ round <= round + 'd1;
+
+ end else if (init || next) begin
+
+ for (i=0; i<25; i=i+1)
+ st[i] <= init ? blk[i] : st[i] ^ blk[i]; // init has priority over next
+
+ round <= 'd0;
+
+ end
+
+ if (w && !addr[8]) // only the first half of memory is writeable
+ //
+ case (addr[2])
+ 1: blk[addr[7:3]][63:32] <= din;
+ 0: blk[addr[7:3]][31: 0] <= din;
+ endcase // case (addr[2])
+
+ end
endmodule // sha3
diff --git a/src/rtl/sha3_wrapper.v b/src/rtl/sha3_wrapper.v
index 9140b08..c19f64f 100644
--- a/src/rtl/sha3_wrapper.v
+++ b/src/rtl/sha3_wrapper.v
@@ -48,8 +48,8 @@ module sha3_wrapper
// Address Decoder
//
localparam ADDR_MSB_REGS = 1'b0;
- localparam ADDR_MSB_CORE = 1'b1;
-
+ localparam ADDR_MSB_CORE = 1'b1;
+
wire [0:0] addr_msb = address[7];
wire [6:0] addr_lsb = address[6:0];
@@ -71,7 +71,7 @@ module sha3_wrapper
localparam ADDR_CONTROL = 5'h08; // {next, init}
localparam ADDR_STATUS = 5'h09; // {valid, ready}
- localparam CONTROL_INIT_BIT = 0;
+ localparam CONTROL_INIT_BIT = 0;
localparam CONTROL_NEXT_BIT = 1;
// localparam STATUS_READY_BIT = 0; -- hardcoded to always read 1
@@ -86,17 +86,17 @@ module sha3_wrapper
// Registers
//
reg [ 1:0] reg_control;
- reg [ 1:0] reg_control_prev;
-
-
- //
- // Flags
- //
- wire reg_control_init_posedge =
- reg_control[CONTROL_INIT_BIT] & ~reg_control_prev[CONTROL_INIT_BIT];
+ reg [ 1:0] reg_control_prev;
+
+
+ //
+ // Flags
+ //
+ wire reg_control_init_posedge =
+ reg_control[CONTROL_INIT_BIT] & ~reg_control_prev[CONTROL_INIT_BIT];
- wire reg_control_next_posedge =
- reg_control[CONTROL_NEXT_BIT] & ~reg_control_prev[CONTROL_NEXT_BIT];
+ wire reg_control_next_posedge =
+ reg_control[CONTROL_NEXT_BIT] & ~reg_control_prev[CONTROL_NEXT_BIT];
//
@@ -109,11 +109,11 @@ module sha3_wrapper
// SHA-3
//
sha3 sha3_inst
- (
+ (
.clk (clk),
- .nreset (rst_n),
+ .nreset (rst_n),
- .init (reg_control_init_posedge),
+ .init (reg_control_init_posedge),
.next (reg_control_next_posedge),
.ready (reg_status_valid),
@@ -122,7 +122,7 @@ module sha3_wrapper
.addr (addr_lsb),
.din (write_data),
.dout (read_data_core)
- );
+ );
//
@@ -136,8 +136,8 @@ module sha3_wrapper
//
always @(posedge clk)
//
- if (!rst_n) reg_control_prev <= 2'b00;
- else reg_control_prev <= reg_control;
+ if (!rst_n) reg_control_prev <= 2'b00;
+ else reg_control_prev <= reg_control;
//
@@ -188,7 +188,7 @@ module sha3_wrapper
reg addr_msb_last;
always @(posedge clk) addr_msb_last <= addr_msb;
- assign read_data = (addr_msb_last == ADDR_MSB_REGS) ? tmp_read_data : read_data_core;
+ assign read_data = (addr_msb_last == ADDR_MSB_REGS) ? tmp_read_data : read_data_core;
endmodule
diff --git a/stm32/sha3_driver_sample.c b/stm32/sha3_driver_sample.c
index 8dcc333..7344ce1 100644
--- a/stm32/sha3_driver_sample.c
+++ b/stm32/sha3_driver_sample.c
@@ -33,162 +33,162 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
- /*
- * Note, that the test program needs a custom bitstream without
- * the core selector, where the DUT is at offset 0.
- */
- // stm32 headers
+/*
+ * Note, that the test program needs a custom bitstream without
+ * the core selector, where the DUT is at offset 0.
+ */
+
+// stm32 headers
#include <string.h>
#include "stm-init.h"
#include "stm-led.h"
#include "stm-fmc.h"
- // locations of core registers
-#define CORE_ADDR_NAME0 (0x00 << 2)
-#define CORE_ADDR_NAME1 (0x01 << 2)
-#define CORE_ADDR_VERSION (0x02 << 2)
-#define CORE_ADDR_CONTROL (0x08 << 2)
-#define CORE_ADDR_STATUS (0x09 << 2)
-
- // control and status register bit maps
-#define CORE_CONTROL_BIT_INIT 0x00000001
-#define CORE_CONTROL_BIT_NEXT 0x00000002
-
-#define CORE_STATUS_BIT_READY 0x00000001
-#define CORE_STATUS_BIT_VALID 0x00000002
-
- // locations of banks (operand buffers)
-#define CORE_ADDR_BANK_BLOCK 0x200
-#define CORE_ADDR_BANK_STATE 0x300
-
- // sha-3 parameters
-#define SHA3_STATE_BITS 1600
-#define SHA3_STATE_BYTES (SHA3_STATE_BITS / 8)
-
-#define SHA3_PADDING_SUFFIX 0x06
-#define SHA3_PADDING_FINAL 0x80
-
-#define SHA3_224_BLOCK_BITS 1152
-#define SHA3_256_BLOCK_BITS 1088
-#define SHA3_384_BLOCK_BITS 832
-#define SHA3_512_BLOCK_BITS 576
-
-#define SHA3_224_OUTPUT_BITS 224
-#define SHA3_256_OUTPUT_BITS 256
-#define SHA3_384_OUTPUT_BITS 384
-#define SHA3_512_OUTPUT_BITS 512
-
- /*
- * test vectors - hashes of empty message
- *
- * https://en.wikipedia.org/wiki/SHA-3#Examples_of_SHA-3_variants
- *
- */
-#define SHA3_224_HASH_EMPTY_MSG \
- {0x6b, 0x4e, 0x03, 0x42, 0x36, 0x67, 0xdb, 0xb7, \
- 0x3b, 0x6e, 0x15, 0x45, 0x4f, 0x0e, 0xb1, 0xab, \
- 0xd4, 0x59, 0x7f, 0x9a, 0x1b, 0x07, 0x8e, 0x3f, \
- 0x5b, 0x5a, 0x6b, 0xc7}
-
-#define SHA3_256_HASH_EMPTY_MSG \
- {0xa7, 0xff, 0xc6, 0xf8, 0xbf, 0x1e, 0xd7, 0x66, \
- 0x51, 0xc1, 0x47, 0x56, 0xa0, 0x61, 0xd6, 0x62, \
- 0xf5, 0x80, 0xff,0x4d, 0xe4, 0x3b, 0x49, 0xfa, \
- 0x82, 0xd8, 0x0a, 0x4b, 0x80, 0xf8, 0x43, 0x4a}
-
-#define SHA3_384_HASH_EMPTY_MSG \
- {0x0c, 0x63, 0xa7, 0x5b, 0x84, 0x5e, 0x4f, 0x7d, \
- 0x01, 0x10, 0x7d, 0x85, 0x2e, 0x4c, 0x24, 0x85, \
- 0xc5, 0x1a, 0x50, 0xaa, 0xaa, 0x94, 0xfc, 0x61, \
- 0x99, 0x5e, 0x71, 0xbb, 0xee, 0x98, 0x3a, 0x2a, \
- 0xc3, 0x71, 0x38, 0x31, 0x26, 0x4a, 0xdb, 0x47, \
- 0xfb, 0x6b, 0xd1, 0xe0, 0x58, 0xd5, 0xf0, 0x04}
-
-#define SHA3_512_HASH_EMPTY_MSG \
- {0xa6, 0x9f, 0x73, 0xcc, 0xa2, 0x3a, 0x9a, 0xc5, \
- 0xc8, 0xb5, 0x67, 0xdc, 0x18, 0x5a, 0x75, 0x6e, \
- 0x97, 0xc9, 0x82, 0x16, 0x4f, 0xe2, 0x58, 0x59, \
- 0xe0, 0xd1, 0xdc, 0xc1, 0x47, 0x5c, 0x80, 0xa6, \
- 0x15, 0xb2, 0x12, 0x3a, 0xf1, 0xf5, 0xf9, 0x4c, \
- 0x11, 0xe3, 0xe9, 0x40, 0x2c, 0x3a, 0xc5, 0x58, \
- 0xf5, 0x00, 0x19, 0x9d, 0x95, 0xb6, 0xd3, 0xe3, \
- 0x01, 0x75, 0x85, 0x86, 0x28, 0x1d, 0xcd, 0x26}
-
- /*
- * test vectors - hashes of short message "abc"
- *
- * https://www.di-mgt.com.au/sha_testvectors.html
- *
- */
-#define SHA3_224_HASH_SHORT_MSG \
- {0xe6, 0x42, 0x82, 0x4c, 0x3f, 0x8c, 0xf2, 0x4a, \
- 0xd0, 0x92, 0x34, 0xee, 0x7d, 0x3c, 0x76, 0x6f, \
- 0xc9, 0xa3, 0xa5, 0x16, 0x8d, 0x0c, 0x94, 0xad, \
- 0x73, 0xb4, 0x6f, 0xdf}
-
-#define SHA3_256_HASH_SHORT_MSG \
- {0x3a, 0x98, 0x5d, 0xa7, 0x4f, 0xe2, 0x25, 0xb2, \
- 0x04, 0x5c, 0x17, 0x2d, 0x6b, 0xd3, 0x90, 0xbd, \
- 0x85, 0x5f, 0x08, 0x6e, 0x3e, 0x9d, 0x52, 0x5b, \
- 0x46, 0xbf, 0xe2, 0x45, 0x11, 0x43, 0x15, 0x32}
-
-#define SHA3_384_HASH_SHORT_MSG \
- {0xec, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6f, 0xc9, \
- 0x26, 0x45, 0x9f, 0x58, 0xe2, 0xc6, 0xad, 0x8d, \
- 0xf9, 0xb4, 0x73, 0xcb, 0x0f, 0xc0, 0x8c, 0x25, \
- 0x96, 0xda, 0x7c, 0xf0, 0xe4, 0x9b, 0xe4, 0xb2, \
- 0x98, 0xd8, 0x8c, 0xea, 0x92, 0x7a, 0xc7, 0xf5, \
- 0x39, 0xf1, 0xed, 0xf2, 0x28, 0x37, 0x6d, 0x25}
-
-#define SHA3_512_HASH_SHORT_MSG \
- {0xb7, 0x51, 0x85, 0x0b, 0x1a, 0x57, 0x16, 0x8a, \
- 0x56, 0x93, 0xcd, 0x92, 0x4b, 0x6b, 0x09, 0x6e, \
- 0x08, 0xf6, 0x21, 0x82, 0x74, 0x44, 0xf7, 0x0d, \
- 0x88, 0x4f, 0x5d, 0x02, 0x40, 0xd2, 0x71, 0x2e, \
- 0x10, 0xe1, 0x16, 0xe9, 0x19, 0x2a, 0xf3, 0xc9, \
- 0x1a, 0x7e, 0xc5, 0x76, 0x47, 0xe3, 0x93, 0x40, \
- 0x57, 0x34, 0x0b, 0x4c, 0xf4, 0x08, 0xd5, 0xa5, \
- 0x65, 0x92, 0xf8, 0x27, 0x4e, 0xec, 0x53, 0xf0}
-
- /*
- * test vectors - hashes of long message (see below)
- *
- * https://csrc.nist.gov/Projects/Cryptographic-Standards-and-Guidelines/example-values
- *
- */
-
-#define SHA3_224_HASH_LONG_MSG \
- {0x93, 0x76, 0x81, 0x6A, 0xBA, 0x50, 0x3F, 0x72, \
- 0xF9, 0x6C, 0xE7, 0xEB, 0x65, 0xAC, 0x09, 0x5D, \
- 0xEE, 0xE3, 0xBE, 0x4B, 0xF9, 0xBB, 0xC2, 0xA1, \
- 0xCB, 0x7E, 0x11, 0xE0}
-
-#define SHA3_256_HASH_LONG_MSG \
- {0x79, 0xF3, 0x8A, 0xDE, 0xC5, 0xC2, 0x03, 0x07, \
- 0xA9, 0x8E, 0xF7, 0x6E, 0x83, 0x24, 0xAF, 0xBF, \
- 0xD4, 0x6C, 0xFD, 0x81, 0xB2, 0x2E, 0x39, 0x73, \
- 0xC6, 0x5F, 0xA1, 0xBD, 0x9D, 0xE3, 0x17, 0x87}
-
-#define SHA3_384_HASH_LONG_MSG \
- {0x18, 0x81, 0xDE, 0x2C, 0xA7, 0xE4, 0x1E, 0xF9, \
- 0x5D, 0xC4, 0x73, 0x2B, 0x8F, 0x5F, 0x00, 0x2B, \
- 0x18, 0x9C, 0xC1, 0xE4, 0x2B, 0x74, 0x16, 0x8E, \
- 0xD1, 0x73, 0x26, 0x49, 0xCE, 0x1D, 0xBC, 0xDD, \
- 0x76, 0x19, 0x7A, 0x31, 0xFD, 0x55, 0xEE, 0x98, \
- 0x9F, 0x2D, 0x70, 0x50, 0xDD, 0x47, 0x3E, 0x8F}
-
-#define SHA3_512_HASH_LONG_MSG \
- {0xE7, 0x6D, 0xFA, 0xD2, 0x20, 0x84, 0xA8, 0xB1, \
- 0x46, 0x7F, 0xCF, 0x2F, 0xFA, 0x58, 0x36, 0x1B, \
- 0xEC, 0x76, 0x28, 0xED, 0xF5, 0xF3, 0xFD, 0xC0, \
- 0xE4, 0x80, 0x5D, 0xC4, 0x8C, 0xAE, 0xEC, 0xA8, \
- 0x1B, 0x7C, 0x13, 0xC3, 0x0A, 0xDF, 0x52, 0xA3, \
- 0x65, 0x95, 0x84, 0x73, 0x9A, 0x2D, 0xF4, 0x6B, \
- 0xE5, 0x89, 0xC5, 0x1C, 0xA1, 0xA4, 0xA8, 0x41, \
- 0x6D, 0xF6, 0x54, 0x5A, 0x1C, 0xE8, 0xBA, 0x00}
-
+// locations of core registers
+#define CORE_ADDR_NAME0 (0x00 << 2)
+#define CORE_ADDR_NAME1 (0x01 << 2)
+#define CORE_ADDR_VERSION (0x02 << 2)
+#define CORE_ADDR_CONTROL (0x08 << 2)
+#define CORE_ADDR_STATUS (0x09 << 2)
+
+// control and status register bit maps
+#define CORE_CONTROL_BIT_INIT 0x00000001
+#define CORE_CONTROL_BIT_NEXT 0x00000002
+
+#define CORE_STATUS_BIT_READY 0x00000001
+#define CORE_STATUS_BIT_VALID 0x00000002
+
+// locations of banks (operand buffers)
+#define CORE_ADDR_BANK_BLOCK 0x200
+#define CORE_ADDR_BANK_STATE 0x300
+
+// sha-3 parameters
+#define SHA3_STATE_BITS 1600
+#define SHA3_STATE_BYTES (SHA3_STATE_BITS / 8)
+
+#define SHA3_PADDING_SUFFIX 0x06
+#define SHA3_PADDING_FINAL 0x80
+
+#define SHA3_224_BLOCK_BITS 1152
+#define SHA3_256_BLOCK_BITS 1088
+#define SHA3_384_BLOCK_BITS 832
+#define SHA3_512_BLOCK_BITS 576
+
+#define SHA3_224_OUTPUT_BITS 224
+#define SHA3_256_OUTPUT_BITS 256
+#define SHA3_384_OUTPUT_BITS 384
+#define SHA3_512_OUTPUT_BITS 512
+
+/*
+ * test vectors - hashes of empty message
+ *
+ * https://en.wikipedia.org/wiki/SHA-3#Examples_of_SHA-3_variants
+ *
+ */
+#define SHA3_224_HASH_EMPTY_MSG \
+ {0x6b, 0x4e, 0x03, 0x42, 0x36, 0x67, 0xdb, 0xb7, \
+ 0x3b, 0x6e, 0x15, 0x45, 0x4f, 0x0e, 0xb1, 0xab, \
+ 0xd4, 0x59, 0x7f, 0x9a, 0x1b, 0x07, 0x8e, 0x3f, \
+ 0x5b, 0x5a, 0x6b, 0xc7}
+
+#define SHA3_256_HASH_EMPTY_MSG \
+ {0xa7, 0xff, 0xc6, 0xf8, 0xbf, 0x1e, 0xd7, 0x66, \
+ 0x51, 0xc1, 0x47, 0x56, 0xa0, 0x61, 0xd6, 0x62, \
+ 0xf5, 0x80,0xff, 0x4d, 0xe4, 0x3b, 0x49, 0xfa, \
+ 0x82, 0xd8, 0x0a, 0x4b, 0x80, 0xf8, 0x43, 0x4a}
+
+#define SHA3_384_HASH_EMPTY_MSG \
+ {0x0c, 0x63, 0xa7, 0x5b, 0x84, 0x5e, 0x4f, 0x7d, \
+ 0x01, 0x10, 0x7d, 0x85, 0x2e, 0x4c, 0x24, 0x85, \
+ 0xc5, 0x1a, 0x50, 0xaa, 0xaa, 0x94, 0xfc, 0x61, \
+ 0x99, 0x5e, 0x71, 0xbb, 0xee, 0x98, 0x3a, 0x2a, \
+ 0xc3, 0x71, 0x38, 0x31, 0x26, 0x4a, 0xdb, 0x47, \
+ 0xfb, 0x6b, 0xd1, 0xe0, 0x58, 0xd5, 0xf0, 0x04}
+
+#define SHA3_512_HASH_EMPTY_MSG \
+ {0xa6, 0x9f, 0x73, 0xcc, 0xa2, 0x3a, 0x9a, 0xc5, \
+ 0xc8, 0xb5, 0x67, 0xdc, 0x18, 0x5a, 0x75, 0x6e, \
+ 0x97, 0xc9, 0x82, 0x16, 0x4f, 0xe2, 0x58, 0x59, \
+ 0xe0, 0xd1, 0xdc, 0xc1, 0x47, 0x5c, 0x80, 0xa6, \
+ 0x15, 0xb2, 0x12, 0x3a, 0xf1, 0xf5, 0xf9, 0x4c, \
+ 0x11, 0xe3, 0xe9, 0x40, 0x2c, 0x3a, 0xc5, 0x58, \
+ 0xf5, 0x00, 0x19, 0x9d, 0x95, 0xb6, 0xd3, 0xe3, \
+ 0x01, 0x75, 0x85, 0x86, 0x28, 0x1d, 0xcd, 0x26}
+
+/*
+ * test vectors - hashes of short message "abc"
+ *
+ * https://www.di-mgt.com.au/sha_testvectors.html
+ *
+ */
+#define SHA3_224_HASH_SHORT_MSG \
+ {0xe6, 0x42, 0x82, 0x4c, 0x3f, 0x8c, 0xf2, 0x4a, \
+ 0xd0, 0x92, 0x34, 0xee, 0x7d, 0x3c, 0x76, 0x6f, \
+ 0xc9, 0xa3, 0xa5, 0x16, 0x8d, 0x0c, 0x94, 0xad, \
+ 0x73, 0xb4, 0x6f, 0xdf}
+
+#define SHA3_256_HASH_SHORT_MSG \
+ {0x3a, 0x98, 0x5d, 0xa7, 0x4f, 0xe2, 0x25, 0xb2, \
+ 0x04, 0x5c, 0x17, 0x2d, 0x6b, 0xd3, 0x90, 0xbd, \
+ 0x85, 0x5f, 0x08, 0x6e, 0x3e, 0x9d, 0x52, 0x5b, \
+ 0x46, 0xbf, 0xe2, 0x45, 0x11, 0x43, 0x15, 0x32}
+
+#define SHA3_384_HASH_SHORT_MSG \
+ {0xec, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6f, 0xc9, \
+ 0x26, 0x45, 0x9f, 0x58, 0xe2, 0xc6, 0xad, 0x8d, \
+ 0xf9, 0xb4, 0x73, 0xcb, 0x0f, 0xc0, 0x8c, 0x25, \
+ 0x96, 0xda, 0x7c, 0xf0, 0xe4, 0x9b, 0xe4, 0xb2, \
+ 0x98, 0xd8, 0x8c, 0xea, 0x92, 0x7a, 0xc7, 0xf5, \
+ 0x39, 0xf1, 0xed, 0xf2, 0x28, 0x37, 0x6d, 0x25}
+
+#define SHA3_512_HASH_SHORT_MSG \
+ {0xb7, 0x51, 0x85, 0x0b, 0x1a, 0x57, 0x16, 0x8a, \
+ 0x56, 0x93, 0xcd, 0x92, 0x4b, 0x6b, 0x09, 0x6e, \
+ 0x08, 0xf6, 0x21, 0x82, 0x74, 0x44, 0xf7, 0x0d, \
+ 0x88, 0x4f, 0x5d, 0x02, 0x40, 0xd2, 0x71, 0x2e, \
+ 0x10, 0xe1, 0x16, 0xe9, 0x19, 0x2a, 0xf3, 0xc9, \
+ 0x1a, 0x7e, 0xc5, 0x76, 0x47, 0xe3, 0x93, 0x40, \
+ 0x57, 0x34, 0x0b, 0x4c, 0xf4, 0x08, 0xd5, 0xa5, \
+ 0x65, 0x92, 0xf8, 0x27, 0x4e, 0xec, 0x53, 0xf0}
+
+/*
+ * test vectors - hashes of long message (see below)
+ *
+ * https://csrc.nist.gov/Projects/Cryptographic-Standards-and-Guidelines/example-values
+ *
+ */
+
+#define SHA3_224_HASH_LONG_MSG \
+ {0x93, 0x76, 0x81, 0x6A, 0xBA, 0x50, 0x3F, 0x72, \
+ 0xF9, 0x6C, 0xE7, 0xEB, 0x65, 0xAC, 0x09, 0x5D, \
+ 0xEE, 0xE3, 0xBE, 0x4B, 0xF9, 0xBB, 0xC2, 0xA1, \
+ 0xCB, 0x7E, 0x11, 0xE0}
+
+#define SHA3_256_HASH_LONG_MSG \
+ {0x79, 0xF3, 0x8A, 0xDE, 0xC5, 0xC2, 0x03, 0x07, \
+ 0xA9, 0x8E, 0xF7, 0x6E, 0x83, 0x24, 0xAF, 0xBF, \
+ 0xD4, 0x6C, 0xFD, 0x81, 0xB2, 0x2E, 0x39, 0x73, \
+ 0xC6, 0x5F, 0xA1, 0xBD, 0x9D, 0xE3, 0x17, 0x87}
+
+#define SHA3_384_HASH_LONG_MSG \
+ {0x18, 0x81, 0xDE, 0x2C, 0xA7, 0xE4, 0x1E, 0xF9, \
+ 0x5D, 0xC4, 0x73, 0x2B, 0x8F, 0x5F, 0x00, 0x2B, \
+ 0x18, 0x9C, 0xC1, 0xE4, 0x2B, 0x74, 0x16, 0x8E, \
+ 0xD1, 0x73, 0x26, 0x49, 0xCE, 0x1D, 0xBC, 0xDD, \
+ 0x76, 0x19, 0x7A, 0x31, 0xFD, 0x55, 0xEE, 0x98, \
+ 0x9F, 0x2D, 0x70, 0x50, 0xDD, 0x47, 0x3E, 0x8F}
+
+#define SHA3_512_HASH_LONG_MSG \
+ {0xE7, 0x6D, 0xFA, 0xD2, 0x20, 0x84, 0xA8, 0xB1, \
+ 0x46, 0x7F, 0xCF, 0x2F, 0xFA, 0x58, 0x36, 0x1B, \
+ 0xEC, 0x76, 0x28, 0xED, 0xF5, 0xF3, 0xFD, 0xC0, \
+ 0xE4, 0x80, 0x5D, 0xC4, 0x8C, 0xAE, 0xEC, 0xA8, \
+ 0x1B, 0x7C, 0x13, 0xC3, 0x0A, 0xDF, 0x52, 0xA3, \
+ 0x65, 0x95, 0x84, 0x73, 0x9A, 0x2D, 0xF4, 0x6B, \
+ 0xE5, 0x89, 0xC5, 0x1C, 0xA1, 0xA4, 0xA8, 0x41, \
+ 0x6D, 0xF6, 0x54, 0x5A, 0x1C, 0xE8, 0xBA, 0x00}
+
static const uint8_t hash_224_empty_msg[SHA3_224_OUTPUT_BITS / 8] = SHA3_224_HASH_EMPTY_MSG;
static const uint8_t hash_256_empty_msg[SHA3_256_OUTPUT_BITS / 8] = SHA3_256_HASH_EMPTY_MSG;
static const uint8_t hash_384_empty_msg[SHA3_384_OUTPUT_BITS / 8] = SHA3_384_HASH_EMPTY_MSG;
@@ -203,271 +203,272 @@ static const uint8_t hash_224_long_msg[SHA3_224_OUTPUT_BITS / 8] = SHA3_224_HASH
static const uint8_t hash_256_long_msg[SHA3_256_OUTPUT_BITS / 8] = SHA3_256_HASH_LONG_MSG;
static const uint8_t hash_384_long_msg[SHA3_384_OUTPUT_BITS / 8] = SHA3_384_HASH_LONG_MSG;
static const uint8_t hash_512_long_msg[SHA3_512_OUTPUT_BITS / 8] = SHA3_512_HASH_LONG_MSG;
-
- /* short message, will always fit in single block */
+
+/* short message, will always fit in single block */
static const char msg_short[] = "abc";
-
- /* long message, guaranteed to _not_ fit in one block */
+
+/* long message, guaranteed to _not_ fit in one block */
static const char msg_long[] =
- "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
- "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
- "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
- "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
- "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
- "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
- "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
- "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
- "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
- "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3";
-
-
- /*
- * prototypes
- */
+ "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
+ "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
+ "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
+ "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
+ "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
+ "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
+ "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
+ "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
+ "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3"
+ "\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3\xA3";
+
+
+/*
+ * prototypes
+ */
void toggle_yellow_led(void);
-int test_sha3( const uint8_t *msg,
- uint32_t num_msg_bytes,
- uint32_t num_block_bits,
- const uint8_t *hash,
- uint32_t num_hash_bits);
+int test_sha3(const uint8_t *msg,
+ uint32_t num_msg_bytes,
+ uint32_t num_block_bits,
+ const uint8_t *hash,
+ uint32_t num_hash_bits);
-void sha3_absorb( uint32_t *state,
- uint32_t num_block_bytes,
- uint32_t block_number);
+void sha3_absorb(uint32_t *state,
+ uint32_t num_block_bytes,
+ uint32_t block_number);
-
- /*
- * test routine
- */
+
+/*
+ * test routine
+ */
int main()
{
- int ok;
-
+ int ok;
+
stm_init();
fmc_init();
-
- // turn on the green led
+
+ // turn on the green led
led_on(LED_GREEN);
led_off(LED_RED);
led_off(LED_YELLOW);
led_off(LED_BLUE);
- // check, that core is present
- uint32_t core_name0;
- uint32_t core_name1;
- uint32_t core_version;
-
- fmc_read_32(CORE_ADDR_NAME0, &core_name0);
- fmc_read_32(CORE_ADDR_NAME1, &core_name1);
- fmc_read_32(CORE_ADDR_VERSION, &core_version);
-
- // must be "sha3", " " [four spaces], "0.10"
- if ( (core_name0 != 0x73686133) ||
- (core_name1 != 0x20202020) ||
- (core_version != 0x302E3130))
- {
- led_off(LED_GREEN);
- led_on(LED_RED);
- while (1);
- }
-
- // repeat forever
- while (1)
- {
- // fresh start
- ok = 1;
-
- // test with empty message
- ok = ok && test_sha3(NULL, 0, SHA3_224_BLOCK_BITS, hash_224_empty_msg, SHA3_224_OUTPUT_BITS);
- ok = ok && test_sha3(NULL, 0, SHA3_256_BLOCK_BITS, hash_256_empty_msg, SHA3_256_OUTPUT_BITS);
- ok = ok && test_sha3(NULL, 0, SHA3_384_BLOCK_BITS, hash_384_empty_msg, SHA3_384_OUTPUT_BITS);
- ok = ok && test_sha3(NULL, 0, SHA3_512_BLOCK_BITS, hash_512_empty_msg, SHA3_512_OUTPUT_BITS);
-
- // test with the short message ("abc")
- ok = ok && test_sha3((uint8_t *)msg_short, strlen(msg_short), SHA3_224_BLOCK_BITS, hash_224_short_msg, SHA3_224_OUTPUT_BITS);
- ok = ok && test_sha3((uint8_t *)msg_short, strlen(msg_short), SHA3_256_BLOCK_BITS, hash_256_short_msg, SHA3_256_OUTPUT_BITS);
- ok = ok && test_sha3((uint8_t *)msg_short, strlen(msg_short), SHA3_384_BLOCK_BITS, hash_384_short_msg, SHA3_384_OUTPUT_BITS);
- ok = ok && test_sha3((uint8_t *)msg_short, strlen(msg_short), SHA3_512_BLOCK_BITS, hash_512_short_msg, SHA3_512_OUTPUT_BITS);
-
- // test with the long message
- ok = ok && test_sha3((uint8_t *)msg_long, strlen(msg_long), SHA3_224_BLOCK_BITS, hash_224_long_msg, SHA3_224_OUTPUT_BITS);
- ok = ok && test_sha3((uint8_t *)msg_long, strlen(msg_long), SHA3_256_BLOCK_BITS, hash_256_long_msg, SHA3_256_OUTPUT_BITS);
- ok = ok && test_sha3((uint8_t *)msg_long, strlen(msg_long), SHA3_384_BLOCK_BITS, hash_384_long_msg, SHA3_384_OUTPUT_BITS);
- ok = ok && test_sha3((uint8_t *)msg_long, strlen(msg_long), SHA3_512_BLOCK_BITS, hash_512_long_msg, SHA3_512_OUTPUT_BITS);
-
- // turn on the red led to indicate something went wrong
- if (!ok)
- { led_off(LED_GREEN);
- led_on(LED_RED);
- }
-
- // indicate, that we're alive doing something...
- toggle_yellow_led();
- }
+ // check, that core is present
+ uint32_t core_name0;
+ uint32_t core_name1;
+ uint32_t core_version;
+
+ fmc_read_32(CORE_ADDR_NAME0, &core_name0);
+ fmc_read_32(CORE_ADDR_NAME1, &core_name1);
+ fmc_read_32(CORE_ADDR_VERSION, &core_version);
+
+ // must be "sha3", " " [four spaces], "0.10"
+ if ((core_name0 != 0x73686133) ||
+ (core_name1 != 0x20202020) ||
+ (core_version != 0x302E3130))
+ {
+ led_off(LED_GREEN);
+ led_on(LED_RED);
+ while (1);
+ }
+
+ // repeat forever
+ while (1)
+ {
+ // fresh start
+ ok = 1;
+
+ // test with empty message
+ ok = ok && test_sha3(NULL, 0, SHA3_224_BLOCK_BITS, hash_224_empty_msg, SHA3_224_OUTPUT_BITS);
+ ok = ok && test_sha3(NULL, 0, SHA3_256_BLOCK_BITS, hash_256_empty_msg, SHA3_256_OUTPUT_BITS);
+ ok = ok && test_sha3(NULL, 0, SHA3_384_BLOCK_BITS, hash_384_empty_msg, SHA3_384_OUTPUT_BITS);
+ ok = ok && test_sha3(NULL, 0, SHA3_512_BLOCK_BITS, hash_512_empty_msg, SHA3_512_OUTPUT_BITS);
+
+ // test with the short message ("abc")
+ ok = ok && test_sha3((uint8_t *)msg_short, strlen(msg_short), SHA3_224_BLOCK_BITS, hash_224_short_msg, SHA3_224_OUTPUT_BITS);
+ ok = ok && test_sha3((uint8_t *)msg_short, strlen(msg_short), SHA3_256_BLOCK_BITS, hash_256_short_msg, SHA3_256_OUTPUT_BITS);
+ ok = ok && test_sha3((uint8_t *)msg_short, strlen(msg_short), SHA3_384_BLOCK_BITS, hash_384_short_msg, SHA3_384_OUTPUT_BITS);
+ ok = ok && test_sha3((uint8_t *)msg_short, strlen(msg_short), SHA3_512_BLOCK_BITS, hash_512_short_msg, SHA3_512_OUTPUT_BITS);
+
+ // test with the long message
+ ok = ok && test_sha3((uint8_t *)msg_long, strlen(msg_long), SHA3_224_BLOCK_BITS, hash_224_long_msg, SHA3_224_OUTPUT_BITS);
+ ok = ok && test_sha3((uint8_t *)msg_long, strlen(msg_long), SHA3_256_BLOCK_BITS, hash_256_long_msg, SHA3_256_OUTPUT_BITS);
+ ok = ok && test_sha3((uint8_t *)msg_long, strlen(msg_long), SHA3_384_BLOCK_BITS, hash_384_long_msg, SHA3_384_OUTPUT_BITS);
+ ok = ok && test_sha3((uint8_t *)msg_long, strlen(msg_long), SHA3_512_BLOCK_BITS, hash_512_long_msg, SHA3_512_OUTPUT_BITS);
+
+ // turn on the red led to indicate something went wrong
+ if (!ok)
+ {
+ led_off(LED_GREEN);
+ led_on(LED_RED);
+ }
+
+ // indicate, that we're alive doing something...
+ toggle_yellow_led();
+ }
}
-int test_sha3( const uint8_t *msg,
- uint32_t num_msg_bytes,
- uint32_t num_block_bits,
- const uint8_t *hash,
- uint32_t num_hash_bits)
+int test_sha3(const uint8_t *msg,
+ uint32_t num_msg_bytes,
+ uint32_t num_block_bits,
+ const uint8_t *hash,
+ uint32_t num_hash_bits)
{
- /* calculate digest of 'msg' and compare it against known reference 'hash' */
-
- // counter
- uint32_t i;
-
- // buffer for input block, consists of 32-bit words to ease copying over FMC
- uint32_t block32[SHA3_STATE_BYTES / 4];
-
- // byte pointer, handy for storing one byte at a time
- uint8_t *block = (uint8_t *)&block32;
-
- // handy values
- uint32_t num_block_bytes = num_block_bits >> 3; // /8
- uint32_t num_hash_bytes = num_hash_bits >> 3; // /8
-
- // counters
- uint32_t block_number = 0; // number of blocks absorbed (we need this, because for the
- // very first block we toggle the 'init' control bit, for all the
- // subsequent blocks we toggle the 'next' bit)
-
- uint32_t block_offset = 0; // current byte position in the input block (we need this to
- // apply padding properly)
-
- // first wipe entire input block...
- for (i=0; i<(SHA3_STATE_BYTES / sizeof(uint32_t)); i++)
- block32[i] = 0;
-
- // ...then absorb all the bytes...
- while (num_msg_bytes)
- {
- // store the next byte
- block[block_offset] = msg[0];
-
- msg++; // advance pointer
- block_offset++; // increment block offset
- num_msg_bytes--; // reduce remaining byte count
-
- // check, whether we've already filled entire block
- if (block_offset == num_block_bytes)
- {
- // absorb part of message accumulated in block
- sha3_absorb(block32, num_block_bytes, block_number);
-
- block_number++; // increment processed block count
- block_offset = 0; // start filling a new block
- }
-
- }
-
- // ...and finally apply padding
-
- // Now do the required padding, block_offset points to the very first empty byte in block
- // (there should be at least 1 empty byte now, because we would have processed completely
- // filled block earlier while absorbing bytes).
-
- /* Padding involves three steps:
- *
- * 1. Add "011" bit string (0x06) to the message ("01" is SHA-3 domain suffix, "1" is actual padding)
- * 2. Add zero or more "0" bits until the message is exactly 1 bit short of full block
- * 3. Add final "1" bit (0x80) to make the message length a multiple of block size
- *
- */
-
- // add "011" part
- block[block_offset] = SHA3_PADDING_SUFFIX;
-
- // wipe all the remaining bytes in block (if there are any)
- while (block_offset < (num_block_bytes - 1))
- {
- block_offset++;
- block[block_offset] = 0x00;
- }
-
-
- // add the final "1" part. note, that we must use |=, not just =,
- // because we could have added no extra null bytes and state[block_offset]
- // might already contain the suffix, we should not overwrite it.
- block[block_offset] |= SHA3_PADDING_FINAL;
-
- // absorb the last block with padding
- sha3_absorb(block32, num_block_bytes, block_number);
-
- // read state from core...
- for (i=0; i<(num_hash_bytes / sizeof(uint32_t)); i++)
- fmc_read_32(CORE_ADDR_BANK_STATE + i * sizeof(uint32_t), block32 + i);
-
- // ...and now compare state to known good hash
- for (i=0; i<num_hash_bytes; i++)
- if (block[i] != hash[i]) return 0;
-
- // everything went just fine
- return 1;
+ /* calculate digest of 'msg' and compare it against known reference 'hash' */
+
+ // counter
+ uint32_t i;
+
+ // buffer for input block, consists of 32-bit words to ease copying over FMC
+ uint32_t block32[SHA3_STATE_BYTES / 4];
+
+ // byte pointer, handy for storing one byte at a time
+ uint8_t *block = (uint8_t *)&block32;
+
+ // handy values
+ uint32_t num_block_bytes = num_block_bits >> 3; // /8
+ uint32_t num_hash_bytes = num_hash_bits >> 3; // /8
+
+ // counters
+ uint32_t block_number = 0; // number of blocks absorbed (we need this, because for the
+ // very first block we toggle the 'init' control bit, for all the
+ // subsequent blocks we toggle the 'next' bit)
+
+ uint32_t block_offset = 0; // current byte position in the input block (we need this to
+ // apply padding properly)
+
+ // first wipe entire input block...
+ for (i=0; i<(SHA3_STATE_BYTES / sizeof(uint32_t)); i++)
+ block32[i] = 0;
+
+ // ...then absorb all the bytes...
+ while (num_msg_bytes)
+ {
+ // store the next byte
+ block[block_offset] = msg[0];
+
+ msg++; // advance pointer
+ block_offset++; // increment block offset
+ num_msg_bytes--; // reduce remaining byte count
+
+ // check, whether we've already filled entire block
+ if (block_offset == num_block_bytes)
+ {
+ // absorb part of message accumulated in block
+ sha3_absorb(block32, num_block_bytes, block_number);
+
+ block_number++; // increment processed block count
+ block_offset = 0; // start filling a new block
+ }
+
+ }
+
+ // ...and finally apply padding
+
+ // Now do the required padding, block_offset points to the very first empty byte in block
+ // (there should be at least 1 empty byte now, because we would have processed completely
+ // filled block earlier while absorbing bytes).
+
+ /* Padding involves three steps:
+ *
+ * 1. Add "011" bit string (0x06) to the message ("01" is SHA-3 domain suffix, "1" is actual padding)
+ * 2. Add zero or more "0" bits until the message is exactly 1 bit short of full block
+ * 3. Add final "1" bit (0x80) to make the message length a multiple of block size
+ *
+ */
+
+ // add "011" part
+ block[block_offset] = SHA3_PADDING_SUFFIX;
+
+ // wipe all the remaining bytes in block (if there are any)
+ while (block_offset < (num_block_bytes - 1))
+ {
+ block_offset++;
+ block[block_offset] = 0x00;
+ }
+
+
+ // add the final "1" part. note, that we must use |=, not just =,
+ // because we could have added no extra null bytes and state[block_offset]
+ // might already contain the suffix, we should not overwrite it.
+ block[block_offset] |= SHA3_PADDING_FINAL;
+
+ // absorb the last block with padding
+ sha3_absorb(block32, num_block_bytes, block_number);
+
+ // read state from core...
+ for (i=0; i<(num_hash_bytes / sizeof(uint32_t)); i++)
+ fmc_read_32(CORE_ADDR_BANK_STATE + i * sizeof(uint32_t), block32 + i);
+
+ // ...and now compare state to known good hash
+ for (i=0; i<num_hash_bytes; i++)
+ if (block[i] != hash[i]) return 0;
+
+ // everything went just fine
+ return 1;
}
- //
- // absorb one block of data into the sponge
- //
+//
+// absorb one block of data into the sponge
+//
void sha3_absorb(uint32_t *block, uint32_t num_block_bytes, uint32_t block_number)
{
- uint32_t i; // word counter
- uint32_t ctrl, sts; // control register, status register
-
- // copy 32-bit words from state into core's input block buffer
- for (i=0; i<(num_block_bytes / sizeof(uint32_t)); i++)
- fmc_write_32(CORE_ADDR_BANK_BLOCK + i * sizeof(uint32_t), block + i);
-
- // note, that the very first block needs special handling: 'init' bit copies
- // input block into core's state, 'next' bit xor's current core's state with input block
-
- // block has enough space for entire core state, lower words are filled with
- // message and upper words remain zeroes. When the very first block is absorbed
- // into the sponge, we need to initialize *all* the core's state bits, because the
- // upper part of core's state may contain leftovers from previously absorbed data.
-
- // for subsequent blocks we don't need to copy the upper null part of block into the input
- // bank, because we've already filled it with zeroes for the very first block
-
- if (block_number == 0)
- {
- for (; i<(SHA3_STATE_BYTES / sizeof(uint32_t)); i++)
- fmc_write_32(CORE_ADDR_BANK_BLOCK + i * sizeof(uint32_t), block + i);
- }
-
- // CONTROL = 0
- ctrl = 0;
- fmc_write_32(CORE_ADDR_CONTROL, &ctrl);
-
- // determine what control bit to set ('init' for the very first block,
- // 'next' for all the subsequent blocks)
- ctrl = (block_number > 0) ? CORE_CONTROL_BIT_NEXT : CORE_CONTROL_BIT_INIT;
- fmc_write_32(CORE_ADDR_CONTROL, &ctrl);
-
- // wait for 'valid' bit to be set
- sts = 0;
- while (!(sts & CORE_STATUS_BIT_VALID))
- fmc_read_32(CORE_ADDR_STATUS, &sts);
+ uint32_t i; // word counter
+ uint32_t ctrl, sts; // control register, status register
+
+ // copy 32-bit words from state into core's input block buffer
+ for (i=0; i<(num_block_bytes / sizeof(uint32_t)); i++)
+ fmc_write_32(CORE_ADDR_BANK_BLOCK + i * sizeof(uint32_t), block + i);
+
+ // note, that the very first block needs special handling: 'init' bit copies
+ // input block into core's state, 'next' bit xor's current core's state with input block
+
+ // block has enough space for entire core state, lower words are filled with
+ // message and upper words remain zeroes. When the very first block is absorbed
+ // into the sponge, we need to initialize *all* the core's state bits, because the
+ // upper part of core's state may contain leftovers from previously absorbed data.
+
+ // for subsequent blocks we don't need to copy the upper null part of block into the input
+ // bank, because we've already filled it with zeroes for the very first block
+
+ if (block_number == 0)
+ {
+ for (; i<(SHA3_STATE_BYTES / sizeof(uint32_t)); i++)
+ fmc_write_32(CORE_ADDR_BANK_BLOCK + i * sizeof(uint32_t), block + i);
+ }
+
+ // CONTROL = 0
+ ctrl = 0;
+ fmc_write_32(CORE_ADDR_CONTROL, &ctrl);
+
+ // determine what control bit to set ('init' for the very first block,
+ // 'next' for all the subsequent blocks)
+ ctrl = (block_number > 0) ? CORE_CONTROL_BIT_NEXT : CORE_CONTROL_BIT_INIT;
+ fmc_write_32(CORE_ADDR_CONTROL, &ctrl);
+
+ // wait for 'valid' bit to be set
+ sts = 0;
+ while (!(sts & CORE_STATUS_BIT_VALID))
+ fmc_read_32(CORE_ADDR_STATUS, &sts);
}
- //
- // toggle the yellow led to indicate that we're not stuck somewhere
- //
+//
+// toggle the yellow led to indicate that we're not stuck somewhere
+//
void toggle_yellow_led(void)
{
- static int led_state = 0;
-
- led_state = !led_state;
-
- if (led_state) led_on(LED_YELLOW);
- else led_off(LED_YELLOW);
+ static int led_state = 0;
+
+ led_state = !led_state;
+
+ if (led_state) led_on(LED_YELLOW);
+ else led_off(LED_YELLOW);
}
- //
- // end of file
- //
+//
+// end of file
+//