diff options
author | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2017-12-05 22:20:55 +0300 |
---|---|---|
committer | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2017-12-05 22:20:55 +0300 |
commit | 9ba428e606573d233b193c8afe0ecd875866e839 (patch) | |
tree | 9194b340c247966c2d621f4715c9d1489e27c89e | |
parent | e5fb10221c1c72292218cf718b4b6e6700924985 (diff) |
Ported core to CrypTech platform
- modified control logic (init & next flags instead of upper address bit)
- registered output data bus
- removed 8/16/32-bit data bus switch (we can only do 32 bits, moreover
Xilinx synthesizer was too stupid to understand it)
-rw-r--r-- | src/rtl/sha3.v | 361 |
1 files changed, 202 insertions, 159 deletions
diff --git a/src/rtl/sha3.v b/src/rtl/sha3.v index c07ce0d..ab18ca0 100644 --- a/src/rtl/sha3.v +++ b/src/rtl/sha3.v @@ -1,159 +1,202 @@ -//====================================================================== -// sha3 -// ---- -// keccak, SHA-3 winner -// derived from "readable keccak" -// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi> -// A baseline Keccak (3rd round) implementation. -// Verilog implementation (c) 2015 by Bernd Paysan -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - 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. -// -// - Neither the name of the NORDUnet nor the names of its contributors may -// be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// 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 -// HOLDER 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. -// -//====================================================================== - -`define rotl64(x, r) ((({x, x}<<r)>>64)& 64'hffffffffffffffff) -`define rotci(i) ((rotc>>((23-i)*6)) & 6'h3f) -`define pilni(i) ((piln>>((23-i)*5)) & 5'h1f) -`define rndci(i) ((rndc>>((23-i)*64)) & 64'hffffffffffffffff) - -module sha3(input wire clk, nreset, w, - input wire [8:bus] addr, - input wire [(8<<bus)-1:0] din, - output reg [(8<<bus)-1:0] dout, - output wire ready); - parameter bus=2; // 2^bus bytes bus width - reg [63:0] st[25], stn[25], bc[5], t; - reg [4:0] round, roundlimit; - reg [(8<<bus)-1:0] dinxor; - integer i, j; - - always @* - begin - case(bus) - 3: dout = st[addr[7:3]]; - 2: dout = st[addr[7:3]] >> (32*addr[2]); - 1: dout = st[addr[7:3]] >> (16*addr[2:1]); - 0: dout = st[addr[7:3]] >> (8*addr[2:0]); - endcase // case (bus) - dinxor = addr[8] ? dout ^ din : din; - end - - wire [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 }; - wire [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 }; - wire [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 }; - - always @* - begin - // theta1 - for(i=0; i<25; i=i+1) begin - stn[i] = st[i]; - end - for(i=0; i<5; i=i+1) begin - bc[i] = stn[i] ^ stn[i+5] ^ stn[i+10] ^ stn[i+15] ^ stn[i+20]; - end - // 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) begin - stn[j] = t ^ stn[j]; - end - 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) begin - bc[i] = stn[j + i]; - end - for (i = 0; i < 5; i = i + 1) begin - stn[j+i] = stn[j+i] ^ (~bc[(i+1)%5] & bc[(i+2)%5]); - end - end - // iota - stn[0] = stn[0] ^ `rndci(round); - end - - assign ready = round >= roundlimit; - - always @(posedge clk or negedge nreset) - if(!nreset) begin - for(i=0; i<25; i=i+1) - st[i] <= 64'h0; - round <= 24; - roundlimit <= 24; - end else begin - if(!w) begin - if(!ready) begin - for(i=0; i<25; i=i+1) - st[i] <= stn[i]; - round <= round + 5'b1; - end - end else begin - if(&addr[8:bus]) begin // last element - round <= 0; - roundlimit <= din[4:0]; - end else begin - case(bus) - 3: st[addr[7:3]] <= dinxor; - 2: case(addr[2]) - 1: st[addr[7:3]][63:32] <= dinxor; - 0: st[addr[7:3]][31:0] <= dinxor; - endcase // case (addr[2]) - 1: case(addr[2:1]) - 3: st[addr[7:3]][63:48] <= dinxor; - 2: st[addr[7:3]][47:32] <= dinxor; - 1: st[addr[7:3]][31:16] <= dinxor; - 0: st[addr[7:3]][15:0] <= dinxor; - endcase // case (addr[2]) - endcase // case (bus) - end - end - end - -endmodule // sha3 -//====================================================================== +//======================================================================
+// sha3
+// ----
+// keccak, SHA-3 winner
+// derived from "readable keccak"
+// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
+// A baseline Keccak (3rd round) implementation.
+// Verilog implementation (c) 2015 by Bernd Paysan
+// Ported to Cryptech Alpha platform by Pavel Shatov
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// - Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// - 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.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+// be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// 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
+// HOLDER 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.
+//
+//======================================================================
+
+`define rotl64(x, r) ((({x, x}<<r)>>64)& 64'hffffffffffffffff)
+`define rotci(i) ((rotc>>((23-i)*6)) & 6'h3f)
+`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
+
+
+endmodule // sha3
+//======================================================================
|