[Cryptech-Commits] [staging/core/hash/sha1] 07/20: Updated W memory module with new sliding window version. Updated README with more info.

git at cryptech.is git at cryptech.is
Tue Mar 17 13:14:13 UTC 2015


This is an automated email from the git hooks/post-receive script.

paul at psgd.org pushed a commit to branch master
in repository staging/core/hash/sha1.

commit 5e6b7c37996926722cd19038c1813b77cf1302c7
Author: Joachim Strömbergson <joachim at secworks.se>
Date:   Sun Feb 23 21:12:10 2014 +0100

    Updated W memory module with new sliding window version. Updated README with more info.
---
 README.md              |  34 ++++++--
 src/rtl/sha1_core.v    |  10 ++-
 src/rtl/sha1_w_mem.v   | 218 +++++++++++++++++++++++++++++++++++--------------
 src/tb/tb_sha1_w_mem.v |  92 ++++++---------------
 4 files changed, 216 insertions(+), 138 deletions(-)

diff --git a/README.md b/README.md
index 730ef3f..36f6d2e 100644
--- a/README.md
+++ b/README.md
@@ -11,21 +11,43 @@ https://github.com/secworks/sha1
 
 ## Implementation details ##
 
-### Altera Cyclone IV GX ###
-Implementation using Altera Quartus-II 13.1 with a EP4CGX22CF19C6 device
-as target.
-* 10718 LEs
-* 3575 Regs
-* 103 MHz
+### Altera Cyclone FPGAs ###
+Implementation results using Altera Quartus-II 13.1.
+
+***Altera Cyclone IV E***
+- EP4CE6F17C6
+- 2913 LEs
+- 1527 regs
+- 107 MHz
+
+***Altera Cyclone IV GX***
+- EP4CGX22CF19C6
+- 2814 LEs
+- 1527 regs
+- 105 MHz
+
+***Altera Cyclone V***
+- 5CGXFC7C7F23C8
+- 1124 ALMs
+- 1527 regs
+- 104 MHz
 
 
 ## TODO ##
 * Extensive functional verification in real HW.
 * Add Wishbone interface.
+* Add results for Xilinx and possibly some other FPGA device.
 * Documentation
 
 
 ## Status ##
+***(2014-02-23):***
+
+New version of the W memory module that quite drastically improves
+resource utilization. And a bit better performance too. Also added some
+new results for other Altera devices.
+
+
 ***(2014-02-21):***
 
 Moved the core to Cryptech.
diff --git a/src/rtl/sha1_core.v b/src/rtl/sha1_core.v
index be83b52..aae578c 100644
--- a/src/rtl/sha1_core.v
+++ b/src/rtl/sha1_core.v
@@ -120,6 +120,7 @@ module sha1_core(
   reg           first_block;
   reg           ready_flag;
   reg           w_init;
+  reg           w_next;
   wire          w_ready;
   wire [31 : 0] w;
               
@@ -131,10 +132,11 @@ module sha1_core(
                    .clk(clk),
                    .reset_n(reset_n),
 
-                   .init(w_init),
                    .block(block),
+
+                   .init(w_init),
+                   .next(w_next),
                    
-                   .addr(round_ctr_reg),
                    .w(w)
                   );
 
@@ -365,6 +367,7 @@ module sha1_core(
       first_block      = 0;
       ready_flag       = 0;
       w_init           = 0;
+      w_next           = 0;
       round_ctr_inc    = 0;
       round_ctr_rst    = 0;
       digest_valid_new = 0;
@@ -407,7 +410,8 @@ module sha1_core(
           begin
             state_update  = 1;
             round_ctr_inc = 1;
-
+            w_next        = 1;
+            
             if (round_ctr_reg == SHA1_ROUNDS)
               begin
                 sha1_ctrl_new = CTRL_DONE;
diff --git a/src/rtl/sha1_w_mem.v b/src/rtl/sha1_w_mem.v
index 9aaa403..7b30683 100644
--- a/src/rtl/sha1_w_mem.v
+++ b/src/rtl/sha1_w_mem.v
@@ -2,8 +2,9 @@
 //
 // sha1_w_mem_reg.v
 // -----------------
-// The SHA-1 W memory. This memory includes functionality to 
-// expand the block into 80 words.
+// The SHA-1 W memory. This memory is based around a sliding window
+// of 16 32-bit registers that are used to create the w words
+// needed by the core during the 80 rounds.
 //
 //
 // Author: Joachim Strombergson
@@ -40,10 +41,11 @@ module sha1_w_mem(
                   input wire           clk,
                   input wire           reset_n,
 
-                  input wire           init,
                   input wire [511 : 0] block,
 
-                  input wire [6 : 0]   addr,
+                  input wire           init,
+                  input wire           next,
+
                   output wire [31 : 0] w
                  );
 
@@ -60,15 +62,30 @@ module sha1_w_mem(
   //----------------------------------------------------------------
   // Registers including update variables and write enable.
   //----------------------------------------------------------------
-  reg [31 : 0] w_mem [0 : 79];
-  reg [31 : 0] w_mem_new;
+  reg [31 : 0] w_mem [0 : 15];
+  reg [31 : 0] w_mem00_new;
+  reg [31 : 0] w_mem01_new;
+  reg [31 : 0] w_mem02_new;
+  reg [31 : 0] w_mem03_new;
+  reg [31 : 0] w_mem04_new;
+  reg [31 : 0] w_mem05_new;
+  reg [31 : 0] w_mem06_new;
+  reg [31 : 0] w_mem07_new;
+  reg [31 : 0] w_mem08_new;
+  reg [31 : 0] w_mem09_new;
+  reg [31 : 0] w_mem10_new;
+  reg [31 : 0] w_mem11_new;
+  reg [31 : 0] w_mem12_new;
+  reg [31 : 0] w_mem13_new;
+  reg [31 : 0] w_mem14_new;
+  reg [31 : 0] w_mem15_new;
   reg          w_mem_we;
   
   reg [6 : 0] w_ctr_reg;
   reg [6 : 0] w_ctr_new;
   reg         w_ctr_we;
   reg         w_ctr_inc;
-  reg         w_ctr_set;
+  reg         w_ctr_rst;
   
   reg         sha1_w_mem_ctrl_reg;
   reg         sha1_w_mem_ctrl_new;
@@ -80,14 +97,13 @@ module sha1_w_mem(
   //----------------------------------------------------------------
   reg [31 : 0] w_tmp;
   reg [31 : 0] w_new;
-  reg [6 : 0]  w_addr;
-  reg          w_update;
+  reg          mem_update;
   
   
   //----------------------------------------------------------------
   // Concurrent connectivity for ports etc.
   //----------------------------------------------------------------
-  assign w     = w_tmp;
+  assign w = w_tmp;
   
   
   //----------------------------------------------------------------
@@ -101,34 +117,45 @@ module sha1_w_mem(
     begin : reg_update
       if (!reset_n)
         begin
+          w_mem[00]           <= 32'h00000000;
+          w_mem[01]           <= 32'h00000000;
+          w_mem[02]           <= 32'h00000000;
+          w_mem[03]           <= 32'h00000000;
+          w_mem[04]           <= 32'h00000000;
+          w_mem[05]           <= 32'h00000000;
+          w_mem[06]           <= 32'h00000000;
+          w_mem[07]           <= 32'h00000000;
+          w_mem[08]           <= 32'h00000000;
+          w_mem[09]           <= 32'h00000000;
+          w_mem[10]           <= 32'h00000000;
+          w_mem[11]           <= 32'h00000000;
+          w_mem[12]           <= 32'h00000000;
+          w_mem[13]           <= 32'h00000000;
+          w_mem[14]           <= 32'h00000000;
+          w_mem[15]           <= 32'h00000000;
           w_ctr_reg           <= 7'b0000000;
           sha1_w_mem_ctrl_reg <= CTRL_IDLE;
         end
       else
         begin
-          if (init)
-            begin
-              w_mem[00] <= block[511 : 480];
-              w_mem[01] <= block[479 : 448];
-              w_mem[02] <= block[447 : 416];
-              w_mem[03] <= block[415 : 384];
-              w_mem[04] <= block[383 : 352];
-              w_mem[05] <= block[351 : 320];
-              w_mem[06] <= block[319 : 288];
-              w_mem[07] <= block[287 : 256];
-              w_mem[08] <= block[255 : 224];
-              w_mem[09] <= block[223 : 192];
-              w_mem[10] <= block[191 : 160];
-              w_mem[11] <= block[159 : 128];
-              w_mem[12] <= block[127 :  96];
-              w_mem[13] <= block[95  :  64];
-              w_mem[14] <= block[63  :  32];
-              w_mem[15] <= block[31  :   0];
-            end
-
           if (w_mem_we)
             begin
-              w_mem[w_addr] <= w_mem_new;
+              w_mem[00] <= w_mem00_new;
+              w_mem[01] <= w_mem01_new;
+              w_mem[02] <= w_mem02_new;
+              w_mem[03] <= w_mem03_new;
+              w_mem[04] <= w_mem04_new;
+              w_mem[05] <= w_mem05_new;
+              w_mem[06] <= w_mem06_new;
+              w_mem[07] <= w_mem07_new;
+              w_mem[08] <= w_mem08_new;
+              w_mem[09] <= w_mem09_new;
+              w_mem[10] <= w_mem10_new;
+              w_mem[11] <= w_mem11_new;
+              w_mem[12] <= w_mem12_new;
+              w_mem[13] <= w_mem13_new;
+              w_mem[14] <= w_mem14_new;
+              w_mem[15] <= w_mem15_new;
             end
           
           if (w_ctr_we)
@@ -146,40 +173,105 @@ module sha1_w_mem(
 
   
   //----------------------------------------------------------------
-  // external_addr_mux
+  // select_w
   //
-  // Mux for the external read operation. This is where we exract
-  // the W variable.
+  // W word selection logic. Returns either directly from the 
+  // memory or the next w value calculated.
   //----------------------------------------------------------------
   always @*
-    begin : external_addr_mux
-      w_tmp = w_mem[addr];
-    end // external_addr_mux
-  
+    begin : w_schedule
+      if (w_ctr_reg < 16)
+        begin
+          w_tmp = w_mem[w_ctr_reg[3 : 0]];
+        end
+      else
+        begin
+          w_tmp = w_new;
+        end
+    end // w_schedule
 
+  
   //----------------------------------------------------------------
-  // w_schedule
+  // w_mem_update_logic
   //
-  // W word expansion logic.
+  // Update logic for the W memory. This is where the scheduling
+  // based on a sliding window is implemented.
   //----------------------------------------------------------------
   always @*
-    begin : w_schedule
-      reg [31 : 0] w_new_tmp;
+    begin : w_mem_update_logic
+      reg [31 : 0] w_0;
+      reg [31 : 0] w_2;
+      reg [31 : 0] w_8;
+      reg [31 : 0] w_13;
+      reg [31 : 0] w_16;
+
+      w_mem00_new = 32'h00000000;
+      w_mem01_new = 32'h00000000;
+      w_mem02_new = 32'h00000000;
+      w_mem03_new = 32'h00000000;
+      w_mem04_new = 32'h00000000;
+      w_mem05_new = 32'h00000000;
+      w_mem06_new = 32'h00000000;
+      w_mem07_new = 32'h00000000;
+      w_mem08_new = 32'h00000000;
+      w_mem09_new = 32'h00000000;
+      w_mem10_new = 32'h00000000;
+      w_mem11_new = 32'h00000000;
+      w_mem12_new = 32'h00000000;
+      w_mem13_new = 32'h00000000;
+      w_mem14_new = 32'h00000000;
+      w_mem15_new = 32'h00000000;
+      w_mem_we    = 0;
+      
+      w_0   = w_mem[0];
+      w_2   = w_mem[2];
+      w_8   = w_mem[8];
+      w_13  = w_mem[13];
+      w_16  = w_13 ^ w_8 ^ w_2 ^ w_0;
+      w_new = {w_16[30 : 0], w_16[31]};
       
-      w_mem_we  = 0;
-      w_new_tmp = 32'h00000000;
-      w_mem_new = 32'h00000000;
-      w_addr    = 0;
+      if (init)
+        begin
+          w_mem00_new = block[511 : 480];
+          w_mem01_new = block[479 : 448];
+          w_mem02_new = block[447 : 416];
+          w_mem03_new = block[415 : 384];
+          w_mem04_new = block[383 : 352];
+          w_mem05_new = block[351 : 320];
+          w_mem06_new = block[319 : 288];
+          w_mem07_new = block[287 : 256];
+          w_mem08_new = block[255 : 224];
+          w_mem09_new = block[223 : 192];
+          w_mem10_new = block[191 : 160];
+          w_mem11_new = block[159 : 128];
+          w_mem12_new = block[127 :  96];
+          w_mem13_new = block[95  :  64];
+          w_mem14_new = block[63  :  32];
+          w_mem15_new = block[31  :   0];
+          w_mem_we    = 1;
+        end
 
-      if (w_update)
+      else if (w_ctr_reg > 15)
         begin
-          w_new_tmp = w_mem[(w_ctr_reg - 3)] ^ w_mem[(w_ctr_reg - 8)] ^
-                      w_mem[(w_ctr_reg - 14)] ^ w_mem[(w_ctr_reg - 16)];
-          w_mem_new = {w_new_tmp[30 : 0], w_new_tmp[31]};
-          w_addr    = w_ctr_reg;
-          w_mem_we  = 1;
+          w_mem00_new = w_mem[01];
+          w_mem01_new = w_mem[02];
+          w_mem02_new = w_mem[03];
+          w_mem03_new = w_mem[04];
+          w_mem04_new = w_mem[05];
+          w_mem05_new = w_mem[06];
+          w_mem06_new = w_mem[07];
+          w_mem07_new = w_mem[08];
+          w_mem08_new = w_mem[09];
+          w_mem09_new = w_mem[10];
+          w_mem10_new = w_mem[11];
+          w_mem11_new = w_mem[12];
+          w_mem12_new = w_mem[13];
+          w_mem13_new = w_mem[14];
+          w_mem14_new = w_mem[15];
+          w_mem15_new = w_new;
+          w_mem_we    = 1;
         end
-    end // w_schedule
+    end // w_mem_update_logic
 
   
   //----------------------------------------------------------------
@@ -193,9 +285,9 @@ module sha1_w_mem(
       w_ctr_new = 0;
       w_ctr_we  = 0;
       
-      if (w_ctr_set)
+      if (w_ctr_rst)
         begin
-          w_ctr_new = 6'h10;
+          w_ctr_new = 6'h00;
           w_ctr_we  = 1;
         end
 
@@ -214,10 +306,8 @@ module sha1_w_mem(
   //----------------------------------------------------------------
   always @*
     begin : sha1_w_mem_fsm
-      w_ctr_set = 0;
-      w_ctr_inc = 0;
-      w_update  = 0;
-      
+      w_ctr_rst           = 0;
+      w_ctr_inc           = 0;
       sha1_w_mem_ctrl_new = CTRL_IDLE;
       sha1_w_mem_ctrl_we  = 0;
       
@@ -226,7 +316,7 @@ module sha1_w_mem(
           begin
             if (init)
               begin
-                w_ctr_set           = 1;
+                w_ctr_rst           = 1;
                 sha1_w_mem_ctrl_new = CTRL_UPDATE;
                 sha1_w_mem_ctrl_we  = 1;
               end
@@ -234,9 +324,11 @@ module sha1_w_mem(
         
         CTRL_UPDATE:
           begin
-            w_update  = 1;
-            w_ctr_inc = 1;
-
+            if (next)
+              begin
+                w_ctr_inc = 1;
+              end
+            
             if (w_ctr_reg == SHA1_ROUNDS)
               begin
                 sha1_w_mem_ctrl_new = CTRL_IDLE;
diff --git a/src/tb/tb_sha1_w_mem.v b/src/tb/tb_sha1_w_mem.v
index 233e409..9ad16da 100644
--- a/src/tb/tb_sha1_w_mem.v
+++ b/src/tb/tb_sha1_w_mem.v
@@ -3,7 +3,6 @@
 // Tb_sha1_w_mem.v
 // ---------------
 // Testbench for the SHA-1 W memory module.
-// This testbench is currently not self testing.
 //
 //
 // Author: Joachim Strombergson
@@ -64,8 +63,8 @@ module tb_sha1_w_mem();
   reg           tb_clk;
   reg           tb_reset_n;
   reg           tb_init;
+  reg           tb_next;
   reg [511 : 0] tb_block;
-  reg [6 : 0]   tb_addr;
   wire [31 : 0] tb_w;
 
   reg [63 : 0] cycle_ctr;
@@ -80,10 +79,11 @@ module tb_sha1_w_mem();
                  .clk(tb_clk),
                  .reset_n(tb_reset_n),
                  
-                 .init(tb_init),
                  .block(tb_block),
+
+                 .init(tb_init),
+                 .next(tb_next),
                  
-                 .addr(tb_addr),
                  .w(tb_w)
                 );
   
@@ -113,13 +113,10 @@ module tb_sha1_w_mem();
         begin
           $display("cycle = %016x:", cycle_ctr);
         end
-      
+
       if (DEBUG)
         begin
-          $display("addr:      0x%02x:", dut.addr);
-          $display("addr4:     0x%02x:", dut.addr[3 : 0]);
-          $display("w_mem_new: 0x%08x:", dut.w_mem_new);
-          $display("w_mem_we:  0x%x:", dut.w_mem_we);
+          dump_w_state();
         end
     end // dut_monitor
       
@@ -132,7 +129,14 @@ module tb_sha1_w_mem();
   task dump_w_state();
     begin
       $display("W state:");
+
       
+      $display("ctrl_reg = %01x, w_ctr_reg = %02x, mem_update = %01x, init = %01x, next = %01x", 
+               dut.sha1_w_mem_ctrl_reg, dut.w_ctr_reg, dut.mem_update, 
+               dut.init, dut.next);
+      
+      $display("w_tmp   = %08x, w_new   = %08x", dut.w_tmp, dut.w_new);
+ 
       $display("w0_reg  = %08x, w1_reg  = %08x, w2_reg  = %08x, w3_reg  = %08x", 
                dut.w_mem[00], dut.w_mem[01], dut.w_mem[02], dut.w_mem[03]);
 
@@ -145,54 +149,6 @@ module tb_sha1_w_mem();
       $display("w12_reg = %08x, w13_reg = %08x, w14_reg = %08x, w15_reg = %08x", 
                dut.w_mem[12], dut.w_mem[13], dut.w_mem[14], dut.w_mem[15]);
 
-      $display("w16_reg = %08x, w17_reg = %08x, w18_reg = %08x, w19_reg = %08x", 
-               dut.w_mem[16], dut.w_mem[17], dut.w_mem[18], dut.w_mem[19]);
-
-      $display("w20_reg = %08x, w21_reg = %08x, w22_reg = %08x, w23_reg = %08x", 
-               dut.w_mem[20], dut.w_mem[21], dut.w_mem[22], dut.w_mem[23]);
-
-      $display("w24_reg = %08x, w25_reg = %08x, w26_reg = %08x, w27_reg = %08x", 
-               dut.w_mem[24], dut.w_mem[25], dut.w_mem[26], dut.w_mem[27]);
-
-      $display("w28_reg = %08x, w29_reg = %08x, w30_reg = %08x, w31_reg = %08x", 
-               dut.w_mem[28], dut.w_mem[29], dut.w_mem[30], dut.w_mem[31]);
-
-      $display("w32_reg = %08x, w33_reg = %08x, w34_reg = %08x, w35_reg = %08x", 
-               dut.w_mem[32], dut.w_mem[33], dut.w_mem[34], dut.w_mem[35]);
-
-      $display("w36_reg = %08x, w37_reg = %08x, w38_reg = %08x, w39_reg = %08x", 
-               dut.w_mem[36], dut.w_mem[37], dut.w_mem[38], dut.w_mem[39]);
-
-      $display("w40_reg = %08x, w41_reg = %08x, w42_reg = %08x, w43_reg = %08x", 
-               dut.w_mem[40], dut.w_mem[41], dut.w_mem[42], dut.w_mem[43]);
-
-      $display("w44_reg = %08x, w45_reg = %08x, w46_reg = %08x, w47_reg = %08x", 
-               dut.w_mem[44], dut.w_mem[45], dut.w_mem[46], dut.w_mem[47]);
-
-      $display("w48_reg = %08x, w49_reg = %08x, w50_reg = %08x, w51_reg = %08x", 
-               dut.w_mem[48], dut.w_mem[49], dut.w_mem[50], dut.w_mem[51]);
-
-      $display("w52_reg = %08x, w53_reg = %08x, w54_reg = %08x, w55_reg = %08x", 
-                dut.w_mem[52], dut.w_mem[53], dut.w_mem[54], dut.w_mem[55]);
-
-      $display("w56_reg = %08x, w57_reg = %08x, w58_reg = %08x, w59_reg = %08x", 
-               dut.w_mem[56], dut.w_mem[57], dut.w_mem[58], dut.w_mem[59]);
-
-      $display("w60_reg = %08x, w61_reg = %08x, w62_reg = %08x, w63_reg = %08x", 
-               dut.w_mem[60], dut.w_mem[61], dut.w_mem[62], dut.w_mem[63]);
-
-      $display("w64_reg = %08x, w65_reg = %08x, w66_reg = %08x, w67_reg = %08x", 
-               dut.w_mem[64], dut.w_mem[65], dut.w_mem[66], dut.w_mem[67]);
-
-      $display("w68_reg = %08x, w69_reg = %08x, w70_reg = %08x, w71_reg = %08x", 
-               dut.w_mem[68], dut.w_mem[69], dut.w_mem[70], dut.w_mem[71]);
-
-      $display("w72_reg = %08x, w73_reg = %08x, w74_reg = %08x, w75_reg = %08x", 
-               dut.w_mem[72], dut.w_mem[73], dut.w_mem[74], dut.w_mem[75]);
-
-      $display("w76_reg = %08x, w77_reg = %08x, w78_reg = %08x, w79_reg = %08x", 
-               dut.w_mem[76], dut.w_mem[77], dut.w_mem[78], dut.w_mem[79]);
-
       $display("");
     end
   endtask // dump_state
@@ -217,13 +173,12 @@ module tb_sha1_w_mem();
   task init_sim();
     begin
       $display("*** Simulation init.");
-      tb_clk = 0;
+      tb_clk     = 0;
       tb_reset_n = 1;
-      cycle_ctr = 0;
-      
-      tb_init = 0;
-      tb_block = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
-      tb_addr = 0;
+      cycle_ctr  = 0;
+      tb_init    = 0;
+      tb_next    = 0;
+      tb_block   = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
     end
   endtask // reset_dut
 
@@ -272,8 +227,9 @@ module tb_sha1_w_mem();
       #(4 * CLK_HALF_PERIOD);
       tb_init = 0;
 
+      tb_next = 1;
       #(200 * CLK_HALF_PERIOD);
-
+      
       dump_w_state();
     end
   endtask // test_w_schedule
@@ -290,10 +246,14 @@ module tb_sha1_w_mem();
     begin
       $display("*** Test of W read operations. --");
       i = 0;
+      tb_init = 1;
+      #(2 * CLK_HALF_PERIOD);
+      tb_init = 0;
+      
       while (i < 80)
         begin
-          tb_addr = i;
-          $display("API: w%02x, internal w%02x = 0x%02x", tb_addr, dut.addr, dut.w_tmp);
+          tb_next = i;
+          $display("API: w%02x = 0x%02x", i, dut.w_tmp);
           i = i + 1;
           #(2 * CLK_HALF_PERIOD);
         end



More information about the Commits mailing list