U
    ZÊ¹j-  ã                   @   s˜   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 d dlmZ d dlmZ dd	lmZ dd
lmZ G dd„ dƒZG dd„ dƒZdS )é    )Úoo)Úsymbols)ÚFiniteFieldÚQQÚRationalFieldÚFF)ÚPoly)Úsolve)Úis_sequence)Úas_inté   )Údivisors)Úpolynomial_congruencec                   @   sœ   e Zd ZdZd!dd„Zd"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edd„ ƒZedd„ ƒZedd„ ƒZd S )#ÚEllipticCurvea_  
    Create the following Elliptic Curve over domain.

    `y^{2} + a_{1} x y + a_{3} y = x^{3} + a_{2} x^{2} + a_{4} x + a_{6}`

    The default domain is ``QQ``. If no coefficient ``a1``, ``a2``, ``a3``,
    is given then it creates a curve with the following form:

    `y^{2} = x^{3} + a_{4} x + a_{6}`

    Examples
    ========

    References
    ==========

    .. [1] J. Silverman "A Friendly Introduction to Number Theory" Third Edition
    .. [2] https://mathworld.wolfram.com/EllipticDiscriminant.html
    .. [3] G. Hardy, E. Wright "An Introduction to the Theory of Numbers" Sixth Edition

    r   c                 C   sØ  |dkrt }nt|ƒ}t|j|||||fƒ\}}}}}|| _|| _|d d|  }d| ||  }	|d d|  }
|d | d| |  || |  ||d   |d  }||	|
|f\| _| _| _| _	|d  | d|	d   d|
d   d| |	 |
  | _
|| _|| _|| _|| _|| _tdƒ\}}}|||  | _| _| _t|d | || | |  || |d   |d  ||d  |  || |d   ||d   |d	�| _t| jtƒ�rÀd| _nt| jtƒ�rÔd | _d S )
Nr   é   é   é   é   é   é	   zx y z)Údomain)r   r   ÚmapÚconvertÚ_domainÚmodulusÚ_b2Ú_b4Ú_b6Z_b8Ú_discrimÚ_a1Ú_a2Ú_a3Ú_a4Ú_a6r   ÚxÚyÚzr   Ú_polyÚ
isinstancer   Ú_rankr   )ÚselfÚa4Úa6Úa1Úa2Úa3r   r   Úb2Zb4Zb6Zb8r$   r%   r&   © r1   ú[/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/ntheory/elliptic_curve.pyÚ__init__#   s0     88jzEllipticCurve.__init__r   c                 C   s   t |||| ƒS ©N©ÚEllipticCurvePoint)r*   r$   r%   r&   r1   r1   r2   Ú__call__?   s    zEllipticCurve.__call__c                 C   s–   t |ƒr4t|ƒdkrd}n|d }|d d… \}}n*t|tƒrV|j|j|j  }}}ntdƒ‚| jdkrt|dkrtdS | j	 
| j|| j|| j|i¡dkS )Nr   r   zInvalid point.r   T)r
   Úlenr(   r6   r$   r%   r&   Ú
ValueErrorÚcharacteristicr'   Úsubs)r*   ÚpointZz1Úx1Úy1r1   r1   r2   Ú__contains__B   s    
zEllipticCurve.__contains__c                 C   s
   | j  ¡ S r4   )r'   Ú__repr__©r*   r1   r1   r2   r@   Q   s    zEllipticCurve.__repr__c                 C   s�   | j }|dkr| S |dkr>t| jd | jd | jd | jd�S | jd d| j  }| jd  d| j | j  d| j  }td| d	| | jd
�S )a<  
        Return minimal Weierstrass equation.

        Examples
        ========

        >>> from sympy.ntheory.elliptic_curve import EllipticCurve

        >>> e1 = EllipticCurve(-10, -20, 0, -1, 1)
        >>> e1.minimal()
        Poly(-x**3 + 13392*x*z**2 + y**2*z + 1080432*z**3, x, y, z, domain='QQ')

        r   r   r   )r.   r   é   é$   éØ   iåÿÿÿiÊÿÿÿ)r   )r:   r   r   r   r   r   )r*   ÚcharÚc4Zc6r1   r1   r2   ÚminimalT   s    $&zEllipticCurve.minimalc                    sn   | j }tƒ }|dkrbt|ƒD ]@‰ | j | jˆ | jdi¡j}t||ƒ}| 	‡ fdd„|D ƒ¡ q|S t
dƒ‚dS )a5  
        Return points of curve over Finite Field.

        Examples
        ========

        >>> from sympy.ntheory.elliptic_curve import EllipticCurve
        >>> e2 = EllipticCurve(1, 1, 1, 1, 1, modulus=5)
        >>> e2.points()
        {(0, 2), (1, 4), (2, 0), (2, 2), (3, 0), (3, 1), (4, 0)}

        r   c                 3   s   | ]}ˆ |fV  qd S r4   r1   )Ú.0Únum©Úir1   r2   Ú	<genexpr>   s     z'EllipticCurve.points.<locals>.<genexpr>zInfinitely many pointsN)r:   ÚsetÚranger'   r;   r$   r&   Úexprr   Úupdater9   )r*   rE   Zall_ptÚcongruence_eqZsolr1   rJ   r2   Úpointsk   s    
zEllipticCurve.pointsc                 C   sv   g }| j tkr8t| j | j|¡ƒD ]}| ||f¡ q"n:| j | j|| jdi¡j}t	|| j
ƒD ]}| ||f¡ q^|S )z7Returns points on the curve for the given x-coordinate.r   )r   r   r	   r'   r;   r$   Úappendr&   rO   r   r:   )r*   r$   Úptr%   rQ   r1   r1   r2   Úpoints_x„   s    
zEllipticCurve.points_xc                 C   sÖ   | j dkrtdƒ‚t | ¡g}t| j | jd| jdi¡ƒD ]}|j	r:| 
| |dƒ¡ q:t| jdd�D ]l}t|d ƒ}|d |krdt| j | j|| jdi¡ƒD ]2}|j	s¨qœ| ||ƒ}| ¡ tkrœ| || g¡ qœqd|S )al  
        Return torsion points of curve over Rational number.

        Return point objects those are finite order.
        According to Nagell-Lutz theorem, torsion point p(x, y)
        x and y are integers, either y = 0 or y**2 is divisor
        of discriminent. According to Mazur's theorem, there are
        at most 15 points in torsion collection.

        Examples
        ========

        >>> from sympy.ntheory.elliptic_curve import EllipticCurve
        >>> e2 = EllipticCurve(-43, 166)
        >>> sorted(e2.torsion_points())
        [(-5, -16), (-5, 16), O, (3, -8), (3, 8), (11, -32), (11, 32)]

        r   z"No torsion point for Finite Field.r   T)Ú	generatorg      à?r   )r:   r9   r6   Úpoint_at_infinityr	   r'   r;   r%   r&   Zis_rationalrS   r   ÚdiscriminantÚintÚorderr   Úextend)r*   ÚlZxxrK   ÚjÚpr1   r1   r2   Útorsion_points�   s     
  
zEllipticCurve.torsion_pointsc                 C   s
   | j  ¡ S )zè
        Return domain characteristic.

        Examples
        ========

        >>> from sympy.ntheory.elliptic_curve import EllipticCurve
        >>> e2 = EllipticCurve(-43, 166)
        >>> e2.characteristic
        0

        )r   r:   rA   r1   r1   r2   r:   ´   s    zEllipticCurve.characteristicc                 C   s
   t | jƒS )zæ
        Return curve discriminant.

        Examples
        ========

        >>> from sympy.ntheory.elliptic_curve import EllipticCurve
        >>> e2 = EllipticCurve(0, 17)
        >>> e2.discriminant
        -124848

        )rY   r   rA   r1   r1   r2   rX   Ä   s    zEllipticCurve.discriminantc                 C   s
   | j dkS )zE
        Return True if curve discriminant is equal to zero.
        r   )rX   rA   r1   r1   r2   Úis_singularÔ   s    zEllipticCurve.is_singularc                 C   s*   | j d d| j  }| j |d | j ¡S )zñ
        Return curve j-invariant.

        Examples
        ========

        >>> from sympy.ntheory.elliptic_curve import EllipticCurve
        >>> e1 = EllipticCurve(-2, 0, 0, 1, 1)
        >>> e1.j_invariant
        1404928/389

        r   rB   r   )r   r   r   Úto_sympyr   )r*   rF   r1   r1   r2   Új_invariantÛ   s    zEllipticCurve.j_invariantc                 C   s   | j dkrtdƒ‚t|  ¡ ƒS )zì
        Number of points in Finite field.

        Examples
        ========

        >>> from sympy.ntheory.elliptic_curve import EllipticCurve
        >>> e2 = EllipticCurve(1, 0, modulus=19)
        >>> e2.order
        19

        r   úStill not implemented)r:   ÚNotImplementedErrorr8   rR   rA   r1   r1   r2   rZ   ì   s    
zEllipticCurve.orderc                 C   s   | j dk	r| j S tdƒ‚dS )zj
        Number of independent points of infinite order.

        For Finite field, it must be 0.
        Nrc   )r)   rd   rA   r1   r1   r2   Úrankþ   s    
zEllipticCurve.rankN)r   r   r   r   )r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r3   r7   r?   r@   rG   rR   rU   r_   Úpropertyr:   rX   r`   rb   rZ   re   r1   r1   r1   r2   r      s*   

$




r   c                   @   sd   e Zd Z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d„ ZdS )r6   a  
    Point of Elliptic Curve

    Examples
    ========

    >>> from sympy.ntheory.elliptic_curve import EllipticCurve
    >>> e1 = EllipticCurve(-17, 16)
    >>> p1 = e1(0, -4, 1)
    >>> p2 = e1(1, 0)
    >>> p1 + p2
    (15, -56)
    >>> e3 = EllipticCurve(-1, 9)
    >>> e3(1, -3) * 3
    (664/169, 17811/2197)
    >>> (e3(1, -3) * 3).order()
    oo
    >>> e2 = EllipticCurve(-2, 0, 0, 1, 1)
    >>> p = e2(-1,1)
    >>> q = e2(0, -1)
    >>> p+q
    (4, 8)
    >>> p-q
    (1, 0)
    >>> 3*p-5*q
    (328/361, -2800/6859)
    c                 C   s   t ddd| ƒS ©Nr   r   r5   )Úcurver1   r1   r2   rW   '  s    z$EllipticCurvePoint.point_at_infinityc                 C   sN   |j j}||ƒ| _||ƒ| _||ƒ| _|| _| jj | _ | j | ¡sJtdƒ‚d S )Nz%The curve does not contain this point)r   r   r$   r%   r&   Ú_curver?   r9   )r*   r$   r%   r&   rl   Údomr1   r1   r2   r3   +  s    



zEllipticCurvePoint.__init__c                 C   sp  | j dkr|S |j dkr| S | j| j  | j| j   }}|j|j  |j|j   }}| jj}| jj}| jj}| jj}	| jj}
||krª|| ||  }|| ||  ||  }n†|| dkrÂ|  	| j¡S d|d  d| |  |	 ||  || | d|   }|d  |	|  d|
  ||  || | d|   }|d ||  | | | }||  | | | }|  ||d¡S )Nr   r   r   r   )
r&   r$   r%   rm   r   r    r!   r"   r#   rW   )r*   r^   r=   r>   Zx2Úy2r-   r.   r/   r+   r,   ZslopeZyintZx3Zy3r1   r1   r2   Ú__add__5  s*    

86zEllipticCurvePoint.__add__c                 C   s    | j | j| jf|j |j|jfk S r4   )r$   r%   r&   ©r*   Úotherr1   r1   r2   Ú__lt__M  s    zEllipticCurvePoint.__lt__c                 C   sb   t |ƒ}|  | j¡}|dkr |S |dk r4|  |  S | }|r^|d@ rL|| }|dL }|| }q8|S rk   )r   rW   rm   )r*   ÚnÚrr^   r1   r1   r2   Ú__mul__P  s    
zEllipticCurvePoint.__mul__c                 C   s   | | S r4   r1   )r*   rt   r1   r1   r2   Ú__rmul___  s    zEllipticCurvePoint.__rmul__c                 C   s.   t | j| j | jj| j  | jj | j| jƒS r4   )r6   r$   r%   rm   r   r!   r&   rA   r1   r1   r2   Ú__neg__b  s    zEllipticCurvePoint.__neg__c                 C   sZ   | j dkrdS | jj}zd | | j¡| | j¡¡W S  tk
rH   Y nX d | j| j¡S )Nr   ÚOz({}, {}))r&   rm   r   Úformatra   r$   r%   Ú	TypeError)r*   rn   r1   r1   r2   r@   e  s    
zEllipticCurvePoint.__repr__c                 C   s   |   | ¡S r4   )rp   rq   r1   r1   r2   Ú__sub__o  s    zEllipticCurvePoint.__sub__c                 C   sÔ   | j dkrdS | jdkrdS | d }|j| j kr6dS d}| jtkrˆt|jƒ|jkr„t|jƒ|jkr„| | }|d7 }|j dkrD|S qDtS |jj|jkrÐ|jj|jkrÐ| | }|d7 }|dkrÀtS |j dkrˆ|S qˆtS )z5
        Return point order n where nP = 0.

        r   r   r   r   é   )r&   r%   r   r   rY   r$   r   Ú	numerator)r*   r^   rK   r1   r1   r2   rZ   r  s.    


 

zEllipticCurvePoint.orderN)rf   rg   rh   ri   ÚstaticmethodrW   r3   rp   rs   rv   rw   rx   r@   r|   rZ   r1   r1   r1   r2   r6   
  s   


r6   N)Zsympy.core.numbersr   Zsympy.core.symbolr   Zsympy.polys.domainsr   r   r   r   Zsympy.polys.polytoolsr   Zsympy.solvers.solversr	   Zsympy.utilities.iterablesr
   Zsympy.utilities.miscr   Zfactor_r   Zresidue_ntheoryr   r   r6   r1   r1   r1   r2   Ú<module>   s      