Updates for endomorphism

This commit is contained in:
bsdevlin 2019-04-10 11:44:47 -04:00
parent 0056a4db5c
commit 612685b0b7
12 changed files with 687 additions and 212 deletions

View File

@ -130,10 +130,10 @@ interface if_axi_stream # (
logic sop_l = 0;
logic done = 0;
logic rdy_l;
rdy = ($urandom % 100) >= bp;
len = 0;
data = 0;
rdy_l = rdy;
rdy = ($urandom % 100) >= bp;
@(posedge i_clk);
while (1) begin

View File

@ -39,6 +39,11 @@ package secp256k1_pkg;
parameter [255:0] p_eq = (1 << 256) - (1 << 32) - (1 << 9) - (1 << 8) - (1 << 7) - (1 << 6) - (1 << 4) - 1;
parameter DO_AFFINE_CHECK = "NO"; // Setting this to YES will convert the final result back to affine coordinates to check signature
// Requires an inversion and so is slower than doing the check in jacobson coordinates
parameter USE_ENDOMORPH = "YES"; // Use the secp256k1 endomorphism to reduce the key bit size. Improves throughput by 2x but uses
// more FPGA logic
// Use register map for debug, holds information on current operation
parameter REGISTER_SIZE = 64;
// The mapping to index

View File

@ -156,16 +156,16 @@ always_ff @ (posedge i_clk) begin
if (o_val1 && o_val2) begin
i_rdy1 <= 1;
i_rdy2 <= 1;
p2_k1 <= p_o1;
p_k1 <= p_o2;
p_k1 <= p_o1;
p2_k1 <= p_o2;
p2_k1_val <= 1;
state <= COMBINE_K_PROD;
i_rdy_decom <= 1;
if (k2_decom[255]) begin
p_k1.y <= secp256k1_pkg::p_eq - p_o2.y;
end
if (k1_decom[255]) begin
p2_k1.y <= secp256k1_pkg::p_eq - p_o1.y;
p_k1.y <= secp256k1_pkg::p_eq - p_o1.y;
end
if (k2_decom[255]) begin
p2_k1.y <= secp256k1_pkg::p_eq - p_o2.y;
end
end

View File

@ -1,8 +1,6 @@
module secp256k1_top #(
parameter DAT_BYTS = 8,
parameter DAT_BITS = DAT_BYTS*8,
parameter DO_AFFINE_CHECK = 0,
parameter USE_ENDOMORPH = 0
module secp256k1_top import secp256k1_pkg::*; #(
parameter DO_AFFINE_CHECK = secp256k1_pkg::DO_AFFINE_CHECK,
parameter USE_ENDOMORPH = secp256k1_pkg::USE_ENDOMORPH
)(
input i_clk,
input i_rst,
@ -13,7 +11,8 @@ module secp256k1_top #(
if_axi_mm.sink if_axi_mm
);
import secp256k1_pkg::*;
localparam DAT_BYTS = 8;
localparam DAT_BITS = DAT_BYTS*8;
import zcash_fpga_pkg::*;
// Register map is used for storing command data
@ -296,7 +295,7 @@ always_ff @ (posedge i_clk) begin
cnt <= 0;
// Just store our value temp
pt_mult0_in_p2 <= pt_mult0_out_p;
if (DO_AFFINE_CHECK) begin
if (DO_AFFINE_CHECK == "YES") begin
secp256k1_state <= CALC_X_AFFINE;
mult_in_if[2].val <= 1;
mult_in_if[2].dat <= {pt_mult0_out_p.z, pt_mult0_out_p.z};
@ -469,8 +468,6 @@ bin_inv (
.i_rdy ( bin_inv_out_if.rdy )
);
localparam RESOURCE_SHARE = "YES";
localparam ARB_BIT = 12;
localparam MULT_CTL_BIT = 6; // 2 bits
@ -588,50 +585,91 @@ always_comb begin
mult_out_if[3].mod = 0;
end
secp256k1_point_mult #(
.RESOURCE_SHARE ( RESOURCE_SHARE )
)
secp256k1_point_mult0 (
.i_clk ( i_clk ),
.i_rst ( i_rst ),
.i_p ( pt_mult0_in_p ),
.i_k ( pt_mult0_in_k ),
.i_val ( pt_mult0_in_val ),
.o_rdy ( pt_mult0_in_rdy ),
.o_p ( pt_mult0_out_p ),
.i_rdy ( pt_mult0_out_rdy ),
.o_val ( pt_mult0_out_val ),
.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 )
);
secp256k1_point_mult #(
.RESOURCE_SHARE ( RESOURCE_SHARE )
)
secp256k1_point_mult1 (
.i_clk ( i_clk ),
.i_rst ( i_rst ),
.i_p ( pt_mult1_in_p ),
.i_k ( pt_mult1_in_k ),
.i_val ( pt_mult1_in_val ),
.o_rdy ( pt_mult1_in_rdy ),
.o_p ( pt_mult1_out_p ),
.i_rdy ( pt_mult1_out_rdy ),
.o_val ( pt_mult1_out_val ),
.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 )
);
generate if (USE_ENDOMORPH == "NO") begin
secp256k1_point_mult #(
.RESOURCE_SHARE ( "YES" )
)
secp256k1_point_mult0 (
.i_clk ( i_clk ),
.i_rst ( i_rst ),
.i_p ( pt_mult0_in_p ),
.i_k ( pt_mult0_in_k ),
.i_val ( pt_mult0_in_val ),
.o_rdy ( pt_mult0_in_rdy ),
.o_p ( pt_mult0_out_p ),
.i_rdy ( pt_mult0_out_rdy ),
.o_val ( pt_mult0_out_val ),
.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 )
);
secp256k1_point_mult #(
.RESOURCE_SHARE ( "YES" )
)
secp256k1_point_mult1 (
.i_clk ( i_clk ),
.i_rst ( i_rst ),
.i_p ( pt_mult1_in_p ),
.i_k ( pt_mult1_in_k ),
.i_val ( pt_mult1_in_val ),
.o_rdy ( pt_mult1_in_rdy ),
.o_p ( pt_mult1_out_p ),
.i_rdy ( pt_mult1_out_rdy ),
.o_val ( pt_mult1_out_val ),
.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 )
);
end else begin
secp256k1_point_mult_endo
secp256k1_point_mult_endo0 (
.i_clk ( i_clk ),
.i_rst ( i_rst ),
.i_p ( pt_mult0_in_p ),
.i_k ( pt_mult0_in_k ),
.i_val ( pt_mult0_in_val ),
.o_rdy ( pt_mult0_in_rdy ),
.o_p ( pt_mult0_out_p ),
.i_rdy ( pt_mult0_out_rdy ),
.o_val ( pt_mult0_out_val ),
.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 )
);
secp256k1_point_mult_endo
secp256k1_point_mult_endo1 (
.i_clk ( i_clk ),
.i_rst ( i_rst ),
.i_p ( pt_mult1_in_p ),
.i_k ( pt_mult1_in_k ),
.i_val ( pt_mult1_in_val ),
.o_rdy ( pt_mult1_in_rdy ),
.o_p ( pt_mult1_out_p ),
.i_rdy ( pt_mult1_out_rdy ),
.o_val ( pt_mult1_out_val ),
.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 )
);
end endgenerate
// Task to help build reply messages. Assume no message will be more than MAX_BYT_MSG bytes
task send_message(input logic [$clog2(MAX_BYT_MSG)-1:0] msg_size);
if (~if_cmd_tx.val || (if_cmd_tx.rdy && if_cmd_tx.val)) begin

View File

@ -29,7 +29,7 @@ package zcash_fpga_pkg;
// What features are enabled in this build
parameter bit ENB_VERIFY_SECP256K1_SIG = 1;
parameter bit ENB_VERIFY_EQUIHASH = 1;
parameter bit ENB_VERIFY_EQUIHASH = 0;
localparam [63:0] FPGA_CMD_CAP = {{61'd0},
ENB_VERIFY_SECP256K1_SIG,

View File

@ -24,7 +24,7 @@ localparam CLK_PERIOD = 100;
logic clk, rst;
if_axi_stream #(.DAT_BYTS(512/8), .CTL_BITS(1)) in_if(clk);
if_axi_stream #(.DAT_BYTS(512/8), .CTL_BITS(2)) in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8)) out_if(clk);
initial begin
@ -55,7 +55,7 @@ secp256k1_mult_mod secp256k1_mult_mod (
.i_cmd( in_if.ctl ),
.i_ctl ( 8'd0 ),
.i_dat_a( in_if.dat[0 +: 256] ),
.i_dat_b( in_if.dat[256 +: 256] ),
.i_dat_b( in_if.dat[256 +: 256] ),
.i_val( in_if.val ),
.i_err( in_if.err ),
.o_rdy( in_if.rdy ),
@ -71,46 +71,70 @@ begin
logic [common_pkg::MAX_SIM_BYTS*8-1:0] expected, get_dat;
logic [255:0] in_a, in_b;
integer i, max;
logic type_ctl;
logic [1:0] type_ctl;
$display("Running test_loop...");
i = 0;
max = 10000;
while (i < max) begin
type_ctl = $random;
type_ctl = $urandom % 3;
in_a = random_vector(256/8) % (type_ctl == 0 ? p_eq : secp256k1_pkg::n);
in_b = random_vector(256/8) % (type_ctl== 0 ? p_eq : secp256k1_pkg::n);
expected = (in_a * in_b) % (type_ctl == 0 ? p_eq : secp256k1_pkg::n);
expected = (in_a * in_b);
case (type_ctl)
0: begin
expected = expected % p_eq;
end
1: begin
expected = expected % secp256k1_pkg::n;
end
2: begin
expected = expected >> 256;
expected = expected % p_eq;
end
endcase
fork
in_if.put_stream({in_b, in_a}, 512/8, type_ctl);
out_if.get_stream(get_dat, get_len, 0);
out_if.get_stream(get_dat, get_len, 50);
join
common_pkg::compare_and_print(get_dat, expected);
$display("test_loop PASSED loop %d/%d", i, max);
i = i + 1;
end
$display("test_loop PASSED");
end
endtask;
task test_pipeline();
begin
logic type_cmd [10];
logic [1:0] type_cmd [10];
logic [255:0] in_a [10];
logic [255:0] in_b [10];
logic [511:0] expected [10];
integer max = 10;
$display("Running test_pipeline...");
for(int i = 0; i < 10; i++) begin
type_cmd[i] = $random;
in_a[i] = random_vector(256/8) % (type_cmd[i] == 0 ? p_eq : secp256k1_pkg::n);
in_b[i] = random_vector(256/8) % (type_cmd[i]== 0 ? p_eq : secp256k1_pkg::n);
expected[i] = (in_a[i] * in_b[i]) % (type_cmd[i] == 0 ? p_eq : secp256k1_pkg::n);
type_cmd[i] = $urandom % 3;
in_a[i] = random_vector(256/8) % ((type_cmd[i] == 2'd0 || type_cmd[i] == 2'd2) ? p_eq : secp256k1_pkg::n);
in_b[i] = random_vector(256/8) % ((type_cmd[i] == 2'd0 || type_cmd[i] == 2'd2) ? p_eq : secp256k1_pkg::n);
expected[i] = (in_a[i] * in_b[i]);
case (type_cmd[i])
0: begin
expected[i] = expected[i] % p_eq;
end
1: begin
expected[i] = expected[i] % secp256k1_pkg::n;
end
2: begin
expected[i] = expected[i] >> 256;
expected[i] = expected[i] % p_eq;
end
endcase
end
fork
begin
for(int i = 0; i < max; i++) begin
@ -129,12 +153,12 @@ begin
integer signed get_len;
logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat;
for(int i = 0; i < max; i++) begin
out_if.get_stream(get_dat, get_len);
out_if.get_stream(get_dat, get_len, 50);
common_pkg::compare_and_print(get_dat, expected[i]);
$display("test_pipeline PASSED loop %d/%d", i, max);
end
end
join
join
$display("test_pipeline PASSED");
end
@ -144,7 +168,7 @@ initial begin
out_if.rdy = 0;
in_if.reset_source();
#(40*CLK_PERIOD);
test_pipeline();
test_loop();

View File

@ -27,18 +27,18 @@ logic clk, rst;
if_axi_stream #(.DAT_BYTS(256*6/8)) in_if(clk); // Two points
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(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(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(16)) mod_in_if(clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mod_out_if(clk);
jb_point_t in_p1, in_p2, out_p;
always_comb begin
in_p1 = in_if.dat[0 +: 256*3];
in_p2 = in_if.dat[256*3 +: 256*3];
in_p1 = in_if.dat[0 +: 256*3];
in_p2 = in_if.dat[256*3 +: 256*3];
out_if.dat = out_p;
end
@ -82,10 +82,22 @@ secp256k1_point_add secp256k1_point_add(
.i_mod_if ( mod_out_if )
);
always_comb begin
mult_out_if.sop = 1;
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
// In full design these could use dedicated multipliers or be arbitrated
secp256k1_mult_mod #(
.CTL_BITS ( 8 )
.CTL_BITS ( 16 )
)
secp256k1_mult_mod (
.i_clk ( clk ),
@ -95,17 +107,18 @@ secp256k1_mult_mod (
.i_val ( mult_in_if.val ),
.i_err ( mult_in_if.err ),
.i_ctl ( mult_in_if.ctl ),
.i_cmd ( 2'd0 ),
.o_rdy ( mult_in_if.rdy ),
.o_dat ( mult_out_if.dat ),
.i_rdy ( mult_out_if.rdy ),
.o_val ( mult_out_if.val ),
.o_ctl ( mult_out_if.ctl ),
.o_err ( mult_out_if.err )
.o_err ( mult_out_if.err )
);
secp256k1_mod #(
.USE_MULT ( 0 ),
.CTL_BITS ( 8 )
.CTL_BITS ( 16 )
)
secp256k1_mod (
.i_clk( clk ),
@ -122,65 +135,78 @@ secp256k1_mod (
.o_val( mod_out_if.val )
);
task test_0();
task test(input integer index, input jb_point_t p1, p2);
begin
integer signed get_len;
logic [common_pkg::MAX_SIM_BYTS*8-1:0] expected, get_dat;
logic [255:0] in_a, in_b;
jb_point_t p1, p2, p_exp, p_temp, p_out;
$display("Running test_0...");
//p1 = {x:3, y:4, z:1};
// p2 = {x:1, y:2, z:1};
/*p1 = {x:256'h79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
y:256'h483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8,
z:256'h0000000000000000000000000000000000000000000000000000000000000001};
p2 = {x:256'h7d152c041ea8e1dc2191843d1fa9db55b68f88fef695e2c791d40444b365afc2,
y:256'h56915849f52cc8f76f5fd7e4bf60db4a43bf633e1b1383f85fe89164bfadcbdb,
z:256'h9075b4ee4d4788cabb49f7f81c221151fa2f68914d0aa833388fa11ff621a970};
*/
p1 = {x:256'h79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
y:256'h483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8,
z:256'h1};
p2 = {x:256'h7d152c041ea8e1dc2191843d1fa9db55b68f88fef695e2c791d40444b365afc2,
y:256'h56915849f52cc8f76f5fd7e4bf60db4a43bf633e1b1383f85fe89164bfadcbdb,
z:256'h9075b4ee4d4788cabb49f7f81c221151fa2f68914d0aa833388fa11ff621a970};
jb_point_t p_exp, p_temp, p_out;
$display("Running test %d ...", index);
p_exp = add_jb_point(p1, p2);
fork
in_if.put_stream({p2, p1}, 256*6/8);
out_if.get_stream(get_dat, get_len);
join
p_out = get_dat;
$display("%d %d %d", on_curve(p1), on_curve(p2), on_curve(p_out));//, on_curve(p_temp));
if (p_exp != p_out) begin
$display("Expected:");
print_jb_point(p_exp);
$display("Was:");
print_jb_point(p_out);
$fatal(1, "%m %t ERROR: test_0 point was wrong", $time);
end
$display("test_0 PASSED");
end
$display("test %d PASSED", index);
end
endtask;
function compare_point();
endfunction
initial begin
out_if.rdy = 0;
in_if.val = 0;
#(40*CLK_PERIOD);
test_0();
test(0,
{x:256'h2475abeb8f0fc52f627afb4c18227dfa756706ceb5923cd8a209bf43c2f08815,
y:256'h4361473bccf308998bbb8c0b9a0184d186ada6e85e1cb1b82ac202380df8f762,
z:256'hdda493ffbcdc8daf0996a769bf192cc4627839d0025b4ad960c3e25dab464863},
{x:256'h4a58b6edef1379306fce3372763fd87eaf2c8f447c6408416e746e672ee6ce21,
y:256'h33adac20db34d12166586c56aa8a352b155bcfdd011f46b38c21e0c4d39968a4,
z:256'h8631df8718bcb2d2920dfd313c714a153cfc6db607891e341b0856411717cf4f});
test(1,
{x:256'd21093662951128507222548537960537987883266099219826518477955151519492458533937,
y:256'd11718937855299224635656538406325081070585145153119064354000306947171340794663,
z:256'd95062982235784117998228889817699378193266444799407382177811223706903593950986},
{x:256'd56542328592951707446199365077593875570107826996267232506335199217850131398833,
y:256'd40054381197676821721097330834174068128555866625836435038947476656223470027610,
z:256'd55019374069926147245812105698770268552109628033761289528651825525953166671152}
);
test(2,{x:256'd56542328592951707446199365077593875570107826996267232506335199217850131398833,
y:256'd40054381197676821721097330834174068128555866625836435038947476656223470027610,
z:256'd55019374069926147245812105698770268552109628033761289528651825525953166671152},
{x:256'd21093662951128507222548537960537987883266099219826518477955151519492458533937,
y:256'd11718937855299224635656538406325081070585145153119064354000306947171340794663,
z:256'd95062982235784117998228889817699378193266444799407382177811223706903593950986}
);
test(3,
{x:256'h79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
y:256'h483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8,
z:256'h1},
{x:256'h7d152c041ea8e1dc2191843d1fa9db55b68f88fef695e2c791d40444b365afc2,
y:256'h56915849f52cc8f76f5fd7e4bf60db4a43bf633e1b1383f85fe89164bfadcbdb,
z:256'h9075b4ee4d4788cabb49f7f81c221151fa2f68914d0aa833388fa11ff621a970});
#1us $finish();
end

View File

@ -0,0 +1,170 @@
/*
Copyright (C) 2019 Benjamin Devlin and Zcash Foundation
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
`timescale 1ps/1ps
module secp256k1_point_mult_endo_decom_tb ();
import common_pkg::*;
import secp256k1_pkg::*;
localparam CLK_PERIOD = 1000;
logic clk, rst;
if_axi_stream #(.DAT_BYTS(256*3/8)) in_if(clk);
if_axi_stream #(.DAT_BYTS((256*2+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);
jb_point_t in_p, out_p;
logic [255:0] k_in;
logic signed [255:0] k1_out, k2_out;
always_comb begin
in_p = in_if.dat;
out_if.dat = {k2_out, k1_out, out_p};
end
initial begin
rst = 0;
repeat(2) #(20*CLK_PERIOD) rst = ~rst;
end
initial begin
clk = 0;
forever #(CLK_PERIOD/2) clk = ~clk;
end
always_comb begin
out_if.sop = 1;
out_if.eop = 1;
out_if.ctl = 0;
out_if.mod = 0;
end
// Check for errors
always_ff @ (posedge clk)
if (out_if.val && out_if.err) begin
out_if.rdy = 1;
$error(1, "%m %t ERROR: output .err asserted", $time);
end
always_comb begin
mult_out_if.sop = 1;
mult_out_if.eop = 1;
mult_out_if.mod = 0;
end
secp256k1_point_mult_endo_decom secp256k1_point_mult_endo_decom (
.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_p ),
.i_rdy ( out_if.rdy ),
.o_val ( out_if.val ),
.o_err ( out_if.err ),
.o_k1 ( k1_out ),
.o_k2 ( k2_out ),
.o_mult_if ( mult_in_if ),
.i_mult_if ( mult_out_if )
);
secp256k1_mult_mod #(
.CTL_BITS ( 16 )
)
secp256k1_mult_mod (
.i_clk ( clk ),
.i_rst ( rst ),
.i_dat_a ( mult_in_if.dat[0 +: 256] ),
.i_dat_b ( mult_in_if.dat[256 +: 256] ),
.i_val ( mult_in_if.val ),
.i_err ( mult_in_if.err ),
.i_ctl ( mult_in_if.ctl ),
.i_cmd ( mult_in_if.ctl[7:6] ),
.o_rdy ( mult_in_if.rdy ),
.o_dat ( mult_out_if.dat ),
.i_rdy ( mult_out_if.rdy ),
.o_val ( mult_out_if.val ),
.o_ctl ( mult_out_if.ctl ),
.o_err ( mult_out_if.err )
);
// Test a point
task test(input integer index, input logic [255:0] k, jb_point_t p_exp, p_in, logic signed [255:0] k1_exp, k2_exp);
begin
integer signed get_len;
logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat;
integer start_time, finish_time;
jb_point_t p_out;
logic signed [255:0] k1, k2;
$display("Running test %d...", index);
k_in = k;
start_time = $time;
fork
in_if.put_stream(p_in, 256*3/8);
out_if.get_stream(get_dat, get_len, 0);
join
finish_time = $time;
p_out = get_dat[3*256-1:0];
k1 = get_dat[3*256 +: 256];
k2 = get_dat[4*256 +: 256];
if (p_exp != p_out || k1 != k1_exp || k2 != k2_exp) begin
$display("Expected:");
print_jb_point(p_exp);
$display("k1 %h k2 %h", k1_exp, k2_exp);
$display("Was:");
print_jb_point(p_out);
$display("k1 %h k2 %h", k1, k2);
$fatal(1, "%m %t ERROR: test %d was wrong", $time, index);
end
$display("test %d PASSED in %d clocks", index, (finish_time-start_time)/CLK_PERIOD);
end
endtask;
initial begin
out_if.rdy = 0;
in_if.val = 0;
#(40*CLK_PERIOD);
test (0,
256'd55241786844846723798409522554861295376012334658573106804016642051374977891741,
{x:256'd85340279321737800624759429340272274763154997815782306132637707972559913914315,
y:256'd32670510020758816978083085130507043184471273380659243275938904335757337482424, z:256'd1},
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'd1},
256'd384458048086738728616354309893792094261,
256'd5290804493113523428570938576690193618);
test (1,
256'd529517403483370943333515471837290126144817603611185636669178179344924684232,
{x:256'd85340279321737800624759429340272274763154997815782306132637707972559913914315,
y:256'd32670510020758816978083085130507043184471273380659243275938904335757337482424, z:256'd1},
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'd1},
256'd220390740267097681469989715867489183793,
-256'd233066591111900161328361760514744826974);
#1us $finish();
end
endmodule

View File

@ -0,0 +1,186 @@
/*
Copyright (C) 2019 Benjamin Devlin and Zcash Foundation
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
`timescale 1ps/1ps
module secp256k1_point_mult_endo_tb ();
import common_pkg::*;
import secp256k1_pkg::*;
localparam CLK_PERIOD = 1000;
logic clk, rst;
if_axi_stream #(.DAT_BYTS(256*3/8)) in_if(clk);
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;
initial begin
rst = 0;
repeat(2) #(20*CLK_PERIOD) rst = ~rst;
end
initial begin
clk = 0;
forever #(CLK_PERIOD/2) clk = ~clk;
end
always_comb begin
out_if.sop = 1;
out_if.eop = 1;
out_if.ctl = 0;
out_if.mod = 0;
end
// Check for errors
always_ff @ (posedge clk)
if (out_if.val && out_if.err) begin
out_if.rdy = 1;
$error(1, "%m %t ERROR: output .err asserted", $time);
end
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 (
.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_mult_mod #(
.CTL_BITS ( 16 )
)
secp256k1_mult_mod (
.i_clk ( clk ),
.i_rst ( rst ),
.i_dat_a ( mult_in_if.dat[0 +: 256] ),
.i_dat_b ( mult_in_if.dat[256 +: 256] ),
.i_val ( mult_in_if.val ),
.i_err ( mult_in_if.err ),
.i_ctl ( mult_in_if.ctl ),
.i_cmd ( mult_in_if.ctl[7:6] ),
.o_rdy ( mult_in_if.rdy ),
.o_dat ( mult_out_if.dat ),
.i_rdy ( mult_out_if.rdy ),
.o_val ( mult_out_if.val ),
.o_ctl ( mult_out_if.ctl ),
.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
integer signed get_len;
logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat;
logic [255:0] in_a, in_b;
integer start_time, finish_time;
jb_point_t p_out;
$display("Running test %d ...", index);
k_in = k;
start_time = $time;
fork
in_if.put_stream(p_in, 256*3/8);
out_if.get_stream(get_dat, get_len, 0);
join
finish_time = $time;
p_out = get_dat;
if (p_exp != p_out) begin
$display("Expected:");
print_jb_point(p_exp);
$display("Was:");
print_jb_point(p_out);
$fatal(1, "%m %t ERROR: test %d was wrong", $time, index);
end
$display("test %d PASSED in %d clocks", index, (finish_time-start_time)/CLK_PERIOD);
end
endtask;
initial begin
out_if.rdy = 0;
in_if.val = 0;
#(40*CLK_PERIOD);
// k1 is positive, k2 is negative here
test(0,
256'd36644297199723006697238902796853752627288044630575801382304802161070535512204,
{x:256'd45213033352668070164952185425578516070995776451206690854440958351598421068498,
y:256'd85642664275538481518837161207205935282875677695988033260377207212529188560350,
z:256'd46619474838719077565729441946941961955107434058466874326193136242340363932614},
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
// k1 and k2 is positive
test(1,
256'd55241786844846723798409522554861295376012334658573106804016642051374977891741,
{x:256'd76090149308608015449280928223196394375371085422355638787623027177573248394427,
y:256'd52052533613727108316308539229264312767646640577338787268425139698990399010025,
z:256'd114906227987603512981917844669318868106181860518720331222560351511921461319286},
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
#1us $finish();
end
endmodule

View File

@ -27,19 +27,15 @@ logic clk, rst;
if_axi_stream #(.DAT_BYTS(256*3/8)) in_if(clk);
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(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(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(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;
always_comb begin
in_p = in_if.dat;
out_if.dat = out_p;
end
initial begin
rst = 0;
@ -71,31 +67,35 @@ always_comb begin
mult_out_if.mod = 0;
mod_out_if.sop = 1;
mod_out_if.eop = 1;
mod_out_if.mod = 0;
mod_out_if.mod = 0;
end
secp256k1_point_mult #(
.RESOURCE_SHARE ("YES")
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_p ),
.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 )
);
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_mult_mod #(
.CTL_BITS ( 8 )
.CTL_BITS ( 16 )
)
secp256k1_mult_mod (
.i_clk ( clk ),
@ -105,18 +105,18 @@ 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 ( mult_in_if.ctl[7:6] ),
.o_rdy ( mult_in_if.rdy ),
.o_dat ( mult_out_if.dat ),
.i_rdy ( mult_out_if.rdy ),
.o_val ( mult_out_if.val ),
.o_ctl ( mult_out_if.ctl ),
.o_err ( mult_out_if.err )
.o_err ( mult_out_if.err )
);
secp256k1_mod #(
.USE_MULT ( 0 ),
.CTL_BITS ( 8 )
.CTL_BITS ( 16 )
)
secp256k1_mod (
.i_clk( clk ),
@ -134,14 +134,14 @@ secp256k1_mod (
);
// Test a point
task test(input logic [255:0] k, jb_point_t p_exp, p_in = secp256k1_pkg::G_p);
task test(input integer index, input logic [255:0] k, jb_point_t p_exp, p_in);
begin
integer signed get_len;
logic [common_pkg::MAX_SIM_BYTS*8-1:0] expected, get_dat;
logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat;
logic [255:0] in_a, in_b;
integer start_time, finish_time;
jb_point_t p_out;
$display("Running test_0...");
$display("Running test %d ...", index);
k_in = k;
start_time = $time;
fork
@ -149,17 +149,18 @@ begin
out_if.get_stream(get_dat, get_len);
join
finish_time = $time;
p_out = get_dat;
if (p_exp != p_out) begin
$display("Expected:");
print_jb_point(p_exp);
$display("Was:");
print_jb_point(p_out);
$fatal(1, "%m %t ERROR: test with k=%d was wrong", $time, integer'(k));
end
$fatal(1, "%m %t ERROR: test %d was wrong", $time, index);
end
$display("test with k=%d PASSED in %d clocks", integer'(k), (finish_time-start_time)/CLK_PERIOD);
$display("test %d PASSED in %d clocks", index, (finish_time-start_time)/CLK_PERIOD);
end
endtask;
@ -168,35 +169,60 @@ initial begin
out_if.rdy = 0;
in_if.val = 0;
#(40*CLK_PERIOD);
/*
test(1, {x:256'h79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
y:256'h483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8,
z:256'h1});
test(2, {x:256'h7d152c041ea8e1dc2191843d1fa9db55b68f88fef695e2c791d40444b365afc2,
y:256'h56915849f52cc8f76f5fd7e4bf60db4a43bf633e1b1383f85fe89164bfadcbdb,
z:256'h9075b4ee4d4788cabb49f7f81c221151fa2f68914d0aa833388fa11ff621a970});
test(3, {x:256'hca90ef9b06d7eb51d650e9145e3083cbd8df8759168862036f97a358f089848,
y:256'h435afe76017b8d55d04ff8a98dd60b2ba7eb6f87f6b28182ca4493d7165dd127,
z:256'h9242fa9c0b9f23a3bfea6a0eb6dbcfcbc4853fe9a25ee948105dc66a2a9b5baa});
test(4, {x:256'h9bae2d5bac61e6ea5de635bca754b2564b7d78c45277cad67e45c4cbbea6e706,
y:256'h34fb8147eed1c0fbe29ead4d6c472eb4ef7b2191fde09e494b2a9845fe3f605e,
z:256'hc327b5d2636b32f27b051e4742b1bbd5324432c1000bfedca4368a29f6654152});
test(0,
1, {x:256'h79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
y:256'h483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8,
z:256'h1},
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
test(1514155, {x:256'h759267d17957f567381462db6e240b75c9f6016091a7427cfbef33c398964a9d,
y:256'hd81ce7034647587a9b0ea5b52ac08c91f5cfae30f4eba2ade7fa68856fc0d691,
z:256'h7c9d27fb2de7927c982792630a0c86f411f2de60e8df44c5e9caff976658009c});
*/
test(256'hbad45c59dcd6d81c6a96b46a678cb893c53decc8e57465bd84efa78676ccc64a,
{x:256'he7e2b526cd2822c69ea688586501db564f28430319cdeb95cb38feb2c77fdfc3,
y:256'h6dda26c3c991cfab33a12ed7b56a0afa17d375d8fa5cabe2d1d143bb21cab887,
z:256'h2f8a851f9aec0f095a31472456a91cca12dd21da865e5a83e5d1b1085835c36c},
{x:256'h808a2c66c5b90fa1477d7820fc57a8b7574cdcb8bd829bdfcf98aa9c41fde3b4, // Not multiplying by generator
y:256'heed249ffde6e46d784cb53b4df8c9662313c1ce8012da56cb061f12e55a32249,
z:256'h1});
test(1,
2, {x:256'h7d152c041ea8e1dc2191843d1fa9db55b68f88fef695e2c791d40444b365afc2,
y:256'h56915849f52cc8f76f5fd7e4bf60db4a43bf633e1b1383f85fe89164bfadcbdb,
z:256'h9075b4ee4d4788cabb49f7f81c221151fa2f68914d0aa833388fa11ff621a970},
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
test(3,
3, {x:256'hca90ef9b06d7eb51d650e9145e3083cbd8df8759168862036f97a358f089848,
y:256'h435afe76017b8d55d04ff8a98dd60b2ba7eb6f87f6b28182ca4493d7165dd127,
z:256'h9242fa9c0b9f23a3bfea6a0eb6dbcfcbc4853fe9a25ee948105dc66a2a9b5baa},
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
test(4,
4, {x:256'h9bae2d5bac61e6ea5de635bca754b2564b7d78c45277cad67e45c4cbbea6e706,
y:256'h34fb8147eed1c0fbe29ead4d6c472eb4ef7b2191fde09e494b2a9845fe3f605e,
z:256'hc327b5d2636b32f27b051e4742b1bbd5324432c1000bfedca4368a29f6654152},
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
test(5,
256'd55241786844846723798409522554861295376012334658573106804016642051374977891741,
{x:256'd114452044609218547356220974436632746395277736533029276044444520652934189718100,
y:256'd105574650075160330358790852048157558974413633249451800413065016023266456843289,
z:256'd114502749188206279151476081115998896219274334632701318332065731739168923561257},
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
test(6,
256'd36644297199723006697238902796853752627288044630575801382304802161070535512204,
{x:256'd19559730912111231547572828279398263948482589709742643847415187021767406006262,
y:256'd56669196538343662577389952407416094360513459515269228018156259621856885572646,
z:256'd93622651521811893405023705294943233553232134901881469090144140953361623198206},
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
test(7,
1514155, {x:256'h759267d17957f567381462db6e240b75c9f6016091a7427cfbef33c398964a9d,
y:256'hd81ce7034647587a9b0ea5b52ac08c91f5cfae30f4eba2ade7fa68856fc0d691,
z:256'h7c9d27fb2de7927c982792630a0c86f411f2de60e8df44c5e9caff976658009c},
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
test(8,
256'hbad45c59dcd6d81c6a96b46a678cb893c53decc8e57465bd84efa78676ccc64a,
{x:256'he7e2b526cd2822c69ea688586501db564f28430319cdeb95cb38feb2c77fdfc3,
y:256'h6dda26c3c991cfab33a12ed7b56a0afa17d375d8fa5cabe2d1d143bb21cab887,
z:256'h2f8a851f9aec0f095a31472456a91cca12dd21da865e5a83e5d1b1085835c36c},
{x:256'h808a2c66c5b90fa1477d7820fc57a8b7574cdcb8bd829bdfcf98aa9c41fde3b4, // Not multiplying by generator
y:256'heed249ffde6e46d784cb53b4df8c9662313c1ce8012da56cb061f12e55a32249,
z:256'h1});
#1us $finish();
end
endmodule

View File

@ -22,6 +22,7 @@ import secp256k1_pkg::*;
import zcash_fpga_pkg::*;
localparam CLK_PERIOD = 5000;
localparam USE_ENDOMORPH = "NO";
logic clk, rst;
@ -42,8 +43,7 @@ end
// Check for errors
always_ff @ (posedge clk)
if (out_if.val && out_if.err) begin
out_if.rdy = 1;
if (out_if.val && out_if.err) begin;
$error(1, "%m %t ERROR: output .err asserted", $time);
end

View File

@ -1,6 +1,6 @@
/*
The zcash_fpga_top testbench.
Copyright (C) 2019 Benjamin Devlin and Zcash Foundation
This program is free software: you can redistribute it and/or modify
@ -77,7 +77,7 @@ end
always_comb begin
tx_346_if.rdy = 0;
tx_if.val = 0;
if (start_346 && ~done_346) begin
tx_346_if.rdy = tx_if.rdy;
tx_if.val = tx_346_if.val;
@ -88,7 +88,7 @@ always_comb begin
tx_if.err = tx_346_if.err;
tx_if.dat = tx_346_if.dat;
end
end
@ -135,8 +135,8 @@ begin
logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat1, get_dat2, get_dat3;
logic fail = 0;
$display("Running test_block_346_equihash...");
fork
fork
begin
// First send reset
header.cmd = RESET_FPGA;
@ -158,18 +158,18 @@ begin
rx_if.get_stream(get_dat3, get_len3); // equihash rpl
end
join
fpga_reset_rpl = get_dat1;
verify_equihash_rpl = get_dat3;
fpga_status_rpl = get_dat2;
fail |= get_len3 != $bits(verify_equihash_rpl_t)/8;
fail |= verify_equihash_rpl.hdr.cmd != VERIFY_EQUIHASH_RPL;
fail |= verify_equihash_rpl.hdr.len != $bits(verify_equihash_rpl_t)/8;
fail |= verify_equihash_rpl.index != 1;
fail |= verify_equihash_rpl.bm != 0;
assert (~fail) else $fatal(1, "%m %t ERROR: test_block_346_equihash equihash rply was wrong:\n%p", $time, verify_equihash_rpl);
fail |= get_len2 != $bits(fpga_status_rpl_t)/8;
fail |= fpga_status_rpl.hdr.cmd != FPGA_STATUS_RPL;
fail |= fpga_status_rpl.hdr.len != $bits(fpga_status_rpl_t)/8;
@ -179,13 +179,13 @@ begin
fail |= fpga_status_rpl.build_date != "20180311";
fail |= fpga_status_rpl.fpga_state == 1;
assert (~fail) else $fatal(1, "%m %t ERROR: test_block_346_equihash status reply was wrong:\n%p", $time, fpga_status_rpl);
fail |= get_len1 != $bits(fpga_reset_rpl_t)/8;
fail |= fpga_reset_rpl.hdr.cmd != RESET_FPGA_RPL;
assert (~fail) else $fatal(1, "%m %t ERROR: test_block_346_equihash reset reply was wrong:\n%p", $time, fpga_reset_rpl);
$display("test_block_346_equihash PASSED");
end
endtask
@ -198,24 +198,24 @@ begin
logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat;
logic fail = 0;
$display("Running test_ignored_message...");
// Some header value that is invalid
header = {$bits(header_t){1'b1}};
header.cmd[8 +: 8] = 0;
fork
fork
tx_if.put_stream(header, $bits(header)/8);
rx_if.get_stream(get_dat, get_len);
join
fpga_ignore_rpl = get_dat;
fail |= get_len != $bits(fpga_ignore_rpl_t)/8;
fail |= fpga_ignore_rpl.hdr.cmd != FPGA_IGNORE_RPL;
fail |= fpga_ignore_rpl.hdr.len != $bits(fpga_ignore_rpl_t)/8;
assert (~fail) else $fatal(1, "%m %t ERROR: test_ignored_message rply was wrong:\n%p", $time, fpga_ignore_rpl);
$display("test_ignored_message PASSED");
end
endtask
@ -228,7 +228,7 @@ begin
logic fail = 0;
verify_secp256k1_sig_t verify_secp256k1_sig;
verify_secp256k1_sig_rpl_t verify_secp256k1_sig_rpl;
$display("Running test_block_secp256k1...");
verify_secp256k1_sig.hdr.cmd = VERIFY_SECP256K1_SIG;
verify_secp256k1_sig.hdr.len = $bits(verify_secp256k1_sig_t)/8;
@ -238,21 +238,21 @@ begin
verify_secp256k1_sig.s = 256'hde0f72e442f7b5e8e7d53274bf8f97f0674f4f63af582554dbecbb4aa9d5cbcb;
verify_secp256k1_sig.Qx = 256'h808a2c66c5b90fa1477d7820fc57a8b7574cdcb8bd829bdfcf98aa9c41fde3b4;
verify_secp256k1_sig.Qy = 256'heed249ffde6e46d784cb53b4df8c9662313c1ce8012da56cb061f12e55a32249;
start_time = $time;
fork
tx_if.put_stream(verify_secp256k1_sig, $bits(verify_secp256k1_sig)/8);
rx_if.get_stream(get_dat, get_len);
join
finish_time = $time;
verify_secp256k1_sig_rpl = get_dat;
fail |= verify_secp256k1_sig_rpl.hdr.cmd != VERIFY_SECP256K1_SIG_RPL;
fail |= (verify_secp256k1_sig_rpl.bm != 0);
fail |= (verify_secp256k1_sig_rpl.index != verify_secp256k1_sig.index);
assert (~fail) else $fatal(1, "%m %t ERROR: test_block_secp256k1 failed :\n%p", $time, verify_secp256k1_sig_rpl);
$display("test_block_secp256k1 PASSED");
end
@ -262,11 +262,11 @@ endtask;
initial begin
rx_if.rdy = 0;
#20us; // Let internal memories reset
test_ignored_message();
test_block_346_equihash();
//test_ignored_message();
//test_block_346_equihash();
test_block_secp256k1();
#1us $finish();
end