[Cryptech-Commits] [core/pkey/ed25519] 03/06: Double-and-add point multiplication framework

git at cryptech.is git at cryptech.is
Mon Sep 24 22:28:19 UTC 2018


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

meisterpaul1 at yandex.ru pushed a commit to branch master
in repository core/pkey/ed25519.

commit 0770d120f20bab87df10df989790d9157afa91a2
Author: Pavel V. Shatov (Meister) <meisterpaul1 at yandex.ru>
AuthorDate: Tue Sep 25 01:18:36 2018 +0300

    Double-and-add point multiplication framework
---
 rtl/ed25519_multiplier.v | 250 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 250 insertions(+)

diff --git a/rtl/ed25519_multiplier.v b/rtl/ed25519_multiplier.v
new file mode 100644
index 0000000..d6960ec
--- /dev/null
+++ b/rtl/ed25519_multiplier.v
@@ -0,0 +1,250 @@
+//------------------------------------------------------------------------------
+//
+// ed25519_multiplier.v
+// -----------------------------------------------------------------------------
+// Ed25519 base point scalar multiplier.
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2018, NORDUnet A/S
+//
+// 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.
+//
+//------------------------------------------------------------------------------
+
+module ed25519_multiplier
+(
+    clk, rst_n,
+    ena, rdy,
+    k_addr, qy_addr,
+    qy_wren,
+    k_din,
+    qy_dout
+);
+
+
+    //
+    // Microcode Header
+    //
+`include "ed25519_uop.v"
+    
+
+    //
+    // Ports
+    //
+    input           clk;        // system clock
+    input           rst_n;      // active-low async reset
+
+    input           ena;        // enable input
+    output          rdy;        // ready output
+
+    output  [ 2:0]  k_addr;     //
+    output  [ 2:0]  qy_addr;    //
+    output          qy_wren;    //
+    input   [31:0]  k_din;      //
+    output  [31:0]  qy_dout;    //
+
+
+    //
+    // FSM
+    //
+    localparam [3:0] FSM_STATE_IDLE                 = 4'd00;
+    localparam [3:0] FSM_STATE_PREPARE_TRIG         = 4'd01;
+    localparam [3:0] FSM_STATE_PREPARE_WAIT         = 4'd02;
+    localparam [3:0] FSM_STATE_BEFORE_ROUND_TRIG    = 4'd03;
+    localparam [3:0] FSM_STATE_BEFORE_ROUND_WAIT    = 4'd04;
+    localparam [3:0] FSM_STATE_DURING_ROUND_TRIG    = 4'd05;
+    localparam [3:0] FSM_STATE_DURING_ROUND_WAIT    = 4'd06;
+    localparam [3:0] FSM_STATE_AFTER_ROUND_TRIG     = 4'd07;
+    localparam [3:0] FSM_STATE_AFTER_ROUND_WAIT     = 4'd08;
+    localparam [3:0] FSM_STATE_DONE                 = 4'd15;
+
+    reg [3:0] fsm_state = FSM_STATE_IDLE;
+    reg [3:0] fsm_state_next;
+
+
+    //
+    // Round Counter
+    //
+    reg  [7:0] bit_counter;
+    wire [7:0] bit_counter_max  = 8'hFF;    // 255
+    wire [7:0] bit_counter_zero = 8'h00;    // 0
+    wire [7:0] bit_counter_next =
+        (bit_counter < bit_counter_max) ? bit_counter + 1'b1 : bit_counter_zero;
+
+    assign k_addr = bit_counter[7:5];
+
+
+    //
+    // Worker Trigger Logic
+    //
+    reg  worker_trig = 1'b0;
+    wire worker_done;
+
+    wire fsm_wait_done = !worker_trig && worker_done;
+
+    always @(posedge clk or negedge rst_n)
+        //
+        if (rst_n == 1'b0)                  worker_trig <= 1'b0;
+        else case (fsm_state)
+            FSM_STATE_PREPARE_TRIG,
+            FSM_STATE_BEFORE_ROUND_TRIG,
+            FSM_STATE_DURING_ROUND_TRIG,
+            FSM_STATE_AFTER_ROUND_TRIG:     worker_trig <= 1'b1;
+            default:                        worker_trig <= 1'b0;
+        endcase
+        
+        
+    //
+    // Round Counter Increment Logic
+    //
+    always @(posedge clk)
+        //
+        case (fsm_state_next)
+            FSM_STATE_PREPARE_TRIG:         bit_counter <= bit_counter_zero;
+            FSM_STATE_AFTER_ROUND_TRIG:     bit_counter <= bit_counter_next;
+        endcase
+
+
+    //
+    // Final Round Detection Logic
+    //
+    wire [ 3: 0] fsm_state_after_round = (bit_counter != bit_counter_zero) ?
+        FSM_STATE_BEFORE_ROUND_TRIG : FSM_STATE_DONE;
+
+
+  
+
+    //
+    // K Latch
+    //
+    reg [31:0] k_din_shreg;
+    
+    wire [4:0] k_bit_index = bit_counter[4:0];
+    
+    always @(posedge clk)
+        //
+        if (fsm_state_next == FSM_STATE_BEFORE_ROUND_TRIG)
+            //
+            if (k_bit_index == 5'd0)
+                //
+                case (k_addr)
+                    3'd0:       k_din_shreg <= {k_din[31:3], 3'b000};
+                    3'd7:       k_din_shreg <= {2'b01, k_din[29:0]};
+                    default:    k_din_shreg <= k_din;
+                endcase
+                //
+            else                k_din_shreg <= {k_din_shreg[0], k_din_shreg[31:1]};
+    
+
+    //
+    // Worker Offset Logic
+    //
+    reg [UOP_ADDR_WIDTH-1:0] worker_offset;
+    
+    always @(posedge clk)
+        //
+        case (fsm_state)
+            FSM_STATE_PREPARE_TRIG:         worker_offset <= UOP_OFFSET_PREPARE;
+            FSM_STATE_BEFORE_ROUND_TRIG:    worker_offset <= k_din_shreg[0] ? UOP_OFFSET_BEFORE_ROUND_K1 : UOP_OFFSET_BEFORE_ROUND_K0;
+            default:                        worker_offset <= {UOP_ADDR_WIDTH{1'bX}};
+        endcase
+        
+    
+    //
+    // FSM Process
+    //
+    always @(posedge clk or negedge rst_n)
+        //
+        if (rst_n == 1'b0)  fsm_state <= FSM_STATE_IDLE;
+        else                fsm_state <= fsm_state_next;
+
+
+    //
+    // FSM Transition Logic
+    //
+    always @* begin
+        //
+        fsm_state_next = FSM_STATE_IDLE;
+        //
+        case (fsm_state)
+
+            FSM_STATE_IDLE:                 fsm_state_next = ena ? FSM_STATE_PREPARE_TRIG : FSM_STATE_IDLE;
+
+            FSM_STATE_PREPARE_TRIG:         fsm_state_next = FSM_STATE_PREPARE_WAIT;
+            FSM_STATE_PREPARE_WAIT:         fsm_state_next = fsm_wait_done ? FSM_STATE_BEFORE_ROUND_TRIG : FSM_STATE_PREPARE_WAIT;
+
+            FSM_STATE_BEFORE_ROUND_TRIG:    fsm_state_next = FSM_STATE_BEFORE_ROUND_WAIT;
+            FSM_STATE_BEFORE_ROUND_WAIT:    fsm_state_next = fsm_wait_done ? FSM_STATE_DURING_ROUND_TRIG : FSM_STATE_BEFORE_ROUND_WAIT;
+
+            FSM_STATE_DURING_ROUND_TRIG:    fsm_state_next = FSM_STATE_DURING_ROUND_WAIT;
+            FSM_STATE_DURING_ROUND_WAIT:    fsm_state_next = fsm_wait_done ? FSM_STATE_AFTER_ROUND_TRIG : FSM_STATE_DURING_ROUND_WAIT;
+
+            FSM_STATE_AFTER_ROUND_TRIG:     fsm_state_next = FSM_STATE_AFTER_ROUND_WAIT;
+            FSM_STATE_AFTER_ROUND_WAIT:     fsm_state_next = fsm_wait_done ? fsm_state_after_round : FSM_STATE_AFTER_ROUND_WAIT;
+
+            FSM_STATE_DONE:                 fsm_state_next = FSM_STATE_IDLE;
+
+        endcase
+        //
+    end
+
+
+    //
+    // Worker
+    //
+    ed25519_worker uop_worker
+    (
+        .clk        (clk),
+        .rst_n      (rst_n),
+        .ena        (worker_trig),
+        .rdy        (worker_done),
+        .uop_offset (worker_offset)
+    );
+
+
+    //
+    // Ready Flag Logic
+    //
+    reg rdy_reg = 1'b1;
+    assign rdy = rdy_reg;
+
+    always @(posedge clk or negedge rst_n)
+        //
+        if (rst_n == 1'b0)              rdy_reg <= 1'b1;
+        else case (fsm_state)
+            FSM_STATE_IDLE: if (ena)    rdy_reg <= 1'b0;
+            FSM_STATE_DONE:             rdy_reg <= 1'b1;
+        endcase
+
+
+endmodule
+
+
+//------------------------------------------------------------------------------
+// End-of-File
+//------------------------------------------------------------------------------



More information about the Commits mailing list