
    wg-                         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      Z G d d      Zy)    )oo)symbols)FiniteFieldQQRationalFieldFF)Poly)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)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

    c                    |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  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)domain)r   r   mapconvert_domainmodulus_b2_b4_b6_b8_discrim_a1_a2_a3_a4_a6r   xyzr	   _poly
isinstancer   _rankr   )selfa4a6a1a2a3r   r   b2b4b6b8r(   r)   r*   s                  a/home/mcse/projects/flask/flask-venv/lib/python3.12/site-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!Q$q&2a46!8+bd1a4i7!Q$>AqDJRPQTRSUVRVYVY[\]_`\`Y``iop
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      dk(  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__B   s    u5zQ1X2AYFB12%''577BB-..!#azzDFFBCDIIr:   c                 6    | j                   j                         S r<   )r+   __repr__r.   s    r8   rK   zEllipticCurve.__repr__Q   s    zz""$$r:   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()
        Poly(-x**3 + 13392*x*z**2 + y**2*z + 1080432*z**3, x, y, z, domain='QQ')

        r   r   r   )r2   r      $      ii)r   )rC   r   r   r    r   r   )r.   charc4c6s       r8   minimalzEllipticCurve.minimalT   s     ""19K19 !TXXaZDHHQJPTP\P\]]XXq[2dhh;&hhk\BtxxK003txx<?SVSVT\\BBr:   c                 :   | j                   }t               }|dk\  rut        |      D ]e  | j                  j	                  | j
                  | j                  di      j                  }t        ||      }|j                  fd|D               g |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   c              3   &   K   | ]  }|f 
 y wr<    ).0numis     r8   	<genexpr>z'EllipticCurve.points.<locals>.<genexpr>   s     63q#h6s   zInfinitely many points)rC   setranger+   rD   r(   r*   exprr   updaterB   )r.   rQ   all_ptcongruence_eqsolrZ   s        @r8   pointszEllipticCurve.pointsk   s     ""194[ 7 $

DFFA0F G L L+M4@6#667 M566r:   c                    g }| j                   t        k(  rIt        | j                  j	                  | j
                  |            D ]  }|j                  ||f        |S | j                  j	                  | j
                  || j                  di      j                  }t        || j                        D ]  }|j                  ||f        |S )z7Returns points on the curve for the given x-coordinate.r   )r   r   r
   r+   rD   r(   appendr*   r^   r   rC   )r.   r(   ptr)   ra   s        r8   points_xzEllipticCurve.points_x   s    <<24::??466156 "		1a&!" 	 !JJOOTVVQ,BCHHM*=$:M:MN "		1a&!"	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_rationalre   r   discriminantintorderr   extend)r.   lxxrZ   jps         r8   torsion_pointszEllipticCurve.torsion_points   s   & "ABB11$78

DFFA(>?@ 	&B~~b!%	& $++t< 	*AArE
A!tqy

DFFA0F GH *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

        )rm   r"   rL   s    r8   rl   zEllipticCurve.discriminant   s     4==!!r:   c                      | j                   dk(  S )zE
        Return True if curve discriminant is equal to zero.
        r   )rl   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   rN   r   )r   r   r   to_sympyr"   )r.   rR   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   rc   rL   s    r8   rn   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   rK   rT   rc   rg   rt   propertyrC   rl   rx   r{   rn   r   rW   r:   r8   r   r      s    ,81J%C.72
"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   rj   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'   rj   )r.   rs   rG   rH   x2y2r1   r2   r3   r/   r0   slopeyintx3y3s                  r8   __add__zEllipticCurvePoint.__add__5  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__M  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   rj   r   )r.   nrrs   s       r8   __mul__zEllipticCurvePoint.__mul__P  sv    1I""4;;/6Hq55A2:1uE!GAAA	 
 r:   c                     | |z  S r<   rW   )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__b  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   formatrz   r(   r)   	TypeError)r.   r   s     r8   rK   zEllipticCurvePoint.__repr__e  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__o  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   rm   r(   r   	numerator)r.   rs   rZ   s      r8   rn   zEllipticCurvePoint.orderr  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   staticmethodrj   r9   r   r   r   r   r   rK   r   rn   rW   r:   r8   r>   r>   
  sK    8 2 2F&0Fs1$r:   r>   N)sympy.core.numbersr   sympy.core.symbolr   sympy.polys.domainsr   r   r   r   sympy.polys.polytoolsr	   sympy.solvers.solversr
   sympy.utilities.iterablesr   sympy.utilities.miscr   factor_r   residue_ntheoryr   r   r>   rW   r:   r8   <module>r      s<    ! % B B & ' 1 '  2{; {;|C Cr:   