
    E#i                         S SK Jr  SSKJr   " S S\5      r " S S\5      r " S S	\5      r " S
 S\5      r\" SSS5      r	g)    )division   )numbertheoryc                   <    \ rS rSrSrS rS rS rS rS r	S r
S	rg
)CurveFp(   z9Elliptic Curve over the field of integers modulo a prime.c                 (    Xl         X l        X0l        g)z;The curve of points satisfying y^2 = x^3 + a*x + b (mod p).N_CurveFp__p_CurveFp__a_CurveFp__b)selfpabs       f/home/james-whalen/.local/lib/python3.13/site-packages/ccxt/static_dependencies/ecdsa/ellipticcurve.py__init__CurveFp.__init__+   s        c                     U R                   $ N)r   r   s    r   r   	CurveFp.p1       xxr   c                     U R                   $ r   )r   r   s    r   r   	CurveFp.a4   r   r   c                     U R                   $ r   )r   r   s    r   r   	CurveFp.b7   r   r   c                 t    X"-  X-  U-  U R                   U-  -   U R                  -   -
  U R                  -  S:H  $ )z!Is the point (x,y) on this curve?r   )r   r   r   )r   xys      r   contains_pointCurveFp.contains_point:   s9    TXX\1DHH<=IQNNr   c                 N    SU R                   U R                  U R                  4-  $ )NzCurveFp(p=%d, a=%d, b=%d)r
   r   s    r   __str__CurveFp.__str__>   s     *dhh$((-KKKr   )__a__b__pN)__name__
__module____qualname____firstlineno____doc__r   r   r   r   r"   r%   __static_attributes__ r   r   r   r   (   s%    COLr   r   c                   ^    \ rS rSrSrSS jrS rS rS rS r	S	 r
S
 rS rS rS rS rSrg)PointB   znA point on an elliptic curve. Altering x and y is forbidding,
but they can be read by the x() and y() methods.Nc                     Xl         X l        X0l        X@l        U R                   (       a"  U R                   R	                  X#5      (       d   eU(       a  X-  [
        :X  d   egg)z@curve, x, y, order; order (optional) is the order of this point.N)_Point__curve	_Point__x	_Point__y_Point__orderr"   INFINITY)r   curver    r!   orders        r   r   Point.__init__F   sP    <<<<..q4444<8+++ r   c                     U R                   UR                   :X  a5  U R                  UR                  :X  a  U R                  UR                  :X  a  gg)z9Return True if the points are identical, False otherwise.TF)r5   r6   r7   r   others     r   __eq__Point.__eq__R   s8    <<5==(HH		)HH		)r   c                    U[         :X  a  U $ U [         :X  a  U$ U R                  UR                  :X  d   eU R                  UR                  :X  aN  U R                  UR                  -   U R                  R	                  5       -  S:X  a  [         $ U R                  5       $ U R                  R	                  5       nUR                  U R                  -
  [        R                  " UR                  U R                  -
  U5      -  U-  nX3-  U R                  -
  UR                  -
  U-  nX0R                  U-
  -  U R                  -
  U-  n[        U R                  XE5      $ )zAdd one point to another point.r   )	r9   r5   r6   r7   r   doubler   inverse_modr2   )r   r?   r   lx3y3s         r   __add__Point.__add__[   s   
 HK8L||u}},,,88uyy 599$(88A={{}$LLNNii$(("%%eii$((&:A>?BCD edhh*a/88b=!DHH,1T\\2**r   c                    S nUnU R                   (       a  X0R                   -  nUS:X  a  [        $ U [        :X  a  [        $ US:  d   eSU-  n[        U R                  U R                  U R
                  * U R                   5      nU" U5      S-  nU nUS:  aE  UR                  5       nXF-  S:w  a  X6-  S:X  a  Xp-   nXF-  S:X  a  X6-  S:w  a  Xu-   nUS-  nUS:  a  ME  U$ )Multiply a point by an integer.c                 B    U S:  d   eSnX::  a  SU-  nX::  a  M  US-  $ )Nr   r      r0   )r    results     r   leftmost_bit#Point.__mul__.<locals>.leftmost_bitx   s1    q5L5F+V +Q;r   r      rM   r   )r8   r9   r2   r5   r6   r7   rC   )r   r?   rO   ee3negative_selfirN   s           r   __mul__Point.__mul__u   s    	 <<LL A6O8O1uu UdllDHHtxxiN!!e]]_F1}!%A1}!%A/QA !e r   c                 
    X-  $ )rK   r0   r>   s     r   __rmul__Point.__rmul__   s     |r   c                 N    U [         :X  a  gSU R                  U R                  4-  $ )Ninfinityz(%d,%d))r9   r6   r7   r   s    r   r%   Point.__str__   s%    8DHHdhh///r   c                    U [         :X  a  [         $ U R                  R                  5       nU R                  R                  5       nSU R                  -  U R                  -  U-   [
        R                  " SU R                  -  U5      -  U-  nX3-  SU R                  -  -
  U-  nX0R                  U-
  -  U R                  -
  U-  n[        U R                  XE5      $ )z)Return a new point that is twice the old.rQ   rM   )	r9   r5   r   r   r6   r   rD   r7   r2   )r   r   r   rE   rF   rG   s         r   rC   Point.double   s     8O LLNNLLNN$((lTXX%)%%a$((lA67:;< ea$((l"a'88b=!DHH,1T\\2**r   c                     U R                   $ r   )r6   r   s    r   r    Point.x   r   r   c                     U R                   $ r   )r7   r   s    r   r!   Point.y   r   r   c                     U R                   $ r   )r5   r   s    r   r:   Point.curve       ||r   c                     U R                   $ r   )r8   r   s    r   r;   Point.order   rf   r   )__curve__order__x__yr   )r*   r+   r,   r-   r.   r   r@   rH   rV   rY   r%   rC   r    r!   r:   r;   r/   r0   r   r   r2   r2   B   s?    9
,+4#J
0
+&r   r2   c                       \ rS rSrSr\S 5       r\S 5       r\S 5       r	\S 5       r
\ SS j5       rS	 rS
 rS rS rSS jr\S 5       rSrg)AbstractPoint   z2Class for common methods of elliptic curve points.c                     [        U 5      U:X  d   eU SUS-   nXS-  S n[        U5      US-  :X  d   e[        U5      US-  :X  d   e[        U5      n[        U5      nXE4$ )z
Decode public point from :term:`raw encoding`.

:term:`raw encoding` is the same as the :term:`uncompressed` encoding,
but without the 0x04 byte at the beginning.
NrM   )lenstring_to_number)dataraw_encoding_lengthxsyscoord_xcoord_ys         r   _from_raw_encoding AbstractPoint._from_raw_encoding   s     4y////,'1,-*,- 2w-22222w-2222"2&"2&r   c                    U SS S;  a  [        S5      eU SS S:H  n[        U SS 5      nUR                  5       n[        USU5      UR	                  5       U-  -   UR                  5       -   U-  n [        R                  " XT5      nU[        US-  5      :X  a  XF-
  nX84$ UnX84$ ! [        R                   a  n[        SU5      eSnAff = f)z-Decode public point from compressed encoding.Nr   )      z#Malformed compressed point encodingr|   rQ   0Encoding does not correspond to a point on curve)
MalformedPointErrorrr   r   powr   r   r   square_root_mod_primeErrorbool)	rs   r:   is_evenr    r   alphabetarR   r!   s	            r   _from_compressedAbstractPoint._from_compressed   s     8--%&KLLr(g%T!"X&GGIQ1Q/%'');q@	55e?D
 d4!8n$A t At !! 	%BA 	s   1B% %C
9CC
c                     USS S;   d   eU R                  USS U5      u  pEU(       a1  US-  (       a	  USS S:w  d  US-  (       d  USS S:w  a  [        S5      eXE4$ )z)Decode public point from hybrid encoding.Nr         r   r   z"Inconsistent hybrid point encoding)ry   r   )clsrs   rt   validate_encodingr    r!   s         r   _from_hybridAbstractPoint._from_hybrid   sx     BQx---- %%d12h0CD ERaG#ERaG#%&JKKtr   c                 8   [        U5      nUR                  5       n[        U5      S-   S-   S-  n[        U5      U:w  a  [	        S5      eUS   S-  S-	  nUS==   S-  ss'   [        US5      n[        (       a  [        U5      nXf-  S-
  [        R                  " UR                  5       U-  U-  UR                  5       -
  U5      -  U-  n [        R                  " Xs5      nUS-  U:w  a  U* U-  nX4$ ! [        R                   a  n	[	        S	U	5      eS
n	A	ff = f)z#Decode a point on an Edwards curve.r         z%Point length doesn't match the curve.      littler~   NrM   )	bytearrayr   
bit_lengthrq   r   bytes_to_intGMPYmpzr   rD   dr   r   r   )
r   r:   rs   r   exp_lenx_0r!   x2r    rR   s
             r   _from_edwardsAbstractPoint._from_edwards  s(    GGIa=1$q(Q.t9%&MNNBx$1$RHx(4AA UQY&&uwwy1}q'85779'DaHI 		2229A q5C<QAt !! 	%BA 	s   C4 4DDDNc                    U(       d  [        / SQ5      n[        S U 5       5      (       d  [        S5      e[        U5      n[	        U[
        5      (       a  U R                  X5      $ [        U5      nS[        UR                  5       5      -  nXV:X  a  SU;   a  U R                  X&5      u  pxXx4$ XVS-   :X  af  SU;   d  SU;   aZ  US	S S
;   a  SU;   a  U R                  X&U5      u  pxXx4$ US	S S:X  a   SU;   a  U R                  USS	 U5      u  pxXx4$ [        S5      eXVS-  S-   :X  a  SU;   a  U R                  X!5      u  pxXx4$ [        SR                  SR                  U5      5      5      e)a  
Initialise the object from byte encoding of a point.

The method does accept and automatically detect the type of point
encoding used. It supports the :term:`raw encoding`,
:term:`uncompressed`, :term:`compressed`, and :term:`hybrid` encodings.

Note: generally you will want to call the ``from_bytes()`` method of
either a child class, PointJacobi or Point.

:param data: single point encoding of the public key
:type data: :term:`bytes-like object`
:param curve: the curve on which the public key is expected to lay
:type curve: ~ecdsa.ellipticcurve.CurveFp
:param validate_encoding: whether to verify that the encoding of the
    point is self-consistent, defaults to True, has effect only
    on ``hybrid`` encoding
:type validate_encoding: bool
:param valid_encodings: list of acceptable point encoding formats,
    supported ones are: :term:`uncompressed`, :term:`compressed`,
    :term:`hybrid`, and :term:`raw encoding` (specified with ``raw``
    name). All formats by default (specified with ``None``).
:type valid_encodings: :term:`set-like object`

:raises `~ecdsa.errors.MalformedPointError`: if the public point does
    not lay on the curve or the encoding is invalid

:return: x and y coordinates of the encoded point
:rtype: tuple(int, int)
uncompressed
compressedhybridrawc              3   >   #    U  H  nU[        S 5      ;   v   M     g7f)r   N)set).0rU   s     r   	<genexpr>+AbstractPoint.from_bytes.<locals>.<genexpr>N  s"      
$ DEE$s   z@Only uncompressed, compressed, hybrid or raw encoding supported.rM   r   r   r   r   Nr      z*Invalid X9.62 encoding of the public pointr   z[Length of string does not match lengths of any of the enabled ({0}) encodings of the curve.z, )r   all
ValueErrornormalise_bytes
isinstance	CurveEdTwr   rq   orderlenr   ry   r   r   r   formatjoin)	r   r:   rs   r   valid_encodingskey_lenrt   rw   rx   s	            r   
from_bytesAbstractPoint.from_bytes(  s   D !?O  
$
 
 
   t$eY''$$U11d)(5779"55)e.F"55 G: 5 a//'>_+LBQx--(o2M#&#3#3/@$ , ' bqW$?)J#&#9#9H1$ $  *@  a/!33/"33D@G  &		/ :; r   c                     U R                  5       R                  5       n[        U R                  5       U5      n[        U R	                  5       U5      nX#-   $ )z.Convert the point to the :term:`raw encoding`.r:   r   number_to_stringr    r!   )r   primex_stry_strs       r   _raw_encodeAbstractPoint._raw_encode}  s@    

  51 51}r   c                     U R                  5       R                  5       n[        U R                  5       U5      nU R	                  5       S-  (       a  SU-   $ SU-   $ )z*Encode the point into the compressed form.r   r}   r|   r   )r   r   r   s      r   _compressed_encode AbstractPoint._compressed_encode  sG    

  51668a<U?"r   c                 f    U R                  5       nU R                  5       S-  (       a  SU-   $ SU-   $ )z&Encode the point into the hybrid form.r   r   r   )r   r!   )r   raw_encs     r   _hybrid_encodeAbstractPoint._hybrid_encode  s3    ""$668a<W$$  r   c                    U R                  5         U R                  5       U R                  5       U R                  5       R	                  5       p2n[        U5      S-   S-   S-  n[        X$S5      nUS-  (       a  US==   S-  ss'   U$ )z/Encode the point according to RFC8032 encoding.r   r   r   r   rM   r   r   )scaler    r!   r:   r   r   int_to_bytes)r   r    r!   r   enc_lenr   s         r   _edwards_encodeAbstractPoint._edwards_encode  so    

&&(DFFHdjjlnn&6a a=1$q(Q.Q2q5"IIr   c                 &   US;   d   eU R                  5       n[        U[        5      (       a  U R                  5       $ US:X  a  U R	                  5       $ US:X  a  SU R	                  5       -   $ US:X  a  U R                  5       $ U R                  5       $ )a  
Convert the point to a byte string.

The method by default uses the :term:`raw encoding` (specified
by `encoding="raw"`. It can also output points in :term:`uncompressed`,
:term:`compressed`, and :term:`hybrid` formats.

For points on Edwards curves `encoding` is ignored and only the
encoding defined in RFC 8032 is supported.

:return: :term:`raw encoding` of a public on the curve
:rtype: bytes
)r   r   r   r   r   r   r   r   )r:   r   r   r   r   r   r   )r   encodingr:   s      r   to_bytesAbstractPoint.to_bytes  s     JJJJ

eY''''))##%%'T--///!&&((**,,r   c                     / nU (       aO  U S-  (       a&  U S-  nUS:  a  US-  nUR                  U5        X-  n OUR                  S5        U S-  n U (       a  MO  U$ )z&Calculate non-adjacent form of number.rM      r   )append)multretnds      r   _nafAbstractPoint._naf  s`     axAX7!GB

2


1QJD d 
r   r0   )TN)r   )r*   r+   r,   r-   r.   staticmethodry   r   classmethodr   r   r   r   r   r   r   r   r   r/   r0   r   r   rn   rn      s    <   (  *  &    D BFR  R h!
-6  r   rn   c                     ^  \ rS rSrSrS!U 4S jjr\    S"U 4S jj5       rS rS r	S r
S rS	 rS
 rS rS rS rS rS r\S#S j5       rS rS rS rS rS rS rS rS rS rS rS rS r S r!S r"S r#S r$U =r%$ )$PointJacobii  u   
Point on a short Weierstrass elliptic curve. Uses Jacobi coordinates.

In Jacobian coordinates, there are three parameters, X, Y and Z.
They correspond to affine parameters 'x' and 'y' like so:

x = X / Z²
y = Y / Z³
c                   > [         [        U ]  5         Xl        [        (       a?  [        U5      [        U5      [        U5      4U l        U=(       a    [        U5      U l        OX#U4U l        XPl        X`l        / U l	        g)a  
Initialise a point that uses Jacobi representation internally.

:param CurveFp curve: curve on which the point resides
:param int x: the X parameter of Jacobi representation (equal to x when
  converting from affine coordinates
:param int y: the Y parameter of Jacobi representation (equal to y when
  converting from affine coordinates
:param int z: the Z parameter of Jacobi representation (equal to 1 when
  converting from affine coordinates
:param int order: the point order, must be non zero when using
  generator=True
:param bool generator: the point provided is a curve generator, as
  such, it will be commonly used with scalar multiplication. This will
  cause to precompute multiplication table generation for it
N)
superr   r   _PointJacobi__curver   r   _PointJacobi__coords_PointJacobi__order_PointJacobi__generator_PointJacobi__precompute)r   r:   r    r!   zr;   	generator	__class__s          r   r   PointJacobi.__init__  sd    " 	k4)+4 VSVSV4DM /SZDL1IDM L$r   c                 L   > [         [        U ]  XX45      u  px[        XUSXV5      $ )ax  
Initialise the object from byte encoding of a point.

The method does accept and automatically detect the type of point
encoding used. It supports the :term:`raw encoding`,
:term:`uncompressed`, :term:`compressed`, and :term:`hybrid` encodings.

:param data: single point encoding of the public key
:type data: :term:`bytes-like object`
:param curve: the curve on which the public key is expected to lay
:type curve: ~ecdsa.ellipticcurve.CurveFp
:param validate_encoding: whether to verify that the encoding of the
    point is self-consistent, defaults to True, has effect only
    on ``hybrid`` encoding
:type validate_encoding: bool
:param valid_encodings: list of acceptable point encoding formats,
    supported ones are: :term:`uncompressed`, :term:`compressed`,
    :term:`hybrid`, and :term:`raw encoding` (specified with ``raw``
    name). All formats by default (specified with ``None``).
:type valid_encodings: :term:`set-like object`
:param int order: the point order, must be non zero when using
    generator=True
:param bool generator: the point provided is a curve generator, as
    such, it will be commonly used with scalar multiplication. This
    will cause to precompute multiplication table generation for it

:raises `~ecdsa.errors.MalformedPointError`: if the public point does
    not lay on the curve or the encoding is invalid

:return: Point on curve
:rtype: PointJacobi
r   )r   r   r   )
r   r:   rs   r   r   r;   r   rw   rx   r   s
            r   r   PointJacobi.from_bytes  s3    T !c=*
 57AuHHr   c                    U R                   (       a  U R                  (       a  g U R                  nU(       d   e/ nSnUS-  nU R                  u  pEn[	        U R
                  XEXa5      nUS-  nUR                  UR                  5       UR                  5       45        X1:  aY  US-  nUR                  5       R                  5       nUR                  UR                  5       UR                  5       45        X1:  a  MY  X l        g )Nr   rM   )r   r   r   r   r   r   r   r    r!   rC   r   )r   r;   
precomputerU   rw   rx   coord_zdoublers           r   _maybe_precomputePointJacobi._maybe_precompute!  s    4#4#4 u

$(MM!'dllGgM
799;		45iFAnn&,,.Gwyy{GIIK89 i
 'r   c                 :    U R                   R                  5       nU$ r   )__dict__copyr   states     r   __getstate__PointJacobi.__getstate__;  s    
 ""$r   c                 :    U R                   R                  U5        g r   )r   updater   s     r   __setstate__PointJacobi.__setstate__C  s    U#r   c                    U R                   u  p#nU[        L a  U(       + $ [        U[        5      (       a"  UR	                  5       UR                  5       SpvnO+[        U[        5      (       a  UR                   u  pVnO[        $ U R                  UR                  5       :w  a  gU R                  R                  5       nXD-  U-  n	Xw-  U-  n
X*-  XY-  -
  U-  S:H  =(       a    X:-  U-  Xi-  U-  -
  U-  S:H  $ )zmCompare for equality two points with each-other.

Note: only points that lay on the same curve can be equal.
r   Fr   )r   r9   r   r2   r    r!   r   NotImplementedr   r:   r   )r   r?   x1y1z1r   y2z2r   zz1zz2s              r   r@   PointJacobi.__eq__F  s    
 ]]
H6MeU##EGGIqBBB{++JBB!!<<5;;=(LLNNgkgk
 28#q(A- HrMBHrM)33 	r   c                     X:X  + $ )z2Compare for inequality two points with each-other.r0   r>   s     r   __ne__PointJacobi.__ne__b  s      r   c                     U R                   $ )z9Return the order of the point.

None if it is undefined.
)r   r   s    r   r;   PointJacobi.orderf  s    
 ||r   c                     U R                   $ )z-Return curve over which the point is defined.)r   r   s    r   r:   PointJacobi.curvem  s    ||r   c                     U R                   u  pnUS:X  a  U$ U R                  R                  5       n[        R                  " X45      nXS-  -  U-  $ )a  
Return affine x coordinate.

This method should be used only when the 'y' coordinate is not needed.
It's computationally more efficient to use `to_affine()` and then
call x() and y() on the returned instance. Or call `scale()`
and then x() and y() on the returned instance.
r   rM   r   r   r   r   rD   )r   r    _r   r   s        r   r    PointJacobi.xq  M     --a6HLLNN$$Q*a4x!|r   c                     U R                   u  pnUS:X  a  U$ U R                  R                  5       n[        R                  " X45      nX#S-  -  U-  $ )a  
Return affine y coordinate.

This method should be used only when the 'x' coordinate is not needed.
It's computationally more efficient to use `to_affine()` and then
call x() and y() on the returned instance. Or call `scale()`
and then x() and y() on the returned instance.
r   rQ   r  )r   r  r!   r   r   s        r   r!   PointJacobi.y  r  r   c                     U R                   u  pnUS:X  a  U $ U R                  R                  5       n[        R                  " X45      nXU-  U-  nX-  U-  nX&-  U-  U-  nXS4U l         U $ )zM
Return point scaled so that z == 1.

Modifies point in place, returns self.
r   r  )r   r    r!   r   r   z_invzz_invs          r   r   PointJacobi.scale  sw     --a6K LLNN((."JNJ"q	r   c                    U R                   u    pU R                  R                  5       nX#-  (       d  [        $ U R	                  5         U R                   u  pEnUS:X  d   e[        U R                  XEU R                  5      $ )zReturn point in affine form.r   )r   r   r   r9   r   r2   r   )r   r  r   r   r    r!   s         r   	to_affinePointJacobi.to_affine  sa    --1LLNNO

--aAvvT\\166r   c                     [        U R                  5       U R                  5       U R                  5       SU R	                  5       U5      $ )zCreate from an affine point.

:param bool generator: set to True to make the point to precalculate
  multiplication table - useful for public point when verifying many
  signatures (around 100 or so) or for generator points of a curve.
r   )r   r:   r    r!   r;   )pointr   s     r   from_affinePointJacobi.from_affine  s6     KKM5779eggiEKKM9
 	
r   c                     X-  U-  X"-  U-  peU(       d  gXf-  U-  nSX-   S-  U-
  U-
  -  U-  nSU-  U-   n	X-  SU-  -
  U-  n
XU
-
  -  SU-  -
  U-  nSU-  U-  nXU4$ )z"Add a point to itself with z == 1.r   r   r   rM   rQ   r   r0   )r   X1Y1r   r   XXYYYYYYSMTY3Z3s                r   _double_with_z_1PointJacobi._double_with_z_1  s     1bgkBw{"'a"$t+,q0FQJUQU]aq5kAH$)VaZbyr   c                 0   US:X  a  U R                  XXE5      $ U(       d  gX-  U-  X"-  U-  pvU(       d  gXw-  U-  nX3-  U-  n	SX-   S-  U-
  U-
  -  U-  n
SU-  XY-  U	-  -   U-  nX-  SU
-  -
  U-  nXU-
  -  SU-  -
  U-  nX#-   S-  U-
  U	-
  U-  nXU4$ )z#Add a point to itself, arbitrary z.r   r"  rM   rQ   r   )r-  )r   r#  r$  Z1r   r   r%  r&  r'  ZZr(  r)  r*  r+  r,  s                  r   _doublePointJacobi._double  s    7((66 1bgkBw{Wq["'a"$t+,q0Vafrk!Q&UQU]aq5kAH$)w1nr!B&!+byr   c                 (   U R                   u  pnU(       d  [        $ U R                  R                  5       U R                  R	                  5       pTU R                  XX4U5      u  pgnU(       d  [        $ [        U R                  XgXR                  5      $ )zAdd a point to itself.)r   r9   r   r   r   r2  r   r   )	r   r#  r$  r0  r   r   X3r+  r,  s	            r   rC   PointJacobi.double  si    ]]
O||~~!11\\""3
O4<<\\BBr   c                    X1-
  nXf-  nSU-  U-  nXh-  n	SXB-
  -  n
U(       d1  U
(       d*  U R                  XXPR                  R                  5       5      $ X-  nU
S-  U	-
  SU-  -
  U-  nXU-
  -  SU-  U	-  -
  U-  nSU-  U-  nXU4$ )z&add points when both Z1 and Z2 equal 1r   rM   r-  r   r   )r   r#  r$  X2Y2r   HHHIJrVr5  r+  r,  s                  r   _add_with_z_1PointJacobi._add_with_z_1  s     GUFQJEM((LLNN4DEEFdQhQ!#r6lQVaZ'1,UQYrzr   c                 
   XA-
  S-  U-  nX-  U-  nXG-  n	XR-
  S-  U-  n
U(       d2  U
(       d+  U R                  XX6U R                  R                  5       5      $ X-
  U	-
  U-  nXR-
  X-
  -  X)U-
  -  -
  U-  nX4U-
  -  U-  nXU4$ )zadd points when Z1 == Z2rM   r2  r   r   )r   r#  r$  r0  r9  r:  r   ABCDr5  r+  r,  s                 r   _add_with_z_eqPointJacobi._add_with_z_eq  s     WNQFQJFWNQ<<t||~~/?@@eai1_w16"Rq5\1Q67^arzr   c                 `   X3-  U-  nXG-  U-  XS-  U-  U-  pX-
  U-  n
X-  U-  nSU-  U-  nX-  nSX-
  -  U-  nU(       d1  U
(       d*  U R                  XEX`R                  R                  5       5      $ X-  nX-  U-
  SU-  -
  U-  nXU-
  -  SU-  U-  -
  U-  nX:-   S-  U-
  U-
  U-  nUUU4$ )zadd points when Z2 == 1r   rM   r8  )r   r#  r$  r0  r9  r:  r   Z1Z1U2S2r;  r<  r=  r>  r?  r@  r5  r+  r,  s                      r   _add_with_z2_1PointJacobi._add_with_z2_1  s     w{Q$ 2BWMUQYFQJEMA((LLNN4DEEFeai!a%1$r6lQVaZ'1,v!md"R'1,2rzr   c                    X3-  U-  nXf-  U-  n	X-  U-  n
XH-  U-  nX&-  U	-  U-  nXS-  U-  U-  nX-
  nSU-  U-  U-  nX-  U-  nSX-
  -  U-  nU(       d2  U(       d+  U R                  XX7U R                  R                  5       5      $ X-  nUU-  U-
  SU-  -
  U-  nUUU-
  -  SU-  U-  -
  U-  nX6-   S-  U-
  U	-
  U-  U-  nUUU4$ )zadd points with arbitrary zr   rM   rD  )r   r#  r$  r0  r9  r:  Z2r   rL  Z2Z2U1rM  S1rN  r;  r=  r>  r?  r@  r5  r+  r,  s                         r   _add_with_z_nePointJacobi._add_with_z_ne/  s    w{w{Y]Y]Wt^aWt^aGEAIMEAIMA<<t||~~/?@@F!eai!a%1$1r6lQVaZ'1,w1nt#d*a/!32rzr   c                 
    X-   $ )zAdd other to self.r0   r>   s     r   __radd__PointJacobi.__radd__F  
    |r   c           	      8   U(       d  XG-  XW-  Xg-  4$ U(       d  X-  X'-  X7-  4$ X6:X  a,  US:X  a  U R                  XXEU5      $ U R                  XX4XW5      $ US:X  a  U R                  XEXaX'5      $ US:X  a  U R                  XX4XW5      $ U R                  XX4XVU5      $ )z&add two points, select fastest method.r   )rA  rI  rO  rV  )r   r#  r$  r0  r9  r:  rR  r   s           r   _addPointJacobi._addJ  s    62626))62626))8Qw))""!<<&&rrr==7&&rrr==7&&rrr==""2221==r   c           	         U [         :X  a  U$ U[         :X  a  U $ [        U[        5      (       a  [        R	                  U5      nU R
                  UR
                  :w  a  [        S5      eU R
                  R                  5       nU R                  u  p4nUR                  u  pgnU R                  X4XVXxU5      u  pnU(       d  [         $ [        U R
                  XXR                  5      $ )z!Add two points on elliptic curve.z%The other point is on different curve)r9   r   r2   r   r  r   r   r   r   r]  r   )r   r?   r   r#  r$  r0  r9  r:  rR  r5  r+  r,  s               r   rH   PointJacobi.__add__Z  s    8LHKeU##++E2E<<5==(DEELLNN]]
^^
YYrrrq9
O4<<\\BBr   c                 
    X-  $ )Multiply point by an integer.r0   r>   s     r   rY   PointJacobi.__rmul__o  r[  r   c           
      x   SSSU R                   R                  5       4u  p#pEU R                  nU R                   HP  u  pxUS-  (       a<  US-  S:  a  US-   S-  nU" X#XGU* SU5      u  p#nM2  US-
  S-  nU" X#XGUSU5      u  p#nMK  US-  nMR     U(       d  [        $ [        U R                   X#X@R                  5      $ )z4Multiply point by integer with precomputation table.r   rM   r   r   )r   r   r]  r   r9   r   r   )	r   r?   r5  r+  r,  r   r]  r9  r:  s	            r   _mul_precomputePointJacobi._mul_precomputes  s    1a!11yy''FBqy19>"QY1,E!%bbrc1a!@JBB"QY1,E!%bbb!Q!?JBB! ( O4<<\\BBr   c           
         U R                   S   (       a  U(       d  [        $ US:X  a  U $ U R                  (       a  XR                  S-  -  nU R                  5         U R                  (       a  U R                  U5      $ U R                  5       n U R                   u  p#nSu  pVnU R                  R                  5       U R                  R                  5       pU R                  n
U R                  n[        U R                  U5      5       H?  nU
" XVXxU	5      u  pVnUS:  a  U" XVXrU* SU5      u  pVnM(  US:  d  M0  U" XVXrUSU5      u  pVnMA     U(       d  [        $ [        U R                  XVXpR                  5      $ )rb  r   rM   r"  r   )r   r9   r   r   r   re  r   r   r   r   r2  r]  reversedr   r   )r   r?   r9  r:  r  r5  r+  r,  r   r   r2  r]  rU   s                r   rV   PointJacobi.__mul__  s8   }}QuOA:K<<\\A-.E ''..zz|MM	
||~~!11,,yy $))E*+A 2JBB1u!""2#q!<
Q!"""a;
 , O4<<\\BBr   c           
         U[         :X  d  US:X  a  X-  $ US:X  a  X#-  $ [        U[        5      (       d  [        R                  U5      nU R	                  5         UR	                  5         U R
                  (       a  UR
                  (       a	  X-  X#-  -   $ U R                  (       a  XR                  -  nX0R                  -  nSu  pEnU R                  R                  5       U R                  R                  5       pU R                  5         U R                  u  pnUR                  5         UR                  u  pnU R                  nU R                  nU" X* XU* X5      u  nnnU" XXU* X5      u  nnnUU* UnnnUU* UnnnU(       d	  X-  X#-  -   $ [        [        U R!                  [#        U5      5      5      5      n[        [        U R!                  [#        U5      5      5      5      n[%        U5      [%        U5      :  a  S/[%        U5      [%        U5      -
  -  U-   nO6[%        U5      [%        U5      :  a  S/[%        U5      [%        U5      -
  -  U-   n['        UU5       H  u  nn U" XEXgU5      u  pEnUS:X  a7  U S:X  a  M!  U S:  a  U" XEXlU* X5      u  pEnM8  U S:  d   eU" XEXlXU5      u  pEnMP  US:  aI  U S:X  a  U" XEXiU
* X5      u  pEnMm  U S:  a  U" XEUUUUU5      u  pEnM  U S:  d   eU" XEUUUUU5      u  pEnM  US:  d   eU S:X  a  U" XEXiXU5      u  pEnM  U S:  a  U" XEUUUUU5      u  pEnM  U S:  d   eU" XEUUUUU5      u  pEnM     U(       d  [         $ [        U R                  XEX`R                  5      $ )zc
Do two multiplications at the same time, add results.

calculates self*self_mul + other*other_mul
r   r"  )r9   r   r   r  r   r   r   r   r   r   r   r   r2  r]  listrh  r   intrq   zip)!r   self_mulr?   	other_mulr5  r+  r,  r   r   r#  r$  r0  r9  r:  rR  r2  r]  mAmB_XmAmB_YmAmB_ZpAmB_XpAmB_YpAmB_ZmApB_XmApB_YmApB_ZpApB_XpApB_YpApB_Zself_naf	other_nafrE  rF  s!                                    r   mul_addPointJacobi.mul_add  so    H	Q?"q=$$%--++E2E 	 !!3!3?U%666<<,,.H!LL0I 
||~~!11 	

]]
^^
,,yy "&b#rsB!B!%bbrc2!A!'&&!'&& ?U%666
 3x=!9:;$))C	N";<=	 x=3y>)sc)ns8}<=HH]S^+s8}s9~=>JI),DAq 2JBB Av6U!%bbrc2!AJBBq5L5!%bbba!@JBBQ6!%bbrc2!AJBBU!%bb&&&!!LJBBq5L5!%bb&&&!!LJBB1uu6!%bbba!@JBBU!%bb&&&!!LJBBq5L5!%bb&&&!!LJBB9 -< O4<<\\BBr   c                 d    U R                   u  pn[        U R                  X* X0R                  5      $ )zReturn negated point.)r   r   r   r   )r   r    r!   r   s       r   __neg__PointJacobi.__neg__	  s(    --a4<<B<<@@r   )__coordsri   __generatorrj   __precompute)NF)TNNF)F)&r*   r+   r,   r-   r.   r   r   r   r   r   r   r@   r	  r;   r:   r    r!   r   r  r   r  r-  r2  rC   rA  rI  rO  rV  rY  r]  rH   rY   re  rV   r~  r  r/   __classcell__)r   s   @r   r   r     s    8 
 ,I ,I\'4$8!  (	7 	
 	
, ,C"&.> C*C&CB`CDA Ar   r   N)

__future__r    r   objectr   r2   rn   r   r9   r0   r   r   <module>r     s[   F   Lf L4F BEF EPA	A- A	AH tT"r   