o
    6h                     @   s$  d dl mZ z
d dlmZ dZW n ey/   z
d dlmZ dZW n ey,   dZY nw Y nw d dlmZ ddl	m
Z
 ddlmZmZmZmZ dd	lmZ dd
lmZmZmZ eG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZedddZdS )    )division)mpzTF)python_2_unicode_compatible   )numbertheory)normalise_bytesint_to_bytes
bit_lengthbytes_to_int)MalformedPointError)orderlenstring_to_numbernumber_to_stringc                   @   sr   e Zd ZdZerdddZndddZdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd ZdS )CurveFpzd
    :term:`Short Weierstrass Elliptic Curve <short Weierstrass curve>` over a
    prime field.
    Nc                 C   s(   t || _t || _t || _|| _dS a  
            The curve of points satisfying y^2 = x^3 + a*x + b (mod p).

            h is an integer that is the cofactor of the elliptic curve domain
            parameters; it is the number of points satisfying the elliptic
            curve equation divided by the order of the base point. It is used
            for selection of efficient algorithm for public point verification.
            N)r   _CurveFp__p_CurveFp__a_CurveFp__b_CurveFp__hselfpabh r   g/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/ecdsa/ellipticcurve.py__init__B   s   
	


zCurveFp.__init__c                 C   s   || _ || _|| _|| _dS r   )r   r   r   r   r   r   r   r   r   T   s   	
c                 C   H   t |tr"| j}| j|jko!| j| |j| ko!| j| |j| kS tS )a^  Return True if other is an identical curve, False otherwise.

        Note: the value of the cofactor of the curve is not taken into account
        when comparing curves, as it's derived from the base point and
        intrinsic curve characteristic (but it's complex to compute),
        only the prime and curve parameters are considered.
        )
isinstancer   r   r   r   NotImplementedr   otherr   r   r   r   __eq__b   s   
zCurveFp.__eq__c                 C   
   | |k S )z<Return False if other is an identical curve, True otherwise.r   r   r"   r   r   r   __ne__s      
zCurveFp.__ne__c                 C      t | j| j| jfS N)hashr   r   r   r   r   r   r   __hash__w      zCurveFp.__hash__c                 C      | j S r)   )r   r+   r   r   r   r   z      z	CurveFp.pc                 C   r.   r)   )r   r+   r   r   r   r   }   r/   z	CurveFp.ac                 C   r.   r)   )r   r+   r   r   r   r      r/   z	CurveFp.bc                 C   r.   r)   )r   r+   r   r   r   cofactor   r/   zCurveFp.cofactorc                 C   s*   || || | j  | | j  | j dkS )z!Is the point (x,y) on this curve?r   )r   r   r   r   xyr   r   r   contains_point   s   *zCurveFp.contains_pointc                 C   6   | j d urd| j| j| j| j S d| j| j| jS )Nz#CurveFp(p={0}, a={1}, b={2}, h={3})zCurveFp(p={0}, a={1}, b={2}))r   formatr   r   r   r+   r   r   r   __str__      
zCurveFp.__str__r)   )__name__
__module____qualname____doc__GMPYr   r#   r&   r,   r   r   r   r0   r4   r7   r   r   r   r   r   9   s    
r   c                   @   sz   e Zd ZdZerdddZndddZdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd ZdS )	CurveEdTwz/Parameters for a Twisted Edwards Elliptic CurveNc                 C   s.   t || _t || _t || _|| _|| _dS z
            The curve of points satisfying a*x^2 + y^2 = 1 + d*x^2*y^2 (mod p).

            h is the cofactor of the curve.
            hash_func is the hash function associated with the curve
             (like SHA-512 for Ed25519)
            N)r   _CurveEdTw__p_CurveEdTw__a_CurveEdTw__d_CurveEdTw__h_CurveEdTw__hash_funcr   r   r   dr   	hash_funcr   r   r   r      s
   



zCurveEdTw.__init__c                 C   s"   || _ || _|| _|| _|| _dS r?   )r@   rA   rB   rC   rD   rE   r   r   r   r      s
   
c                 C   r   )z,Returns True if other is an identical curve.)r   r>   r@   rA   rB   r    r!   r   r   r   r#      s   
zCurveEdTw.__eq__c                 C   r$   )z@Return False if the other is an identical curve, True otherwise.r   r%   r   r   r   r&      r'   zCurveEdTw.__ne__c                 C   r(   r)   )r*   r@   rA   rB   r+   r   r   r   r,      r-   zCurveEdTw.__hash__c                 C   s:   | j | | ||  d | j| | | |  | j dkS )z"Is the point (x, y) on this curve?r   r   )rA   rB   r@   r1   r   r   r   r4      s
   .zCurveEdTw.contains_pointc                 C   r.   r)   )r@   r+   r   r   r   r      r/   zCurveEdTw.pc                 C   r.   r)   )rA   r+   r   r   r   r      r/   zCurveEdTw.ac                 C   r.   r)   )rB   r+   r   r   r   rF      r/   zCurveEdTw.dc                 C   s
   |  |S r)   )rD   )r   datar   r   r   rG      s   
zCurveEdTw.hash_funcc                 C   r.   r)   )rC   r+   r   r   r   r0      r/   zCurveEdTw.cofactorc                 C   r5   )Nz%CurveEdTw(p={0}, a={1}, d={2}, h={3})zCurveEdTw(p={0}, a={1}, d={2}))rC   r6   r@   rA   rB   r+   r   r   r   r7      r8   zCurveEdTw.__str__)NN)r9   r:   r;   r<   r=   r   r#   r&   r,   r4   r   r   rF   rG   r0   r7   r   r   r   r   r>      s    
r>   c                   @   s   e Zd ZdZedd Zedd Zedd Zedd	 Z	e	dddZ
dd Zdd Zdd Zdd ZdddZedd ZdS )AbstractPointz2Class for common methods of elliptic curve points.c                 C   sp   t | |ksJ | d|d  }| |d d }t ||d ks"J t ||d 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.
        N   )lenr   )rH   raw_encoding_lengthxsyscoord_xcoord_yr   r   r   _from_raw_encoding   s   	z AbstractPoint._from_raw_encodingc           	   
   C   s   | dd dvrt d| dd dk}t| dd }| }t|d|| |  |  | }zt||}W n tjyL } zt d|d}~ww |t	|d@ kr]|| }||fS |}||fS )z-Decode public point from compressed encoding.Nr   )      z#Malformed compressed point encodingrR      0Encoding does not correspond to a point on curve)
r   r   r   powr   r   r   square_root_mod_primeErrorbool)	rH   curveis_evenr2   r   alphabetaer3   r   r   r   _from_compressed
  s&   $zAbstractPoint._from_compressedc                 C   sp   |dd dv s
J |  |dd |\}}|r4|d@ r$|dd dks0|d@ s4|dd dkr4td||fS )z)Decode public point from hybrid encoding.Nr         rb   ra   z"Inconsistent hybrid point encoding)rQ   r   )clsrH   rL   validate_encodingr2   r3   r   r   r   _from_hybrid   s   zAbstractPoint._from_hybridc           
   
   C   s   t |}| }t|d d d }t||krtd|d d@ d? }|d  dM  < t|d}tr7t|}|| d t	|
 | | |  | | }zt||}W n tjyi }	 ztd	|	d
}	~	ww |d |kru| | }||fS )z#Decode a point on an Edwards curve.r         z%Point length doesn't match the curve.      littlerU   NrJ   )	bytearrayr   r	   rK   r   r
   r=   r   r   inverse_modrF   r   rW   rX   )
rc   rZ   rH   r   exp_lenx_0r3   x2r2   r^   r   r   r   _from_edwards4  s6   


zAbstractPoint._from_edwardsTNc           	      C   sZ  |st g d}tdd |D stdt|}t|tr$| ||S t|}dt|	  }||krDd|v rD| 
||\}}||fS ||d krd|v sRd	|v r|d
d dv rkd|v rk| |||\}}||fS |d
d dkrd	|v r| 
|dd
 |\}}||fS td||d d krd|v r| ||\}}||fS tdd|)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                 s   s    | ]	}|t d v V  qdS )rr   N)set).0ir   r   r   	<genexpr>}  s
    

z+AbstractPoint.from_bytes.<locals>.<genexpr>z@Only uncompressed, compressed, hybrid or raw encoding supported.rJ   rv   r   ru   rs   Nr`      z*Invalid X9.62 encoding of the public pointrt   z[Length of string does not match lengths of any of the enabled ({0}) encodings of the curve.z, )rw   all
ValueErrorr   r   r>   rq   rK   r   r   rQ   re   r   r_   r6   join)	rc   rZ   rH   rd   valid_encodingskey_lenrL   rO   rP   r   r   r   
from_bytesW  sV   "
zAbstractPoint.from_bytesc                 C   s0   |    }t|  |}t|  |}|| S )z.Convert the point to the :term:`raw encoding`.rZ   r   r   r2   r3   )r   primex_stry_strr   r   r   _raw_encode  s   zAbstractPoint._raw_encodec                 C   s6   |    }t|  |}|  d@ rd| S d| S )z*Encode the point into the compressed form.r   rS   rR   r   )r   r   r   r   r   r   _compressed_encode  s
   z AbstractPoint._compressed_encodec                 C   s$   |   }|  d@ rd| S d| S )z&Encode the point into the hybrid form.r   rb   ra   )r   r3   )r   raw_encr   r   r   _hybrid_encode  s   zAbstractPoint._hybrid_encodec                 C   sd   |    |  |  |   }}}t|d d d }t||d}|d r0|d  dO  < |S )z/Encode the point according to RFC8032 encoding.r   rf   rg   rk   rJ   rh   ri   )scaler2   r3   rZ   r   r	   r   )r   r2   r3   r   enc_lenr   r   r   r   _edwards_encode  s    zAbstractPoint._edwards_encoderv   c                 C   sb   |dv sJ |   }t|tr|  S |dkr|  S |dkr%d|   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
        )rv   rs   rt   ru   rv   rs   r{   ru   )rZ   r   r>   r   r   r   r   )r   encodingrZ   r   r   r   to_bytes  s   
zAbstractPoint.to_bytesc                 C   sV   g }| r)| d r| d }|dkr|d8 }| | | |8 } n| d | d } | s|S )z&Calculate non-adjacent form of number.rJ      r   )append)multretndr   r   r   _naf  s   



zAbstractPoint._naf)TN)rv   )r9   r:   r;   r<   staticmethodrQ   r_   classmethodre   rq   r   r   r   r   r   r   r   r   r   r   r   rI      s(    



"T
rI   c                       s  e Zd ZdZd? fdd	Ze				d@ fdd	Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd ZedAdd Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9d: Z d;d< Z!d=d> Z"  Z#S )B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                    sb   t t|   || _tr t|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__curver=   r   _PointJacobi__coords_PointJacobi__order_PointJacobi__generator_PointJacobi__precompute)r   rZ   r2   r3   zorder	generator	__class__r   r   r     s   
zPointJacobi.__init__Tc           	         s,   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   	rc   rZ   rH   rd   r   r   r   rO   rP   r   r   r   r   !  s   
*zPointJacobi.from_bytesc                 C   s   | j r| jrd S | j}|sJ g }d}|d9 }| j\}}}t| j||||}|d9 }|| | f ||k rR|d9 }|	 
 }|| | f ||k s9|| _d S )Nr   rJ   )r   r   r   r   r   r   r   r2   r3   doubler   )r   r   
precomputery   rO   rP   coord_zdoublerr   r   r   _maybe_precomputeP  s"   
zPointJacobi._maybe_precomputec                 C   s   | j  }|S r)   )__dict__copyr   stater   r   r   __getstate__j  s   
zPointJacobi.__getstate__c                 C   s   | j | d S r)   )r   updater   r   r   r   __setstate__r  s   zPointJacobi.__setstate__c                 C   s   | j \}}}|tu r| S t|tr| | d}}}nt|tr+|j \}}}ntS | j|	 kr6dS | j
 }|| | }	|| | }
||
 ||	  | dkob||
 | ||	 |  | 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   INFINITYr   Pointr2   r3   r   r    r   rZ   r   )r   r"   x1y1z1rp   y2z2r   zz1zz2r   r   r   r#   u  s&   


zPointJacobi.__eq__c                 C   r$   z2Compare for inequality two points with each-other.r   r%   r   r   r   r&     r'   zPointJacobi.__ne__c                 C   r.   )zIReturn the order of the point.

        None if it is undefined.
        )r   r+   r   r   r   r     s   zPointJacobi.orderc                 C   r.   )z-Return curve over which the point is defined.)r   r+   r   r   r   rZ        zPointJacobi.curvec                 C   s>   | j \}}}|dkr|S | j }t||}||d  | 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   rJ   r   r   r   r   rm   )r   r2   _r   r   r   r   r   r2        	
zPointJacobi.xc                 C   s>   | j \}}}|dkr|S | j }t||}||d  | 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   rT   r   )r   r   r3   r   r   r   r   r   r3     r   zPointJacobi.yc                 C   sf   | j \}}}|dkr| S | j }t||}|| | }|| | }|| | | }||df| _ | S ze
        Return point scaled so that z == 1.

        Modifies point in place, returns self.
        r   r   )r   r2   r3   r   r   z_invzz_invr   r   r   r     s   
zPointJacobi.scalec                 C   sT   | j \}}}| j }|| 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   r2   r3   r   r   r   	to_affine  s   
zPointJacobi.to_affinec                 C   s"   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   rZ   r2   r3   r   )pointr   r   r   r   from_affine  s   zPointJacobi.from_affinec                 C   s   || | || | }}|sdS || | }d|| d | |  | }d| | }	|	|	 d|  | }
|	||
  d|  | }d| | }|
||fS )z"Add a point to itself with z == 1.r   r   r   rJ   rT   rg   r   )r   X1Y1r   r   XXYYYYYYSMTY3Z3r   r   r   _double_with_z_1  s   
zPointJacobi._double_with_z_1c                 C   s   |dkr|  ||||S |sdS || | || | }}|s!dS || | }|| | }	d|| d | |  | }
d| ||	 |	  | }|| d|
  | }||
|  d|  | }|| d | |	 | }|||fS )z#Add a point to itself, arbitrary z.r   r   rJ   rT   rg   )r   )r   r   r   Z1r   r   r   r   r   ZZr   r   r   r   r   r   r   r   _double  s   
zPointJacobi._doublec           	      C   s^   | 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   r   r   r   r     s   zPointJacobi.doublec                 C   s   || }|| }d| | }|| }	d||  }
|s'|
s'|  |||| j S || }|
d |	 d|  | }|
||  d| |	  | }d| | }|||fS )z&add points when both Z1 and Z2 equal 1r   rJ   r   r   r   )r   r   r   X2Y2r   HHHIJrVr   r   r   r   r   r   _add_with_z_1+  s   
zPointJacobi._add_with_z_1c                 C   s   || d | }|| | }|| }	|| d | }
|s*|
s*|  ||||| j S |
| |	 | }|| ||  ||	|   | }|||  | }|||fS )zadd points when Z1 == Z2rJ   r   r   r   )r   r   r   r   r   r   r   ABCDr   r   r   r   r   r   _add_with_z_eq<  s    
zPointJacobi._add_with_z_eqc                 C   s   || | }|| | || | | }}	|| | }
|
|
 | }d| | }|
| }d|	|  | }|sB|
sB|  |||| j S || }|| | d|  | }|||  d| |  | }||
 d | | | }|||fS )zadd points when Z2 == 1r   rJ   r   )r   r   r   r   r   r   r   Z1Z1U2S2r   r   r   r   r   r   r   r   r   r   r   r   _add_with_z2_1K  s   
zPointJacobi._add_with_z2_1c                 C   s  || | }|| | }	||	 | }
|| | }|| |	 | }|| | | }||
 }d| | | }|| | }d||  | }|sR|sR|  ||||| j S |
| }|| | d|  | }|||  d| |  | }|| d | |	 | | }|||fS )zadd points with arbitrary zr   rJ   r   )r   r   r   r   r   r   Z2r   r   Z2Z2U1r   S1r   r   r   r   r   r   r   r   r   r   r   r   _add_with_z_ne^  s"   
zPointJacobi._add_with_z_nec                 C      | | S zAdd other to self.r   r%   r   r   r   __radd__u     zPointJacobi.__radd__c              	   C   s   |s|| || || fS |s|| || || fS ||kr5|dkr+|  |||||S | ||||||S |dkrC| ||||||S |dkrQ| ||||||S | |||||||S )z&add two points, select fastest method.r   )r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   _addy  s   zPointJacobi._addc              	   C   s   | t kr|S |t kr| S t|trt|}| j|jkr td| j }| j\}}}|j\}}}| 	|||||||\}	}
}|sCt 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   r"   r   r   r   r   r   r   r   r   r   r   r   r   r   __add__  s   


zPointJacobi.__add__c                 C      | | S Multiply point by an integer.r   r%   r   r   r   __rmul__  r   zPointJacobi.__rmul__c           	   	   C   s   ddd| j  f\}}}}| j}| jD ];\}}|d rJ|d dkr6|d d }|||||| d|\}}}q|d d }||||||d|\}}}q|d }q|sStS t| j |||| jS )4Multiply point by integer with precomputation table.r   rJ   r   r   )r   r   r   r   r   r   r   )	r   r"   r   r   r   r   r   r   r   r   r   r   _mul_precompute  s   
zPointJacobi._mul_precomputec              	   C   s  | j d r|s	tS |dkr| S | jr|| jd  }|   | jr%| |S |  } | j \}}}d\}}}| j | j	 }}	| j
}
| j}t| |D ]1}|
|||||	\}}}|dk rl|||||| d|\}}}qL|dkr}||||||d|\}}}qL|stS t| j|||| jS )r   r   rJ   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   reversedr   r   )r   r"   r   r   r   r   r   r   r   r   r   r   ry   r   r   r   __mul__  s2   

zPointJacobi.__mul__c           !   	   C   s~  |t ks|dkr| | S |dkr|| S t|tst|}|   |  | jr4|jr4| | ||  S | jrA|| j }|| j }d\}}}| j | j	 }}| 
  | j\}	}
}|
  |j\}}}| j}| j}||	|
 ||| ||\}}}||	|
||| ||\}}}|| |}}}|| |}}}|s| | ||  S tt| t|}tt| t|}t|t|k rdgt|t|  | }nt|t|krdgt|t|  | }t||D ]\}} ||||||\}}}|dkr-| dkrq| dk r|||||| ||\}}}q| dksJ ||||||||\}}}q|dk rn| dkrF|||||	|
 ||\}}}q| dk rY||||||||\}}}q| dks`J ||||||||\}}}q|dksuJ | dkr|||||	|
||\}}}q| dk r||||||||\}}}q| dksJ ||||||||\}}}q|st 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   intrK   zip)!r   self_mulr"   	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   r   r   r   mul_add  sv   












zPointJacobi.mul_addc                 C   s"   | j \}}}t| j|| || jS )zReturn negated point.)r   r   r   r   )r   r2   r3   r   r   r   r   __neg__8  s   zPointJacobi.__neg__NF)TNNF)F)$r9   r:   r;   r<   r   r   r   r   r   r   r#   r&   r   rZ   r2   r3   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  __classcell__r   r   r   r   r     sJ    
.!br   c                       s   e Zd ZdZd  fdd	Ze			d! fdd	Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Z  ZS )"r   zA point on a short Weierstrass elliptic curve. Altering x and y is
    forbidden, but they can be read by the x() and y() methods.Nc                    s   t t|   || _tr"|ot|| _|ot|| _|ot|| _n	|| _|| _|| _| jr7| j	||s7J |rI|
 dkrK|rM| | tksOJ dS dS dS dS )z@curve, x, y, order; order (optional) is the order of this point.r   N)r   r   r   _Point__curver=   r   	_Point__x	_Point__y_Point__orderr4   r0   r   )r   rZ   r2   r3   r   r   r   r   r   B  s   zPoint.__init__Tc                    s(   t t| ||||\}}t||||S )ag  
        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

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

        :return: Point on curve
        :rtype: Point
        )r   r   r   )rc   rZ   rH   rd   r   r   rO   rP   r   r   r   r   W  s   
&zPoint.from_bytesc                 C   sN   |t u r| jdu p| jdu S t|tr%| j|jko$| j|jko$| j|jkS tS )zReturn True if the points are identical, False otherwise.

        Note: only points that lay on the same curve can be equal.
        N)r   r  r  r   r   r  r    r%   r   r   r   r#     s   


zPoint.__eq__c                 C   r$   )z6Returns False if points are identical, True otherwise.r   r%   r   r   r   r&     r'   zPoint.__ne__c                 C   s   t | j| j| j | j S r)   )r   r  r  r   r  r+   r   r   r   r    s   zPoint.__neg__c                 C   s   t |tstS |tkr| S | tkr|S | j|jksJ | j|jkr4| j|j | j  dkr0tS |  S | j }|j| j t	
|j| j | | }|| | j |j | }|| j|  | j | }t| j||S )zAdd one point to another point.r   )r   r   r    r   r  r  r  r   r   r   rm   )r   r"   r   lx3y3r   r   r   r     s(   


zPoint.__add__c                 C   s   dd }|}|dks| j r|| j  dkrtS | tkrtS |dk r&|  |  S d| }t| j| j| j | j  | j }||d }| }|dkrs| }||@ dkr[||@ dkr[||  }||@ dkrk||@ dkrk|| }|d }|dksG|S )Multiply a point by an integer.c                 S   s0   | dksJ d}|| krd| }|| ks|d S )Nr   r   rJ   r   )r2   resultr   r   r   leftmost_bit  s   z#Point.__mul__.<locals>.leftmost_bitr   rT   rJ   r   )r  r   r   r  r  r  r   r   )r   r"   r  r^   e3negative_selfry   r  r   r   r   r     s4   	zPoint.__mul__c                 C   r   )r  r   r%   r   r   r   r     s   zPoint.__rmul__c                 C   s   | t krdS d| j| jf S )Ninfinityz(%d,%d))r   r  r  r+   r   r   r   r7     s   zPoint.__str__c                 C   s   | t krt S | j }| j }d| j | j | td| j | | }|s)t S || d| j  | }|| j|  | j | }t| j||S )z)Return a new point that is twice the old.rT   rJ   )	r   r  r   r   r  r   rm   r  r   )r   r   r   r  r  r  r   r   r   r     s   

zPoint.doublec                 C   r.   r)   )r  r+   r   r   r   r2      r/   zPoint.xc                 C   r.   r)   )r  r+   r   r   r   r3     r/   zPoint.yc                 C   r.   r)   )r  r+   r   r   r   rZ     r/   zPoint.curvec                 C   r.   r)   )r  r+   r   r   r   r   	  r/   zPoint.orderr)   )TNN)r9   r:   r;   r<   r   r   r   r#   r&   r  r   r   r   r7   r   r2   r3   rZ   r   r  r   r   r   r   r   >  s(    *)r   c                       s   e Zd ZdZd( fdd	Ze				d) fdd	Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Z  ZS )*PointEdwardszPoint on Twisted Edwards curve.

    Internally represents the coordinates on the curve using four parameters,
    X, Y, Z, T. They correspond to affine parameters 'x' and 'y' like so:

    x = X / Z
    y = Y / Z
    x*y = T / Z
    NFc                    sj   t t|   || _tr#t|t|t|t|f| _|o t|| _n
||||f| _|| _|| _g | _	dS )zS
        Initialise a point that uses the extended coordinates internally.
        N)
r   r  r   _PointEdwards__curver=   r   _PointEdwards__coords_PointEdwards__order_PointEdwards__generator_PointEdwards__precompute)r   rZ   r2   r3   r   tr   r   r   r   r   r     s   
zPointEdwards.__init__c           	         s2   t t| ||||\}}t|||d|| ||S )a  
        Initialise the object from byte encoding of a point.

        `validate_encoding` and `valid_encodings` are provided for
        compatibility with Weierstrass curves, they are ignored for Edwards
        points.

        :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.CurveEdTw
        :param None validate_encoding: Ignored, encoding is always validated
        :param None valid_encodings: Ignored, there is just one encoding
            supported
        :param int order: the point order, must be non zero when using
            generator=True
        :param bool generator: Flag to mark the point as a curve generator,
            this will cause the library to pre-compute some values to
            make repeated usages of the point much faster

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

        :return: Initialised point on an Edwards curve
        :rtype: PointEdwards
        r   )r   r  r   r   r   r   r   r   '  s   
$zPointEdwards.from_bytesc           
      C   s   | j r| jr	| jS | j}|sJ g }d}|d9 }| j\}}}}| j }t| j|||||}	|d9 }||k r]|	 }	|	 |		 }}|| | }|
|||f |d9 }|	 }	||k s6|| _| jS )Nr   rJ   r   )r#  r$  r"  r!  r   r   r  r   r2   r3   r   r   )
r   r   r   ry   rO   rP   r   coord_tr   r   r   r   r   r   R  s.   
	zPointEdwards._maybe_precomputec                 C   s<   | j \}}}}|dkr|S | j }t||}|| | S )zReturn affine x coordinate.r   r!  r   r   r   rm   )r   r   r   r   r   r   r   r   r   r2   w     
zPointEdwards.xc                 C   s<   | j \}}}}|dkr|S | j }t||}|| | S )zReturn affine y coordinate.r   r'  )r   r   r   r   r   r   r   r   r   r3     r(  zPointEdwards.yc                 C   r.   )zReturn the curve of the point.)r   r+   r   r   r   rZ     r   zPointEdwards.curvec                 C   r.   r)   )r"  r+   r   r   r   r     r/   zPointEdwards.orderc           
      C   sf   | j \}}}}|dkr| S | j }t||}|| | }|| | }|| | }	||d|	f| _ | S r   r'  )
r   r   r   r   r   r   r   r2   r3   r%  r   r   r   r     s   
zPointEdwards.scalec                 C   s   | j \}}}}|tu r| p| S t|tr|j \}}}}	ntS | j| kr)dS | j }
|| |
 }|| |
 }|| |
 }|| |
 }||koM||kS )ztCompare for equality two points with each-other.

        Note: only points on the same curve can be equal.
        F)r!  r   r   r  r    r   rZ   r   )r   r"   r   r   r   t1rp   r   r   t2r   xn1xn2yn1yn2r   r   r   r#     s   

zPointEdwards.__eq__c                 C   r$   r   r   r%   r   r   r   r&     r'   zPointEdwards.__ne__c                 C   s   || |	 }|| |	 }|| |	 }|| |	 }|| }|| ||  | | |	 }||
|  }|| }|s@|  |||||	|
S || |	 }|| |	 }|| |	 }|| |	 }||||fS )z'add two points, assume sane parameters.)r   )r   r   r   r   T1r   r   r   T2r   r   r   r   r   r   EFGr   r   r   T3r   r   r   r   r     s   zPointEdwards._addc                 C   s   |t kr| S t|tr| j|jkrtd| j | j }}| j\}}}}|j\}}	}
}| ||||||	|
|||
\}}}}|rD|sFt S t| j||||| j	S )zAdd point to another.z(The other point is on a different curve.)
r   r   r  r   r}   r   r   r!  r   r"  )r   r"   r   r   r   r   r   r/  r   r   r   r0  r   r   r   r4  r   r   r   r     s   $zPointEdwards.__add__c                 C   r   r   r   r%   r   r   r   r     r   zPointEdwards.__radd__c                 C   s   || | }|| | }d| | | }	|| | }
|| ||  | | | }|
| }||	 }|
| }|| | }|| | }|| | }|| | }||||fS )z)Double the point, assume sane parameters.rJ   r   )r   r   r   r   r/  r   r   r   r   r   r   r1  r3  r2  r   r   r   r4  r   r   r   r   r     s   zPointEdwards._doublec                 C   sn   | j \}}}}|r|stS | j | j }}| ||||||\}}}	}
|r*|
s,tS t| j|||	|
| jS )zReturn point added to itself.)r!  r   r   r   r   r   r  r"  )r   r   r   r   r/  r   r   r   r   r   r4  r   r   r   r     s   zPointEdwards.doublec                 C   r   r   r   r%   r   r   r   r     r   zPointEdwards.__rmul__c                 C   s   dddd| j  | j  f\}}}}}}| j}| jD ]Q\}	}
}|d }|dks+|dkr0|d }q|dkrN|d d }||||||	 |
d| ||
\}}}}q|dksTJ |d d }||||||	|
d|||
\}}}}q|rp|srtS t| j ||||| jS )r   r   r   r   rJ   rT   )r   r   r   r   r$  r   r  r"  )r   r"   r   r   r   r4  r   r   r   r   r   r0  remr   r   r   r     s   (
($zPointEdwards._mul_precomputec                 C   s(  | j \}}}}|r|r|stS |dkr| S | jr|| jd  }|  r(| |S d\}}}}	| j | j }
}| j}| j	}t
| |D ]<}|||||	|
|\}}}}	|dk rm|||||	| ||| |
|
\}}}}	qF|dkr|||||	|||||
|
\}}}}	qF|r|	stS t| j||||	| jS )r   r   rJ   )r   r   r   r   r   )r!  r   r"  r   r   r   r   r   r   r   r   r   r  )r   r"   r   r   r   r0  r   r   r   r4  r   r   r   r   ry   r   r   r   r   )  s.   
("zPointEdwards.__mul__r  )NNNF)r9   r:   r;   r<   r   r   r   r   r2   r3   rZ   r   r   r#   r&   r   r   r   r   r   r   r   r   r  r   r   r   r   r    s2    
*%		r  N)
__future__r   gmpy2r   r=   ImportErrorgmpysixr    r   _compatr   r   r	   r
   errorsr   utilr   r   r   objectr   r>   rI   r   r   r  r   r   r   r   r   <module>   sF   "	_Y  
    H P  >