o
    wÔ+fy  ã                   @   s   d dl mZ G dd„ dƒZdS )é   )ÚPointc                   @   sx   e Zd Zedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZed	d
„ ƒZedd„ ƒZ	edd„ ƒZ
edd„ ƒZedd„ ƒZdS )ÚMathc                 C   s   t ||d d |ƒS )Nr   é   )Úpow)ÚclsÚvalueÚprime© r	   úE/var/www/html/venv/lib/python3.10/site-packages/ellipticcurve/math.pyÚmodularSquareRoot   s   zMath.modularSquareRootc              	   C   s    |   |  |  |¡||||¡|¡S )aÉ  
        Fast way to multily point and scalar in elliptic curves

        :param p: First Point to mutiply
        :param n: Scalar to mutiply
        :param N: Order of the elliptic curve
        :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
        :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p)
        :return: Point that represents the sum of First and Second Point
        )Ú_fromJacobianÚ_jacobianMultiplyÚ_toJacobian©r   ÚpÚnÚNÚAÚPr	   r	   r
   Úmultiply
   s   ÿzMath.multiplyc                 C   s$   |   |  |  |¡|  |¡||¡|¡S )a¡  
        Fast way to add two points in elliptic curves

        :param p: First Point you want to add
        :param q: Second Point you want to add
        :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
        :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p)
        :return: Point that represents the sum of First and Second Point
        )r   Ú_jacobianAddr   )r   r   Úqr   r   r	   r	   r
   Úadd   s   ÿzMath.addc           
      C   sh   |dkrdS d}d}|| }|}|dkr0|| }|||  }|||  }	|}|}|	}|}|dks|| S )zÅ
        Extended Euclidean Algorithm. It's the 'division' in elliptic curves

        :param x: Divisor
        :param n: Mod for division
        :return: Value representing the division
        é    r   r	   )
r   Úxr   ÚlmÚhmÚlowÚhighÚrÚnmÚnwr	   r	   r
   Úinv)   s    	ù	zMath.invc                 C   s   t |j|jdƒS )z•
        Convert point to Jacobian coordinates

        :param p: First Point you want to add
        :return: Point in Jacobian coordinates
        r   )r   r   Úy)r   r   r	   r	   r
   r   E   s   zMath._toJacobianc                 C   s>   |   |j|¡}|j|d  | }|j|d  | }t||dƒS )zô
        Convert point back from Jacobian coordinates

        :param p: First Point you want to add
        :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
        :return: Point in default coordinates
        é   é   r   )r"   Úzr   r#   r   )r   r   r   r&   r   r#   r	   r	   r
   r   O   s   	zMath._fromJacobianc           
      C   s¦   |j dkrtdddƒS |j d | }d|j | | }d|jd  ||jd   | }|d d|  | }|||  d|d   | }d|j  |j | }	t|||	ƒS )ac  
        Double a point in elliptic curves

        :param p: Point you want to double
        :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
        :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p)
        :return: Point that represents the sum of First and Second Point
        r   r$   r   r%   é   )r#   r   r   r&   )
r   r   r   r   ÚysqÚSÚMÚnxÚnyÚnzr	   r	   r
   Ú_jacobianDouble^   s   

 zMath._jacobianDoublec                 C   s  |j dkr|S |j dkr|S |j|jd  | }|j|jd  | }|j |jd  | }|j |jd  | }||krK||krDtdddƒS |  |||¡S || }	|| }
|	|	 | }|	| | }|| | }|
d | d|  | }|
||  ||  | }|	|j |j | }t|||ƒS )a•  
        Add two points in elliptic curves

        :param p: First Point you want to add
        :param q: Second Point you want to add
        :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
        :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p)
        :return: Point that represents the sum of First and Second Point
        r   r$   r%   r   )r#   r   r&   r   r.   )r   r   r   r   r   ÚU1ÚU2ÚS1ÚS2ÚHÚRÚH2ÚH3ÚU1H2r+   r,   r-   r	   r	   r
   r   t   s*   

zMath._jacobianAddc                 C   s¨   |j dks	|dkrtdddƒS |dkr|S |dk s||kr(|  ||| |||¡S |d dkr>|  |  ||d |||¡||¡S |  |  |  ||d |||¡||¡|||¡S )a½  
        Multily point and scalar in elliptic curves

        :param p: First Point to mutiply
        :param n: Scalar to mutiply
        :param N: Order of the elliptic curve
        :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
        :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p)
        :return: Point that represents the sum of First and Second Point
        r   r   r$   )r#   r   r   r.   r   r   r	   r	   r
   r   ™   s   ÿ$ÿzMath._jacobianMultiplyN)Ú__name__Ú
__module__Ú__qualname__Úclassmethodr   r   r   r"   r   r   r.   r   r   r	   r	   r	   r
   r      s&    




	


$r   N)Úpointr   r   r	   r	   r	   r
   Ú<module>   s    