diff options
author | Joachim StroĢmbergson <joachim@secworks.se> | 2015-03-09 15:47:46 +0100 |
---|---|---|
committer | Joachim StroĢmbergson <joachim@secworks.se> | 2015-03-09 15:47:46 +0100 |
commit | cfbd3284da108126eda1252cea430c57ce5cea2e (patch) | |
tree | b0befcc2c4f10d2d076cc20261341bf1f2dbb8e3 /src | |
parent | 771fb751070cb2e6e2f8dba5d7ff42a372e4b09c (diff) |
Adding initial version of sha3 core by Bernd Paysan.
Diffstat (limited to 'src')
-rw-r--r-- | src/rtl/sha3.v | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/src/rtl/sha3.v b/src/rtl/sha3.v new file mode 100644 index 0000000..c07ce0d --- /dev/null +++ b/src/rtl/sha3.v @@ -0,0 +1,159 @@ +//====================================================================== +// 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 +//====================================================================== |