@@ -219,6 +219,8 @@ class _ECAddStepTwo(Bloq):
219
219
References:
220
220
[How to compute a 256-bit elliptic curve private key with only 50 million Toffoli gates](https://arxiv.org/abs/2306.08585)
221
221
Fig 10.
222
+ [Validation of Quantum Elliptic Curve Point Addition Circuits](https://arxiv.org/abs/2506.03318)
223
+ Fig 1.
222
224
"""
223
225
224
226
n : 'SymbolicInt'
@@ -665,7 +667,7 @@ class _ECAddStepFive(Bloq):
665
667
is 0, the computed λ is undefined (and with this construction the computed λ will be set to 0),
666
668
however the λ is non-zero and should be cleared with λ_r. We accomplish this with a controled
667
669
Xor bloq controlled on the ctrl qubit and the condition that the x register (a - x_r) = 0. In
668
- this ase we clear the λ register with λ_r.
670
+ this case we clear the λ register with λ_r.
669
671
670
672
Args:
671
673
n: The bitsize of the two registers storing the elliptic curve point
@@ -686,6 +688,8 @@ class _ECAddStepFive(Bloq):
686
688
References:
687
689
[How to compute a 256-bit elliptic curve private key with only 50 million Toffoli gates](https://arxiv.org/abs/2306.08585)
688
690
Fig 10.
691
+ [Validation of Quantum Elliptic Curve Point Addition Circuits](https://arxiv.org/abs/2506.03318)
692
+ Fig 2.
689
693
"""
690
694
691
695
n : 'SymbolicInt'
@@ -826,12 +830,16 @@ class _ECAddStepSix(Bloq):
826
830
Include bugfixes for the following scenarios:
827
831
1. f_2 is improperly cleared when ((x, y) = (0, 0) AND b = 0) OR ((a, b) = (0, 0) AND
828
832
y = 0).
829
- 2. f_4 is improperly cleared when P_1 = P_2 AND f_4 is set.
833
+ 2. f_1 is improperly cleared when ((x, y) = (0, 0) AND a = 0) OR ((a, b) = (0, 0) AND
834
+ x = 0).
835
+ 3. f_4 is improperly cleared when P_1 = P_2 AND f_4 is set.
830
836
831
837
The bugs are fixed respectively by:
832
838
1. Clearing f_2 when x = y = b = 0 OR a = b = y = 0 using an XGate controlled on those
833
839
registers.
834
- 2. Moving the CModSub and CModAdd bloqs before the Equals bloq.
840
+ 2. Clearing f_1 when x = y = a = 0 OR a = b = x = 0 using an XGate controlled on those
841
+ registers.
842
+ 3. Moving the CModSub and CModAdd bloqs before the Equals bloq.
835
843
836
844
Args:
837
845
n: The bitsize of the two registers storing the elliptic curve point
@@ -853,6 +861,8 @@ class _ECAddStepSix(Bloq):
853
861
References:
854
862
[How to compute a 256-bit elliptic curve private key with only 50 million Toffoli gates](https://arxiv.org/abs/2306.08585)
855
863
Fig 10.
864
+ [Validation of Quantum Elliptic Curve Point Addition Circuits](https://arxiv.org/abs/2506.03318)
865
+ Fig 3.
856
866
"""
857
867
858
868
n : 'SymbolicInt'
@@ -917,8 +927,12 @@ def build_composite_bloq(
917
927
f3 = f_ctrls [1 ]
918
928
f4 = f_ctrls [2 ]
919
929
920
- # Unset f2 if ((a, b ) = (0, 0) AND y = 0) OR ((x, y ) = (0, 0) AND b = 0).
930
+ # Unset f1 if ((x, y ) = (0, 0) AND a = 0) OR ((a, b ) = (0, 0) AND x = 0).
921
931
mcx = XGate ().controlled (CtrlSpec (qdtypes = QMontgomeryUInt (self .n ), cvs = [0 , 0 , 0 ]))
932
+ [a , x , y ], f1 = bb .add (mcx , ctrl = [a , x , y ], q = f1 )
933
+ [x , a , b ], f1 = bb .add (mcx , ctrl = [x , a , b ], q = f1 )
934
+
935
+ # Unset f2 if ((a, b) = (0, 0) AND y = 0) OR ((x, y) = (0, 0) AND b = 0).
922
936
[a , b , y ], f2 = bb .add (mcx , ctrl = [a , b , y ], q = f2 )
923
937
[x , y , b ], f2 = bb .add (mcx , ctrl = [x , y , b ], q = f2 )
924
938
@@ -1015,7 +1029,7 @@ def build_call_graph(self, ssa: SympySymbolAllocator) -> BloqCountDictT:
1015
1029
cvs2 = HasLength (2 * self .n )
1016
1030
return {
1017
1031
MultiControlX (cvs = cvs2 ): 1 ,
1018
- XGate ().controlled (CtrlSpec (qdtypes = QMontgomeryUInt (self .n ), cvs = [0 , 0 , 0 ])): 2 ,
1032
+ XGate ().controlled (CtrlSpec (qdtypes = QMontgomeryUInt (self .n ), cvs = [0 , 0 , 0 ])): 4 ,
1019
1033
MultiControlX (cvs = [0 ] * 3 ): 1 ,
1020
1034
CModSub (QMontgomeryUInt (self .n ), mod = self .mod ): 1 ,
1021
1035
CModAdd (QMontgomeryUInt (self .n ), mod = self .mod ): 1 ,
0 commit comments