Update secp256k1 core to use ec_ modules for point add and double

This commit is contained in:
bsdevlin 2019-06-22 15:26:07 +08:00
parent 78dadeff48
commit aecbc2ae75
8 changed files with 289 additions and 337 deletions

View File

@ -19,7 +19,9 @@
package secp256k1_pkg;
parameter [255:0] p = 256'hFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFC2F;
parameter DAT_BITS = 256;
parameter [255:0] P = 256'hFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFC2F;
parameter [255:0] a = 256'h0;
parameter [255:0] b = 256'h7;
parameter [255:0] Gx = 256'h79BE667E_F9DCBBAC_55A06295_CE870B07_029BFCDB_2DCE28D9_59F2815B_16F81798;
@ -60,10 +62,18 @@ package secp256k1_pkg;
parameter SIG_VER_X = 40; // Result of (u1.P + u2.Q) 256 * 3 bits as is in jb coords.
parameter SIG_VER_X_AFF = 52; // 256 bits, SIG_VER_X result's X in affine coords.
typedef logic [255:0] fe_t;
logic [256:0] P_ = P;
logic [255:0] p = P; //TODO remove me
// Expected to be in Jacobian coordinates
typedef struct packed {
logic [255:0] x, y, z;
fe_t x, y, z;
} jb_point_t;
jb_point_t g_point = {x:Gx, y:Gy, z:256'd1};
typedef struct packed {
logic [2:0] padding;
@ -78,34 +88,92 @@ package secp256k1_pkg;
is_zero = (p.x == 0 && p.y == 0 && p.z == 1);
return is_zero;
endfunction
function jb_point_t dbl_jb_point(input jb_point_t p);
fe_t I_X, I_Y, I_Z, A, B, C, D, X, Y, Z;
// Function to double point in Jacobian coordinates (for comparison in testbench)
// Here a is 0, and we also mod p the result
function jb_point_t dbl_jb_point(jb_point_t p);
logic signed [512:0] I_X, I_Y, I_Z, A, B, C, D, X, Y, Z;
if (p.z == 0) return p;
if (p.z == 0) return p;
I_X = p.x;
I_Y = p.y;
I_Z = p.z;
A = fe_mul(I_Y, I_Y);
B = fe_mul(fe_mul(4, I_X), A);
C = fe_mul(fe_mul(8, A), A);
D = fe_mul(fe_mul(3, I_X), I_X);
X = fe_mul(D, D);
X = fe_sub(X, fe_mul(2, B));
I_X = p.x;
I_Y = p.y;
I_Z = p.z;
A = (I_Y*I_Y) % p_eq;
B = (((4*I_X) % p_eq)*A) % p_eq;
C = (((8*A) % p_eq)*A) % p_eq;
D = (((3*I_X)% p_eq)*I_X) % p_eq;
X = (D*D)% p_eq;
X = X + ((2*B) % p_eq > X ? p_eq : 0) - (2*B) % p_eq;
Y = fe_mul(D, fe_sub(B, X));
Y = fe_sub(Y, C);
Z = fe_mul(fe_mul(2, I_Y), I_Z);
Y = (D*((B + (X > B ? p_eq : 0)-X) % p_eq)) % p_eq;
Y = Y + (C > Y ? p_eq : 0) - C;
Z = (((2*I_Y)% p_eq)*I_Z) % p_eq;
dbl_jb_point.x = X;
dbl_jb_point.y = Y;
dbl_jb_point.z = Z;
return dbl_jb_point;
endfunction
function fe_t fe_add(fe_t a, b);
logic [$bits(fe_t):0] a_, b_;
a_ = a;
b_ = b;
fe_add = a_ + b_ >= P_ ? a_ + b_ - P_ : a_ + b_;
endfunction
dbl_jb_point.x = X;
dbl_jb_point.y = Y;
dbl_jb_point.z = Z;
return dbl_jb_point;
endfunction
function fe_t fe_sub(fe_t a, b);
logic [$bits(fe_t):0] a_, b_;
a_ = a;
b_ = b;
fe_sub = b_ > a_ ? a_- b_ + P_ : a_ - b_;
endfunction
function fe_t fe_mul(fe_t a, b);
logic [$bits(fe_t)*2:0] m_;
m_ = a * b;
fe_mul = m_ % P;
endfunction
function jb_point_t add_jb_point(jb_point_t p1, p2);
fe_t A, U1, U2, S1, S2, H, H3, R;
if (p1.z == 0) return p2;
if (p2.z == 0) return p1;
if (p1.y == p2.y && p1.x == p2.x)
return (dbl_jb_point(p1));
U1 = fe_mul(p1.x, p2.z);
U1 = fe_mul(U1, p2.z);
U2 = fe_mul(p2.x, p1.z);
U2 = fe_mul(U2, p1.z);
S1 = fe_mul(p1.y, p2.z);
S1 = fe_mul(fe_mul(S1, p2.z), p2.z);
S2 = fe_mul(p2.y, p1.z);
S2 = fe_mul(fe_mul(S2, p1.z), p1.z);
H = fe_sub(U2, U1);
R = fe_sub(S2, S1);
H3 = fe_mul(fe_mul(H, H), H);
A = fe_mul(fe_mul(fe_mul(2, U1), H), H);
add_jb_point.z = fe_mul(fe_mul(H, p1.z), p2.z);
add_jb_point.x = fe_mul(R, R);
add_jb_point.x = fe_sub(add_jb_point.x, H3);
add_jb_point.x = fe_sub(add_jb_point.x, A);
A = fe_mul(fe_mul(U1, H), H);
A = fe_sub(A, add_jb_point.x);
A = fe_mul(A, R);
add_jb_point.y = fe_mul(S1, H3);
add_jb_point.y = fe_sub(A, add_jb_point.y);
endfunction
/*
function jb_point_t add_jb_point(jb_point_t p1, p2);
logic signed [512:0] A, U1, U2, S1, S2, H, H3, R;
@ -127,17 +195,12 @@ package secp256k1_pkg;
H = U2 + (U1 > U2 ? p_eq : 0) -U1;
R = S2 + (S1 > S2 ? p_eq : 0) -S1;
//$display("R = %x", R);
//$display("H = %x", H);
//$display("H^2 = %x", (H * H %p_eq ));
H3 = ((H * H %p_eq ) * H ) % p_eq;
A = (((2*U1 % p_eq) *H % p_eq) * H % p_eq);
add_jb_point.z = ((H * p1.z % p_eq) * p2.z) % p_eq;
add_jb_point.x = R*R % p_eq;
//$display("R^2 = %x", add_jb_point.x);
//$display("H^3 = %x", H3);
add_jb_point.x = add_jb_point.x + (H3 > add_jb_point.x ? p_eq : 0) - H3;
add_jb_point.x = add_jb_point.x + (A > add_jb_point.x ? p_eq : 0) - A;
@ -150,7 +213,7 @@ package secp256k1_pkg;
add_jb_point.y = A + (add_jb_point.y > A ? p_eq : 0) - add_jb_point.y;
endfunction
*/
function on_curve(jb_point_t p);
return (p.y*p.y - p.x*p.x*p.x - secp256k1_pkg::a*p.x*p.z*p.z*p.z*p.z - secp256k1_pkg::b*p.z*p.z*p.z*p.z*p.z*p.z);
endfunction

View File

@ -1,6 +1,9 @@
/*
This performs point multiplication. We use the standard double
and add algorithm.
Same as ec_point_mult but also has additional input for adding points
which is needed in secp256k1 key verification.
Copyright (C) 2019 Benjamin Devlin and Zcash Foundation
@ -37,10 +40,6 @@ module secp256k1_point_mult
// Interface to 256bit multiplier (mod p) (if RESOURCE_SHARE == "YES")
if_axi_stream.source o_mult_if,
if_axi_stream.sink i_mult_if,
// Interface to only mod reduction block (if RESOURCE_SHARE == "YES")
if_axi_stream.source o_mod_if,
if_axi_stream.sink i_mod_if,
// We provide another input so that the final point addition can be done
input jb_point_t i_p2,
input i_p2_val
@ -49,8 +48,10 @@ module secp256k1_point_mult
// [0] is connection from/to dbl block, [1] is add block, [2] is arbitrated value
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mult_in_if [2:0] (i_clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mult_out_if [2:0] (i_clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mod_in_if [2:0] (i_clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mod_out_if [2:0] (i_clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) add_in_if [2:0] (i_clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) add_out_if [2:0] (i_clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) sub_in_if [2:0] (i_clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) sub_out_if [2:0] (i_clk);
logic [255:0] k_l;
jb_point_t p_n, p_q, p_dbl, p_add;
@ -200,7 +201,11 @@ always_ff @ (posedge i_clk) begin
end
end
secp256k1_point_dbl secp256k1_point_dbl(
ec_point_dbl
#(
.FP_TYPE ( jb_point_t ),
.FE_TYPE ( fe_t )
) ec_point_dbl (
.i_clk ( i_clk ),
.i_rst ( i_rst ),
// Input point
@ -212,14 +217,20 @@ secp256k1_point_dbl secp256k1_point_dbl(
.o_err ( p_dbl_out_err ),
.i_rdy ( p_dbl_out_rdy ),
.o_val ( p_dbl_out_val ),
// Interfaces to shared multipliers / modulo blocks
.o_mult_if ( mult_in_if[0] ),
.i_mult_if ( mult_out_if[0] ),
.o_mod_if ( mod_in_if[0] ),
.i_mod_if ( mod_out_if[0] )
// Interface to multiplier (mod p)
.o_mul_if ( mult_in_if[0] ),
.i_mul_if ( mult_out_if[0] ),
.o_add_if ( add_in_if[0] ),
.i_add_if ( add_out_if[0] ),
.o_sub_if ( sub_in_if[0] ),
.i_sub_if ( sub_out_if[0] )
);
secp256k1_point_add secp256k1_point_add(
ec_point_add #(
.FP_TYPE ( jb_point_t ),
.FE_TYPE ( fe_t )
)
ec_point_add (
.i_clk ( i_clk ),
.i_rst ( i_rst ),
// Input points
@ -232,35 +243,60 @@ secp256k1_point_add secp256k1_point_add(
.o_err ( p_add_out_err ),
.i_rdy ( p_add_out_rdy ),
.o_val ( p_add_out_val ),
// Interfaces to shared multipliers / modulo blocks
.o_mult_if ( mult_in_if[1] ),
.i_mult_if ( mult_out_if[1] ),
.o_mod_if ( mod_in_if[1] ),
.i_mod_if ( mod_out_if[1] )
.o_mul_if ( mult_in_if[1] ),
.i_mul_if ( mult_out_if[1] ),
.o_add_if ( add_in_if[1] ),
.i_add_if ( add_out_if[1] ),
.o_sub_if ( sub_in_if[1] ),
.i_sub_if ( sub_out_if[1] )
);
// We add arbitrators to these to share with the point add module
localparam ARB_BIT = 8;
resource_share # (
.NUM_IN ( 2 ),
.OVR_WRT_BIT ( ARB_BIT ),
.PIPELINE_IN ( 0 ),
.PIPELINE_OUT ( 0 )
.NUM_IN ( 2 ),
.CTL_BITS ( 16 ),
.DAT_BITS ( 512 ),
.DAT_BYTS ( 512/8 ),
.OVR_WRT_BIT ( ARB_BIT ),
.PIPELINE_IN ( 0 ),
.PIPELINE_OUT ( 0 )
)
resource_share_mod (
resource_share_add (
.i_clk ( i_clk ),
.i_rst ( i_rst ),
.i_axi ( mod_in_if[1:0] ),
.o_res ( mod_in_if[2] ),
.i_res ( mod_out_if[2] ),
.o_axi ( mod_out_if[1:0] )
.i_axi ( add_in_if[1:0] ),
.o_res ( add_in_if[2] ),
.i_res ( add_out_if[2] ),
.o_axi ( add_out_if[1:0] )
);
resource_share # (
.NUM_IN ( 2 ),
.OVR_WRT_BIT ( ARB_BIT ),
.PIPELINE_IN ( 0 ),
.PIPELINE_OUT ( 0 )
.NUM_IN ( 2 ),
.CTL_BITS ( 16 ),
.DAT_BITS ( 512 ),
.DAT_BYTS ( 512/8 ),
.OVR_WRT_BIT ( ARB_BIT ),
.PIPELINE_IN ( 0 ),
.PIPELINE_OUT ( 0 )
)
resource_share_sub (
.i_clk ( i_clk ),
.i_rst ( i_rst ),
.i_axi ( sub_in_if[1:0] ),
.o_res ( sub_in_if[2] ),
.i_res ( sub_out_if[2] ),
.o_axi ( sub_out_if[1:0] )
);
resource_share # (
.NUM_IN ( 2 ),
.CTL_BITS ( 16 ),
.DAT_BITS ( 512 ),
.DAT_BYTS ( 512/8 ),
.OVR_WRT_BIT ( ARB_BIT ),
.PIPELINE_IN ( 0 ),
.PIPELINE_OUT ( 0 )
)
resource_share_mult (
.i_clk ( i_clk ),
@ -270,6 +306,36 @@ resource_share_mult (
.i_res ( mult_out_if[2] ),
.o_axi ( mult_out_if[1:0] )
);
// Adder and subtractor are internal
always_comb begin
add_in_if[2].rdy = add_out_if[2].rdy;
sub_in_if[2].rdy = sub_out_if[2].rdy;
end
always_ff @ (posedge i_clk) begin
if (i_rst) begin
add_out_if[2].reset_source();
sub_out_if[2].reset_source();
end else begin
if (~add_out_if[2].val || (add_out_if[2].val && add_out_if[2].rdy)) begin
add_out_if[2].val <= add_in_if[2].val;
add_out_if[2].dat <= fe_add(add_in_if[2].dat[0 +: 256], add_in_if[2].dat[256 +: 256]);
add_out_if[2].ctl <= add_in_if[2].ctl;
add_out_if[2].sop <= 1;
add_out_if[2].eop <= 1;
end
if (~sub_out_if[2].val || (sub_out_if[2].val && sub_out_if[2].rdy)) begin
sub_in_if[2].rdy <= sub_out_if[2].rdy;
sub_out_if[2].val <= sub_in_if[2].val;
sub_out_if[2].dat <= fe_sub(sub_in_if[2].dat[0 +: 256], sub_in_if[2].dat[256 +: 256]);
sub_out_if[2].ctl <= sub_in_if[2].ctl;
sub_out_if[2].sop <= 1;
sub_out_if[2].eop <= 1;
end
end
end
generate
if (RESOURCE_SHARE == "YES") begin: RESOURCE_GEN
always_comb begin
@ -282,31 +348,16 @@ generate
o_mult_if.eop = 1;
mult_in_if[2].rdy = o_mult_if.rdy;
o_mod_if.val = mod_in_if[2].val;
o_mod_if.dat = mod_in_if[2].dat;
o_mod_if.ctl = mod_in_if[2].ctl;
o_mod_if.err = 0;
o_mod_if.mod = 0;
o_mod_if.sop = 1;
o_mod_if.eop = 1;
mod_in_if[2].rdy = o_mod_if.rdy;
i_mult_if.rdy = mult_out_if[2].rdy;
mult_out_if[2].val = i_mult_if.val;
mult_out_if[2].dat = i_mult_if.dat;
mult_out_if[2].ctl = i_mult_if.ctl;
i_mod_if.rdy = mod_out_if[2].rdy;
mod_out_if[2].val = i_mod_if.val;
mod_out_if[2].dat = i_mod_if.dat;
mod_out_if[2].ctl = i_mod_if.ctl;
end
end else begin
always_comb begin
o_mult_if.reset_source();
i_mult_if.rdy = 0;
o_mod_if.reset_source();
i_mod_if.rdy = 0;
end
secp256k1_mult_mod #(
.CTL_BITS ( 16 )
@ -327,25 +378,6 @@ generate
.o_ctl ( mult_out_if[2].ctl ),
.o_err ( mult_out_if[2].err )
);
secp256k1_mod #(
.USE_MULT ( 0 ),
.CTL_BITS ( 16 )
)
secp256k1_mod (
.i_clk( i_clk ),
.i_rst( i_rst ),
.i_dat( mod_in_if[2].dat ),
.i_val( mod_in_if[2].val ),
.i_err( mod_in_if[2].err ),
.i_ctl( mod_in_if[2].ctl ),
.o_rdy( mod_in_if[2].rdy ),
.o_dat( mod_out_if[2].dat ),
.o_ctl( mod_out_if[2].ctl ),
.o_err( mod_out_if[2].err ),
.i_rdy( mod_out_if[2].rdy ),
.o_val( mod_out_if[2].val )
);
end
endgenerate

View File

@ -36,10 +36,6 @@ module secp256k1_point_mult_endo
// Interface to 256bit multiplier
if_axi_stream.source o_mult_if,
if_axi_stream.sink i_mult_if,
// Interface to only mod reduction block
if_axi_stream.source o_mod_if,
if_axi_stream.sink i_mod_if,
// We provide another input so that the final point addition can be done
// This is connected to k2 block's addition input
input jb_point_t i_p2,
@ -231,8 +227,6 @@ secp256k1_point_mult_k1 (
.o_err ( o_err1 ),
.o_mult_if ( mult_in_if[0] ),
.i_mult_if ( mult_out_if[0] ),
.o_mod_if ( mod_in_if[0] ),
.i_mod_if ( mod_out_if[0] ),
.i_p2 ( p2_k1 ),
.i_p2_val ( p2_k1_val )
);
@ -253,31 +247,18 @@ secp256k1_point_mult_k2 (
.o_err ( o_err2 ),
.o_mult_if ( mult_in_if[1] ),
.i_mult_if ( mult_out_if[1] ),
.o_mod_if ( mod_in_if[1] ),
.i_mod_if ( mod_out_if[1] ),
.i_p2 ( p2_k2 ),
.i_p2_val ( p2_k2_val )
);
// We add arbitrators to these to share with the point add module
localparam ARB_BIT = 10;
resource_share # (
.NUM_IN ( 2 ),
.OVR_WRT_BIT ( ARB_BIT ),
.PIPELINE_IN ( 1 ),
.PIPELINE_OUT ( 0 )
)
resource_share_mod (
.i_clk ( i_clk ),
.i_rst ( i_rst ),
.i_axi ( mod_in_if[1:0] ),
.o_res ( mod_in_if[2] ),
.i_res ( mod_out_if[2] ),
.o_axi ( mod_out_if[1:0] )
);
resource_share # (
.NUM_IN ( 3 ),
.NUM_IN ( 3 ),
.CTL_BITS ( 16 ),
.DAT_BITS ( 512 ),
.DAT_BYTS ( 512/8 ),
.OVR_WRT_BIT ( ARB_BIT ),
.PIPELINE_IN ( 1 ),
.PIPELINE_OUT ( 0 )
@ -302,24 +283,11 @@ always_comb begin
o_mult_if.eop = 1;
mult_in_if[3].rdy = o_mult_if.rdy;
o_mod_if.val = mod_in_if[2].val;
o_mod_if.dat = mod_in_if[2].dat;
o_mod_if.ctl = mod_in_if[2].ctl;
o_mod_if.err = 0;
o_mod_if.mod = 0;
o_mod_if.sop = 1;
o_mod_if.eop = 1;
mod_in_if[2].rdy = o_mod_if.rdy;
i_mult_if.rdy = mult_out_if[3].rdy;
mult_out_if[3].val = i_mult_if.val;
mult_out_if[3].dat = i_mult_if.dat;
mult_out_if[3].ctl = i_mult_if.ctl;
i_mod_if.rdy = mod_out_if[2].rdy;
mod_out_if[2].val = i_mod_if.val;
mod_out_if[2].dat = i_mod_if.dat;
mod_out_if[2].ctl = i_mod_if.ctl;
end

View File

@ -21,8 +21,6 @@ if_axi_stream #(.DAT_BYTS(256/8)) bin_inv_out_if(i_clk);
// [0] is connection from/to point_mult0 block, [1] is add point_mult1 block, 2 is this state machine, [3] is arbitrated value
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mult_in_if [3:0] (i_clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mult_out_if [3:0] (i_clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mod_in_if [2:0] (i_clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mod_out_if [2:0] (i_clk);
jb_point_t pt_mult0_in_p, pt_mult0_out_p, pt_mult1_in_p, pt_mult1_out_p, pt_X0, pt_X1, pt_X, pt_mult0_in_p2;
logic [255:0] pt_mult0_in_k, pt_mult1_in_k;
@ -444,44 +442,13 @@ secp256k1_mult_mod (
.o_err ( mult_out_if[3].err )
);
secp256k1_mod #(
.USE_MULT ( 0 ),
.CTL_BITS ( 16 )
)
secp256k1_mod (
.i_clk( i_clk ),
.i_rst( i_rst ),
.i_dat( mod_in_if[2].dat ),
.i_val( mod_in_if[2].val ),
.i_err( mod_in_if[2].err ),
.i_ctl( mod_in_if[2].ctl ),
.o_rdy( mod_in_if[2].rdy ),
.o_dat( mod_out_if[2].dat ),
.o_ctl( mod_out_if[2].ctl ),
.o_err( mod_out_if[2].err ),
.i_rdy( mod_out_if[2].rdy ),
.o_val( mod_out_if[2].val )
);
resource_share # (
.NUM_IN ( 2 ),
.NUM_IN ( 3 ),
.CTL_BITS ( 16 ),
.DAT_BITS ( 512 ),
.DAT_BYTS ( 512/8 ),
.OVR_WRT_BIT ( ARB_BIT ),
.PIPELINE_IN ( 0 ),
.PIPELINE_OUT ( 1 )
)
resource_share_mod (
.i_clk ( i_clk ),
.i_rst ( i_rst ),
.i_axi ( mod_in_if[1:0] ),
.o_res ( mod_in_if[2] ),
.i_res ( mod_out_if[2] ),
.o_axi ( mod_out_if[1:0] )
);
resource_share # (
.NUM_IN ( 3 ),
.OVR_WRT_BIT ( ARB_BIT ),
.PIPELINE_IN ( 0 )
.PIPELINE_IN ( 0 )
)
resource_share_mult (
.i_clk ( i_clk ),
@ -509,8 +476,6 @@ generate if (USE_ENDOMORPH == "NO") begin
.o_err ( pt_mult0_out_err ),
.o_mult_if ( mult_in_if[0] ),
.i_mult_if ( mult_out_if[0] ),
.o_mod_if ( mod_in_if[0] ),
.i_mod_if ( mod_out_if[0] ),
.i_p2 ( pt_mult0_in_p2 ),
.i_p2_val ( pt_mult0_in_p2_val )
);
@ -531,8 +496,6 @@ generate if (USE_ENDOMORPH == "NO") begin
.o_err ( pt_mult1_out_err ),
.o_mult_if ( mult_in_if[1] ),
.i_mult_if ( mult_out_if[1] ),
.o_mod_if ( mod_in_if[1] ),
.i_mod_if ( mod_out_if[1] ),
.i_p2 ( '0 ),
.i_p2_val ( 1'b0 )
);
@ -551,8 +514,6 @@ end else begin
.o_err ( pt_mult0_out_err ),
.o_mult_if ( mult_in_if[0] ),
.i_mult_if ( mult_out_if[0] ),
.o_mod_if ( mod_in_if[0] ),
.i_mod_if ( mod_out_if[0] ),
.i_p2 ( pt_mult0_in_p2 ),
.i_p2_val ( pt_mult0_in_p2_val )
);
@ -571,8 +532,6 @@ end else begin
.o_err ( pt_mult1_out_err ),
.o_mult_if ( mult_in_if[1] ),
.i_mult_if ( mult_out_if[1] ),
.o_mod_if ( mod_in_if[1] ),
.i_mod_if ( mod_out_if[1] ),
.i_p2 ( '0 ),
.i_p2_val ( 1'b0 )
);

View File

@ -30,9 +30,11 @@ if_axi_stream #(.DAT_BYTS(256*3/8)) out_if(clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mult_in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mult_out_if(clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mod_in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mod_out_if(clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) add_in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) add_out_if(clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) sub_in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) sub_out_if(clk);
jb_point_t in_p1, in_p2, out_p;
@ -64,22 +66,28 @@ always_ff @ (posedge clk)
if (out_if.val && out_if.err)
$error(1, "%m %t ERROR: output .err asserted", $time);
secp256k1_point_add secp256k1_point_add(
ec_point_add #(
.FP_TYPE ( jb_point_t ),
.FE_TYPE ( fe_t )
)
ec_point_add (
.i_clk ( clk ),
.i_rst ( rst ),
// Input points
.i_p1 ( in_p1 ),
.i_p2 ( in_p2 ),
.i_p1 ( in_p1 ),
.i_p2 ( in_p2 ),
.i_val ( in_if.val ),
.o_rdy ( in_if.rdy ),
.o_p ( out_p ),
.o_err ( out_if.err ),
.i_rdy ( out_if.rdy ),
.o_val ( out_if.val ) ,
.o_mult_if ( mult_in_if ),
.i_mult_if ( mult_out_if ),
.o_mod_if ( mod_in_if ),
.i_mod_if ( mod_out_if )
.o_mul_if ( mult_in_if ),
.i_mul_if ( mult_out_if ),
.o_add_if ( add_in_if ),
.i_add_if ( add_out_if ),
.o_sub_if ( sub_in_if ),
.i_sub_if ( sub_out_if )
);
always_comb begin
@ -87,11 +95,6 @@ always_comb begin
mult_out_if.eop = 1;
mult_out_if.err = 1;
mult_out_if.mod = 1;
mod_out_if.sop = 1;
mod_out_if.eop = 1;
mod_out_if.err = 1;
mod_out_if.mod = 1;
end
// Attach a mod reduction unit and multiply - mod unit
@ -116,24 +119,23 @@ secp256k1_mult_mod (
.o_err ( mult_out_if.err )
);
secp256k1_mod #(
.USE_MULT ( 0 ),
.CTL_BITS ( 16 )
)
secp256k1_mod (
.i_clk( clk ),
.i_rst( rst ),
.i_dat( mod_in_if.dat ),
.i_val( mod_in_if.val ),
.i_err( mod_in_if.err ),
.i_ctl( mod_in_if.ctl ),
.o_rdy( mod_in_if.rdy ),
.o_dat( mod_out_if.dat ),
.o_ctl( mod_out_if.ctl ),
.o_err( mod_out_if.err ),
.i_rdy( mod_out_if.rdy ),
.o_val( mod_out_if.val )
);
always_comb begin
add_in_if.rdy = add_out_if.rdy;
sub_in_if.rdy = sub_out_if.rdy;
end
always_ff @ (posedge clk) begin
add_out_if.val <= add_in_if.val;
add_out_if.dat <= fe_add(add_in_if.dat[0 +: 256], add_in_if.dat[256 +: 256]);
add_out_if.ctl <= add_in_if.ctl;
sub_in_if.rdy <= sub_out_if.rdy;
sub_out_if.val <= sub_in_if.val;
sub_out_if.dat <= fe_sub(sub_in_if.dat[0 +: 256], sub_in_if.dat[256 +: 256]);
sub_out_if.ctl <= sub_in_if.ctl;
end
task test(input integer index, input jb_point_t p1, p2);
begin
@ -168,30 +170,14 @@ begin
end
endtask;
function compare_point();
endfunction
initial begin
out_if.rdy = 0;
in_if.val = 0;
#(40*CLK_PERIOD);
test(0,
{x:256'h2475abeb8f0fc52f627afb4c18227dfa756706ceb5923cd8a209bf43c2f08815,
y:256'h4361473bccf308998bbb8c0b9a0184d186ada6e85e1cb1b82ac202380df8f762,
z:256'hdda493ffbcdc8daf0996a769bf192cc4627839d0025b4ad960c3e25dab464863},
{x:256'h4a58b6edef1379306fce3372763fd87eaf2c8f447c6408416e746e672ee6ce21,
y:256'h33adac20db34d12166586c56aa8a352b155bcfdd011f46b38c21e0c4d39968a4,
z:256'h8631df8718bcb2d2920dfd313c714a153cfc6db607891e341b0856411717cf4f});
test(1,
{x:secp256k1_pkg::Gx,
y:secp256k1_pkg::Gx,
z:256'h1},
{x:256'h4a58b6edef1379306fce3372763fd87eaf2c8f447c6408416e746e672ee6ce21,
y:256'h33adac20db34d12166586c56aa8a352b155bcfdd011f46b38c21e0c4d39968a4,
z:256'h8631df8718bcb2d2920dfd313c714a153cfc6db607891e341b0856411717cf4f});
g_point,
dbl_jb_point(g_point));
test(2,
{x:256'd21093662951128507222548537960537987883266099219826518477955151519492458533937,
y:256'd11718937855299224635656538406325081070585145153119064354000306947171340794663,

View File

@ -30,9 +30,10 @@ if_axi_stream #(.DAT_BYTS(256*3/8)) out_if(clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(8)) mult_in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(8)) mult_out_if(clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(8)) mod_in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(8)) mod_out_if(clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(8)) sub_in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(8)) sub_out_if(clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(8)) add_in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(8)) add_out_if(clk);
jb_point_t in_p, out_p;
@ -63,10 +64,13 @@ always_ff @ (posedge clk)
if (out_if.val && out_if.err)
$error(1, "%m %t ERROR: output .err asserted", $time);
secp256k1_point_dbl secp256k1_point_dbl(
ec_point_dbl
#(
.FP_TYPE ( jb_point_t ),
.FE_TYPE ( fe_t )
) ec_point_dbl (
.i_clk ( clk ),
.i_rst ( rst ),
// Input point
.i_p ( in_p ),
.i_val ( in_if.val ),
.o_rdy ( in_if.rdy ),
@ -74,14 +78,30 @@ secp256k1_point_dbl secp256k1_point_dbl(
.o_err ( out_if.err ),
.i_rdy ( out_if.rdy ),
.o_val ( out_if.val ) ,
.o_mult_if ( mult_in_if ),
.i_mult_if ( mult_out_if ),
.o_mod_if ( mod_in_if ),
.i_mod_if ( mod_out_if )
// Interface to multiplier (mod p)
.o_mul_if ( mult_in_if ),
.i_mul_if ( mult_out_if ),
.o_add_if ( add_in_if ),
.i_add_if ( add_out_if ),
.o_sub_if ( sub_in_if ),
.i_sub_if ( sub_out_if )
);
always_comb begin
add_in_if.rdy = add_out_if.rdy;
add_out_if.val = add_in_if.val;
add_out_if.dat = fe_add(add_in_if.dat[0 +: 256], add_in_if.dat[256 +: 256]);
add_out_if.ctl = add_in_if.ctl;
sub_in_if.rdy = sub_out_if.rdy;
sub_out_if.val = sub_in_if.val;
sub_out_if.dat = fe_sub(sub_in_if.dat[0 +: 256], sub_in_if.dat[256 +: 256]);
sub_out_if.ctl = sub_in_if.ctl;
end
// Attach a mod reduction unit and multiply - mod unit
// In full design these could use dedicated multipliers or be arbitrated
secp256k1_mult_mod #(
.CTL_BITS ( 8 )
)
@ -93,7 +113,7 @@ secp256k1_mult_mod (
.i_val ( mult_in_if.val ),
.i_err ( mult_in_if.err ),
.i_ctl ( mult_in_if.ctl ),
.i_cmd ( 1'd0 ),
.i_cmd ( 2'd0 ),
.o_rdy ( mult_in_if.rdy ),
.o_dat ( mult_out_if.dat ),
.i_rdy ( mult_out_if.rdy ),
@ -102,25 +122,6 @@ secp256k1_mult_mod (
.o_err ( mult_out_if.err )
);
secp256k1_mod #(
.USE_MULT ( 0 ),
.CTL_BITS ( 8 )
)
secp256k1_mod (
.i_clk( clk ),
.i_rst( rst ),
.i_dat( mod_in_if.dat ),
.i_val( mod_in_if.val ),
.i_err( mod_in_if.err ),
.i_ctl( mod_in_if.ctl ),
.o_rdy( mod_in_if.rdy ),
.o_dat( mod_out_if.dat ),
.o_ctl( mod_out_if.ctl ),
.o_err( mod_out_if.err ),
.i_rdy( mod_out_if.rdy ),
.o_val( mod_out_if.val )
);
task test_0();
begin
integer signed get_len;
@ -128,9 +129,8 @@ begin
logic [255:0] in_a, in_b;
jb_point_t p_in, p_exp, p_out;
$display("Running test_0...");
//p_in = {z:1, x:4, y:2};
//p_in = {z:10, x:64, y:23};
p_in = {x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gx, z:1};
p_in = g_point;
p_exp = dbl_jb_point(p_in);
fork

View File

@ -29,10 +29,6 @@ if_axi_stream #(.DAT_BYTS(256*3/8)) out_if(clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mult_in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mult_out_if(clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mod_in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mod_out_if(clk);
logic [255:0] k_in;
@ -64,9 +60,6 @@ always_comb begin
mult_out_if.sop = 1;
mult_out_if.eop = 1;
mult_out_if.mod = 0;
mod_out_if.sop = 1;
mod_out_if.eop = 1;
mod_out_if.mod = 0;
end
secp256k1_point_mult_endo secp256k1_point_mult_endo (
@ -82,8 +75,6 @@ end
.o_err ( out_if.err ),
.o_mult_if ( mult_in_if ),
.i_mult_if ( mult_out_if ),
.o_mod_if ( mod_in_if ),
.i_mod_if ( mod_out_if ),
.i_p2_val (0),
.i_p2 (0 )
);
@ -108,25 +99,6 @@ secp256k1_mult_mod (
.o_err ( mult_out_if.err )
);
secp256k1_mod #(
.USE_MULT ( 0 ),
.CTL_BITS ( 16 )
)
secp256k1_mod (
.i_clk( clk ),
.i_rst( rst ),
.i_dat( mod_in_if.dat ),
.i_val( mod_in_if.val ),
.i_err( mod_in_if.err ),
.i_ctl( mod_in_if.ctl ),
.o_rdy( mod_in_if.rdy ),
.o_dat( mod_out_if.dat ),
.o_ctl( mod_out_if.ctl ),
.o_err( mod_out_if.err ),
.i_rdy( mod_out_if.rdy ),
.o_val( mod_out_if.val )
);
// Test a point
task test(input integer index, input logic [255:0] k, jb_point_t p_exp, p_in);
begin

View File

@ -30,9 +30,6 @@ if_axi_stream #(.DAT_BYTS(256*3/8)) out_if(clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mult_in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mult_out_if(clk);
if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mod_in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mod_out_if(clk);
jb_point_t in_p, out_p;
logic [255:0] k_in;
@ -65,34 +62,27 @@ always_comb begin
mult_out_if.sop = 1;
mult_out_if.eop = 1;
mult_out_if.mod = 0;
mod_out_if.sop = 1;
mod_out_if.eop = 1;
mod_out_if.mod = 0;
end
secp256k1_point_mult #(
.RESOURCE_SHARE ("YES")
)
secp256k1_point_mult (
.i_clk ( clk ),
.i_rst ( rst ),
.i_p ( in_if.dat ),
.i_k ( k_in ),
.i_val ( in_if.val ),
.o_rdy ( in_if.rdy ),
.o_p ( out_if.dat ),
.i_rdy ( out_if.rdy ),
.o_val ( out_if.val ),
.o_err ( out_if.err ),
.o_mult_if ( mult_in_if ),
.i_mult_if ( mult_out_if ),
.o_mod_if ( mod_in_if ),
.i_mod_if ( mod_out_if ),
.i_p2_val (0),
.i_p2 (0 )
);
secp256k1_point_mult #(
.RESOURCE_SHARE ("YES")
)
secp256k1_point_mult (
.i_clk ( clk ),
.i_rst ( rst ),
.i_p ( in_if.dat ),
.i_k ( k_in ),
.i_val ( in_if.val ),
.o_rdy ( in_if.rdy ),
.o_p ( out_if.dat ),
.i_rdy ( out_if.rdy ),
.o_val ( out_if.val ),
.o_err ( out_if.err ),
.o_mult_if ( mult_in_if ),
.i_mult_if ( mult_out_if ),
.i_p2_val (0),
.i_p2 (0 )
);
secp256k1_mult_mod #(
.CTL_BITS ( 16 )
@ -114,24 +104,6 @@ secp256k1_mult_mod (
.o_err ( mult_out_if.err )
);
secp256k1_mod #(
.USE_MULT ( 0 ),
.CTL_BITS ( 16 )
)
secp256k1_mod (
.i_clk( clk ),
.i_rst( rst ),
.i_dat( mod_in_if.dat ),
.i_val( mod_in_if.val ),
.i_err( mod_in_if.err ),
.i_ctl( mod_in_if.ctl ),
.o_rdy( mod_in_if.rdy ),
.o_dat( mod_out_if.dat ),
.o_ctl( mod_out_if.ctl ),
.o_err( mod_out_if.err ),
.i_rdy( mod_out_if.rdy ),
.o_val( mod_out_if.val )
);
// Test a point
task test(input integer index, input logic [255:0] k, jb_point_t p_exp, p_in);
@ -174,13 +146,13 @@ initial begin
1, {x:256'h79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
y:256'h483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8,
z:256'h1},
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
g_point);
test(1,
2, {x:256'h7d152c041ea8e1dc2191843d1fa9db55b68f88fef695e2c791d40444b365afc2,
y:256'h56915849f52cc8f76f5fd7e4bf60db4a43bf633e1b1383f85fe89164bfadcbdb,
z:256'h9075b4ee4d4788cabb49f7f81c221151fa2f68914d0aa833388fa11ff621a970},
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
g_point);
test(3,
3, {x:256'hca90ef9b06d7eb51d650e9145e3083cbd8df8759168862036f97a358f089848,