[Cryptech-Commits] [core/pkey/ecdsa256] 03/04: Various clean-ups

git at cryptech.is git at cryptech.is
Wed Mar 8 03:14:51 UTC 2017


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

sra at hactrn.net pushed a commit to branch master
in repository core/pkey/ecdsa256.

commit 9fa6e368879d30835880b3bb0e87c8cf13dd9874
Author: Pavel V. Shatov (Meister) <meisterpaul1 at yandex.ru>
AuthorDate: Sun Feb 12 22:21:57 2017 +0300

    Various clean-ups
    
     * Added sample C program for STM32 to test the core in hardware
     * Parametrized math modules are now instantiated with explicit
       operand width for clarify (previously relied on default
       parameter values in underlying modules)
     * Fixed some comments
---
 bench/tb_modular_multiplier_256.v     | 340 ++++++++++++++++----------------
 rtl/curve/curve_dbl_add_256.v         |  12 +-
 rtl/modular/modular_multiplier_256.v  |  30 +--
 rtl/modular/modular_reductor_256.v    | 352 ++++++++++++++++++----------------
 stm32_driver/ecdsa256_driver_sample.c | 173 +++++++++++++++++
 stm32_driver/ecdsa_model.h            | 204 ++++++++++++++++++++
 6 files changed, 760 insertions(+), 351 deletions(-)

diff --git a/bench/tb_modular_multiplier_256.v b/bench/tb_modular_multiplier_256.v
index 3f62767..5277c20 100644
--- a/bench/tb_modular_multiplier_256.v
+++ b/bench/tb_modular_multiplier_256.v
@@ -38,59 +38,59 @@
 
 //------------------------------------------------------------------------------
 `timescale 1ns / 1ps
-//------------------------------------------------------------------------------
-
-module tb_modular_multiplier_256;
-
-
-		//
-		// Test Vectors
-		//	
-	localparam	[255:0]	N		= 256'hffffffff00000001000000000000000000000000ffffffffffffffffffffffff;
-	
-	localparam	[255:0]	X_1	= 256'h6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296;
-	localparam	[255:0]	Y_1	= 256'h4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5;
-	localparam	[255:0]	P_1	= 256'h823cd15f6dd3c71933565064513a6b2bd183e554c6a08622f713ebbbface98be;
-	
-	localparam	[255:0]	X_2	= 256'h29d05c193da77b710e86323538b77e1b11f904fea42998be16bd8d744ece7ad0;
-	localparam	[255:0]	Y_2	= 256'hb01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae07;
-	localparam	[255:0]	P_2	= 256'h76b2571d1d009ab0e7d1cc086c7d3648f08755b2e2585e780d11f053b06fb6ec;
-	
-	localparam	[255:0]	X_3	= 256'h8101ece47464a6ead70cf69a6e2bd3d88691a3262d22cba4f7635eaff26680a8;
-	localparam	[255:0]	Y_3	= 256'hd8a12ba61d599235f67d9cb4d58f1783d3ca43e78f0a5abaa624079936c0c3a9;
-	localparam	[255:0]	P_3	= 256'h944fea6a4fac7ae475a6bb211db4bbd394bd9b3ee9a038f6c17125a00b3a5375;
-	
-	localparam	[255:0]	X_4	= 256'h7214bc9647160bbd39ff2f80533f5dc6ddd70ddf86bb815661e805d5d4e6f27c;
-	localparam	[255:0]	Y_4	= 256'h8b81e3e977597110c7cf2633435b2294b72642987defd3d4007e1cfc5df84541;
-	localparam	[255:0]	P_4	= 256'h78d3e33c81ab9c652679363c76df004ea6f9a9e3a242a0fb71a4e8fdf41ab519;
-	
-	
+//------------------------------------------------------------------------------
+
+module tb_modular_multiplier_256;
+
+
+		//
+		// Test Vectors
+		//	
+	localparam	[255:0]	N		= 256'hffffffff00000001000000000000000000000000ffffffffffffffffffffffff;
+	
+	localparam	[255:0]	X_1	= 256'h6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296;
+	localparam	[255:0]	Y_1	= 256'h4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5;
+	localparam	[255:0]	P_1	= 256'h823cd15f6dd3c71933565064513a6b2bd183e554c6a08622f713ebbbface98be;
+	
+	localparam	[255:0]	X_2	= 256'h29d05c193da77b710e86323538b77e1b11f904fea42998be16bd8d744ece7ad0;
+	localparam	[255:0]	Y_2	= 256'hb01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae07;
+	localparam	[255:0]	P_2	= 256'h76b2571d1d009ab0e7d1cc086c7d3648f08755b2e2585e780d11f053b06fb6ec;
+	
+	localparam	[255:0]	X_3	= 256'h8101ece47464a6ead70cf69a6e2bd3d88691a3262d22cba4f7635eaff26680a8;
+	localparam	[255:0]	Y_3	= 256'hd8a12ba61d599235f67d9cb4d58f1783d3ca43e78f0a5abaa624079936c0c3a9;
+	localparam	[255:0]	P_3	= 256'h944fea6a4fac7ae475a6bb211db4bbd394bd9b3ee9a038f6c17125a00b3a5375;
+	
+	localparam	[255:0]	X_4	= 256'h7214bc9647160bbd39ff2f80533f5dc6ddd70ddf86bb815661e805d5d4e6f27c;
+	localparam	[255:0]	Y_4	= 256'h8b81e3e977597110c7cf2633435b2294b72642987defd3d4007e1cfc5df84541;
+	localparam	[255:0]	P_4	= 256'h78d3e33c81ab9c652679363c76df004ea6f9a9e3a242a0fb71a4e8fdf41ab519;
+	
+	
 		//
 		// Core Parameters
 		//
 	localparam	WORD_COUNTER_WIDTH	=  3;
-	localparam	OPERAND_NUM_WORDS		=  8;
-	
-
-		//
-		// Clock (100 MHz)
-		//
-	reg clk = 1'b0;
-	always #5 clk = ~clk;
-
-	
-		//
-		// Inputs, Outputs
-		//
-	reg	rst_n;
-	reg	ena;
-	wire	rdy;
-	
-	
+	localparam	OPERAND_NUM_WORDS		=  8;
+	
+
+		//
+		// Clock (100 MHz)
+		//
+	reg clk = 1'b0;
+	always #5 clk = ~clk;
+
+	
+		//
+		// Inputs, Outputs
+		//
+	reg	rst_n;
+	reg	ena;
+	wire	rdy;
+	
+	
 		//
 		// Buffers (X, Y, N, P)
 		//
-	wire	[WORD_COUNTER_WIDTH-1:0]	core_x_addr;
+	wire	[WORD_COUNTER_WIDTH-1:0]	core_x_addr;
 	wire	[WORD_COUNTER_WIDTH-1:0]	core_y_addr;
 	wire	[WORD_COUNTER_WIDTH-1:0]	core_n_addr;
 	wire	[WORD_COUNTER_WIDTH-1:0]	core_p_addr;
@@ -103,7 +103,7 @@ module tb_modular_multiplier_256;
 	wire	[                  31:0]	core_p_data;
 	
 	reg	[WORD_COUNTER_WIDTH-1:0]	tb_xyn_addr;
-	reg	[WORD_COUNTER_WIDTH-1:0]	tb_p_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	tb_p_addr;
 	
 	reg										tb_xyn_wren;
 	
@@ -182,94 +182,94 @@ module tb_modular_multiplier_256;
 
 		.b_addr	(tb_p_addr),
 		.b_out	(tb_p_data)
-	);
-	
-	
-		//
-		// UUT
-		//
-	modular_multiplier_256 uut
-	(
-		.clk		(clk),
-		.rst_n	(rst_n),
-		
-		.ena		(ena),
-		.rdy		(rdy),
-
-		.a_addr	(core_x_addr),
-		.b_addr	(core_y_addr),
-		.n_addr	(core_n_addr),
-		.p_addr	(core_p_addr),
-		.p_wren	(core_p_wren),
-		
-		.a_din	(core_x_data),
-		.b_din	(core_y_data),
-		.n_din	(core_n_data),
-		.p_dout	(core_p_data)
-	);
-
-		
-		//
-		// Testbench Routine
-		//
-	reg ok = 1;
-	initial begin
-		
-			/* initialize control inputs */
-		rst_n				= 0;
-		ena				= 0;
-		
-		tb_xyn_wren		= 0;
-		
-			/* wait for some time */
-		#200;
-		
-			/* de-assert reset */
-		rst_n				= 1;
-		
-			/* wait for some time */
-		#100;		
-		
-			/* run tests */
-		test_modular_multiplier(X_1, Y_1, N, P_1);
-		test_modular_multiplier(X_2, Y_2, N, P_2);
-		test_modular_multiplier(X_3, Y_3, N, P_3);
-		test_modular_multiplier(X_4, Y_4, N, P_4);
-		
-			/* print result */
+	);
+	
+	
+		//
+		// UUT
+		//
+	modular_multiplier_256 uut
+	(
+		.clk		(clk),
+		.rst_n	(rst_n),
+		
+		.ena		(ena),
+		.rdy		(rdy),
+
+		.a_addr	(core_x_addr),
+		.b_addr	(core_y_addr),
+		.n_addr	(core_n_addr),
+		.p_addr	(core_p_addr),
+		.p_wren	(core_p_wren),
+		
+		.a_din	(core_x_data),
+		.b_din	(core_y_data),
+		.n_din	(core_n_data),
+		.p_dout	(core_p_data)
+	);
+
+		
+		//
+		// Testbench Routine
+		//
+	reg ok = 1;
+	initial begin
+		
+			/* initialize control inputs */
+		rst_n				= 0;
+		ena				= 0;
+		
+		tb_xyn_wren		= 0;
+		
+			/* wait for some time */
+		#200;
+		
+			/* de-assert reset */
+		rst_n				= 1;
+		
+			/* wait for some time */
+		#100;		
+		
+			/* run tests */
+		test_modular_multiplier(X_1, Y_1, N, P_1);
+		test_modular_multiplier(X_2, Y_2, N, P_2);
+		test_modular_multiplier(X_3, Y_3, N, P_3);
+		test_modular_multiplier(X_4, Y_4, N, P_4);
+		
+			/* print result */
 		if (ok)	$display("tb_modular_multiplier_256: SUCCESS");
 		else		$display("tb_modular_multiplier_256: FAILURE");
 		//
 		//$finish;
-		//
-	end
-	
-	
-		//
-		// Test Task
-		//
-	reg	[255:0]	p;
-	reg				p_ok;
-	
-	integer			w;
-	
-	reg	[511:0]	pp_full;
-	reg	[255:0]	pp_ref;
-	
-	task test_modular_multiplier;
-	
-		input	[255:0] x;
-		input	[255:0] y;
-		input	[255:0] n;
-		input	[255:0] pp;
-		
+		//
+	end
+	
+	
+		//
+		// Test Task
+		//
+	reg	[255:0]	p;
+	reg				p_ok;
+	
+	integer			w;
+	
+	reg	[511:0]	pp_full;
+	reg	[255:0]	pp_ref;
+	
+	task test_modular_multiplier;
+	
+		input	[255:0] x;
+		input	[255:0] y;
+		input	[255:0] n;
+		input	[255:0] pp;
+		
 		reg	[255:0]	x_shreg;
 		reg	[255:0]	y_shreg;
 		reg	[255:0]	n_shreg;
-		reg	[255:0]	p_shreg;
-	
-		begin
-		
+		reg	[255:0]	p_shreg;
+	
+		begin
+		
 				/* start filling memories */
 			tb_xyn_wren	= 1;
 			
@@ -308,27 +308,27 @@ module tb_modular_multiplier_256;
 			tb_n_data	= {32{1'bX}};
 			
 				/* stop filling memories */
-			tb_xyn_wren	= 0;
-			
-				/* calculate reference value */
-			pp_full = {{256{1'b0}}, x} * {{256{1'b0}}, y};
-			pp_ref = pp_full % {{256{1'b0}}, n};
-			
-				/* compare reference value against hard-coded one */
-			if (pp_ref != pp) begin
-				$display("ERROR: pp_ref != pp");
-				$finish;
-			end
-			
-				/* start operation */
-			ena = 1;
-			
-				/* clear flag */
-			#10 ena = 0;
-			
-				/* wait for operation to complete */
-			while (!rdy) #10;
-			
+			tb_xyn_wren	= 0;
+			
+				/* calculate reference value */
+			pp_full = {{256{1'b0}}, x} * {{256{1'b0}}, y};
+			pp_ref = pp_full % {{256{1'b0}}, n};
+			
+				/* compare reference value against hard-coded one */
+			if (pp_ref != pp) begin
+				$display("ERROR: pp_ref != pp");
+				$finish;
+			end
+			
+				/* start operation */
+			ena = 1;
+			
+				/* clear flag */
+			#10 ena = 0;
+			
+				/* wait for operation to complete */
+			while (!rdy) #10;
+			
 				/* read result */
 			for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin
 				
@@ -341,26 +341,26 @@ module tb_modular_multiplier_256;
 					/* store data word */
 				p_shreg = {tb_p_data, p_shreg[255:32]};
 
-			end				
-			
-				/* compare */
-			p_ok = (p_shreg == pp);
-
-				/* display results */
-			$display("test_modular_multiplier(): %s", p_ok ? "OK" : "ERROR");
-			
-				/* update flag */
-			ok = ok && p_ok;
-		
-		end
-		
-	endtask
-	
-
-	
-      
-endmodule
-
+			end				
+			
+				/* compare */
+			p_ok = (p_shreg == pp);
+
+				/* display results */
+			$display("test_modular_multiplier_256(): %s", p_ok ? "OK" : "ERROR");
+			
+				/* update flag */
+			ok = ok && p_ok;
+		
+		end
+		
+	endtask
+	
+
+	
+      
+endmodule
+
 //------------------------------------------------------------------------------
 // End-of-File
-//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
diff --git a/rtl/curve/curve_dbl_add_256.v b/rtl/curve/curve_dbl_add_256.v
index 08a9931..8ef505d 100644
--- a/rtl/curve/curve_dbl_add_256.v
+++ b/rtl/curve/curve_dbl_add_256.v
@@ -1,8 +1,8 @@
 //------------------------------------------------------------------------------
 //
-// curve_adder_256.v
+// curve_dbl_add_256.v
 // -----------------------------------------------------------------------------
-// Elliptic curve point adder.
+// Elliptic curve point adder and doubler.
 //
 // Authors: Pavel Shatov
 //
@@ -292,7 +292,13 @@ module curve_dbl_add_256
 	wire	[                32-1:0]	mw_mov_din_x;
 	wire	[                32-1:0]	mw_mov_dout_y;
 	
-	mw_mover mw_mover_inst
+	mw_mover #
+	(
+		.WORD_COUNTER_WIDTH	(WORD_COUNTER_WIDTH),
+		.OPERAND_NUM_WORDS	(OPERAND_NUM_WORDS)
+
+	)
+	mw_mover_inst
 	(
 		.clk		(clk),
 		.rst_n	(rst_n),
diff --git a/rtl/modular/modular_multiplier_256.v b/rtl/modular/modular_multiplier_256.v
index 8487aee..c2f2661 100644
--- a/rtl/modular/modular_multiplier_256.v
+++ b/rtl/modular/modular_multiplier_256.v
@@ -293,8 +293,8 @@ module modular_multiplier_256
 		//
 		// Accumulators
 		//
-	wire	[46: 0]	add48_cw0_s;
-	wire	[46: 0]	add48_cw1_s;
+	wire	[46: 0]	add47_cw0_s;
+	wire	[46: 0]	add47_cw1_s;
 	
 	
 		//
@@ -314,26 +314,26 @@ module modular_multiplier_256
 		//
 		si_next_dly <= si_lsb[62:47];
 	
-	wire	[46: 0]	add48_cw0_a = si_lsb[46:0];
-	wire	[46: 0]	add48_cw0_b = {{16{1'b0}}, si_prev_dly};
+	wire	[46: 0]	add47_cw0_a = si_lsb[46:0];
+	wire	[46: 0]	add47_cw0_b = {{16{1'b0}}, si_prev_dly};
 	
-	wire	[46: 0]	add48_cw1_a = add48_cw0_s;
-	wire	[46: 0]	add48_cw1_b = {{15{1'b0}}, si_next_dly, mask_cw1_sum ? {16{1'b0}} : {1'b0, add48_cw1_s[46:32]}};	
+	wire	[46: 0]	add47_cw1_a = add47_cw0_s;
+	wire	[46: 0]	add47_cw1_b = {{15{1'b0}}, si_next_dly, mask_cw1_sum ? {16{1'b0}} : {1'b0, add47_cw1_s[46:32]}};	
 	
-	adder47_wrapper add48_cw0_inst
+	adder47_wrapper add47_cw0_inst
 	(
 		.clk	(clk),
-		.a		(add48_cw0_a),
-		.b		(add48_cw0_b),
-		.s		(add48_cw0_s)
+		.a		(add47_cw0_a),
+		.b		(add47_cw0_b),
+		.s		(add47_cw0_s)
 	);
 	
-	adder47_wrapper add48_cw1_inst
+	adder47_wrapper add47_cw1_inst
 	(
 		.clk	(clk),
-		.a		(add48_cw1_a),
-		.b		(add48_cw1_b),
-		.s		(add48_cw1_s)
+		.a		(add47_cw1_a),
+		.b		(add47_cw1_b),
+		.s		(add47_cw1_s)
 	);
 	
 	
@@ -364,7 +364,7 @@ module modular_multiplier_256
 
 		.a_addr	(bram_c_addr),
 		.a_wr		(store_c_word),
-		.a_in		(add48_cw1_s[31:0]),
+		.a_in		(add47_cw1_s[31:0]),
 		.a_out	(),
 
 		.b_addr	(reduce_c_addr),
diff --git a/rtl/modular/modular_reductor_256.v b/rtl/modular/modular_reductor_256.v
index 774f42e..e4b346a 100644
--- a/rtl/modular/modular_reductor_256.v
+++ b/rtl/modular/modular_reductor_256.v
@@ -1,39 +1,39 @@
-//------------------------------------------------------------------------------
-//
-// modular_reductor_256.v
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//
+// modular_reductor_256.v
+// -----------------------------------------------------------------------------
 // Modular reductor.
-//
-// Authors: Pavel Shatov
-//
-// Copyright (c) 2015-2016, 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.
-//
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2015-2016, 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 modular_reductor_256
@@ -44,62 +44,62 @@ module modular_reductor_256
 		x_din, n_din, p_dout
 	);
 		
-		//
-		// Constants
-		//
+		//
+		// Constants
+		//
 	localparam	OPERAND_NUM_WORDS		= 8;
 	localparam	WORD_COUNTER_WIDTH	= 3;
 	
 	
-		//
-		// Handy Numbers
-		//
-	localparam	[WORD_COUNTER_WIDTH:0]	WORD_INDEX_ZERO	= 0;
+		//
+		// Handy Numbers
+		//
+	localparam	[WORD_COUNTER_WIDTH:0]	WORD_INDEX_ZERO	= 0;
 	localparam	[WORD_COUNTER_WIDTH:0]	WORD_INDEX_LAST	= 2 * OPERAND_NUM_WORDS - 1;
 	
 	
-		//
-		// Handy Functions
-		//
-	function	[WORD_COUNTER_WIDTH:0]	WORD_INDEX_PREVIOUS_OR_LAST;
-		input	[WORD_COUNTER_WIDTH:0]	WORD_INDEX_CURRENT;
-		begin
-			WORD_INDEX_PREVIOUS_OR_LAST = (WORD_INDEX_CURRENT > WORD_INDEX_ZERO) ?
-				WORD_INDEX_CURRENT - 1'b1 : WORD_INDEX_LAST;
-		end
+		//
+		// Handy Functions
+		//
+	function	[WORD_COUNTER_WIDTH:0]	WORD_INDEX_PREVIOUS_OR_LAST;
+		input	[WORD_COUNTER_WIDTH:0]	WORD_INDEX_CURRENT;
+		begin
+			WORD_INDEX_PREVIOUS_OR_LAST = (WORD_INDEX_CURRENT > WORD_INDEX_ZERO) ?
+				WORD_INDEX_CURRENT - 1'b1 : WORD_INDEX_LAST;
+		end
 	endfunction
 	
 	
 		//
 		// Ports
-		//
+		//
 	input		wire										clk;		// system clock
-	input		wire										rst_n;	// active-low async reset
-	
-	input		wire										ena;		// enable input
+	input		wire										rst_n;	// active-low async reset
+	
+	input		wire										ena;		// enable input
 	output	wire										rdy;		// ready output
-	
-	output	wire	[WORD_COUNTER_WIDTH-0:0]	x_addr;	// index of current X word
-	output	wire	[WORD_COUNTER_WIDTH-1:0]	n_addr;	// index of current N word
-	output	wire	[WORD_COUNTER_WIDTH-1:0]	p_addr;	// index of current P word
+	
+	output	wire	[WORD_COUNTER_WIDTH-0:0]	x_addr;	// index of current X word
+	output	wire	[WORD_COUNTER_WIDTH-1:0]	n_addr;	// index of current N word
+	output	wire	[WORD_COUNTER_WIDTH-1:0]	p_addr;	// index of current P word
 	output	wire										p_wren;	// store current P word now	
-	
+	
 	input		wire	[                  31:0]	x_din;	// X
 	input		wire	[                  31:0]	n_din;	// N (must be P-256!)
 	output	wire	[                  31:0]	p_dout;	// P = X mod N
 	
 	
-		//
-		// Word Indices
-		//
+		//
+		// Word Indices
+		//
 	reg	[WORD_COUNTER_WIDTH:0]	index_x;
-	
-		
-		/* map registers to output ports */
+	
+		
+		/* map registers to output ports */
 	assign x_addr	= index_x;
 	
-	
-		//
+	
+		//
 		// FSM
 		//
 	localparam	FSM_SHREG_WIDTH	= (2 * OPERAND_NUM_WORDS + 1) + (5 * 2) + 1;
@@ -136,34 +136,34 @@ module modular_reductor_256
 	
 	wire	reduce_done_all = reduce_adder0_done & reduce_adder1_done & reduce_subtractor_done;
 	
-	always @(posedge clk or negedge rst_n)
-		//
-		if (rst_n == 1'b0)
-			//
-			fsm_shreg <= {{FSM_SHREG_WIDTH-1{1'b0}}, 1'b1};
-			//
-		else begin
-			//
+	always @(posedge clk or negedge rst_n)
+		//
+		if (rst_n == 1'b0)
+			//
+			fsm_shreg <= {{FSM_SHREG_WIDTH-1{1'b0}}, 1'b1};
+			//
+		else begin
+			//
 			if (rdy)
 				//
 				fsm_shreg <= {ena, {FSM_SHREG_WIDTH-2{1'b0}}, ~ena};
-			//
+			//
 			else if (!reduce_stop || reduce_done_all)
 				//
-				fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]};
-			//
+				fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]};
+			//
 		end
 	
 		
-		//
-		// Word Index Increment Logic
-		//
-	always @(posedge clk)
-		//
-		if (rdy)
-			//
-			index_x <= WORD_INDEX_LAST;
-			//
+		//
+		// Word Index Increment Logic
+		//
+	always @(posedge clk)
+		//
+		if (rdy)
+			//
+			index_x <= WORD_INDEX_LAST;
+			//
 		else if (inc_index_x)
 			//
 			index_x	<= WORD_INDEX_PREVIOUS_OR_LAST(index_x);
@@ -173,14 +173,27 @@ module modular_reductor_256
 		// Look-up Table
 		//
 		
-		// TODO: Explain s5!!!
+		//
+		// Take a look at the corresponding C model for more information
+		// on how exactly the math behind reduction works. The first step
+		// is to assemble nine 256-bit values ("z-words") from 32-bit parts
+		// of the full 512-bit product ("c-word"). The problem with z5 is
+		// that it contains c13 two times. This implementation scans from
+		// c15 to c0 and writes current part of c-word into corresponding
+		// parts of z-words. Since those 32-bit parts are stored in block
+		// memories, one source word can only be written to one location in
+		// every z-word at a time. The trick is to delay c13 and then write
+		// the delayed value at the corresponding location in z5 instead of
+		// the next c12. "z_save" flag is used to indicate that the current
+		// word should be delayed and written once again during the next cycle.
+		//
 		
 	reg	[9*WORD_COUNTER_WIDTH-1:0]	z_addr;	//
 	reg	[9                   -1:0]	z_wren;	//
 	reg	[9                   -1:0]	z_mask;	// mask input to store zero word
 	reg	[9                   -1:0]	z_save;	// save previous word once again
 	
-	always @(posedge clk)
+	always @(posedge clk)
 		//
 		if (inc_index_x)
 			//
@@ -204,9 +217,9 @@ module modular_reductor_256
 				4'd13:	z_addr <= {3'd07, 3'd00, 3'd01, 3'd02, 3'd03, 3'd05, 3'd04, 3'd05, 3'dxx};
 				4'd14:	z_addr <= {3'd00, 3'd01, 3'd02, 3'd04, 3'd04, 3'd06, 3'd05, 3'd06, 3'dxx};
 				4'd15:	z_addr <= {3'd01, 3'd02, 3'd03, 3'd05, 3'd05, 3'd07, 3'd06, 3'd07, 3'dxx};
-				//
+				//
             default:	z_addr <= {9*WORD_COUNTER_WIDTH{1'bX}};
-				//
+				//
          endcase
 	
 	always @(posedge clk)
@@ -231,9 +244,9 @@ module modular_reductor_256
 			4'd13:	z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
 			4'd14:	z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
 			4'd15:	z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
-			//
+			//
 			default:	z_wren <= {9{1'b0}};
-			//
+			//
 		endcase
 		
 	always @(posedge clk)
@@ -260,11 +273,11 @@ module modular_reductor_256
 				4'd13:	z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0};
 				4'd14:	z_mask <= {1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
 				4'd15:	z_mask <= {1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
-				//
+				//
             default:	z_mask <= {9{1'bX}};
-				//
+				//
          endcase
-			
+			
 	always @(posedge clk)
 		//
 		if (inc_index_x)
@@ -289,9 +302,9 @@ module modular_reductor_256
 				4'd13:	z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
 				4'd14:	z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
 				4'd15:	z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
-				//
+				//
             default:	z_save <= {9{1'bX}};
-				//
+				//
          endcase
 		
 		
@@ -312,18 +325,18 @@ module modular_reductor_256
 		//
 		begin : gen_z_bram
 			//
-			bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
-			bram_c_inst
-			(
-				.clk		(clk),
-
-				.a_addr	(z_addr[(z-1) * WORD_COUNTER_WIDTH +: WORD_COUNTER_WIDTH]),
-				.a_wr		(z_wren[z-1] & store_word_z),
-				.a_in		(z_mask[z-1] ? {32{1'b0}} : (z_save[z-1] ? x_din_dly : x_din)),
-				.a_out	(),
-
-				.b_addr	(reduce_z_addr[z]),
-				.b_out	(reduce_z_dout[z])
+			bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
+			bram_c_inst
+			(
+				.clk		(clk),
+
+				.a_addr	(z_addr[(z-1) * WORD_COUNTER_WIDTH +: WORD_COUNTER_WIDTH]),
+				.a_wr		(z_wren[z-1] & store_word_z),
+				.a_in		(z_mask[z-1] ? {32{1'b0}} : (z_save[z-1] ? x_din_dly : x_din)),
+				.a_out	(),
+
+				.b_addr	(reduce_z_addr[z]),
+				.b_out	(reduce_z_dout[z])
 			);
 			//
 		end
@@ -355,50 +368,49 @@ module modular_reductor_256
 	reg	[WORD_COUNTER_WIDTH-1:0]	bram_diff_rd_addr;
 
 	
-	bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
-	bram_sum0_inst
-	(
-		.clk		(clk),
-
-		.a_addr	(bram_sum0_wr_addr),
-		.a_wr		(bram_sum0_wr_wren),
-		.a_in		(bram_sum0_wr_din),
-		.a_out	(),
-
-		.b_addr	(bram_sum0_rd_addr),
-		.b_out	(bram_sum0_rd_dout)
+	bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
+	bram_sum0_inst
+	(
+		.clk		(clk),
+
+		.a_addr	(bram_sum0_wr_addr),
+		.a_wr		(bram_sum0_wr_wren),
+		.a_in		(bram_sum0_wr_din),
+		.a_out	(),
+
+		.b_addr	(bram_sum0_rd_addr),
+		.b_out	(bram_sum0_rd_dout)
 	);
 	
-	bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
-	bram_sum1_inst
-	(
-		.clk		(clk),
-
-		.a_addr	(bram_sum1_wr_addr),
-		.a_wr		(bram_sum1_wr_wren),
-		.a_in		(bram_sum1_wr_din),
-		.a_out	(),
-
-		.b_addr	(bram_sum1_rd_addr),
-		.b_out	(bram_sum1_rd_dout)
+	bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
+	bram_sum1_inst
+	(
+		.clk		(clk),
+
+		.a_addr	(bram_sum1_wr_addr),
+		.a_wr		(bram_sum1_wr_wren),
+		.a_in		(bram_sum1_wr_din),
+		.a_out	(),
+
+		.b_addr	(bram_sum1_rd_addr),
+		.b_out	(bram_sum1_rd_dout)
 	);
 	
-	bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
-	bram_diff_inst
-	(
-		.clk		(clk),
-
-		.a_addr	(bram_diff_wr_addr),
-		.a_wr		(bram_diff_wr_wren),
-		.a_in		(bram_diff_wr_din),
-		.a_out	(),
-
-		.b_addr	(bram_diff_rd_addr),
-		.b_out	(bram_diff_rd_dout)
+	bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
+	bram_diff_inst
+	(
+		.clk		(clk),
+
+		.a_addr	(bram_diff_wr_addr),
+		.a_wr		(bram_diff_wr_wren),
+		.a_in		(bram_diff_wr_din),
+		.a_out	(),
+
+		.b_addr	(bram_diff_rd_addr),
+		.b_out	(bram_diff_rd_dout)
 	);
 	
 	
-	
 	wire	[WORD_COUNTER_WIDTH-1:0]	adder0_ab_addr;
 	wire	[WORD_COUNTER_WIDTH-1:0]	adder1_ab_addr;
 	wire	[WORD_COUNTER_WIDTH-1:0]	subtractor_ab_addr;
@@ -414,7 +426,12 @@ module modular_reductor_256
 	
 	// n_addr - only 1 output, because all modules are in sync
 	
-	modular_adder adder_inst0
+	modular_adder #
+	(
+		.OPERAND_NUM_WORDS	(OPERAND_NUM_WORDS),
+		.WORD_COUNTER_WIDTH	(WORD_COUNTER_WIDTH)
+	)
+	adder_inst0
 	(
 		.clk			(clk),
 		.rst_n		(rst_n),
@@ -426,14 +443,19 @@ module modular_reductor_256
 		.n_addr		(),
 		.s_addr		(bram_sum0_wr_addr),
 		.s_wren		(bram_sum0_wr_wren),
-		
+		
 		.a_din		(adder0_a_din),
 		.b_din		(adder0_b_din),
 		.n_din		(n_din),
 		.s_dout		(bram_sum0_wr_din)
 	);
 	
-	modular_adder adder_inst1
+	modular_adder #
+	(
+		.OPERAND_NUM_WORDS	(OPERAND_NUM_WORDS),
+		.WORD_COUNTER_WIDTH	(WORD_COUNTER_WIDTH)
+	)
+	adder_inst1
 	(
 		.clk			(clk),
 		.rst_n		(rst_n),
@@ -445,14 +467,19 @@ module modular_reductor_256
 		.n_addr		(),
 		.s_addr		(bram_sum1_wr_addr),
 		.s_wren		(bram_sum1_wr_wren),
-		
+		
 		.a_din		(adder1_a_din),
 		.b_din		(adder1_b_din),
 		.n_din		(n_din),
 		.s_dout		(bram_sum1_wr_din)
 	);
 	
-	modular_subtractor subtractor_inst
+	modular_subtractor #
+	(
+		.OPERAND_NUM_WORDS	(OPERAND_NUM_WORDS),
+		.WORD_COUNTER_WIDTH	(WORD_COUNTER_WIDTH)
+	)
+	subtractor_inst
 	(
 		.clk			(clk),
 		.rst_n		(rst_n),
@@ -464,7 +491,7 @@ module modular_reductor_256
 		.n_addr		(n_addr),
 		.d_addr		(bram_diff_wr_addr),
 		.d_wren		(bram_diff_wr_wren),
-		
+		
 		.a_din		(subtractor_a_din),
 		.b_din		(subtractor_b_din),
 		.n_din		(n_din),
@@ -473,7 +500,7 @@ module modular_reductor_256
 	
 	
 		//
-		// address
+		// Address (Operand) Selector
 		//
 	always @(*)
 		//
@@ -572,7 +599,6 @@ module modular_reductor_256
 		endcase
 
 	
-	
 		//
 		// adder 0
 		//
@@ -650,17 +676,17 @@ module modular_reductor_256
 	end
 
 
-
-
-	assign p_addr	= bram_sum0_wr_addr;
+		//
+		// Address Mapping
+		//
+	assign p_addr	= bram_sum0_wr_addr;
 	assign p_wren	= bram_sum0_wr_wren & store_p;
 	assign p_dout	= bram_sum0_wr_din;
-	
-	
+		
 		
 endmodule
 
 
-//------------------------------------------------------------------------------
-// End-of-File
+//------------------------------------------------------------------------------
+// End-of-File
 //------------------------------------------------------------------------------
diff --git a/stm32_driver/ecdsa256_driver_sample.c b/stm32_driver/ecdsa256_driver_sample.c
new file mode 100644
index 0000000..cef4af0
--- /dev/null
+++ b/stm32_driver/ecdsa256_driver_sample.c
@@ -0,0 +1,173 @@
+		//
+		// simple driver to test "ecdsa384" core in hardware
+		//
+		
+		//
+		// note, that the test program needs a custom bitstream where
+		// the core is located at offset 0 (without the core selector)
+		//
+
+		// stm32 headers
+#include "stm-init.h"
+#include "stm-led.h"
+#include "stm-fmc.h"
+
+		// locations of core registers
+#define CORE_ADDR_NAME0					(0x00 << 2)
+#define CORE_ADDR_NAME1					(0x01 << 2)
+#define CORE_ADDR_VERSION				(0x02 << 2)
+#define CORE_ADDR_CONTROL				(0x08 << 2)
+#define CORE_ADDR_STATUS				(0x09 << 2)
+
+		// locations of data buffers
+#define CORE_ADDR_BUF_K					(0x20 << 2)
+#define CORE_ADDR_BUF_X					(0x28 << 2)
+#define CORE_ADDR_BUF_Y					(0x30 << 2)
+
+		// bit maps
+#define CORE_CONTROL_BIT_NEXT		0x00000002
+#define CORE_STATUS_BIT_READY		0x00000002
+
+		// curve selection
+#define USE_CURVE								1
+
+#include "ecdsa_model.h"
+
+#define BUF_NUM_WORDS		(OPERAND_WIDTH / (sizeof(uint32_t) << 3))	// 8
+
+		//
+		// test vectors
+		//
+static const uint32_t p256_d[BUF_NUM_WORDS]  = ECDSA_D;
+static const uint32_t p256_qx[BUF_NUM_WORDS] = ECDSA_Q_X;
+static const uint32_t p256_qy[BUF_NUM_WORDS] = ECDSA_Q_Y;
+
+static const uint32_t p256_k[BUF_NUM_WORDS]  = ECDSA_K;
+static const uint32_t p256_rx[BUF_NUM_WORDS] = ECDSA_R_X;
+static const uint32_t p256_ry[BUF_NUM_WORDS] = ECDSA_R_Y;
+
+static const uint32_t p256_i[BUF_NUM_WORDS]  = ECDSA_ONE;
+static const uint32_t p256_gx[BUF_NUM_WORDS] = ECDSA_G_X;
+static const uint32_t p256_gy[BUF_NUM_WORDS] = ECDSA_G_Y;
+
+static const uint32_t p256_z[BUF_NUM_WORDS]  = ECDSA_ZERO;
+static const uint32_t p256_n[BUF_NUM_WORDS]  = ECDSA_N;
+
+		//
+		// prototypes
+		//
+void toggle_yellow_led(void);
+int test_p256_multiplier(const uint32_t *k, const uint32_t *px, const uint32_t *py);
+
+		//
+		// test routine
+		//
+int main()
+{
+		int ok;
+	
+    stm_init();
+    fmc_init();
+	
+    led_on(LED_GREEN);
+    led_off(LED_RED);
+	
+    led_off(LED_YELLOW);
+    led_off(LED_BLUE);
+		
+		uint32_t core_name0;
+		uint32_t core_name1;
+	
+		fmc_read_32(CORE_ADDR_NAME0, &core_name0);
+		fmc_read_32(CORE_ADDR_NAME1, &core_name1);
+
+			// "ecds", "a256"
+		if ((core_name0 != 0x65636473) || (core_name1 != 0x61323536))
+		{
+				led_off(LED_GREEN);
+				led_on(LED_RED);
+				while (1);
+		}
+
+			// repeat forever
+		while (1)
+		{		
+				ok = 1;
+				ok = ok && test_p256_multiplier(p256_d, p256_qx, p256_qy);
+				ok = ok && test_p256_multiplier(p256_k, p256_rx, p256_ry);
+				ok = ok && test_p256_multiplier(p256_z, p256_z,  p256_z);
+				ok = ok && test_p256_multiplier(p256_i, p256_gx, p256_gy);
+				ok = ok && test_p256_multiplier(p256_n, p256_z,  p256_z);
+	
+				if (!ok)
+				{		led_off(LED_GREEN);
+						led_on(LED_RED);
+				}
+				
+				toggle_yellow_led();
+		}
+}
+
+	
+		//
+		// this routine uses the hardware multiplier to obtain Q(qx,qy), which is the
+		// scalar multiple of the base point, qx and qy are then compared to the values
+		// px and py (correct result known in advance)
+		//
+int test_p256_multiplier(const uint32_t *k, const uint32_t *px, const uint32_t *py)
+{
+		int i, num_cyc;
+		uint32_t reg_control, reg_status;
+		uint32_t k_word, qx_word, qy_word;
+	
+				// fill k
+		for (i=0; i<BUF_NUM_WORDS; i++)
+		{		k_word = k[i];
+				fmc_write_32(CORE_ADDR_BUF_K + ((BUF_NUM_WORDS - (i + 1)) * sizeof(uint32_t)), &k_word);
+		}
+
+				// clear 'next' control bit, then set 'next' control bit again to trigger new operation
+		reg_control = 0;
+		fmc_write_32(CORE_ADDR_CONTROL, &reg_control);
+		reg_control = CORE_CONTROL_BIT_NEXT;
+		fmc_write_32(CORE_ADDR_CONTROL, &reg_control);
+	
+				// wait for 'ready' status bit to be set
+		num_cyc = 0;
+		do
+		{		num_cyc++;
+				fmc_read_32(CORE_ADDR_STATUS, &reg_status);
+		}
+		while (!(reg_status & CORE_STATUS_BIT_READY));
+	
+				// read back x and y word-by-word, then compare to the reference values
+		for (i=0; i<BUF_NUM_WORDS; i++)
+		{		
+				fmc_read_32(CORE_ADDR_BUF_X + (i * sizeof(uint32_t)), &qx_word);
+				fmc_read_32(CORE_ADDR_BUF_Y + (i * sizeof(uint32_t)), &qy_word);
+			
+				if ((qx_word != px[BUF_NUM_WORDS - (i + 1)])) return 0;
+				if ((qy_word != py[BUF_NUM_WORDS - (i + 1)])) return 0;
+		}
+	
+				// everything went just fine
+		return 1;
+}
+
+		//
+		// toggle the yellow led to indicate that we're not stuck somewhere
+		//
+void toggle_yellow_led(void)
+{
+		static int led_state = 0;
+	
+		led_state = !led_state;
+	
+		if (led_state) led_on(LED_YELLOW);
+		else           led_off(LED_YELLOW);
+}
+
+
+		//
+		// end of file
+		//
diff --git a/stm32_driver/ecdsa_model.h b/stm32_driver/ecdsa_model.h
new file mode 100644
index 0000000..44ab59f
--- /dev/null
+++ b/stm32_driver/ecdsa_model.h
@@ -0,0 +1,204 @@
+//------------------------------------------------------------------------------
+//
+// ecdsa_model.h
+// --------------------------------------------
+// Base point scalar multiplier model for ECDSA
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2015-2016, 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.
+//
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+//
+// Curve Selection
+//
+// USE_CURVE == 1  -> P-256
+// USE_CURVE == 2  -> P-384
+//
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+// Model Parameters
+//------------------------------------------------------------------------------
+#if USE_CURVE == 1
+#define OPERAND_WIDTH	(256)	// largest supported operand width in bits
+#elif USE_CURVE == 2
+#define OPERAND_WIDTH	(384)	// largest supported operand width in bits
+#else
+#error USE_CURVE must be either 1 or 2!
+#endif
+
+
+//------------------------------------------------------------------------------
+// P-256 Parameters and Test Vectors
+//------------------------------------------------------------------------------
+
+/* Field Size */
+#define P_256_Q			{0xffffffff, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff}
+
+/* Generic Numbers */
+#define P_256_ZERO		{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}
+#define P_256_ONE		{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001}
+
+/* Division Factor  */
+#define P_256_DELTA		{0x7fffffff, 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x80000000, 0x00000000, 0x00000000}
+
+/* Base Point */
+#define P_256_G_X		{0x6b17d1f2, 0xe12c4247, 0xf8bce6e5, 0x63a440f2, 0x77037d81, 0x2deb33a0, 0xf4a13945, 0xd898c296}
+#define P_256_G_Y		{0x4fe342e2, 0xfe1a7f9b, 0x8ee7eb4a, 0x7c0f9e16, 0x2bce3357, 0x6b315ece, 0xcbb64068, 0x37bf51f5}
+
+/* Doubled Base Point */
+#define P_256_H_X		{0x29d05c19, 0x3da77b71, 0x0e863235, 0x38b77e1b, 0x11f904fe, 0xa42998be, 0x16bd8d74, 0x4ece7ad0}
+#define P_256_H_Y		{0xb01cbd1c, 0x01e58065, 0x711814b5, 0x83f061e9, 0xd431cca9, 0x94cea131, 0x3449bf97, 0xc840ae07}
+
+/* Base Point Order */
+#define P_256_N			{0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xbce6faad, 0xa7179e84, 0xf3b9cac2, 0xfc632551}
+
+/* Private Key */
+#define P_256_D			{0x70a12c2d, 0xb16845ed, 0x56ff68cf, 0xc21a472b, 0x3f04d7d6, 0x851bf634, 0x9f2d7d5b, 0x3452b38a}
+
+/* Per-message Random Number */
+#define P_256_K			{0x580ec00d, 0x85643433, 0x4cef3f71, 0xecaed496, 0x5b12ae37, 0xfa47055b, 0x1965c7b1, 0x34ee45d0}
+
+/* Public Key */
+#define P_256_Q_X		{0x8101ece4, 0x7464a6ea, 0xd70cf69a, 0x6e2bd3d8, 0x8691a326, 0x2d22cba4, 0xf7635eaf, 0xf26680a8}
+#define P_256_Q_Y		{0xd8a12ba6, 0x1d599235, 0xf67d9cb4, 0xd58f1783, 0xd3ca43e7, 0x8f0a5aba, 0xa6240799, 0x36c0c3a9}
+
+/* Part of Signature */
+#define P_256_R_X		{0x7214bc96, 0x47160bbd, 0x39ff2f80, 0x533f5dc6, 0xddd70ddf, 0x86bb8156, 0x61e805d5, 0xd4e6f27c}
+#define P_256_R_Y		{0x8b81e3e9, 0x77597110, 0xc7cf2633, 0x435b2294, 0xb7264298, 0x7defd3d4, 0x007e1cfc, 0x5df84541}
+
+
+//------------------------------------------------------------------------------
+// P-384 Parameters and Test Vectors
+//------------------------------------------------------------------------------
+
+/* Field Size */
+#define P_384_Q			{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff}
+
+/* Generic Numbers */
+#define P_384_ZERO		{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}
+#define P_384_ONE		{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001}
+
+/* Division Factor  */
+#define P_384_DELTA		{0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff, 0x80000000, 0x0000000, 0x080000000}
+
+/* Base Point */
+#define P_384_G_X		{0xaa87ca22, 0xbe8b0537, 0x8eb1c71e, 0xf320ad74, 0x6e1d3b62, 0x8ba79b98, 0x59f741e0, 0x82542a38, 0x5502f25d, 0xbf55296c, 0x3a545e38, 0x72760ab7}
+#define P_384_G_Y		{0x3617de4a, 0x96262c6f, 0x5d9e98bf, 0x9292dc29, 0xf8f41dbd, 0x289a147c, 0xe9da3113, 0xb5f0b8c0, 0x0a60b1ce, 0x1d7e819d, 0x7a431d7c, 0x90ea0e5f}
+
+/* Doubled Base Point */
+#define P_384_H_X		{0xaaf06bba, 0x82e9f590, 0xe29c71c2, 0x19bea517, 0x23c5893a, 0xe8b0c8cf, 0x4c117c3e, 0xfb57ab8d, 0x55fa1b42, 0x8155ad27, 0x8b574391, 0x1b13ea8a}
+#define P_384_H_Y		{0xc9e821b5, 0x69d9d390, 0xa2616740, 0x6d6d23d6, 0x070be242, 0xd765eb83, 0x1625ceec, 0x4a0f473e, 0xf59f4e30, 0xe2817e62, 0x85bce284, 0x6f15f19d}
+
+/* Base Point Order */
+#define P_384_N			{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xc7634d81, 0xf4372ddf, 0x581a0db2, 0x48b0a77a, 0xecec196a, 0xccc52973}
+
+/* Private Key */
+#define P_384_D			{0xc838b852, 0x53ef8dc7, 0x394fa580, 0x8a518398, 0x1c7deef5, 0xa69ba8f4, 0xf2117ffe, 0xa39cfcd9, 0x0e95f6cb, 0xc854abac, 0xab701d50, 0xc1f3cf24}
+
+/* Per-message Random Number */
+#define P_384_K			{0xdc6b4403, 0x6989a196, 0xe39d1cda, 0xc000812f, 0x4bdd8b2d, 0xb41bb33a, 0xf5137258, 0x5ebd1db6, 0x3f0ce827, 0x5aa1fd45, 0xe2d2a735, 0xf8749359}
+
+/* Public Key */
+#define P_384_Q_X		{0x1fbac8ee, 0xbd0cbf35, 0x640b39ef, 0xe0808dd7, 0x74debff2, 0x0a2a329e, 0x91713baf, 0x7d7f3c3e, 0x81546d88, 0x3730bee7, 0xe48678f8, 0x57b02ca0}
+#define P_384_Q_Y		{0xeb213103, 0xbd68ce34, 0x3365a8a4, 0xc3d4555f, 0xa385f533, 0x0203bdd7, 0x6ffad1f3, 0xaffb9575, 0x1c132007, 0xe1b24035, 0x3cb0a4cf, 0x1693bdf9}
+
+/* Part of Signature */
+#define P_384_R_X		{0xa0c27ec8, 0x93092dea, 0x1e1bd2cc, 0xfed3cf94, 0x5c8134ed, 0x0c9f8131, 0x1a0f4a05, 0x942db8db, 0xed8dd59f, 0x267471d5, 0x462aa14f, 0xe72de856}
+#define P_384_R_Y		{0x85564940, 0x9815bb91, 0x424eaca5, 0xfd76c973, 0x75d575d1, 0x422ec53d, 0x343bd33b, 0x847fdf0c, 0x11569685, 0xb528ab25, 0x49301542, 0x8d7cf72b}
+
+
+//------------------------------------------------------------------------------
+// Parameter and Test Vector Selection
+//------------------------------------------------------------------------------
+#if USE_CURVE == 1
+
+#define ECDSA_Q			P_256_Q
+
+#define ECDSA_ZERO		P_256_ZERO
+#define ECDSA_ONE		P_256_ONE
+
+#define ECDSA_DELTA		P_256_DELTA
+
+#define ECDSA_G_X		P_256_G_X
+#define ECDSA_G_Y		P_256_G_Y
+
+#define ECDSA_H_X		P_256_H_X
+#define ECDSA_H_Y		P_256_H_Y
+
+#define ECDSA_N			P_256_N
+#define ECDSA_D			P_256_D
+#define ECDSA_K			P_256_K
+
+#define ECDSA_Q_X		P_256_Q_X
+#define ECDSA_Q_Y		P_256_Q_Y
+
+#define ECDSA_R_X		P_256_R_X
+#define ECDSA_R_Y		P_256_R_Y
+
+#elif USE_CURVE == 2
+
+#define ECDSA_Q			P_384_Q
+
+#define ECDSA_ZERO		P_384_ZERO
+#define ECDSA_ONE		P_384_ONE
+
+#define ECDSA_DELTA		P_384_DELTA
+
+#define ECDSA_G_X		P_384_G_X
+#define ECDSA_G_Y		P_384_G_Y
+
+#define ECDSA_H_X		P_384_H_X
+#define ECDSA_H_Y		P_384_H_Y
+
+#define ECDSA_N			P_384_N
+#define ECDSA_D			P_384_D
+#define ECDSA_K			P_384_K
+
+#define ECDSA_Q_X		P_384_Q_X
+#define ECDSA_Q_Y		P_384_Q_Y
+
+#define ECDSA_R_X		P_384_R_X
+#define ECDSA_R_Y		P_384_R_Y
+
+#else
+
+#error USE_CURVE must be either 1 or 2!
+
+#endif
+
+
+//------------------------------------------------------------------------------
+// End-of-File
+//------------------------------------------------------------------------------



More information about the Commits mailing list