
    MZd,                         d dl mZ 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  G d d      Z G d d      Zy)    )oo)Eq)symbols)FiniteFieldQQRationalFieldFF)solve)is_sequence)as_int   )divisors)polynomial_congruencec                       e Zd ZdZddZddZd Zd Zd Zd Z	d Z
d	 Zed
        Zed        Zed        Zed        Zed        Zed        Zy)EllipticCurveaH  
    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``,
    it create curve as 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

    c                 x   |dk(  rt         }nt        |      }t        |j                  |||||f      \  }}}}}|| _        || _        |dz  d|z  z   }d|z  ||z  z   }	|dz  d|z  z   }
|dz  |z  d|z  |z  z   ||z  |z  z
  ||dz  z  z   |dz  z
  }||	|
|f\  | _        | _        | _        | _	        |dz   |z  d|	dz  z  z
  d|
dz  z  z
  d|z  |	z  |
z  z   | _
        || _        || _        || _        || _        || _        t!        d      \  }}}|||c| _        | _        | _        t)        |dz  |z  ||z  |z  |z  z   ||z  |dz  z  z   |dz  ||dz  z  |z  z   ||z  |dz  z  z   ||dz  z  z         | _        t-        | j                  t.              rd| _        y t-        | j                  t2              rd | _        y y )	Nr                  	   zx y z)r   r	   mapconvert_domainmodulus_b2_b4_b6_b8_discrim_a1_a2_a3_a4_a6r   xyzr   _eq
isinstancer   _rankr   )selfa4a6a1a2a3r   domainb2b4b6b8r'   r(   r)   s                  >/usr/lib/python3/dist-packages/sympy/ntheory/elliptic_curve.py__init__zEllipticCurve.__init__$   s    a<F[F "b"b"1EFBBUQV^Vb2gUQV^URZ!b&2+%R"4rBEzABEI13RR.$(DHdhQa"a%i/"r1u*<q2v{R?OO'"1a!"Aqad1fr!tAvax'"Q$q!t)3QTBq!tGAI5E1QPQT	5QTVWXZ[W[T[5[\dllK0DJm4DJ 5    c                     t        ||||       S NEllipticCurvePoint)r-   r'   r(   r)   s       r8   __call__zEllipticCurve.__call__@   s    !!Q400r:   c                 ~   t        |      rt        |      dk(  rd}n|d   }|d d \  }}n@t        |t              r%|j                  |j
                  |j                  }}}nt        d      | j                  dk(  r|dk(  ry| j                  j                  | j                  || j
                  || j                  |i      S )Nr   r   zInvalid point.r   T)r   lenr+   r>   r'   r(   r)   
ValueErrorcharacteristicr*   subs)r-   pointz1x1y1s        r8   __contains__zEllipticCurve.__contains__C   s    u5zQ1X2AYFB12%''577BB-..!#axx}}dffb$&&"dffbABBr:   c                 N    dj                  | j                  | j                        S )Nz	E({}): {})formatr   r*   r-   s    r8   __repr__zEllipticCurve.__repr__R   s    !!$,,99r:   c                    | j                   }|dk(  r| S |dk(  r@t        | j                  dz  | j                  dz  | j                  dz  | j
                        S | j                  dz  d| j                  z  z
  }| j                  dz   d| j                  z  | j                  z  z   d| j                  z  z
  }t        d|z  d	|z  | j
                  
      S )a)  
        Return minimal Weierstrass equation.

        Examples
        ========

        >>> from sympy.ntheory.elliptic_curve import EllipticCurve

        >>> e1 = EllipticCurve(-10, -20, 0, -1, 1)
        >>> e1.minimal()
        E(QQ): Eq(y**2*z, x**3 - 13392*x*z**2 - 1080432*z**3)

        r   r   r   )r1   r      $      ii)r   )rC   r   r   r   r   r   )r-   charc4c6s       r8   minimalzEllipticCurve.minimalU   s     ""19K19 !TXXaZDHHQJPTP\P\]]XXq[2dhh;&hhk\BtxxK003txx<?SVSVT\\BBr:   c                 f   | j                   }t               }|dk\  rt        |      D ]|  }| j                  j                  | j                  j
                  z
  j                  | j                  || j                  di      }t        ||      }|D ]  }|j                  ||f        ~ |S t        d      )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   zInfinitely many points)rC   setranger*   lhsrhsrD   r'   r)   r   addrB   )r-   rR   all_pticongruence_eqsolnums          r8   pointszEllipticCurve.pointsl   s     ""194[ )"&((,,"=!C!CTVVQPTPVPVXYDZ![+M4@ )CJJ3x())
 M566r:   c                    g }| j                   t        k(  rGt        | j                  j	                  | j
                  |            D ]  }|j                  ||f        | j                  j                  | j                  j                  z
  j	                  | j
                  || j                  di      }t        || j                        D ]  }|j                  ||f        |S )z2Returns points on with curve where xcoordinate = xr   )r   r   r
   r*   rD   r'   appendrY   rZ   r)   r   rC   )r-   r'   ptr(   r^   s        r8   points_xzEllipticCurve.points_x   s    <<2488==34 &IIq!f%&((,,5;;TVVQPQ<RS&}d6I6IJ 	AIIq!f		r:   c           	         | j                   dkD  rt        d      t        j                  |       g}t	        | j
                  j                  | j                  d| j                  di            D ]'  }|j                  s|j                   | |d             ) t        | j                  d      D ]  }t        |dz        }|dz  |k(  st	        | j
                  j                  | j                  || j                  di            D ]D  }|j                  s | ||      }|j                         t        k7  s1|j!                  || g       F  |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   )rC   rB   r>   point_at_infinityr
   r*   rD   r(   r)   is_rationalrc   r   discriminantintorderr   extend)r-   lxxr]   jps         r8   torsion_pointszEllipticCurve.torsion_points   s   & "ABB11$78tvvq$&&!&<=> 	&B~~b!%	& $++t< 	*AArE
A!tqytvvq$&&!.D EF *B>> RAwwyB!aR)*	* r:   c                 6    | j                   j                         S )z
        Return domain characteristic.

        Examples
        ========

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

        )r   rC   rL   s    r8   rC   zEllipticCurve.characteristic   s     ||**,,r:   c                 ,    t        | j                        S )z
        Return curve discriminant.

        Examples
        ========

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

        )rk   r!   rL   s    r8   rj   zEllipticCurve.discriminant   s     4==!!r:   c                      | j                   dk(  S )zE
        Return True if curve discriminant is equal to zero.
        r   )rj   rL   s    r8   is_singularzEllipticCurve.is_singular   s    
   A%%r:   c                     | j                   dz  d| j                  z  z
  }| j                  j                  |dz  | j                  z        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   rO   r   )r   r   r   to_sympyr!   )r-   rS   s     r8   j_invariantzEllipticCurve.j_invariant   s@     XXq[2dhh;&||$$RUT]]%:;;r:   c                 h    | j                   dk(  rt        d      t        | j                               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)rC   NotImplementedErrorrA   ra   rL   s    r8   rl   zEllipticCurve.order   s/     !#%&=>>4;;=!!r:   c                 H    | j                   | j                   S t        d      )zj
        Number of independent points of infinite order.

        For Finite field, it must be 0.
        r{   )r,   r|   rL   s    r8   rankzEllipticCurve.rank   s$     ::!::!"9::r:   N)r   r   r   r   )r   )__name__
__module____qualname____doc__r9   r?   rI   rM   rU   ra   re   rr   propertyrC   rj   rv   ry   rl   r~    r:   r8   r   r      s    ,81C:C.74	"H - - " " & & < <  " "" ; ;r:   r   c                   V    e Zd ZdZed        Zd Zd Zd Zd Z	d Z
d Zd	 Zd
 Zd Zy)r>   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                     t        ddd|       S Nr   r   r=   )curves    r8   rh   z$EllipticCurvePoint.point_at_infinity(  s    !!Q511r:   c                    |j                   j                  } ||      | _         ||      | _         ||      | _        || _        | j
                  j                   | _         | j
                  j                  |       st        d      y )Nz%The curve does not contain this point)r   r   r'   r(   r)   _curverI   rB   )r-   r'   r(   r)   r   doms         r8   r9   zEllipticCurvePoint.__init__,  sm    mm##QQQ{{**{{''-DEE .r:   c                    | j                   dk(  r|S |j                   dk(  r| S | j                  | j                   z  | j                  | j                   z  }}|j                  |j                   z  |j                  |j                   z  }}| j                  j                  }| j                  j
                  }| j                  j                  }| j                  j                  }	| j                  j                  }
||k7  r||z
  ||z
  z  }||z  ||z  z
  ||z
  z  }ns||z   dk(  r| j                  | j                        S d|dz  z  d|z  |z  z   |	z   ||z  z
  ||z  |z   d|z  z   z  }|dz   |	|z  z   d|
z  z   ||z  z
  ||z  |z   d|z  z   z  }|dz  ||z  z   |z
  |z
  |z
  }||z    |z  |z
  |z
  }| j                  ||d      S )Nr   r   r   r   )
r)   r'   r(   r   r"   r#   r$   r%   r&   rh   )r-   rq   rG   rH   x2y2r0   r1   r2   r.   r/   slopeyintx3y3s                  r8   __add__zEllipticCurvePoint.__add__6  s   66Q;H33!8KtvvBQSS!##acc'B[[__[[__[[__[[__[[__8"Wb)EGb2g%"r'2DRA~--dkk::QY2b(2-25"r'B,R:OPEUFRUNQrT)BrE1bebj1R46GHDAX5 2%*R/rz]R$&+{{2r1%%r:   c                     | j                   | j                  | j                  f|j                   |j                  |j                  fk  S r<   )r'   r(   r)   r-   others     r8   __lt__zEllipticCurvePoint.__lt__N  s3    '577EGGUWW*EEEr:   c                     t        |      }| j                  | j                        }|dk(  r|S |dk  r|  | z  S | }|r|dz  r||z   }|dz  }||z   }|r|S r   )r   rh   r   )r-   nrrq   s       r8   __mul__zEllipticCurvePoint.__mul__Q  sv    1I""4;;/6Hq55A2:1uE!GAAA	 
 r:   c                     | |z  S r<   r   )r-   r   s     r8   __rmul__zEllipticCurvePoint.__rmul__`  s    axr:   c                     t        | j                  | j                   | j                  j                  | j                  z  z
  | j                  j
                  z
  | j                  | j                        S r<   )r>   r'   r(   r   r"   r$   r)   rL   s    r8   __neg__zEllipticCurvePoint.__neg__c  sN    !$&&466'DKKOODFF4J*JT[[__*\^b^d^dfjfqfqrrr:   c                 B   | j                   dk(  ry| j                  j                  }	 dj                  |j	                  | j
                        |j	                  | j                              S # t        $ r Y nw xY wdj                  | j
                  | j                        S )Nr   Oz({}, {}))r)   r   r   rK   rx   r'   r(   	TypeError)r-   r   s     r8   rM   zEllipticCurvePoint.__repr__f  s~    66Q;kk!!	$$S\\$&&%93<<;OPP 		  00s   AA, ,	A87A8c                 &    | j                  |       S r<   )r   r   s     r8   __sub__zEllipticCurvePoint.__sub__p  s    ||UF##r:   c                 r   | j                   dk(  ry| j                  dk(  ry| dz  }|j                  | j                   k(  ryd}| j                  t        k7  rt	        |j
                        |j
                  k(  rt	        |j                        |j                  k(  r`| |z   }|dz  }|j                   dk(  r|S t	        |j
                        |j
                  k(  r#t	        |j                        |j                  k(  r`t        S |j
                  j                  |j
                  k(  r|j                  j                  |j                  k(  rm| |z   }|dz  }|dkD  rt        S |j                   dk(  r|S |j
                  j                  |j
                  k(  r$|j                  j                  |j                  k(  rmt        S )z5
        Return point order n where nP = 0.

        r   r   r   r      )r)   r(   r   r   rk   r'   r   	numerator)r-   rq   r]   s      r8   rl   zEllipticCurvePoint.orders  sH   
 66Q;66Q;1H33466'><<2acc(acc/c!##h!##o1HQ33!8H	 acc(acc/c!##h!##o
 Iccmmqss"qss}}';qAFA2v	ssax ccmmqss"qss}}'; 	r:   N)r   r   r   r   staticmethodrh   r9   r   r   r   r   r   rM   r   rl   r   r:   r8   r>   r>     sK    8 2 2F&0Fs1$r:   r>   N)sympy.core.numbersr   sympy.core.relationalr   sympy.core.symbolr   sympy.polys.domainsr   r   r   r	   sympy.solvers.solversr
   sympy.utilities.iterablesr   sympy.utilities.miscr   factor_r   residue_ntheoryr   r   r>   r   r:   r8   <module>r      s<    ! $ % B B ' 1 '  2{; {;|C Cr:   