mirror of
https://github.com/tillitis/tillitis-key1.git
synced 2024-10-01 01:45:38 -04:00
Add blake2s core
Signed-off-by: Joachim Strömbergson <joachim@assured.se>
This commit is contained in:
parent
1ab36c7c83
commit
6e6c2ab3ca
@ -66,7 +66,11 @@ VERILOG_SRCS = \
|
||||
$(P)/core/uart/rtl/uart_core.v \
|
||||
$(P)/core/uart/rtl/uart_fifo.v \
|
||||
$(P)/core/uart/rtl/uart.v \
|
||||
$(P)/core/trng/rtl/rosc.v
|
||||
$(P)/core/trng/rtl/rosc.v \
|
||||
$(P)/core/blake2s/rtl/blake2s_core.v \
|
||||
$(P)/core/blake2s/rtl/blake2s_G.v \
|
||||
$(P)/core/blake2s/rtl/blake2s_m_select.v \
|
||||
$(P)/core/blake2s/rtl/blake2s.v \
|
||||
|
||||
FIRMWARE_DEPS = \
|
||||
$(P)/fw/tk1_mem.h \
|
||||
|
230
hw/application_fpga/core/blake2s/rtl/blake2s.v
Normal file
230
hw/application_fpga/core/blake2s/rtl/blake2s.v
Normal file
@ -0,0 +1,230 @@
|
||||
//======================================================================
|
||||
//
|
||||
// blake2s.v
|
||||
// --------
|
||||
// Top level wrapper for the blake2s hash function core providing
|
||||
// a simple memory like interface with 32 bit data access.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strömbergson// Copyright (c) 2018, Assured AB
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or
|
||||
// without modification, are permitted provided that the following
|
||||
// conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in
|
||||
// the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
module blake2s(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire cs,
|
||||
input wire we,
|
||||
|
||||
input wire [7 : 0] address,
|
||||
input wire [31 : 0] write_data,
|
||||
output wire [31 : 0] read_data
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
localparam ADDR_NAME0 = 8'h00;
|
||||
localparam ADDR_NAME1 = 8'h01;
|
||||
localparam ADDR_VERSION = 8'h02;
|
||||
|
||||
localparam ADDR_CTRL = 8'h08;
|
||||
localparam CTRL_INIT_BIT = 0;
|
||||
localparam CTRL_UPDATE_BIT = 1;
|
||||
localparam CTRL_FINISH_BIT = 2;
|
||||
|
||||
localparam ADDR_STATUS = 8'h09;
|
||||
localparam STATUS_READY_BIT = 0;
|
||||
|
||||
localparam ADDR_BLOCKLEN = 8'h0a;
|
||||
|
||||
localparam ADDR_BLOCK0 = 8'h10;
|
||||
localparam ADDR_BLOCK15 = 8'h1f;
|
||||
|
||||
localparam ADDR_DIGEST0 = 8'h40;
|
||||
localparam ADDR_DIGEST7 = 8'h47;
|
||||
|
||||
|
||||
localparam CORE_NAME0 = 32'h626c616b; // "blak"
|
||||
localparam CORE_NAME1 = 32'h65327320; // "e2s "
|
||||
localparam CORE_VERSION = 32'h302e3830; // "0.80"
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers including update variables and write enable.
|
||||
//----------------------------------------------------------------
|
||||
reg init_reg;
|
||||
reg init_new;
|
||||
reg update_reg;
|
||||
reg update_new;
|
||||
reg finish_reg;
|
||||
reg finish_new;
|
||||
reg [6 : 0] blocklen_reg;
|
||||
reg blocklen_we;
|
||||
|
||||
reg [31 : 0] block_mem [0 : 15];
|
||||
reg block_mem_we;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Wires.
|
||||
//----------------------------------------------------------------
|
||||
wire core_ready;
|
||||
wire [511 : 0] core_block;
|
||||
wire [255 : 0] core_digest;
|
||||
|
||||
reg [31 : 0] tmp_read_data;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign core_block = {block_mem[0], block_mem[1], block_mem[2], block_mem[3],
|
||||
block_mem[4], block_mem[5], block_mem[6], block_mem[7],
|
||||
block_mem[8], block_mem[9], block_mem[10], block_mem[11],
|
||||
block_mem[12], block_mem[13], block_mem[14], block_mem[15]};
|
||||
|
||||
assign read_data = tmp_read_data;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// core instantiation.
|
||||
//----------------------------------------------------------------
|
||||
blake2s_core core(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.init(init_reg),
|
||||
.update(update_reg),
|
||||
.finish(finish_reg),
|
||||
|
||||
.block(core_block),
|
||||
.blocklen(blocklen_reg),
|
||||
|
||||
.digest(core_digest),
|
||||
.ready(core_ready)
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update
|
||||
//----------------------------------------------------------------
|
||||
always @ (posedge clk)
|
||||
begin : reg_update
|
||||
integer i;
|
||||
|
||||
if (!reset_n)
|
||||
begin
|
||||
for (i = 0 ; i < 16 ; i = i + 1)
|
||||
block_mem[i] <= 32'h0;
|
||||
|
||||
init_reg <= 1'h0;
|
||||
update_reg <= 1'h0;
|
||||
finish_reg <= 1'h0;
|
||||
blocklen_reg <= 7'h0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
init_reg <= init_new;
|
||||
update_reg <= update_new;
|
||||
finish_reg <= finish_new;
|
||||
|
||||
if (blocklen_we) begin
|
||||
blocklen_reg <= write_data[6 : 0];
|
||||
end
|
||||
|
||||
if (block_mem_we) begin
|
||||
block_mem[address[3 : 0]] <= write_data;
|
||||
end
|
||||
end
|
||||
end // reg_update
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// api
|
||||
// The interface command decoding logic.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : api
|
||||
init_new = 1'h0;
|
||||
update_new = 1'h0;
|
||||
finish_new = 1'h0;
|
||||
block_mem_we = 1'h0;
|
||||
blocklen_we = 1'h0;
|
||||
tmp_read_data = 32'h0;
|
||||
|
||||
if (cs)
|
||||
begin
|
||||
if (we)
|
||||
begin
|
||||
if (address == ADDR_CTRL) begin
|
||||
init_new = write_data[CTRL_INIT_BIT];
|
||||
update_new = write_data[CTRL_UPDATE_BIT];
|
||||
finish_new = write_data[CTRL_FINISH_BIT];
|
||||
end
|
||||
|
||||
if (address == ADDR_BLOCKLEN) begin
|
||||
blocklen_we = 1;
|
||||
end
|
||||
|
||||
if ((address >= ADDR_BLOCK0) && (address <= ADDR_BLOCK15)) begin
|
||||
block_mem_we = 1;
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
if (address == ADDR_NAME0) begin
|
||||
tmp_read_data = CORE_NAME0;
|
||||
end
|
||||
|
||||
if (address == ADDR_NAME1) begin
|
||||
tmp_read_data = CORE_NAME1;
|
||||
end
|
||||
|
||||
if (address == ADDR_VERSION) begin
|
||||
tmp_read_data = CORE_VERSION;
|
||||
end
|
||||
|
||||
if (address == ADDR_STATUS) begin
|
||||
tmp_read_data = {31'h0, core_ready};
|
||||
end
|
||||
|
||||
if ((address >= ADDR_DIGEST0) && (address <= ADDR_DIGEST7)) begin
|
||||
tmp_read_data = core_digest[(7 - (address - ADDR_DIGEST0)) * 32 +: 32];
|
||||
end
|
||||
end
|
||||
end
|
||||
end // api
|
||||
endmodule // blake2s
|
||||
|
||||
//======================================================================
|
||||
// EOF blake2s.v
|
||||
//======================================================================
|
112
hw/application_fpga/core/blake2s/rtl/blake2s_G.v
Normal file
112
hw/application_fpga/core/blake2s/rtl/blake2s_G.v
Normal file
@ -0,0 +1,112 @@
|
||||
//======================================================================
|
||||
//
|
||||
// blake2s_G.v
|
||||
// -----------
|
||||
// Verilog 2001 implementation of the G function in the
|
||||
// blake2s hash function core. This is pure combinational logic in a
|
||||
// separade module to allow us to build versions with 1, 2, 4
|
||||
// and even 8 parallel compression functions.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strömbergson
|
||||
// Copyright (c) 2018, Assured AB
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or
|
||||
// without modification, are permitted provided that the following
|
||||
// conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in
|
||||
// the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
module blake2s_G(
|
||||
input wire [31 : 0] a,
|
||||
input wire [31 : 0] b,
|
||||
input wire [31 : 0] c,
|
||||
input wire [31 : 0] d,
|
||||
input wire [31 : 0] m0,
|
||||
input wire [31 : 0] m1,
|
||||
|
||||
output wire [31 : 0] a_prim,
|
||||
output wire [31 : 0] b_prim,
|
||||
output wire [31 : 0] c_prim,
|
||||
output wire [31 : 0] d_prim
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Wires.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] a1;
|
||||
reg [31 : 0] a2;
|
||||
reg [31 : 0] b1;
|
||||
reg [31 : 0] b2;
|
||||
reg [31 : 0] b3;
|
||||
reg [31 : 0] b4;
|
||||
reg [31 : 0] c1;
|
||||
reg [31 : 0] c2;
|
||||
reg [31 : 0] d1;
|
||||
reg [31 : 0] d2;
|
||||
reg [31 : 0] d3;
|
||||
reg [31 : 0] d4;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports.
|
||||
//----------------------------------------------------------------
|
||||
assign a_prim = a2;
|
||||
assign b_prim = b4;
|
||||
assign c_prim = c2;
|
||||
assign d_prim = d4;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// G_function
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : G_function
|
||||
a1 = a + b + m0;
|
||||
|
||||
d1 = d ^ a1;
|
||||
d2 = {d1[15 : 0], d1[31 : 16]};
|
||||
|
||||
c1 = c + d2;
|
||||
|
||||
b1 = b ^ c1;
|
||||
b2 = {b1[11 : 0], b1[31 : 12]};
|
||||
|
||||
a2 = a1 + b2 + m1;
|
||||
|
||||
d3 = d2 ^ a2;
|
||||
d4 = {d3[7 : 0], d3[31 : 8]};
|
||||
|
||||
c2 = c1 + d4;
|
||||
|
||||
b3 = b2 ^ c2;
|
||||
b4 = {b3[6 : 0], b3[31 : 7]};
|
||||
end // G_function
|
||||
endmodule // blake2s_G
|
||||
|
||||
//======================================================================
|
||||
// EOF blake2s_G.v
|
||||
//======================================================================
|
713
hw/application_fpga/core/blake2s/rtl/blake2s_core.v
Normal file
713
hw/application_fpga/core/blake2s/rtl/blake2s_core.v
Normal file
@ -0,0 +1,713 @@
|
||||
//======================================================================
|
||||
//
|
||||
// blake2s_core.v
|
||||
// --------------
|
||||
// Verilog 2001 implementation of the hash function blake2s.
|
||||
// This is the internal core with wide interfaces.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strömbergson
|
||||
// Copyright (c) 2018, Assured AB
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or
|
||||
// without modification, are permitted provided that the following
|
||||
// conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in
|
||||
// the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
module blake2s_core(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire init,
|
||||
input wire update,
|
||||
input wire finish,
|
||||
|
||||
input wire [511 : 0] block,
|
||||
input wire [6 : 0] blocklen,
|
||||
|
||||
output wire [255 : 0] digest,
|
||||
output wire ready
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Parameter block.
|
||||
// See BLAKE2 paper and RFC 7693 for definition.
|
||||
// Chapter 2.8 in https://blake2.net/blake2.pdf
|
||||
// Section 2.5 in https://tools.ietf.org/html/rfc7693
|
||||
//----------------------------------------------------------------
|
||||
// The digest length in bytes. Minimum: 1, Maximum: 32
|
||||
localparam [7 : 0] DIGEST_LENGTH = 8'd32;
|
||||
localparam [7 : 0] KEY_LENGTH = 8'd0;
|
||||
localparam [7 : 0] FANOUT = 8'd1;
|
||||
localparam [7 : 0] DEPTH = 8'd01;
|
||||
localparam [31 : 0] LEAF_LENGTH = 32'd0;
|
||||
localparam [47 : 0] NODE_OFFSET = 48'd0;
|
||||
localparam [7 : 0] NODE_DEPTH = 8'd0;
|
||||
localparam [7 : 0] INNER_LENGTH = 8'd0;
|
||||
localparam [63 : 0] SALT = 64'h0;
|
||||
localparam [63 : 0] PERSONALIZATION = 64'h0;
|
||||
|
||||
wire [255 : 0] parameter_block = {PERSONALIZATION, SALT, INNER_LENGTH,
|
||||
NODE_DEPTH, NODE_OFFSET, LEAF_LENGTH,
|
||||
DEPTH, FANOUT, KEY_LENGTH, DIGEST_LENGTH};
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant definitions.
|
||||
//----------------------------------------------------------------
|
||||
localparam NUM_ROUNDS = 10;
|
||||
localparam BLOCK_BYTES = 7'd64;
|
||||
|
||||
// G function modes.
|
||||
localparam G_ROW = 1'h0;
|
||||
localparam G_DIAGONAL = 1'h1;
|
||||
|
||||
// Initial vectors.
|
||||
localparam IV0 = 32'h6a09e667;
|
||||
localparam IV1 = 32'hbb67ae85;
|
||||
localparam IV2 = 32'h3c6ef372;
|
||||
localparam IV3 = 32'ha54ff53a;
|
||||
localparam IV4 = 32'h510e527f;
|
||||
localparam IV5 = 32'h9b05688c;
|
||||
localparam IV6 = 32'h1f83d9ab;
|
||||
localparam IV7 = 32'h5be0cd19;
|
||||
|
||||
// Control FSM state names.
|
||||
localparam CTRL_IDLE = 3'h0;
|
||||
localparam CTRL_INIT_ROUND = 3'h1;
|
||||
localparam CTRL_G_ROW = 3'h2;
|
||||
localparam CTRL_G_DIAGONAL = 3'h3;
|
||||
localparam CTRL_COMP_DONE = 3'h4;
|
||||
localparam CTRL_FINISH = 3'h5;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers including update variables and write enable.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] h_reg [0 : 7];
|
||||
reg [31 : 0] h_new [0 : 7];
|
||||
reg h_we;
|
||||
|
||||
reg [31 : 0] v_reg [0 : 15];
|
||||
reg [31 : 0] v_new [0 : 15];
|
||||
reg v_we;
|
||||
reg init_v;
|
||||
reg update_v;
|
||||
|
||||
reg [3 : 0] round_ctr_reg;
|
||||
reg [3 : 0] round_ctr_new;
|
||||
reg round_ctr_we;
|
||||
reg round_ctr_inc;
|
||||
reg round_ctr_rst;
|
||||
|
||||
reg [31 : 0] t0_reg;
|
||||
reg [31 : 0] t0_new;
|
||||
reg t0_we;
|
||||
reg [31 : 0] t1_reg;
|
||||
reg [31 : 0] t1_new;
|
||||
reg t1_we;
|
||||
reg t_ctr_inc;
|
||||
reg t_ctr_rst;
|
||||
|
||||
reg last_reg;
|
||||
reg last_new;
|
||||
reg last_we;
|
||||
|
||||
reg ready_reg;
|
||||
reg ready_new;
|
||||
reg ready_we;
|
||||
|
||||
reg [2 : 0] blake2s_ctrl_reg;
|
||||
reg [2 : 0] blake2s_ctrl_new;
|
||||
reg blake2s_ctrl_we;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Wires.
|
||||
//----------------------------------------------------------------
|
||||
reg init_state;
|
||||
reg update_state;
|
||||
reg load_m;
|
||||
reg G_mode;
|
||||
|
||||
reg [31 : 0] G0_a;
|
||||
reg [31 : 0] G0_b;
|
||||
reg [31 : 0] G0_c;
|
||||
reg [31 : 0] G0_d;
|
||||
wire [31 : 0] G0_m0;
|
||||
wire [31 : 0] G0_m1;
|
||||
wire [31 : 0] G0_a_prim;
|
||||
wire [31 : 0] G0_b_prim;
|
||||
wire [31 : 0] G0_c_prim;
|
||||
wire [31 : 0] G0_d_prim;
|
||||
|
||||
reg [31 : 0] G1_a;
|
||||
reg [31 : 0] G1_b;
|
||||
reg [31 : 0] G1_c;
|
||||
reg [31 : 0] G1_d;
|
||||
wire [31 : 0] G1_m0;
|
||||
wire [31 : 0] G1_m1;
|
||||
wire [31 : 0] G1_a_prim;
|
||||
wire [31 : 0] G1_b_prim;
|
||||
wire [31 : 0] G1_c_prim;
|
||||
wire [31 : 0] G1_d_prim;
|
||||
|
||||
reg [31 : 0] G2_a;
|
||||
reg [31 : 0] G2_b;
|
||||
reg [31 : 0] G2_c;
|
||||
reg [31 : 0] G2_d;
|
||||
wire [31 : 0] G2_m0;
|
||||
wire [31 : 0] G2_m1;
|
||||
wire [31 : 0] G2_a_prim;
|
||||
wire [31 : 0] G2_b_prim;
|
||||
wire [31 : 0] G2_c_prim;
|
||||
wire [31 : 0] G2_d_prim;
|
||||
|
||||
reg [31 : 0] G3_a;
|
||||
reg [31 : 0] G3_b;
|
||||
reg [31 : 0] G3_c;
|
||||
reg [31 : 0] G3_d;
|
||||
wire [31 : 0] G3_m0;
|
||||
wire [31 : 0] G3_m1;
|
||||
wire [31 : 0] G3_a_prim;
|
||||
wire [31 : 0] G3_b_prim;
|
||||
wire [31 : 0] G3_c_prim;
|
||||
wire [31 : 0] G3_d_prim;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Module instantations.
|
||||
//----------------------------------------------------------------
|
||||
blake2s_m_select mselect(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.load(load_m),
|
||||
.m(block),
|
||||
.round(round_ctr_reg),
|
||||
.mode(G_mode),
|
||||
.G0_m0(G0_m0),
|
||||
.G0_m1(G0_m1),
|
||||
.G1_m0(G1_m0),
|
||||
.G1_m1(G1_m1),
|
||||
.G2_m0(G2_m0),
|
||||
.G2_m1(G2_m1),
|
||||
.G3_m0(G3_m0),
|
||||
.G3_m1(G3_m1)
|
||||
);
|
||||
|
||||
|
||||
blake2s_G G0(
|
||||
.a(G0_a),
|
||||
.b(G0_b),
|
||||
.c(G0_c),
|
||||
.d(G0_d),
|
||||
.m0(G0_m0),
|
||||
.m1(G0_m1),
|
||||
.a_prim(G0_a_prim),
|
||||
.b_prim(G0_b_prim),
|
||||
.c_prim(G0_c_prim),
|
||||
.d_prim(G0_d_prim)
|
||||
);
|
||||
|
||||
|
||||
blake2s_G G1(
|
||||
.a(G1_a),
|
||||
.b(G1_b),
|
||||
.c(G1_c),
|
||||
.d(G1_d),
|
||||
.m0(G1_m0),
|
||||
.m1(G1_m1),
|
||||
.a_prim(G1_a_prim),
|
||||
.b_prim(G1_b_prim),
|
||||
.c_prim(G1_c_prim),
|
||||
.d_prim(G1_d_prim)
|
||||
);
|
||||
|
||||
|
||||
blake2s_G G2(
|
||||
.a(G2_a),
|
||||
.b(G2_b),
|
||||
.c(G2_c),
|
||||
.d(G2_d),
|
||||
.m0(G2_m0),
|
||||
.m1(G2_m1),
|
||||
|
||||
.a_prim(G2_a_prim),
|
||||
.b_prim(G2_b_prim),
|
||||
.c_prim(G2_c_prim),
|
||||
.d_prim(G2_d_prim)
|
||||
);
|
||||
|
||||
|
||||
blake2s_G G3(
|
||||
.a(G3_a),
|
||||
.b(G3_b),
|
||||
.c(G3_c),
|
||||
.d(G3_d),
|
||||
.m0(G3_m0),
|
||||
.m1(G3_m1),
|
||||
.a_prim(G3_a_prim),
|
||||
.b_prim(G3_b_prim),
|
||||
.c_prim(G3_c_prim),
|
||||
.d_prim(G3_d_prim)
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign digest = {h_reg[0][7 : 0], h_reg[0][15 : 8], h_reg[0][23 : 16], h_reg[0][31 : 24],
|
||||
h_reg[1][7 : 0], h_reg[1][15 : 8], h_reg[1][23 : 16], h_reg[1][31 : 24],
|
||||
h_reg[2][7 : 0], h_reg[2][15 : 8], h_reg[2][23 : 16], h_reg[2][31 : 24],
|
||||
h_reg[3][7 : 0], h_reg[3][15 : 8], h_reg[3][23 : 16], h_reg[3][31 : 24],
|
||||
h_reg[4][7 : 0], h_reg[4][15 : 8], h_reg[4][23 : 16], h_reg[4][31 : 24],
|
||||
h_reg[5][7 : 0], h_reg[5][15 : 8], h_reg[5][23 : 16], h_reg[5][31 : 24],
|
||||
h_reg[6][7 : 0], h_reg[6][15 : 8], h_reg[6][23 : 16], h_reg[6][31 : 24],
|
||||
h_reg[7][7 : 0], h_reg[7][15 : 8], h_reg[7][23 : 16], h_reg[7][31 : 24]};
|
||||
|
||||
assign ready = ready_reg;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update
|
||||
//----------------------------------------------------------------
|
||||
always @ (posedge clk)
|
||||
begin : reg_update
|
||||
integer i;
|
||||
|
||||
if (!reset_n) begin
|
||||
for (i = 0; i < 8; i = i + 1) begin
|
||||
h_reg[i] <= 32'h0;
|
||||
end
|
||||
|
||||
for (i = 0; i < 16; i = i + 1) begin
|
||||
v_reg[i] <= 32'h0;
|
||||
end
|
||||
|
||||
t0_reg <= 32'h0;
|
||||
t1_reg <= 32'h0;
|
||||
last_reg <= 1'h0;
|
||||
ready_reg <= 1'h1;
|
||||
round_ctr_reg <= 4'h0;
|
||||
blake2s_ctrl_reg <= CTRL_IDLE;
|
||||
end
|
||||
else begin
|
||||
if (h_we) begin
|
||||
for (i = 0; i < 8; i = i + 1) begin
|
||||
h_reg[i] <= h_new[i];
|
||||
end
|
||||
end
|
||||
|
||||
if (v_we) begin
|
||||
for (i = 0; i < 16; i = i + 1) begin
|
||||
v_reg[i] <= v_new[i];
|
||||
end
|
||||
end
|
||||
|
||||
if (t0_we) begin
|
||||
t0_reg <= t0_new;
|
||||
end
|
||||
|
||||
if (t1_we) begin
|
||||
t1_reg <= t1_new;
|
||||
end
|
||||
|
||||
if (last_we) begin
|
||||
last_reg <= last_new;
|
||||
end
|
||||
|
||||
if (ready_we) begin
|
||||
ready_reg <= ready_new;
|
||||
end
|
||||
|
||||
if (round_ctr_we) begin
|
||||
round_ctr_reg <= round_ctr_new;
|
||||
end
|
||||
|
||||
if (blake2s_ctrl_we) begin
|
||||
blake2s_ctrl_reg <= blake2s_ctrl_new;
|
||||
end
|
||||
end
|
||||
end // reg_update
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// state_logic
|
||||
//
|
||||
// Logic for updating the hash state.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : state_logic
|
||||
integer i;
|
||||
|
||||
for (i = 0; i < 8; i = i + 1) begin
|
||||
h_new[i] = 32'h0;
|
||||
end
|
||||
h_we = 1'h0;
|
||||
|
||||
if (init_state) begin
|
||||
h_new[0] = IV0 ^ parameter_block[31 : 0];
|
||||
h_new[1] = IV1 ^ parameter_block[63 : 32];
|
||||
h_new[2] = IV2 ^ parameter_block[95 : 64];
|
||||
h_new[3] = IV3 ^ parameter_block[127 : 96];
|
||||
h_new[4] = IV4 ^ parameter_block[159 : 128];
|
||||
h_new[5] = IV5 ^ parameter_block[191 : 160];
|
||||
h_new[6] = IV6 ^ parameter_block[223 : 192];
|
||||
h_new[7] = IV7 ^ parameter_block[255 : 224];
|
||||
h_we = 1;
|
||||
end
|
||||
|
||||
if (update_state) begin
|
||||
h_new[0] = h_reg[0] ^ v_reg[0] ^ v_reg[8];
|
||||
h_new[1] = h_reg[1] ^ v_reg[1] ^ v_reg[9];
|
||||
h_new[2] = h_reg[2] ^ v_reg[2] ^ v_reg[10];
|
||||
h_new[3] = h_reg[3] ^ v_reg[3] ^ v_reg[11];
|
||||
h_new[4] = h_reg[4] ^ v_reg[4] ^ v_reg[12];
|
||||
h_new[5] = h_reg[5] ^ v_reg[5] ^ v_reg[13];
|
||||
h_new[6] = h_reg[6] ^ v_reg[6] ^ v_reg[14];
|
||||
h_new[7] = h_reg[7] ^ v_reg[7] ^ v_reg[15];
|
||||
h_we = 1;
|
||||
end
|
||||
end // state_logic
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// compress_logic
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : compress_logic
|
||||
integer i;
|
||||
|
||||
for (i = 0; i < 16; i = i + 1) begin
|
||||
v_new[i] = 32'h0;
|
||||
end
|
||||
v_we = 1'h0;
|
||||
|
||||
G0_a = 32'h0;
|
||||
G0_b = 32'h0;
|
||||
G0_c = 32'h0;
|
||||
G0_d = 32'h0;
|
||||
G1_a = 32'h0;
|
||||
G1_b = 32'h0;
|
||||
G1_c = 32'h0;
|
||||
G1_d = 32'h0;
|
||||
G2_a = 32'h0;
|
||||
G2_b = 32'h0;
|
||||
G2_c = 32'h0;
|
||||
G2_d = 32'h0;
|
||||
G3_a = 32'h0;
|
||||
G3_b = 32'h0;
|
||||
G3_c = 32'h0;
|
||||
G3_d = 32'h0;
|
||||
|
||||
if (init_v)
|
||||
begin
|
||||
v_new[0] = h_reg[0];
|
||||
v_new[1] = h_reg[1];
|
||||
v_new[2] = h_reg[2];
|
||||
v_new[3] = h_reg[3];
|
||||
v_new[4] = h_reg[4];
|
||||
v_new[5] = h_reg[5];
|
||||
v_new[6] = h_reg[6];
|
||||
v_new[7] = h_reg[7];
|
||||
v_new[8] = IV0;
|
||||
v_new[9] = IV1;
|
||||
v_new[10] = IV2;
|
||||
v_new[11] = IV3;
|
||||
v_new[12] = t0_reg ^ IV4;
|
||||
v_new[13] = t1_reg ^ IV5;
|
||||
|
||||
if (last_reg) begin
|
||||
v_new[14] = ~IV6;
|
||||
end else begin
|
||||
v_new[14] = IV6;
|
||||
end
|
||||
|
||||
v_new[15] = IV7;
|
||||
v_we = 1;
|
||||
end
|
||||
|
||||
if (update_v)
|
||||
begin
|
||||
v_we = 1;
|
||||
|
||||
if (G_mode == G_ROW) begin
|
||||
// Row updates.
|
||||
G0_a = v_reg[0];
|
||||
G0_b = v_reg[4];
|
||||
G0_c = v_reg[8];
|
||||
G0_d = v_reg[12];
|
||||
v_new[0] = G0_a_prim;
|
||||
v_new[4] = G0_b_prim;
|
||||
v_new[8] = G0_c_prim;
|
||||
v_new[12] = G0_d_prim;
|
||||
|
||||
G1_a = v_reg[1];
|
||||
G1_b = v_reg[5];
|
||||
G1_c = v_reg[9];
|
||||
G1_d = v_reg[13];
|
||||
v_new[1] = G1_a_prim;
|
||||
v_new[5] = G1_b_prim;
|
||||
v_new[9] = G1_c_prim;
|
||||
v_new[13] = G1_d_prim;
|
||||
|
||||
G2_a = v_reg[2];
|
||||
G2_b = v_reg[6];
|
||||
G2_c = v_reg[10];
|
||||
G2_d = v_reg[14];
|
||||
v_new[2] = G2_a_prim;
|
||||
v_new[6] = G2_b_prim;
|
||||
v_new[10] = G2_c_prim;
|
||||
v_new[14] = G2_d_prim;
|
||||
|
||||
G3_a = v_reg[3];
|
||||
G3_b = v_reg[7];
|
||||
G3_c = v_reg[11];
|
||||
G3_d = v_reg[15];
|
||||
v_new[3] = G3_a_prim;
|
||||
v_new[7] = G3_b_prim;
|
||||
v_new[11] = G3_c_prim;
|
||||
v_new[15] = G3_d_prim;
|
||||
end
|
||||
else begin
|
||||
// Diagonal updates.
|
||||
G0_a = v_reg[0];
|
||||
G0_b = v_reg[5];
|
||||
G0_c = v_reg[10];
|
||||
G0_d = v_reg[15];
|
||||
v_new[0] = G0_a_prim;
|
||||
v_new[5] = G0_b_prim;
|
||||
v_new[10] = G0_c_prim;
|
||||
v_new[15] = G0_d_prim;
|
||||
|
||||
G1_a = v_reg[1];
|
||||
G1_b = v_reg[6];
|
||||
G1_c = v_reg[11];
|
||||
G1_d = v_reg[12];
|
||||
v_new[1] = G1_a_prim;
|
||||
v_new[6] = G1_b_prim;
|
||||
v_new[11] = G1_c_prim;
|
||||
v_new[12] = G1_d_prim;
|
||||
|
||||
G2_a = v_reg[2];
|
||||
G2_b = v_reg[7];
|
||||
G2_c = v_reg[8];
|
||||
G2_d = v_reg[13];
|
||||
v_new[2] = G2_a_prim;
|
||||
v_new[7] = G2_b_prim;
|
||||
v_new[8] = G2_c_prim;
|
||||
v_new[13] = G2_d_prim;
|
||||
|
||||
G3_a = v_reg[3];
|
||||
G3_b = v_reg[4];
|
||||
G3_c = v_reg[9];
|
||||
G3_d = v_reg[14];
|
||||
v_new[3] = G3_a_prim;
|
||||
v_new[4] = G3_b_prim;
|
||||
v_new[9] = G3_c_prim;
|
||||
v_new[14] = G3_d_prim;
|
||||
end
|
||||
end // if (update_v)
|
||||
end // compress_logic
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// t_ctr
|
||||
// Update logic for the length counter t, a monotonically
|
||||
// increasing counter with reset.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : t_ctr
|
||||
t0_new = 32'h0;
|
||||
t0_we = 1'h0;
|
||||
t1_new = 32'h0;
|
||||
t1_we = 1'h0;
|
||||
|
||||
if (t_ctr_rst) begin
|
||||
t0_new = 32'h0;
|
||||
t0_we = 1'h1;
|
||||
t1_new = 32'h0;
|
||||
t1_we = 1'h1;
|
||||
end
|
||||
|
||||
if (t_ctr_inc) begin
|
||||
t0_we = 1'h1;
|
||||
|
||||
if (last_new) begin
|
||||
t0_new = t0_reg + {25'h0, blocklen};
|
||||
end else begin
|
||||
t0_new = t0_reg + {25'h0, BLOCK_BYTES};
|
||||
end
|
||||
|
||||
if (t0_new < t0_reg) begin
|
||||
t1_new = t1_reg + 1'h1;
|
||||
t1_we = 1'h1;
|
||||
end
|
||||
end
|
||||
end // t_ctr
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// round_ctr
|
||||
// Update logic for the round counter, a monotonically
|
||||
// increasing counter with reset.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : round_ctr
|
||||
round_ctr_new = 4'h0;
|
||||
round_ctr_we = 1'h0;
|
||||
|
||||
if (round_ctr_rst)
|
||||
begin
|
||||
round_ctr_new = 4'h0;
|
||||
round_ctr_we = 1'h1;
|
||||
end
|
||||
|
||||
if (round_ctr_inc)
|
||||
begin
|
||||
round_ctr_new = round_ctr_reg + 1'b1;
|
||||
round_ctr_we = 1'h1;
|
||||
end
|
||||
end // round_ctr
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// blake2s_ctrl
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : blake2s_ctrl
|
||||
init_state = 1'h0;
|
||||
update_state = 1'h0;
|
||||
init_v = 1'h0;
|
||||
update_v = 1'h0;
|
||||
load_m = 1'h0;
|
||||
G_mode = G_ROW;
|
||||
round_ctr_inc = 1'h0;
|
||||
round_ctr_rst = 1'h0;
|
||||
t_ctr_inc = 1'h0;
|
||||
t_ctr_rst = 1'h0;
|
||||
last_new = 1'h0;
|
||||
last_we = 1'h0;
|
||||
ready_new = 1'h0;
|
||||
ready_we = 1'h0;
|
||||
blake2s_ctrl_new = CTRL_IDLE;
|
||||
blake2s_ctrl_we = 1'h0;
|
||||
|
||||
|
||||
case (blake2s_ctrl_reg)
|
||||
CTRL_IDLE: begin
|
||||
if (init) begin
|
||||
last_new = 1'h0;
|
||||
last_we = 1'h1;
|
||||
init_state = 1'h1;
|
||||
t_ctr_rst = 1'h1;
|
||||
ready_new = 1'h0;
|
||||
ready_we = 1'h1;
|
||||
blake2s_ctrl_new = CTRL_FINISH;
|
||||
blake2s_ctrl_we = 1'h1;
|
||||
end
|
||||
|
||||
if (update) begin
|
||||
if (blocklen == BLOCK_BYTES) begin
|
||||
load_m = 1'h1;
|
||||
t_ctr_inc = 1'h1;
|
||||
ready_new = 1'h0;
|
||||
ready_we = 1'h1;
|
||||
blake2s_ctrl_new = CTRL_INIT_ROUND;
|
||||
blake2s_ctrl_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
if (finish) begin
|
||||
load_m = 1'h1;
|
||||
t_ctr_inc = 1'h1;
|
||||
last_new = 1'h1;
|
||||
last_we = 1'h1;
|
||||
ready_new = 1'h0;
|
||||
ready_we = 1'h1;
|
||||
blake2s_ctrl_new = CTRL_INIT_ROUND;
|
||||
blake2s_ctrl_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
CTRL_INIT_ROUND: begin
|
||||
init_v = 1'h1;
|
||||
round_ctr_rst = 1'h1;
|
||||
blake2s_ctrl_new = CTRL_G_ROW;
|
||||
blake2s_ctrl_we = 1'h1;
|
||||
end
|
||||
|
||||
|
||||
CTRL_G_ROW: begin
|
||||
G_mode = G_ROW;
|
||||
update_v = 1'h1;
|
||||
blake2s_ctrl_new = CTRL_G_DIAGONAL;
|
||||
blake2s_ctrl_we = 1'h1;
|
||||
end
|
||||
|
||||
|
||||
CTRL_G_DIAGONAL: begin
|
||||
G_mode = G_DIAGONAL;
|
||||
update_v = 1'h1;
|
||||
round_ctr_inc = 1'h1;
|
||||
if (round_ctr_reg == (NUM_ROUNDS - 1)) begin
|
||||
blake2s_ctrl_new = CTRL_COMP_DONE;
|
||||
blake2s_ctrl_we = 1'h1;
|
||||
end
|
||||
else begin
|
||||
blake2s_ctrl_new = CTRL_G_ROW;
|
||||
blake2s_ctrl_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
CTRL_COMP_DONE: begin
|
||||
last_new = 1'h0;
|
||||
last_we = 1'h1;
|
||||
update_state = 1'h1;
|
||||
blake2s_ctrl_new = CTRL_FINISH;
|
||||
blake2s_ctrl_we = 1'h1;
|
||||
end
|
||||
|
||||
|
||||
CTRL_FINISH: begin
|
||||
ready_new = 1'h1;
|
||||
ready_we = 1'h1;
|
||||
blake2s_ctrl_new = CTRL_IDLE;
|
||||
blake2s_ctrl_we = 1'h1;
|
||||
end
|
||||
|
||||
|
||||
default: begin end
|
||||
endcase // case (blake2s_ctrl_reg)
|
||||
end // blake2s_ctrl
|
||||
endmodule // blake2s_core
|
||||
|
||||
//======================================================================
|
||||
// EOF blake2s_core.v
|
||||
//======================================================================
|
391
hw/application_fpga/core/blake2s/rtl/blake2s_m_select.v
Normal file
391
hw/application_fpga/core/blake2s/rtl/blake2s_m_select.v
Normal file
@ -0,0 +1,391 @@
|
||||
//======================================================================
|
||||
//
|
||||
// blake2s_m_select.v
|
||||
// ------------------
|
||||
// Verilog 2001 implementation of the message word selection in the
|
||||
// blake2 hash function core. Based on the given round and mode, we
|
||||
// extract the indices for the eight m words to select.
|
||||
// The words are then selected and returned. This is basically a
|
||||
// mux based implementation of the permutation table in combination
|
||||
// with the actual word selection.
|
||||
//
|
||||
//
|
||||
// Note that we use the mode to signal which indices to select
|
||||
// for a given round. This is because we don't do 8 G-functions
|
||||
// in a single cycle.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strömbergson
|
||||
// Copyright (c) 2018, Assured AB
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or
|
||||
// without modification, are permitted provided that the following
|
||||
// conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in
|
||||
// the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
module blake2s_m_select(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire load,
|
||||
input wire [511 : 0] m,
|
||||
|
||||
input wire [3 : 0] round,
|
||||
input wire mode,
|
||||
|
||||
output wire [31 : 0] G0_m0,
|
||||
output wire [31 : 0] G0_m1,
|
||||
output wire [31 : 0] G1_m0,
|
||||
output wire [31 : 0] G1_m1,
|
||||
output wire [31 : 0] G2_m0,
|
||||
output wire [31 : 0] G2_m1,
|
||||
output wire [31 : 0] G3_m0,
|
||||
output wire [31 : 0] G3_m1
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// regs.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] m_mem [0 : 15];
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Wires.
|
||||
//----------------------------------------------------------------
|
||||
reg [3 : 0] i_G0_m0;
|
||||
reg [3 : 0] i_G0_m1;
|
||||
reg [3 : 0] i_G1_m0;
|
||||
reg [3 : 0] i_G1_m1;
|
||||
reg [3 : 0] i_G2_m0;
|
||||
reg [3 : 0] i_G2_m1;
|
||||
reg [3 : 0] i_G3_m0;
|
||||
reg [3 : 0] i_G3_m1;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports.
|
||||
//----------------------------------------------------------------
|
||||
// Eight parallel, muxes that extract the message block words.
|
||||
assign G0_m0 = m_mem[i_G0_m0];
|
||||
assign G0_m1 = m_mem[i_G0_m1];
|
||||
assign G1_m0 = m_mem[i_G1_m0];
|
||||
assign G1_m1 = m_mem[i_G1_m1];
|
||||
assign G2_m0 = m_mem[i_G2_m0];
|
||||
assign G2_m1 = m_mem[i_G2_m1];
|
||||
assign G3_m0 = m_mem[i_G3_m0];
|
||||
assign G3_m1 = m_mem[i_G3_m1];
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update
|
||||
//
|
||||
// Update functionality for all registers in the core.
|
||||
// All registers are positive edge triggered with synchronous,
|
||||
// active low reset. All registers have write enable.
|
||||
//----------------------------------------------------------------
|
||||
always @ (posedge clk)
|
||||
begin : reg_update
|
||||
integer i;
|
||||
|
||||
if (!reset_n)
|
||||
begin
|
||||
for (i = 0 ; i < 16 ; i = i + 1)
|
||||
m_mem[i] <= 32'h0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (load)
|
||||
begin
|
||||
// Big to little endian conversion during register load.
|
||||
m_mem[00] <= {m[0487 : 0480], m[0495 : 0488], m[0503 : 0496], m[0511 : 0504]};
|
||||
m_mem[01] <= {m[0455 : 0448], m[0463 : 0456], m[0471 : 0464], m[0479 : 0472]};
|
||||
m_mem[02] <= {m[0423 : 0416], m[0431 : 0424], m[0439 : 0432], m[0447 : 0440]};
|
||||
m_mem[03] <= {m[0391 : 0384], m[0399 : 0392], m[0407 : 0400], m[0415 : 0408]};
|
||||
m_mem[04] <= {m[0359 : 0352], m[0367 : 0360], m[0375 : 0368], m[0383 : 0376]};
|
||||
m_mem[05] <= {m[0327 : 0320], m[0335 : 0328], m[0343 : 0336], m[0351 : 0344]};
|
||||
m_mem[06] <= {m[0295 : 0288], m[0303 : 0296], m[0311 : 0304], m[0319 : 0312]};
|
||||
m_mem[07] <= {m[0263 : 0256], m[0271 : 0264], m[0279 : 0272], m[0287 : 0280]};
|
||||
m_mem[08] <= {m[0231 : 0224], m[0239 : 0232], m[0247 : 0240], m[0255 : 0248]};
|
||||
m_mem[09] <= {m[0199 : 0192], m[0207 : 0200], m[0215 : 0208], m[0223 : 0216]};
|
||||
m_mem[10] <= {m[0167 : 0160], m[0175 : 0168], m[0183 : 0176], m[0191 : 0184]};
|
||||
m_mem[11] <= {m[0135 : 0128], m[0143 : 0136], m[0151 : 0144], m[0159 : 0152]};
|
||||
m_mem[12] <= {m[0103 : 0096], m[0111 : 0104], m[0119 : 0112], m[0127 : 0120]};
|
||||
m_mem[13] <= {m[0071 : 0064], m[0079 : 0072], m[0087 : 0080], m[0095 : 0088]};
|
||||
m_mem[14] <= {m[0039 : 0032], m[0047 : 0040], m[0055 : 0048], m[0063 : 0056]};
|
||||
m_mem[15] <= {m[0007 : 0000], m[0015 : 0008], m[0023 : 0016], m[0031 : 0024]};
|
||||
end
|
||||
end
|
||||
end // reg_update
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// get_indices
|
||||
//
|
||||
// Get the indices from the permutation table given the
|
||||
// round and the G function mode. This is the SIGMA table.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : get_indices
|
||||
i_G0_m0 = 4'd0;
|
||||
i_G0_m1 = 4'd0;
|
||||
i_G1_m0 = 4'd0;
|
||||
i_G1_m1 = 4'd0;
|
||||
i_G2_m0 = 4'd0;
|
||||
i_G2_m1 = 4'd0;
|
||||
i_G3_m0 = 4'd0;
|
||||
i_G3_m1 = 4'd0;
|
||||
|
||||
case ({round, mode})
|
||||
0: begin
|
||||
i_G0_m0 = 4'd00;
|
||||
i_G0_m1 = 4'd01;
|
||||
i_G1_m0 = 4'd02;
|
||||
i_G1_m1 = 4'd03;
|
||||
i_G2_m0 = 4'd04;
|
||||
i_G2_m1 = 4'd05;
|
||||
i_G3_m0 = 4'd06;
|
||||
i_G3_m1 = 4'd07;
|
||||
end
|
||||
|
||||
1: begin
|
||||
i_G0_m0 = 4'd08;
|
||||
i_G0_m1 = 4'd09;
|
||||
i_G1_m0 = 4'd10;
|
||||
i_G1_m1 = 4'd11;
|
||||
i_G2_m0 = 4'd12;
|
||||
i_G2_m1 = 4'd13;
|
||||
i_G3_m0 = 4'd14;
|
||||
i_G3_m1 = 4'd15;
|
||||
end
|
||||
|
||||
2: begin
|
||||
i_G0_m0 = 4'd14;
|
||||
i_G0_m1 = 4'd10;
|
||||
i_G1_m0 = 4'd04;
|
||||
i_G1_m1 = 4'd08;
|
||||
i_G2_m0 = 4'd09;
|
||||
i_G2_m1 = 4'd15;
|
||||
i_G3_m0 = 4'd13;
|
||||
i_G3_m1 = 4'd06;
|
||||
end
|
||||
|
||||
3: begin
|
||||
i_G0_m0 = 4'd01;
|
||||
i_G0_m1 = 4'd12;
|
||||
i_G1_m0 = 4'd00;
|
||||
i_G1_m1 = 4'd02;
|
||||
i_G2_m0 = 4'd11;
|
||||
i_G2_m1 = 4'd07;
|
||||
i_G3_m0 = 4'd05;
|
||||
i_G3_m1 = 4'd03;
|
||||
end
|
||||
|
||||
4: begin
|
||||
i_G0_m0 = 4'd11;
|
||||
i_G0_m1 = 4'd08;
|
||||
i_G1_m0 = 4'd12;
|
||||
i_G1_m1 = 4'd00;
|
||||
i_G2_m0 = 4'd05;
|
||||
i_G2_m1 = 4'd02;
|
||||
i_G3_m0 = 4'd15;
|
||||
i_G3_m1 = 4'd13;
|
||||
end
|
||||
|
||||
5: begin
|
||||
i_G0_m0 = 4'd10;
|
||||
i_G0_m1 = 4'd14;
|
||||
i_G1_m0 = 4'd03;
|
||||
i_G1_m1 = 4'd06;
|
||||
i_G2_m0 = 4'd07;
|
||||
i_G2_m1 = 4'd01;
|
||||
i_G3_m0 = 4'd09;
|
||||
i_G3_m1 = 4'd04;
|
||||
end
|
||||
|
||||
6: begin
|
||||
i_G0_m0 = 4'd07;
|
||||
i_G0_m1 = 4'd09;
|
||||
i_G1_m0 = 4'd03;
|
||||
i_G1_m1 = 4'd01;
|
||||
i_G2_m0 = 4'd13;
|
||||
i_G2_m1 = 4'd12;
|
||||
i_G3_m0 = 4'd11;
|
||||
i_G3_m1 = 4'd14;
|
||||
end
|
||||
|
||||
7: begin
|
||||
i_G0_m0 = 4'd02;
|
||||
i_G0_m1 = 4'd06;
|
||||
i_G1_m0 = 4'd05;
|
||||
i_G1_m1 = 4'd10;
|
||||
i_G2_m0 = 4'd04;
|
||||
i_G2_m1 = 4'd00;
|
||||
i_G3_m0 = 4'd15;
|
||||
i_G3_m1 = 4'd08;
|
||||
end
|
||||
|
||||
8: begin
|
||||
i_G0_m0 = 4'd09;
|
||||
i_G0_m1 = 4'd00;
|
||||
i_G1_m0 = 4'd05;
|
||||
i_G1_m1 = 4'd07;
|
||||
i_G2_m0 = 4'd02;
|
||||
i_G2_m1 = 4'd04;
|
||||
i_G3_m0 = 4'd10;
|
||||
i_G3_m1 = 4'd15;
|
||||
end
|
||||
|
||||
9: begin
|
||||
i_G0_m0 = 4'd14;
|
||||
i_G0_m1 = 4'd01;
|
||||
i_G1_m0 = 4'd11;
|
||||
i_G1_m1 = 4'd12;
|
||||
i_G2_m0 = 4'd06;
|
||||
i_G2_m1 = 4'd08;
|
||||
i_G3_m0 = 4'd03;
|
||||
i_G3_m1 = 4'd13;
|
||||
end
|
||||
|
||||
10: begin
|
||||
i_G0_m0 = 4'd02;
|
||||
i_G0_m1 = 4'd12;
|
||||
i_G1_m0 = 4'd06;
|
||||
i_G1_m1 = 4'd10;
|
||||
i_G2_m0 = 4'd00;
|
||||
i_G2_m1 = 4'd11;
|
||||
i_G3_m0 = 4'd08;
|
||||
i_G3_m1 = 4'd03;
|
||||
end
|
||||
|
||||
11: begin
|
||||
i_G0_m0 = 4'd04;
|
||||
i_G0_m1 = 4'd13;
|
||||
i_G1_m0 = 4'd07;
|
||||
i_G1_m1 = 4'd05;
|
||||
i_G2_m0 = 4'd15;
|
||||
i_G2_m1 = 4'd14;
|
||||
i_G3_m0 = 4'd01;
|
||||
i_G3_m1 = 4'd09;
|
||||
end
|
||||
|
||||
12: begin
|
||||
i_G0_m0 = 4'd12;
|
||||
i_G0_m1 = 4'd05;
|
||||
i_G1_m0 = 4'd01;
|
||||
i_G1_m1 = 4'd15;
|
||||
i_G2_m0 = 4'd14;
|
||||
i_G2_m1 = 4'd13;
|
||||
i_G3_m0 = 4'd04;
|
||||
i_G3_m1 = 4'd10;
|
||||
end
|
||||
|
||||
13: begin
|
||||
i_G0_m0 = 4'd00;
|
||||
i_G0_m1 = 4'd07;
|
||||
i_G1_m0 = 4'd06;
|
||||
i_G1_m1 = 4'd03;
|
||||
i_G2_m0 = 4'd09;
|
||||
i_G2_m1 = 4'd02;
|
||||
i_G3_m0 = 4'd08;
|
||||
i_G3_m1 = 4'd11;
|
||||
end
|
||||
|
||||
14: begin
|
||||
i_G0_m0 = 4'd13;
|
||||
i_G0_m1 = 4'd11;
|
||||
i_G1_m0 = 4'd07;
|
||||
i_G1_m1 = 4'd14;
|
||||
i_G2_m0 = 4'd12;
|
||||
i_G2_m1 = 4'd01;
|
||||
i_G3_m0 = 4'd03;
|
||||
i_G3_m1 = 4'd09;
|
||||
end
|
||||
|
||||
15: begin
|
||||
i_G0_m0 = 4'd05;
|
||||
i_G0_m1 = 4'd00;
|
||||
i_G1_m0 = 4'd15;
|
||||
i_G1_m1 = 4'd04;
|
||||
i_G2_m0 = 4'd08;
|
||||
i_G2_m1 = 4'd06;
|
||||
i_G3_m0 = 4'd02;
|
||||
i_G3_m1 = 4'd10;
|
||||
end
|
||||
|
||||
16: begin
|
||||
i_G0_m0 = 4'd06;
|
||||
i_G0_m1 = 4'd15;
|
||||
i_G1_m0 = 4'd14;
|
||||
i_G1_m1 = 4'd09;
|
||||
i_G2_m0 = 4'd11;
|
||||
i_G2_m1 = 4'd03;
|
||||
i_G3_m0 = 4'd00;
|
||||
i_G3_m1 = 4'd08;
|
||||
end
|
||||
|
||||
17: begin
|
||||
i_G0_m0 = 4'd12;
|
||||
i_G0_m1 = 4'd02;
|
||||
i_G1_m0 = 4'd13;
|
||||
i_G1_m1 = 4'd07;
|
||||
i_G2_m0 = 4'd01;
|
||||
i_G2_m1 = 4'd04;
|
||||
i_G3_m0 = 4'd10;
|
||||
i_G3_m1 = 4'd05;
|
||||
end
|
||||
|
||||
18: begin
|
||||
i_G0_m0 = 4'd10;
|
||||
i_G0_m1 = 4'd02;
|
||||
i_G1_m0 = 4'd08;
|
||||
i_G1_m1 = 4'd04;
|
||||
i_G2_m0 = 4'd07;
|
||||
i_G2_m1 = 4'd06;
|
||||
i_G3_m0 = 4'd01;
|
||||
i_G3_m1 = 4'd05;
|
||||
end
|
||||
|
||||
19: begin
|
||||
i_G0_m0 = 4'd15;
|
||||
i_G0_m1 = 4'd11;
|
||||
i_G1_m0 = 4'd09;
|
||||
i_G1_m1 = 4'd14;
|
||||
i_G2_m0 = 4'd03;
|
||||
i_G2_m1 = 4'd12;
|
||||
i_G3_m0 = 4'd13;
|
||||
i_G3_m1 = 4'd00;
|
||||
end
|
||||
|
||||
default: begin end
|
||||
endcase // case ({round, mode})
|
||||
end
|
||||
|
||||
endmodule // blake2s_m_select
|
||||
|
||||
//======================================================================
|
||||
// EOF blake2s_m_select.v
|
||||
//======================================================================
|
@ -49,6 +49,7 @@ module application_fpga(
|
||||
localparam UART_PREFIX = 6'h03;
|
||||
localparam TOUCH_SENSE_PREFIX = 6'h04;
|
||||
localparam FW_RAM_PREFIX = 6'h10;
|
||||
localparam BLAKE2S_PREFIX = 6'h12;
|
||||
localparam TK1_PREFIX = 6'h3f;
|
||||
|
||||
// Instruction used to cause a trap.
|
||||
@ -103,6 +104,15 @@ module application_fpga(
|
||||
wire [31 : 0] trng_read_data;
|
||||
wire trng_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg blake2s_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg blake2s_we;
|
||||
reg [7 : 0] blake2s_address;
|
||||
reg [31 : 0] blake2s_write_data;
|
||||
wire [31 : 0] blake2s_read_data;
|
||||
wire blake2s_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg timer_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
@ -258,6 +268,17 @@ module application_fpga(
|
||||
);
|
||||
|
||||
|
||||
blake2s blake2s_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.cs(blake2s_cs),
|
||||
.we(blake2s_we),
|
||||
.address(blake2s_address),
|
||||
.write_data(blake2s_write_data),
|
||||
.read_data(blake2s_read_data)
|
||||
);
|
||||
|
||||
|
||||
timer timer_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
@ -398,6 +419,11 @@ module application_fpga(
|
||||
trng_address = cpu_addr[9 : 2];
|
||||
trng_write_data = cpu_wdata;
|
||||
|
||||
blake2s_cs = 1'h0;
|
||||
blake2s_we = |cpu_wstrb;
|
||||
blake2s_address = cpu_addr[9 : 2];
|
||||
blake2s_write_data = cpu_wdata;
|
||||
|
||||
timer_cs = 1'h0;
|
||||
timer_we = |cpu_wstrb;
|
||||
timer_address = cpu_addr[9 : 2];
|
||||
@ -482,6 +508,12 @@ module application_fpga(
|
||||
muxed_ready_new = fw_ram_ready;
|
||||
end
|
||||
|
||||
BLAKE2S_PREFIX: begin
|
||||
blake2s_cs = 1'h1;
|
||||
muxed_rdata_new = blake2s_read_data;
|
||||
muxed_ready_new = 1'h1;
|
||||
end
|
||||
|
||||
TK1_PREFIX: begin
|
||||
tk1_cs = 1'h1;
|
||||
muxed_rdata_new = tk1_read_data;
|
||||
|
Loading…
Reference in New Issue
Block a user