
    ei                         d dl mZ ddlmZ  G d de          Z G d de          Z G d d	e          Z G d
 de          Z eddd          Z	dS )    )division   )numbertheoryc                   6    e Zd ZdZd Zd Zd Zd Zd Zd Z	dS )	CurveFpz9Elliptic Curve over the field of integers modulo a prime.c                 0    || _         || _        || _        dS )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       j/var/www/html/volatility/venv/lib/python3.11/site-packages/ccxt/static_dependencies/ecdsa/ellipticcurve.py__init__zCurveFp.__init__+   s        c                     | j         S N)r
   r   s    r   r   z	CurveFp.p1   	    xr   c                     | j         S r   )r   r   s    r   r   z	CurveFp.a4   r   r   c                     | j         S r   )r   r   s    r   r   z	CurveFp.b7   r   r   c                 \    ||z  ||z  |z  | j         |z  z   | j        z   z
  | j        z  dk    S )z!Is the point (x,y) on this curve?r   )r   r   r
   )r   xys      r   contains_pointzCurveFp.contains_point:   s7    AQTX\1DH<=IQNNr   c                 0    d| j         | j        | j        fz  S )NzCurveFp(p=%d, a=%d, b=%d)r	   r   s    r   __str__zCurveFp.__str__>   s    *dh$(-KKKr   N)
__name__
__module____qualname____doc__r   r   r   r   r   r    r   r   r   r   (   s|        CC        O O OL L L L Lr   r   c                   V    e Zd ZdZddZd Zd Zd Zd Zd Z	d	 Z
d
 Zd Zd Zd ZdS )PointzsA point on an elliptic curve. Altering x and y is forbidding,
     but they can be read by the x() and y() methods.Nc                     || _         || _        || _        || _        | j         r| j                             ||          sJ |r| |z  t
          k    sJ dS dS )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   zPoint.__init__F   ss    < 	5<..q!44444 	,%<8++++	, 	,++r   c                 j    | j         |j         k    r"| j        |j        k    r| j        |j        k    rdS dS )z9Return True if the points are identical, False otherwise.TF)r(   r)   r*   r   others     r   __eq__zPoint.__eq__R   s9    <5=((H	))H	))45r   c                 2   |t           k    r| S | t           k    r|S | j        |j        k    sJ | j        |j        k    rH| j        |j        z   | j                                        z  dk    rt           S |                                 S | j                                        }|j        | j        z
  t          j        |j        | j        z
  |          z  |z  }||z  | j        z
  |j        z
  |z  }|| j        |z
  z  | j        z
  |z  }t          | j        ||          S )zAdd one point to another point.r   )	r,   r(   r)   r*   r   doubler   inverse_modr&   )r   r1   r   lx3y3s         r   __add__zPoint.__add__[   s   
 HK8L|u},,,,8uy  59$(8(88A=={{}}$LNNi$("%ei$(&:A>>?BCD !edh*a/48b=!DH,1T\2r***r   c                    d }|}| j         r
|| j         z  }|dk    rt          S | t          k    rt          S |dk    sJ d|z  }t          | j        | j        | j         | j                   } ||          dz  }| }|dk    rM|                                }||z  dk    r||z  dk    r|| z   }||z  dk    r||z  dk    r||z   }|dz  }|dk    M|S )Multiply a point by an integer.c                 B    | dk    sJ d}|| k    rd|z  }|| k    |dz  S )Nr   r      r$   )r   results     r   leftmost_bitz#Point.__mul__.<locals>.leftmost_bitx   s;    q5555FA++V A++Q;r   r      r=   r   )r+   r,   r&   r(   r)   r*   r4   )r   r1   r?   ee3negative_selfir>   s           r   __mul__zPoint.__mul__u   s   	 	 	 < 	!DL A66O8O1uuuu UdlDHtxiNNL!!ee]]__FQ1}}!a%A$Q1}}!a%A-/QA !ee r   c                     | |z  S )r;   r$   r0   s     r   __rmul__zPoint.__rmul__   s     e|r   c                 >    | t           k    rdS d| j        | j        fz  S )Ninfinityz(%d,%d))r,   r)   r*   r   s    r   r   zPoint.__str__   s&    8:DHdh///r   c                 x   | t           k    rt           S | j                                        }| j                                        }d| j        z  | j        z  |z   t          j        d| j        z  |          z  |z  }||z  d| j        z  z
  |z  }|| j        |z
  z  | j        z
  |z  }t          | j        ||          S )z)Return a new point that is twice the old.r@   r=   )	r,   r(   r   r   r)   r   r5   r*   r&   )r   r   r   r6   r7   r8   s         r   r4   zPoint.double   s     8O LNNLNN$(lTX%)%a$(lA667:;< !ea$(l"a'48b=!DH,1T\2r***r   c                     | j         S r   )r)   r   s    r   r   zPoint.x   r   r   c                     | j         S r   )r*   r   s    r   r   zPoint.y   r   r   c                     | j         S r   )r(   r   s    r   r-   zPoint.curve   
    |r   c                     | j         S r   )r+   r   s    r   r.   zPoint.order   rN   r   r   )r    r!   r"   r#   r   r2   r9   rE   rG   r   r4   r   r   r-   r.   r$   r   r   r&   r&   B   s        9 9
, 
, 
, 
,  + + +4# # #J  
0 0 0
+ + +&          r   r&   c                       e Zd ZdZed             Zed             Zed             Zed             Z	e	 dd            Z
d	 Zd
 Zd Zd ZddZed             ZdS )AbstractPointz2Class for common methods of elliptic curve points.c                    t          |           |k    sJ | d|dz           }| |dz  d         }t          |          |dz  k    sJ t          |          |dz  k    sJ t          |          }t          |          }||fS )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.
        Nr=   )lenstring_to_number)dataraw_encoding_lengthxsyscoord_xcoord_ys         r   _from_raw_encodingz AbstractPoint._from_raw_encoding   s     4yy/////,'1,,-%*,,- 2ww-222222ww-22222"2&&"2&&r   c                    | dd         dvrt          d          | dd         dk    }t          | dd                   }|                                }t          |d|          |                                |z  z   |                                z   |z  }	 t          j        ||          }n'# t          j        $ r}t          d|          d}~ww xY w|t          |dz            k    r||z
  }n|}||fS )z-Decode public point from compressed encoding.Nr   )      z#Malformed compressed point encodingr]   r@   0Encoding does not correspond to a point on curve)
MalformedPointErrorrT   r   powr   r   r   square_root_mod_primeErrorbool)	rU   r-   is_evenr   r   alphabetarA   r   s	            r   _from_compressedzAbstractPoint._from_compressed   s    8---%&KLLLrr(g%T!""X&&GGIIQ1Q/%''));q@	5eQ??DD! 	 	 	%BA  	 d4!8nn$$DAAA!ts   B- -C<CCc                     |dd         dv sJ |                      |dd         |          \  }}|r5|dz  r|dd         dk    s|dz  s|dd         dk    rt          d          ||fS )z)Decode public point from hybrid encoding.Nr         rl   rk   z"Inconsistent hybrid point encoding)r[   r`   )clsrU   rV   validate_encodingr   r   s         r   _from_hybridzAbstractPoint._from_hybrid   s     BQBx----- %%d122h0CDD1  	LE	LRaRG##E $RaRG##%&JKKK!tr   c                    t          |          }|                                }t          |          dz   dz   dz  }t          |          |k    rt	          d          |d         dz  dz	  }|dxx         dz  cc<   t          |d          }t          rt          |          }||z  dz
  t          j	        |
                                |z  |z  |                                z
  |          z  |z  }	 t          j        ||          }n'# t          j        $ r}	t	          d	|	          d
}	~	ww xY w|dz  |k    r| |z  }||fS )z#Decode a point on an Edwards curve.r         z%Point length doesn't match the curve.      littler_   Nr=   )	bytearrayr   
bit_lengthrS   r`   bytes_to_intGMPYmpzr   r5   dr   rb   rc   )
rm   r-   rU   r   exp_lenx_0r   x2r   rA   s
             r   _from_edwardszAbstractPoint._from_edwards  sc    GGIIa==1$q(Q.t99%&MNNNBx$1$RHx(( 	AA UQY&uwwyy1}q'857799'DaHHI 		22q99AA! 	 	 	%BA  	
 q5C<<QA!ts   1D D+D&&D+TNc                 ^   |st          g d          }t          d |D                       st          d          t          |          }t	          |t
                    r|                     ||          S t          |          }dt          |	                                          z  }||k    rd|v r| 
                    ||          \  }}n||dz   k    rvd|v sd|v rn|d	d         d
v rd|v r|                     |||          \  }}n|d	d         dk    r&d|v r"| 
                    |dd	         |          \  }}nnt          d          ||dz  dz   k    rd|v r|                     ||          \  }}n5t          d                    d                    |                              ||fS )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   8   K   | ]}|t          d           v V  dS )r   N)set).0rD   s     r   	<genexpr>z+AbstractPoint.from_bytes.<locals>.<genexpr>N  sD       
 
 DEEE
 
 
 
 
 
r   z@Only uncompressed, compressed, hybrid or raw encoding supported.r=   r   r   r   r   Nrj      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   rS   orderlenr   r[   ro   r`   rh   formatjoin)	rm   r-   rU   rn   valid_encodingskey_lenrV   rY   rZ   s	            r   
from_byteszAbstractPoint.from_bytes(  sJ   D  	!??? O  
 
$
 
 
 
 
 	    t$$eY'' 	2$$UD111d))(57799"5"55)))e.F.F"55)   GWW +a///''>_+L+LBQBx---(o2M2M#&#3#3-/@$ $  bqbW$$?)J)J#&#9#9H1$ $  *@   *a/!333//"33D%@@GWW%		/ : :;;  
 r   c                     |                                                                  }t          |                                 |          }t          |                                 |          }||z   S )z.Convert the point to the :term:`raw encoding`.r-   r   number_to_stringr   r   )r   primex_stry_strs       r   _raw_encodezAbstractPoint._raw_encode}  sQ    

   511 511u}r   c                     |                                                                  }t          |                                 |          }|                                 dz  rd|z   S d|z   S )z*Encode the point into the compressed form.r   r^   r]   r   )r   r   r   s      r   _compressed_encodez AbstractPoint._compressed_encode  sX    

   5116688a< 	#U?"r   c                 l    |                                  }|                                 dz  rd|z   S d|z   S )z&Encode the point into the hybrid form.r   rl   rk   )r   r   )r   raw_encs     r   _hybrid_encodezAbstractPoint._hybrid_encode  s=    ""$$6688a< 	%W$$  r   c                 F   |                                   |                                 |                                 |                                                                 }}}t          |          dz   dz   dz  }t          ||d          }|dz  r|dxx         dz  cc<   |S )z/Encode the point according to RFC8032 encoding.r   rq   rr   rv   r=   rs   rt   )scaler   r   r-   r   rx   int_to_bytes)r   r   r   r   enc_lenr   s         r   _edwards_encodezAbstractPoint._edwards_encode  s    

&&((DFFHHdjjllnn&6&6a1 a==1$q(Q.Q22q5 	"IIIIIIr   r   c                 R   |dv sJ |                                  }t          |t                    r|                                 S |dk    r|                                 S |dk    rd|                                 z   S |dk    r|                                 S |                                 S )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_byteszAbstractPoint.to_bytes  s     JJJJJ

eY'' 		-'')))##%%%''T--////!!&&(((**,,,r   c                     g }| rL| dz  r+| dz  }|dk    r|dz  }|                     |           | |z  } n|                     d           | dz  } | L|S )z&Calculate non-adjacent form of number.r=      r   )append)multretnds      r   _nafzAbstractPoint._naf  s{      		ax AX77!GB

2


1QJD  		 
r   )TN)r   )r    r!   r"   r#   staticmethodr[   rh   classmethodro   r   r   r   r   r   r   r   r   r$   r   r   rQ   rQ      s       <<    \ (   \*   [&     [ D BFR  R  R  [R h    ! ! !
 
 
- - - -6   \  r   rQ   c                        e Zd ZdZd" fd	Ze	 	 	 	 d# fd	            Zd Zd Zd	 Z	d
 Z
d Zd Zd Zd Zd Zd Zd Zed$d            Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d  Z!d! Z" xZ#S )%PointJacobiu   
    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³
    NFc                 @   t          t          |                                            || _        t          rHt          |          t          |          t          |          f| _        |ot          |          | _        n|||f| _        || _        || _        g | _	        dS )aF  
        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__curverz   r{   _PointJacobi__coords_PointJacobi__order_PointJacobi__generator_PointJacobi__precompute)r   r-   r   r   zr.   	generator	__class__s          r   r   zPointJacobi.__init__  s    " 	k4  ))+++ 	! VVSVVSVV4DM /SZZDLL1IDM DL$r   Tc                     t          t          |                               ||||          \  }}t          |||d||          S )aP  
        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   )
rm   r-   rU   rn   r   r.   r   rY   rZ   r   s
            r   r   zPointJacobi.from_bytes  sN    T !c22==4*O
 
 5'7AuiHHHr   c                    | j         r| j        rd S | j        }|sJ g }d}|dz  }| j        \  }}}t	          | j        ||||          }|dz  }|                    |                                |                                f           ||k     rl|dz  }|	                                
                                }|                    |                                |                                f           ||k     l|| _        d S )Nr   r=   )r   r   r   r   r   r   r   r   r   r4   r   )r   r.   
precomputerD   rY   rZ   coord_zdoublers           r   _maybe_precomputezPointJacobi._maybe_precompute!  s	    	4#4 	F 

$(M!'dlGWguMM
799;;		4555%iiFAnn&&,,..Gwyy{{GIIKK8999 %ii
 'r   c                 8    | j                                         }|S r   )__dict__copyr   states     r   __getstate__zPointJacobi.__getstate__;  s    
 ""$$r   c                 :    | j                             |           d S r   )r   updater   s     r   __setstate__zPointJacobi.__setstate__C  s    U#####r   c                    | j         \  }}}|t          u r| S t          |t                    r+|                                |                                d}}}n(t          |t                    r|j         \  }}}nt          S | j        |	                                k    rdS | j        
                                }||z  |z  }	||z  |z  }
||
z  ||	z  z
  |z  dk    o||
z  |z  ||	z  |z  z
  |z  dk    S )z}Compare for equality two points with each-other.

        Note: only points that lay on the same curve can be equal.
        r   Fr   )r   r,   r   r&   r   r   r   NotImplementedr   r-   r   )r   r1   x1y1z1r   y2z2r   zz1zz2s              r   r2   zPointJacobi.__eq__F  s   
 ]
BH6MeU## 	"EGGIIqBBB{++ 	"JBBB!!<5;;==((5LNN2gk2gk
 S28#q(A- HrMBHrM)33 	r   c                     | |k     S )z2Compare for inequality two points with each-other.r$   r0   s     r   __ne__zPointJacobi.__ne__b  s    5=  r   c                     | j         S )zIReturn the order of the point.

        None if it is undefined.
        )r   r   s    r   r.   zPointJacobi.orderf  s    
 |r   c                     | j         S )z-Return curve over which the point is defined.)r   r   s    r   r-   zPointJacobi.curvem  s
    |r   c                     | j         \  }}}|dk    r|S | j                                        }t          j        ||          }||dz  z  |z  S )aC  
        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   r=   r   r   r   r   r5   )r   r   _r   r   s        r   r   zPointJacobi.xq  T     -1a66HLNN$Q**1a4x!|r   c                     | j         \  }}}|dk    r|S | j                                        }t          j        ||          }||dz  z  |z  S )aC  
        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   r@   r   )r   r   r   r   r   s        r   r   zPointJacobi.y  r   r   c                     | j         \  }}}|dk    r| S | j                                        }t          j        ||          }||z  |z  }||z  |z  }||z  |z  |z  }||df| _         | S )ze
        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   zPointJacobi.scale  s     -1a66K LNN(A.."JNJ"Aq	r   c                     | j         \  }}}| j                                        }||z  st          S |                                  | j         \  }}}|dk    sJ t          | j        ||| j                  S )zReturn point in affine form.r   )r   r   r   r,   r   r&   r   )r   r   r   r   r   r   s         r   	to_affinezPointJacobi.to_affine  sp    -1aLNNA 	O

-1aAvvvvT\1a666r   c                     t          |                                 |                                 |                                 d|                                 |          S )a  Create 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_affinezPointJacobi.from_affine  sC     KKMM57799eggiiEKKMM9
 
 	
r   c                     ||z  |z  ||z  |z  }}|sdS ||z  |z  }d||z   dz  |z
  |z
  z  |z  }d|z  |z   }	|	|	z  d|z  z
  |z  }
|	||
z
  z  d|z  z
  |z  }d|z  |z  }|
||fS )z"Add a point to itself with z == 1.r   r   r   r=   r@   rr   r$   )r   X1Y1r   r   XXYYYYYYSMTY3Z3s                r   _double_with_z_1zPointJacobi._double_with_z_1  s     b1b2gkB 	7Bw{"r'a"$t+,q0FQJUQU]a1q5kAH$)VaZ"byr   c                 B   |dk    r|                      ||||          S |sdS ||z  |z  ||z  |z  }}|sdS ||z  |z  }||z  |z  }	d||z   dz  |z
  |z
  z  |z  }
d|z  ||	z  |	z  z   |z  }||z  d|
z  z
  |z  }||
|z
  z  d|z  z
  |z  }||z   dz  |z
  |	z
  |z  }|||fS )z#Add a point to itself, arbitrary z.r   r   r=   r@   rr   )r   )r   r   r   Z1r   r   r   r   r   ZZr   r   r   r   r   s                  r   _doublezPointJacobi._double  s	   77((RA666 	7 b1b2gkB 	7Bw{"Wq["r'a"$t+,q0Va"frk!Q&UQU]a1q5kAH$)Bw1nr!B&!+"byr   c                    | j         \  }}}|st          S | j                                        | j                                        }}|                     |||||          \  }}}|st          S t          | j        |||| j                  S )zAdd a point to itself.)r   r,   r   r   r   r   r   r   )	r   r   r   r   r   r   X3r   r   s	            r   r4   zPointJacobi.double  s    ]
B 	O|~~!1!11\\"b"a33
B 	O4<RT\BBBr   c                    ||z
  }||z  }d|z  |z  }||z  }	d||z
  z  }
|s1|
s/|                      |||| j                                                  S ||z  }|
dz  |	z
  d|z  z
  |z  }|
||z
  z  d|z  |	z  z
  |z  }d|z  |z  }|||fS )z&add points when both Z1 and Z2 equal 1r   r=   r   r   r   )r   r   r   X2Y2r   HHHIJrVr   r   r   s                  r   _add_with_z_1zPointJacobi._add_with_z_1  s     GUFQJEbM 	F 	F((RDLNN4D4DEEEFdQhQ!#1r6lQVaZ'1,UQY2rzr   c                    ||z
  dz  |z  }||z  |z  }||z  }	||z
  dz  |z  }
|s2|
s0|                      ||||| j                                                  S |
|z
  |	z
  |z  }||z
  ||z
  z  ||	|z
  z  z
  |z  }|||z
  z  |z  }|||fS )zadd points when Z1 == Z2r=   r   r   r   )r   r   r   r   r   r   r   ABCDr   r   r   s                 r   _add_with_z_eqzPointJacobi._add_with_z_eq  s     "WNQFQJF"WNQ 	A 	A<<BAt|~~/?/?@@@!eai1_Bw1r6"R1q5\1Q627^a2rzr   c                 n   ||z  |z  }||z  |z  ||z  |z  |z  }	}||z
  |z  }
|
|
z  |z  }d|z  |z  }|
|z  }d|	|z
  z  |z  }|s1|
s/|                      |||| j                                                  S ||z  }||z  |z
  d|z  z
  |z  }|||z
  z  d|z  |z  z
  |z  }||
z   dz  |z
  |z
  |z  }|||fS )zadd points when Z2 == 1r   r=   r   )r   r   r   r   r   r   r   Z1Z1U2S2r   r  r  r  r  r  r   r   r   s                      r   _add_with_z2_1zPointJacobi._add_with_z2_1  s    Bw{dQR$ 2B"WMUQYFQJEbMA 	F 	F((RDLNN4D4DEEEF!eai!a%1$1r6lQVaZ'1,Av!md"R'1,2rzr   c                    ||z  |z  }||z  |z  }	||	z  |z  }
||z  |z  }||z  |	z  |z  }||z  |z  |z  }||
z
  }d|z  |z  |z  }||z  |z  }d||z
  z  |z  }|s2|s0|                      ||||| j                                                  S |
|z  }||z  |z
  d|z  z
  |z  }|||z
  z  d|z  |z  z
  |z  }||z   dz  |z
  |	z
  |z  |z  }|||fS )zadd points with arbitrary zr   r=   r  )r   r   r   r   r   r   Z2r   r  Z2Z2U1r  S1r  r   r  r  r  r  r   r   r   s                         r   _add_with_z_nezPointJacobi._add_with_z_ne/  s<    Bw{Bw{$Y]$Y]"Wt^a"Wt^aGEAIMEAIbMA 	A 	A<<BAt|~~/?/?@@@F!eai!a%1$1r6lQVaZ'1,Bw1nt#d*a/!32rzr   c                     | |z   S )zAdd other to self.r$   r0   s     r   __radd__zPointJacobi.__radd__F      e|r   c           	      v   |s||z  ||z  ||z  fS |s||z  ||z  ||z  fS ||k    r9|dk    r|                      |||||          S |                     ||||||          S |dk    r|                     ||||||          S |dk    r|                     ||||||          S |                     |||||||          S )z&add two points, select fastest method.r   )r  r  r  r  )r   r   r   r   r   r   r  r   s           r   _addzPointJacobi._addJ  s     	*62626)) 	*62626))88Qww))"b"b!<<<&&r2r2r1===77&&r2r2r1===77&&r2r2r1===""2r2r2r1===r   c           	         | t           k    r|S |t           k    r| S t          |t                    rt                              |          }| j        |j        k    rt          d          | j                                        }| j        \  }}}|j        \  }}}| 	                    |||||||          \  }	}
}|st           S t          | j        |	|
|| j
                  S )z!Add two points on elliptic curve.z%The other point is on different curve)r,   r   r&   r   r   r   r   r   r   r  r   )r   r1   r   r   r   r   r   r   r  r   r   r   s               r   r9   zPointJacobi.__add__Z  s    8LHKeU## 	3++E22E<5=((DEEELNN]
B^
BYYr2r2r2q99
B 	O4<RT\BBBr   c                     | |z  S )Multiply point by an integer.r$   r0   s     r   rG   zPointJacobi.__rmul__o  r  r   c           
      Z   ddd| j                                         f\  }}}}| j        }| j        D ]U\  }}|dz  rF|dz  dk    r|dz   dz  } |||||| d|          \  }}}2|dz
  dz  } ||||||d|          \  }}}P|dz  }V|st          S t          | j         |||| j                  S )z4Multiply point by integer with precomputation table.r   r=   r   r   )r   r   r  r   r,   r   r   )	r   r1   r   r   r   r   r  r   r   s	            r   _mul_precomputezPointJacobi._mul_precomputes  s    1a!1!11BAy' 		 		FBqy 19>>"QY1,E!%b"b"rc1a!@!@JBBB"QY1,E!%b"b"b!Q!?!?JBBB! 	O4<RT\BBBr   c           
         | j         d         r|st          S |dk    r| S | j        r|| j        dz  z  }|                                  | j        r|                     |          S |                                 } | j         \  }}}d\  }}}| j                                        | j        	                                }	}| j
        }
| j        }t          |                     |                    D ]M} |
|||||	          \  }}}|dk     r |||||| d|          \  }}}2|dk    r ||||||d|          \  }}}N|st          S t          | j        |||| j                  S )r   r   r=   r   r   )r   r,   r   r   r   r"  r   r   r   r   r   r  reversedr   r   )r   r1   r   r   r   r   r   r   r   r   r   r  rD   s                r   rE   zPointJacobi.__mul__  s   }Q 	u 	OA::K< 	/T\A-.E    	/''...zz||M	B
B|~~!1!11,y $))E**++ 	< 	<A RQ22JBB1uu!T"b"b2#q!<<
BQ!T"b"b"a;;
B 	O4<RT\BBBr   c           
         |t           k    s|dk    r| |z  S |dk    r||z  S t          |t                    st                              |          }|                                  |                                 | j        r|j        r| |z  ||z  z   S | j        r|| j        z  }|| j        z  }d\  }}}| j                                        | j        	                                }}| 
                                 | j        \  }	}
}|
                                 |j        \  }}}| j        }| j        } ||	|
 ||| ||          \  }}} ||	|
||| ||          \  }}}|| |}}}|| |}}}|s| |z  ||z  z   S t          t          |                     t#          |                                        }t          t          |                     t#          |                                        }t%          |          t%          |          k     r'dgt%          |          t%          |          z
  z  |z   }nFt%          |          t%          |          k    r&dgt%          |          t%          |          z
  z  |z   }t'          ||          D ]\  }}  ||||||          \  }}}|dk    rB| dk    r&| dk     r |||||| ||          \  }}}C| dk    sJ  ||||||||          \  }}}a|dk     rW| dk    r |||||	|
 ||          \  }}}| dk     r ||||||||          \  }}}| dk    sJ  ||||||||          \  }}}|dk    sJ | dk    r |||||	|
||          \  }}}| dk     r ||||||||          \  }}}| dk    sJ  ||||||||          \  }}}|st           S t          | j        |||| j                  S )z{
        Do two multiplications at the same time, add results.

        calculates self*self_mul + other*other_mul
        r   r   )r,   r   r   r   r   r   r   r   r   r   r   r   r   r  listr$  r   intrS   zip)!r   self_mulr1   	other_mulr   r   r   r   r   r   r   r   r   r   r  r   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_nafr	  r
  s!                                    r   mul_addzPointJacobi.mul_add  s    H	Q(?"q==9$$%-- 	3++E22E 	   !!! 	7!3 	7(?UY%666< 	1$,.H!DL0I 
B|~~!1!11 	

]
B^
B,y "&b2#r2sB!B!B!%b"b"rc2q!A!A!'&&!'&&  	7(?UY%666
 3x==!9!9::;;$))C	NN";";<<==	 x==3y>>))sc)nns8}}<=HHH]]S^^++s8}}s9~~=>JI),, 	M 	MDAq RQ22JBB Avv66UU!%b"b"rc2q!A!AJBBBq5555!%b"b"b"a!@!@JBBBQ66!%b"b"rc2q!A!AJBBBUU!%b"b&&&!!L!LJBBBq5555!%b"b&&&!!L!LJBBB1uuuu66!%b"b"b"a!@!@JBBBUU!%b"b&&&!!L!LJBBBq5555!%b"b&&&!!L!LJBBB 	O4<RT\BBBr   c                 T    | j         \  }}}t          | j        || || j                  S )zReturn negated point.)r   r   r   r   )r   r   r   r   s       r   __neg__zPointJacobi.__neg__	  s+    -1a4<QB4<@@@r   )NF)TNNF)F)$r    r!   r"   r#   r   r   r   r   r   r   r2   r   r.   r-   r   r   r   r   r   r   r   r   r4   r  r  r  r  r  r  r9   rG   r"  rE   r9  r;  __classcell__)r   s   @r   r   r     sG             8 
 ,I ,I ,I ,I ,I [,I\' ' '4  $ $ $  8! ! !            (	7 	7 	7 	
 	
 	
 \	
,     ,C C C  "    &  .  > > > C C C*  C C C&C C CB`C `C `CDA A A A A A Ar   r   N)

__future__r    r   objectr   r&   rQ   r   r,   r$   r   r   <module>r@     s  F             L L L L Lf L L L4    F   BE E E E EF E E EPA	A A	A A	A A	A A	A- A	A A	A A	AH 5tT""r   