Merge branch 'master' of https://github.com/bsdevlin/zcash-fpga.git
This commit is contained in:
commit
5bb98c1349
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
This performs point addition.
|
||||
|
||||
|
||||
Copyright (C) 2019 Benjamin Devlin and Zcash Foundation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -17,7 +17,7 @@
|
|||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
module secp256k1_point_add
|
||||
module secp256k1_point_add3
|
||||
import secp256k1_pkg::*;
|
||||
#(
|
||||
)(
|
||||
|
@ -46,7 +46,7 @@ module secp256k1_point_add
|
|||
will trigger other equations. [] show what equations must be valid before this starts.
|
||||
We reuse input points (as they are latched) when possible to reduce register usage.
|
||||
Taken from https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates
|
||||
|
||||
|
||||
U1 = X1*Z2^2
|
||||
U2 = X2*Z1^2
|
||||
S1 = Y1*Z2^3
|
||||
|
@ -66,13 +66,13 @@ module secp256k1_point_add
|
|||
5. A = A * i_p1.y [eq4] ... S1
|
||||
6. C = C * i_p1.z mod p [eq3]
|
||||
7. C = C * i_p2.y mod p [eq6] .. S2
|
||||
8. i_p1.y = i_p2.x - i_p1.x mod p [eq3, eq1, eq5] .. H
|
||||
8. B = i_p2.x - i_p1.x mod p [eq3, eq1] .. H
|
||||
9. i_p2.y = C - A mod p [eq5,eq7] ... R
|
||||
10. o_p.x = i_p2.y * i_p2.y mod p [eq9] ... R^2
|
||||
11. C = i_p1.y * i_p1.y mod p [eq9] .. H^2
|
||||
12. i_p2.x = C * i_p1.y mod p [eq8, eq11] ..H^3
|
||||
11. D = B * B mod p [eq8] .. H^2
|
||||
12. i_p2.x = D * B mod p [eq8, eq11] ..H^3
|
||||
13. o_p.x = o_p.x - i_p2.x mod p [eq12, eq10]
|
||||
14. i_p1.x = i_p1.x*C [eq11, eq8] ..U1*H^2
|
||||
14. i_p1.x = i_p1.x*D [eq1, eq8] ..U1*H^2
|
||||
15. o_p.y = i_p1.x [eq14]
|
||||
16. i_p1.x = 2* i_p1.x mod p [eq15, eq14]
|
||||
17. o_p.x = o_p.x - i_p1.x [eq16, eq13]
|
||||
|
@ -81,16 +81,17 @@ module secp256k1_point_add
|
|||
20. i_p2.x = i_p2.x * A [eq5, eq12]
|
||||
21. o_p.y = o_p.y - i_p2.x [eq20, eq19]
|
||||
22. o_p.z = i_p1.z * i_p2.z mod p
|
||||
23. o_p.z = o_p.z * i_p1.y mod p [eq22, eq8]
|
||||
*/
|
||||
|
||||
23. o_p.z = o_p.z * B mod p [eq22, eq8]
|
||||
*/
|
||||
|
||||
// We also check in the inital state if one of the inputs is "None" (.z == 0), and set the output to the other point
|
||||
logic [23:0] eq_val, eq_wait;
|
||||
|
||||
// Temporary variables
|
||||
logic [255:0] A, C;
|
||||
logic [255:0] A, B, C, D;
|
||||
jb_point_t i_p1_l, i_p2_l;
|
||||
|
||||
|
||||
always_comb begin
|
||||
o_mult_if.sop = 1;
|
||||
o_mult_if.eop = 1;
|
||||
|
@ -123,14 +124,16 @@ always_ff @ (posedge i_clk) begin
|
|||
i_p2_l <= 0;
|
||||
o_err <= 0;
|
||||
A <= 0;
|
||||
B <= 0;
|
||||
C <= 0;
|
||||
D <= 0;
|
||||
end else begin
|
||||
|
||||
|
||||
o_mult_if.ctl[7:6] <= 0; // All operations are mod p
|
||||
|
||||
if (o_mult_if.rdy) o_mult_if.val <= 0;
|
||||
if (o_mod_if.rdy) o_mod_if.val <= 0;
|
||||
|
||||
|
||||
case(state)
|
||||
{IDLE}: begin
|
||||
o_rdy <= 1;
|
||||
|
@ -141,7 +144,9 @@ always_ff @ (posedge i_clk) begin
|
|||
i_p1_l <= i_p1;
|
||||
i_p2_l <= i_p2;
|
||||
A <= 0;
|
||||
B <= 0;
|
||||
C <= 0;
|
||||
D <= 0;
|
||||
if (i_val && o_rdy) begin
|
||||
state <= START;
|
||||
o_rdy <= 0;
|
||||
|
@ -179,7 +184,7 @@ always_ff @ (posedge i_clk) begin
|
|||
default: o_err <= 1;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// Check any results from multiplier
|
||||
if (i_mult_if.val && i_mult_if.rdy) begin
|
||||
eq_val[i_mult_if.ctl[5:0]] <= 1;
|
||||
|
@ -193,7 +198,7 @@ always_ff @ (posedge i_clk) begin
|
|||
6: C <= i_mult_if.dat;
|
||||
7: C <= i_mult_if.dat;
|
||||
10: o_p.x <= i_mult_if.dat;
|
||||
11: C <= i_mult_if.dat;
|
||||
11: D <= i_mult_if.dat;
|
||||
12: i_p2_l.x <= i_mult_if.dat;
|
||||
14: i_p1_l.x <= i_mult_if.dat;
|
||||
19: o_p.y <= i_mult_if.dat;
|
||||
|
@ -202,8 +207,8 @@ always_ff @ (posedge i_clk) begin
|
|||
23: o_p.z <= i_mult_if.dat;
|
||||
default: o_err <= 1;
|
||||
endcase
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
// Issue new multiplies
|
||||
if (~eq_wait[0]) begin // 0. A = i_p2.z*i_p2.z mod p
|
||||
multiply(0, i_p2_l.z, i_p2_l.z);
|
||||
|
@ -232,14 +237,14 @@ always_ff @ (posedge i_clk) begin
|
|||
if (eq_val[9] && ~eq_wait[10]) begin // 10. o_p.x = i_p2.y * i_p2.y mod p [eq9]
|
||||
multiply(10, i_p2_l.y, i_p2_l.y);
|
||||
end else
|
||||
if (eq_val[9] && ~eq_wait[11]) begin // 11. C = i_p1.y * i_p1.y mod p [eq9] .. H^2
|
||||
multiply(11, i_p1_l.y, i_p1_l.y);
|
||||
if (eq_val[8] && ~eq_wait[11]) begin // 11. C = B * B mod p [eq8] .. H^2
|
||||
multiply(11, B, B);
|
||||
end else
|
||||
if (eq_val[11] && eq_val[8] && ~eq_wait[12]) begin // 12. i_p2.x = C * i_p1.y mod p [eq8, eq11] ..H^3
|
||||
multiply(12, C, i_p1_l.y);
|
||||
if (eq_val[11] && eq_val[8] && ~eq_wait[12]) begin // 12. i_p2.x = C * B mod p [eq8, eq11] ..H^3
|
||||
multiply(12, D, B);
|
||||
end else
|
||||
if (eq_val[11] && eq_val[8] && ~eq_wait[14]) begin // 14. i_p1.x = i_p1.x*C [eq11, eq8] ..U1*H^2
|
||||
multiply(14, C, i_p1_l.x);
|
||||
if (eq_val[1] && eq_val[11] && ~eq_wait[14]) begin // 14. i_p1.x = i_p1.x*C [eq1, eq11] ..U1*H^2
|
||||
multiply(14, D, i_p1_l.x);
|
||||
end else
|
||||
if (eq_val[18] && eq_val[9] && ~eq_wait[19]) begin // 19. o_p.y = o_p.y * i_p2.y mod p [eq18, eq9]
|
||||
multiply(19, o_p.y, i_p2_l.y);
|
||||
|
@ -250,42 +255,42 @@ always_ff @ (posedge i_clk) begin
|
|||
if (~eq_wait[22]) begin // 22. o_p.z = i_p1.z * i_p2.z mod p
|
||||
multiply(22, i_p1_l.z, i_p2_l.z);
|
||||
end else
|
||||
if (eq_val[8] && eq_val[22] && ~eq_wait[23]) begin // 23. o_p.z = o_p.z * i_p1.y mod p [eq22, eq8]
|
||||
multiply(23, o_p.z, i_p1_l.y);
|
||||
if (eq_val[8] && eq_val[22] && ~eq_wait[23]) begin // 23. o_p.z = o_p.z * B mod p [eq22, eq8]
|
||||
multiply(23, o_p.z, B);
|
||||
end
|
||||
|
||||
|
||||
// Issue new modulo reductions
|
||||
if (eq_val[15] && eq_val[14] && ~eq_wait[16]) begin // 16. i_p1.x = 2* i_p1.x mod p [eq15, eq14]
|
||||
modulo(16, 2 * i_p1_l.x);
|
||||
end
|
||||
|
||||
|
||||
// Subtractions we do in-module
|
||||
if (eq_val[1] && eq_val[3] && eq_val[5] && ~eq_wait[8]) begin //8. i_p1.y = i_p2.x - i_p1.x mod p [eq3, eq1, eq5] .. H
|
||||
i_p1_l.y <= subtract(8, i_p2_l.x, i_p1_l.x);
|
||||
if (eq_val[1] && eq_val[3] && ~eq_wait[8]) begin //8. B = i_p2.x - i_p1.x mod p [eq3, eq1] .. H
|
||||
B <= subtract(8, i_p2_l.x, i_p1_l.x);
|
||||
end
|
||||
if (eq_val[5] && eq_val[7] && ~eq_wait[9]) begin //9. i_p2.y = C - A mod p [eq5,eq7] ... R
|
||||
i_p2_l.y <= subtract(9, C, A);
|
||||
end
|
||||
end
|
||||
if (eq_val[12] && eq_val[10] && ~eq_wait[13]) begin //13. o_p.x = o_p.x - i_p2.x mod p [eq12, eq10]
|
||||
o_p.x <= subtract(13, o_p.x, i_p2_l.x);
|
||||
end
|
||||
end
|
||||
if (eq_val[16] && eq_val[13] && ~eq_wait[17]) begin //17. o_p.x = o_p.x - i_p1.x [eq16, eq13]
|
||||
o_p.x <= subtract(17, o_p.x, i_p1_l.x);
|
||||
end
|
||||
end
|
||||
if (eq_val[17] && eq_val[15] && ~eq_wait[18]) begin //18. o_p.y = o_p.y - o_p.x mod p [eq17, eq15]
|
||||
o_p.y <= subtract(18, o_p.y, o_p.x);
|
||||
end
|
||||
end
|
||||
if (eq_val[20] && eq_val[19] && ~eq_wait[21]) begin //21. o_p.y = o_p.y - i_p2.x [eq20, eq19]
|
||||
o_p.y <= subtract(21, o_p.y, i_p2_l.x);
|
||||
end
|
||||
end
|
||||
|
||||
// Assignments
|
||||
if (eq_val[14] && ~eq_wait[15]) begin //15. o_p.y = i_p1.x [eq14]
|
||||
eq_wait[15] <= 1;
|
||||
eq_val[15] <= 1;
|
||||
o_p.y <= i_p1_l.x;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if (&eq_val) begin
|
||||
state <= FINISHED;
|
||||
o_val <= 1;
|
||||
|
@ -299,7 +304,7 @@ always_ff @ (posedge i_clk) begin
|
|||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
|
||||
if (o_err) begin
|
||||
o_val <= 1;
|
||||
if (o_val && i_rdy) begin
|
||||
|
@ -307,7 +312,7 @@ always_ff @ (posedge i_clk) begin
|
|||
state <= IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -163,6 +163,8 @@ begin
|
|||
end
|
||||
|
||||
$display("test %d PASSED", index);
|
||||
$display("Expected:");
|
||||
print_jb_point(p_exp);
|
||||
end
|
||||
endtask;
|
||||
|
||||
|
@ -175,15 +177,22 @@ initial begin
|
|||
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,
|
||||
|
||||
test(1,
|
||||
{x:secp256k1_pkg::Gx,
|
||||
y:secp256k1_pkg::Gx,
|
||||
z:256'h1},
|
||||
{x:256'h4a58b6edef1379306fce3372763fd87eaf2c8f447c6408416e746e672ee6ce21,
|
||||
y:256'h33adac20db34d12166586c56aa8a352b155bcfdd011f46b38c21e0c4d39968a4,
|
||||
z:256'h8631df8718bcb2d2920dfd313c714a153cfc6db607891e341b0856411717cf4f});
|
||||
test(2,
|
||||
{x:256'd21093662951128507222548537960537987883266099219826518477955151519492458533937,
|
||||
y:256'd11718937855299224635656538406325081070585145153119064354000306947171340794663,
|
||||
z:256'd95062982235784117998228889817699378193266444799407382177811223706903593950986},
|
||||
|
@ -192,7 +201,7 @@ initial begin
|
|||
z:256'd55019374069926147245812105698770268552109628033761289528651825525953166671152}
|
||||
);
|
||||
|
||||
test(2,{x:256'd56542328592951707446199365077593875570107826996267232506335199217850131398833,
|
||||
test(3,{x:256'd56542328592951707446199365077593875570107826996267232506335199217850131398833,
|
||||
y:256'd40054381197676821721097330834174068128555866625836435038947476656223470027610,
|
||||
z:256'd55019374069926147245812105698770268552109628033761289528651825525953166671152},
|
||||
{x:256'd21093662951128507222548537960537987883266099219826518477955151519492458533937,
|
||||
|
@ -200,13 +209,21 @@ initial begin
|
|||
z:256'd95062982235784117998228889817699378193266444799407382177811223706903593950986}
|
||||
);
|
||||
|
||||
test(3,
|
||||
test(4,
|
||||
{x:256'h79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
|
||||
y:256'h483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8,
|
||||
z:256'h1},
|
||||
{x:256'h7d152c041ea8e1dc2191843d1fa9db55b68f88fef695e2c791d40444b365afc2,
|
||||
y:256'h56915849f52cc8f76f5fd7e4bf60db4a43bf633e1b1383f85fe89164bfadcbdb,
|
||||
z:256'h9075b4ee4d4788cabb49f7f81c221151fa2f68914d0aa833388fa11ff621a970});
|
||||
|
||||
test(5,
|
||||
{x:256'h7d152c041ea8e1dc2191843d1fa9db55b68f88fef695e2c791d40444b365afc2,
|
||||
y:256'h56915849f52cc8f76f5fd7e4bf60db4a43bf633e1b1383f85fe89164bfadcbdb,
|
||||
z:256'h9075b4ee4d4788cabb49f7f81c221151fa2f68914d0aa833388fa11ff621a970},
|
||||
{x:256'h79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
|
||||
y:256'h483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8,
|
||||
z:256'h1});
|
||||
|
||||
#1us $finish();
|
||||
end
|
||||
|
|
|
@ -163,9 +163,27 @@ initial begin
|
|||
out_if.rdy = 0;
|
||||
in_if.val = 0;
|
||||
#(40*CLK_PERIOD);
|
||||
|
||||
// small k
|
||||
test(0,
|
||||
256'd100,
|
||||
{x:256'd58873311125979645330689234758693990322142718482440736004992395581543649864914,
|
||||
y:256'd47377800525027909577048237938220344060490567826003050245752695071342182390566,
|
||||
z:256'd51761553477962655215909011819833151162194986797617471671622162861494790249339},
|
||||
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
|
||||
|
||||
// non-generator point
|
||||
test(1,
|
||||
256'd88597706962255542391918876972219263734377338585627945549538415112195940452672,
|
||||
{x:256'd80552615195390186547923971127606116870109658210822194698567280189432004385386,
|
||||
y:256'd55329616680323056768790645890299667681467256304685784433459139116355568202824,
|
||||
z:256'd59220439792108354484526017468353461062276312804340225301633930264091097218632},
|
||||
{x:256'd58873311125979645330689234758693990322142718482440736004992395581543649864914,
|
||||
y:256'd47377800525027909577048237938220344060490567826003050245752695071342182390566,
|
||||
z:256'd51761553477962655215909011819833151162194986797617471671622162861494790249339});
|
||||
|
||||
// k1 is positive, k2 is negative here
|
||||
test(0,
|
||||
test(2,
|
||||
256'd36644297199723006697238902796853752627288044630575801382304802161070535512204,
|
||||
{x:256'd45213033352668070164952185425578516070995776451206690854440958351598421068498,
|
||||
y:256'd85642664275538481518837161207205935282875677695988033260377207212529188560350,
|
||||
|
@ -173,12 +191,14 @@ initial begin
|
|||
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
|
||||
|
||||
// k1 and k2 is positive
|
||||
test(1,
|
||||
test(3,
|
||||
256'd55241786844846723798409522554861295376012334658573106804016642051374977891741,
|
||||
{x:256'd76090149308608015449280928223196394375371085422355638787623027177573248394427,
|
||||
y:256'd52052533613727108316308539229264312767646640577338787268425139698990399010025,
|
||||
z:256'd114906227987603512981917844669318868106181860518720331222560351511921461319286},
|
||||
{x:secp256k1_pkg::Gx, y:secp256k1_pkg::Gy, z:256'h1});
|
||||
|
||||
|
||||
|
||||
|
||||
#1us $finish();
|
||||
|
|
Loading…
Reference in New Issue