@@ -111,12 +111,12 @@ def __init__(self, curve, x, y, z, order=None, generator=False):
111111 order *= 2
112112 doubler = PointJacobi (curve , x , y , z , order )
113113 order *= 2
114- self .__precompute .append (doubler )
114+ self .__precompute .append (( doubler . x (), doubler . y ()) )
115115
116116 while i < order :
117117 i *= 2
118118 doubler = doubler .double ().scale ()
119- self .__precompute .append (doubler )
119+ self .__precompute .append (( doubler . x (), doubler . y ()) )
120120
121121 def __eq__ (self , other ):
122122 """Compare two points with each-other."""
@@ -247,6 +247,8 @@ def _double(self, X1, Y1, Z1, p, a):
247247 """Add a point to itself, arbitrary z."""
248248 if Z1 == 1 :
249249 return self ._double_with_z_1 (X1 , Y1 , p , a )
250+ if not Z1 :
251+ return 0 , 0 , 1
250252 # after:
251253 # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl
252254 XX , YY = X1 * X1 % p , Y1 * Y1 % p
@@ -274,7 +276,7 @@ def double(self):
274276
275277 X3 , Y3 , Z3 = self ._double (X1 , Y1 , Z1 , p , a )
276278
277- if not Y3 :
279+ if not Y3 or not Z3 :
278280 return INFINITY
279281 return PointJacobi (self .__curve , X3 , Y3 , Z3 , self .__order )
280282
@@ -358,6 +360,10 @@ def __radd__(self, other):
358360
359361 def _add (self , X1 , Y1 , Z1 , X2 , Y2 , Z2 , p ):
360362 """add two points, select fastest method."""
363+ if not Y1 or not Z1 :
364+ return X2 , Y2 , Z2
365+ if not Y2 or not Z2 :
366+ return X1 , Y1 , Z1
361367 if Z1 == Z2 :
362368 if Z1 == 1 :
363369 return self ._add_with_z_1 (X1 , Y1 , X2 , Y2 , p )
@@ -394,16 +400,22 @@ def __rmul__(self, other):
394400
395401 def _mul_precompute (self , other ):
396402 """Multiply point by integer with precomputation table."""
397- result = INFINITY
398- for precomp in self .__precompute :
403+ X3 , Y3 , Z3 , p = 0 , 0 , 1 , self .__curve .p ()
404+ _add = self ._add
405+ for X2 , Y2 in self .__precompute :
399406 if other % 2 :
400407 if other % 4 >= 2 :
401- other , result = (other + 1 )// 2 , result + (- precomp )
408+ other = (other + 1 )// 2
409+ X3 , Y3 , Z3 = _add (X3 , Y3 , Z3 , X2 , - Y2 , 1 , p )
402410 else :
403- other , result = (other - 1 )// 2 , result + precomp
411+ other = (other - 1 )// 2
412+ X3 , Y3 , Z3 = _add (X3 , Y3 , Z3 , X2 , Y2 , 1 , p )
404413 else :
405414 other //= 2
406- return result
415+
416+ if not Y3 or not Z3 :
417+ return INFINITY
418+ return PointJacobi (self .__curve , X3 , Y3 , Z3 , self .__order )
407419
408420 @staticmethod
409421 def _naf (mult ):
@@ -434,16 +446,24 @@ def __mul__(self, other):
434446 return self ._mul_precompute (other )
435447
436448 self = self .scale ()
437- result = INFINITY
449+ X2 , Y2 = self .__x , self .__y
450+ X3 , Y3 , Z3 = 0 , 0 , 1
451+ p , a = self .__curve .p (), self .__curve .a ()
452+ _double = self ._double
453+ _add = self ._add
438454 # since adding points when at least one of them is scaled
439455 # is quicker, reverse the NAF order
440456 for i in reversed (self ._naf (other )):
441- result = result . double ( )
457+ X3 , Y3 , Z3 = _double ( X3 , Y3 , Z3 , p , a )
442458 if i < 0 :
443- result = result + ( - self )
459+ X3 , Y3 , Z3 = _add ( X3 , Y3 , Z3 , X2 , - Y2 , 1 , p )
444460 elif i > 0 :
445- result = result + self
446- return result
461+ X3 , Y3 , Z3 = _add (X3 , Y3 , Z3 , X2 , Y2 , 1 , p )
462+
463+ if not Y3 or not Z3 :
464+ return INFINITY
465+
466+ return PointJacobi (self .__curve , X3 , Y3 , Z3 , self .__order )
447467
448468 @staticmethod
449469 def _leftmost_bit (x ):
@@ -467,21 +487,36 @@ def mul_add(self, self_mul, other, other_mul):
467487 if not isinstance (other , PointJacobi ):
468488 other = PointJacobi .from_affine (other )
469489
490+ if self .__order :
491+ self_mul = self_mul % self .__order
492+ other_mul = other_mul % self .__order
493+
470494 i = self ._leftmost_bit (max (self_mul , other_mul ))* 2
471- result = INFINITY
495+ X3 , Y3 , Z3 = 0 , 0 , 1
496+ p , a = self .__curve .p (), self .__curve .a ()
472497 self = self .scale ()
498+ X1 , Y1 = self .__x , self .__y
473499 other = other .scale ()
500+ X2 , Y2 = other .__x , other .__y
474501 both = (self + other ).scale ()
502+ X4 , Y4 = both .__x , both .__y
503+ _double = self ._double
504+ _add = self ._add
475505 while i > 1 :
476- result = result . double ( )
506+ X3 , Y3 , Z3 = _double ( X3 , Y3 , Z3 , p , a )
477507 i = i // 2
508+
478509 if self_mul & i and other_mul & i :
479- result = result + both
510+ X3 , Y3 , Z3 = _add ( X3 , Y3 , Z3 , X4 , Y4 , 1 , p )
480511 elif self_mul & i :
481- result = result + self
512+ X3 , Y3 , Z3 = _add ( X3 , Y3 , Z3 , X1 , Y1 , 1 , p )
482513 elif other_mul & i :
483- result = result + other
484- return result
514+ X3 , Y3 , Z3 = _add (X3 , Y3 , Z3 , X2 , Y2 , 1 , p )
515+
516+ if not Y3 or not Z3 :
517+ return INFINITY
518+
519+ return PointJacobi (self .__curve , X3 , Y3 , Z3 , self .__order )
485520
486521 def __neg__ (self ):
487522 """Return negated point."""
0 commit comments