U
    gW@                     @   s   d dl Z d dlmZmZ d dlmZmZmZmZm	Z	m
Z
 d dlmZ d dlmZ G dd deZG dd	 d	eZe ZG d
d deZG dd deZdS )    N)bytes_to_longlong_to_bytes)VoidPointernull_pointerSmartPointerc_size_tc_uint8_ptrc_ulonglong)Integer)getrandbitsc                   @   s0   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
S )CurveID                        	   N)__name__
__module____qualname__P192P224P256P384P521ED25519ED448
CURVE25519CURVE448 r"   r"   ?/tmp/pip-unpacked-wheel-_q8s9isk/Cryptodome/PublicKey/_point.pyr      s   r   c                   @   s   e Zd Zi Ze ZddddddgZddd	d
ddgZddddddgZ	ddddddgZ
ddddddgZdd gZd!d"gZd#d$d%gZd&d'd(gZee e	 e
 e e e e e Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3S )4_Curvesp192z
NIST P-192zP-192Z
prime192v1Z	secp192r1Znistp192p224z
NIST P-224zP-224Z
prime224v1Z	secp224r1Znistp224p256z
NIST P-256zP-256Z
prime256v1Z	secp256r1Znistp256p384z
NIST P-384zP-384Z
prime384v1Z	secp384r1Znistp384p521z
NIST P-521zP-521Z
prime521v1Z	secp521r1Znistp521ed25519ZEd25519ed448ZEd448
curve25519Z
Curve25519ZX25519curve448ZCurve448ZX448c                 C   s
   || j kS N	all_names)selfitemr"   r"   r#   __contains__1   s    z_Curves.__contains__c                 C   s   | j S r.   r/   r1   r"   r"   r#   __dir__4   s    z_Curves.__dir__c                 C   sZ  || j kr@ddlm} | }tj|_| jt	
| j | n|| jkrddlm} | }tj|_| jt	
| j| n|| jkrddlm} | }tj|_| jt	
| j| n|| jkrddlm} | }tj|_| jt	
| j| nN|| jkrDddlm} | }tj|_| jt	
| j| n|| jkrddlm} | }	tj|	_| jt	
| j|	 n|| jkrddlm} | }
tj|
_| jt	
| j|
 n|| jkrddlm} |  }tj!|_| jt	
| j| nL|| j"krDddlm} |# }tj$|_| jt	
| j"| nt%d| | j| S )Nr   )	_nist_ecc)_edwards)_montgomeryzUnsupported curve '%s')&
p192_names r6   Z
p192_curver   r   idcurvesupdatedictfromkeys
p224_namesZ
p224_curver   
p256_namesZ
p256_curver   
p384_namesZ
p384_curver   
p521_namesZ
p521_curver   ed25519_namesr7   Zed25519_curver   ed448_namesZed448_curver   curve25519_namesr8   Zcurve25519_curver    curve448_namesZcurve448_curver!   
ValueError)r1   namer6   r%   r&   r'   r(   r)   r7   r*   r+   r8   r,   r-   r"   r"   r#   load7   s^    


z_Curves.loadc              	   C   s   | j  | j|}|d kr| |}|| jks:|| jkrJt|j||_nt	|j|j
||_|jtjtjfk|_|jtjtjfk|_|jp|j |_W 5 Q R X |S r.   )curves_lockr<   getrJ   rF   rG   	EccXPointZGxGEccPointZGyr;   r   r   r   
is_edwardsr    r!   Zis_montgomeryZis_weierstrass)r1   rI   curver"   r"   r#   __getitem__i   s    
z_Curves.__getitem__c                 C   s   | j D ]}| | }q| j S r.   )r0   r<   items)r1   rI   _r"   r"   r#   rS   y   s    

z_Curves.itemsN)r   r   r   r<   	threadingRLockrK   r9   r@   rA   rB   rC   rD   rE   rF   rG   r0   r3   r5   rJ   rR   rS   r"   r"   r"   r#   r$      sF   






2r$   c                   @   s   e Zd ZdZ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edd Zedd Ze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 )+rO   a  A class to model a point on an Elliptic Curve.

    The class supports operators for:

    * Adding two points: ``R = S + T``
    * In-place addition: ``S += T``
    * Negating a point: ``R = -T``
    * Comparing two points: ``if S == T: ...`` or ``if S != T: ...``
    * Multiplying a point by a scalar: ``R = S*k``
    * In-place multiplication by a scalar: ``T *= k``

    :ivar curve: The **canonical** name of the curve as defined in the `ECC table`_.
    :vartype curve: string

    :ivar x: The affine X-coordinate of the ECC point
    :vartype x: integer

    :ivar y: The affine Y-coordinate of the ECC point
    :vartype y: integer

    :ivar xy: The tuple with affine X- and Y- coordinates
    r'   c                 C   s2  zt | | _W n$ tk
r2   tdt| Y nX | jj| _| jjtj	krTtd| 
 }t||}t||}t||kst||krtd| jjj}| jjj}t | _z| jj }	W n tk
r   t}	Y nX || j t|t|t||	}
|
r|
dkrtdtd|
 t| j || _d S )NUnknown curve name %sz)EccPoint cannot be created for Curve25519Incorrect coordinate length   )The EC point does not belong to the curve(Error %d while instantiating an EC point)_curves_curveKeyErrorrH   str	canonicalrQ   r;   r   r    size_in_bytesr   lenrawlib	new_point
free_pointr   _pointcontextrL   AttributeErrorr   
address_ofr   r   r   )r1   xyrQ   modulus_bytesxbybrd   	free_funcrg   resultr"   r"   r#   __init__   s<    







zEccPoint.__init__c                 C   sX   | j jj}| j jj}t | _|| j |j }|rBtd| t	| j || _| S Nz"Error %d while cloning an EC point
r]   rc   clonere   r   rf   ri   rL   rH   r   r1   pointrt   ro   rp   r"   r"   r#   set   s    


zEccPoint.setc                 C   s2   t |tsdS | jjj}d|| j |j kS NFr   )
isinstancerO   r]   rc   cmprf   rL   )r1   rv   cmp_funcr"   r"   r#   __eq__   s    

zEccPoint.__eq__c                 C   s
   | |k S r.   r"   )r1   rv   r"   r"   r#   __ne__   s    zEccPoint.__ne__c                 C   s4   | j jj}|  }||j }|r0td| |S )Nz$Error %d while inverting an EC point)r]   rc   negcopyrf   rL   rH   )r1   Zneg_funcnprp   r"   r"   r#   __neg__   s    
zEccPoint.__neg__c                 C   s   | j \}}t||| j}|S zReturn a copy of this point.)xyrO   rQ   )r1   rj   rk   r   r"   r"   r#   r      s    
zEccPoint.copyc                 C   s    | j jr| jdkS | jdkS dS ),``True`` if this is the *point-at-infinity*.r   )r   r   N)r]   rP   rj   r   r4   r"   r"   r#   is_point_at_infinity   s    
zEccPoint.is_point_at_infinityc                 C   s(   | j jrtdd| jS tdd| jS dS )-Return the *point-at-infinity* for the curve.r   r   N)r]   rP   rO   rQ   r4   r"   r"   r#   point_at_infinity   s    zEccPoint.point_at_infinityc                 C   s
   | j d S )Nr   r   r4   r"   r"   r#   rj      s    z
EccPoint.xc                 C   s
   | j d S )Nr   r   r4   r"   r"   r#   rk      s    z
EccPoint.yc                 C   sj   |   }t|}t|}| jjj}|t|t|t|| j }|rRt	d| t
t|t
t|fS )Nz#Error %d while encoding an EC point)ra   	bytearrayr]   rc   get_xyr   r   rf   rL   rH   r
   r   )r1   rl   rm   rn   r   rp   r"   r"   r#   r     s    
zEccPoint.xyc                 C   s   |   d d S z"Size of each coordinate, in bytes.r   r   size_in_bitsr4   r"   r"   r#   ra     s    zEccPoint.size_in_bytesc                 C   s   | j jS z!Size of each coordinate, in bits.r]   Zmodulus_bitsr4   r"   r"   r#   r     s    zEccPoint.size_in_bitsc                 C   s,   | j jj}|| j }|r(td| | S )zuDouble this point (in-place operation).

        Returns:
            This same object (to enable chaining).
        z#Error %d while doubling an EC point)r]   rc   doublerf   rL   rH   )r1   Zdouble_funcrp   r"   r"   r#   r     s
    
zEccPoint.doublec                 C   sD   | j jj}|| j |j }|r@|dkr4tdtd| | S )zAdd a second point to this one   z#EC points are not on the same curvez#Error %d while adding two EC points)r]   rc   addrf   rL   rH   )r1   rv   Zadd_funcrp   r"   r"   r#   __iadd__'  s    
zEccPoint.__iadd__c                 C   s   |   }||7 }|S )z8Return a new point, the addition of this one and anotherr   )r1   rv   r   r"   r"   r#   __add__2  s    zEccPoint.__add__c                 C   s^   | j jj}|dk rtdt|}|| j t|tt	|t
td}|rZtd| | S zMultiply this point by a scalarr   z?Scalar multiplication is only defined for non-negative integers@   z%Error %d during scalar multiplicationr]   rc   scalarrH   r   rf   rL   r   r   rb   r	   r   r1   r   Zscalar_funcZsbrp   r"   r"   r#   __imul__9  s    



zEccPoint.__imul__c                 C   s   |   }||9 }|S z2Return a new point, the scalar product of this oner   r1   r   r   r"   r"   r#   __mul__H  s    zEccPoint.__mul__c                 C   s
   |  |S r.   r   r1   Z	left_handr"   r"   r#   __rmul__O  s    zEccPoint.__rmul__N)r'   )r   r   r   __doc__rq   rw   r|   r}   r   r   r   r   propertyrj   rk   r   ra   r   r   r   r   r   r   r   r"   r"   r"   r#   rO      s.   
)


rO   c                   @   st   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	e
dd Zdd Zdd Zdd Zdd Zdd ZdS )rM   a  A class to model a point on an Elliptic Curve,
    where only the X-coordinate is exposed.

    The class supports operators for:

    * Multiplying a point by a scalar: ``R = S*k``
    * In-place multiplication by a scalar: ``T *= k``

    :ivar curve: The **canonical** name of the curve as defined in the `ECC table`_.
    :vartype curve: string

    :ivar x: The affine X-coordinate of the ECC point
    :vartype x: integer
    c           	      C   s2  zt | | _W n$ tk
r2   tdt| Y nX | jj| _| jjtj	tj
fkrZtd| jjj}| jjj}t | _z| jj }W n tk
r   t}Y nX |  }|d krt}n"tt||}t||krtdt | _|| j |t||}|dkr
td|rtd| t| j || _d S )NrW   z5EccXPoint can only be created for Curve25519/Curve448rX   rY   rZ   r[   )r\   r]   r^   rH   r_   r`   rQ   r;   r   r    r!   rc   rd   re   r   rf   rg   rL   rh   r   ra   r   r   rb   ri   r   r   )	r1   rj   rQ   rd   ro   rg   rl   rm   rp   r"   r"   r#   rq   c  s>    





zEccXPoint.__init__c                 C   sX   | j jj}| j jj}t | _|| j |j }|rBtd| t	| j || _| S rr   rs   ru   r"   r"   r#   rw     s    


zEccXPoint.setc                 C   s>   t |tsdS | jjj}| j }|j }|||}d|kS rx   )ry   rM   r]   rc   rz   rf   rL   )r1   rv   r{   p1p2resr"   r"   r#   r|     s    




zEccXPoint.__eq__c                 C   s4   z
| j }W n tk
r&   |   Y S X t|| jS r   )rj   rH   r   rM   rQ   )r1   rj   r"   r"   r#   r     s
    
zEccXPoint.copyc                 C   s&   z
| j }W n tk
r    Y dS X dS )r   TF)rj   rH   )r1   rT   r"   r"   r#   r     s
    
zEccXPoint.is_point_at_infinityc                 C   s   t d| jS )r   N)rM   rQ   r4   r"   r"   r#   r     s    zEccXPoint.point_at_infinityc                 C   s`   |   }t|}| jjj}|t|t|| j }|dkrDt	d|rTt	d| t
t|S )N   z)No X coordinate for the point at infinityz'Error %d while getting X of an EC point)ra   r   r]   rc   get_xr   r   rf   rL   rH   r
   r   )r1   rl   rm   r   rp   r"   r"   r#   rj     s    
zEccXPoint.xc                 C   s   |   d d S r   r   r4   r"   r"   r#   ra     s    zEccXPoint.size_in_bytesc                 C   s   | j jS r   r   r4   r"   r"   r#   r     s    zEccXPoint.size_in_bitsc                 C   s^   | j jj}|dk rtdt|}|| j t|tt	|t
td}|rZtd| | S r   r   r   r"   r"   r#   r     s    



zEccXPoint.__imul__c                 C   s   |   }||9 }|S r   r   r   r"   r"   r#   r     s    zEccXPoint.__mul__c                 C   s
   |  |S r.   r   r   r"   r"   r#   r     s    zEccXPoint.__rmul__N)r   r   r   r   rq   rw   r|   r   r   r   r   rj   ra   r   r   r   r   r"   r"   r"   r#   rM   S  s   /
		
rM   )rU   ZCryptodome.Util.numberr   r   ZCryptodome.Util._raw_apir   r   r   r   r   r	   ZCryptodome.Math.Numbersr
   ZCryptodome.Random.randomr   objectr   r$   r\   rO   rM   r"   r"   r"   r#   <module>   s    f Q