ó
    Š*£hZ:  ã                   ó¼   • S SK JrJr  S SKJr  S SKJrJrJrJ	r
  S SKJr  S SKJr  S SKJr   " S S5      r " S	 S
5      rS rS rS rS rS rS rSS jrSS jrg)é    )ÚexpÚlog)Ú_randint)Ú	bit_scan1ÚgcdÚinvertÚsqrt)Ú_perfect_power)Úisprime)Ú_sqrt_mod_prime_powerc                   ó&   • \ rS rSrS rS rS rSrg)ÚSievePolynomialé	   c                 ód   • Xl         X l        US-  U l        SU-  U-  U l        US-  U-
  U l        g)zôThis class denotes the sieve polynomial.
Provide methods to compute `(a*x + b)**2 - N` and
`a*x + b` when given `x`.

Parameters
==========

a : parameter of the sieve polynomial
b : parameter of the sieve polynomial
N : number to be factored

é   N)ÚaÚbÚa2ÚabÚb2)Úselfr   r   ÚNs       ÚM/home/mande/repo/quber/.venv/lib/python3.13/site-packages/sympy/ntheory/qs.pyÚ__init__ÚSievePolynomial.__init__
   s7   € ð ŒØŒØ�Q‘$ˆŒØ�A‘#�a‘%ˆŒØ�Q‘$˜‘(ˆ�ó    c                 ó:   • U R                   U-  U R                  -   $ ©N)r   r   ©r   Úxs     r   Úeval_uÚSievePolynomial.eval_u   s   € Ø�v‰v�a‰x˜$Ÿ&™&Ñ Ð r   c                 óZ   • U R                   U-  U R                  -   U-  U R                  -   $ r   )r   r   r   r   s     r   Úeval_vÚSievePolynomial.eval_v    s'   € Ø—‘˜‘	˜DŸG™GÑ# QÑ&¨¯©Ñ0Ð0r   )r   r   r   r   r   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r   r!   r$   Ú__static_attributes__© r   r   r   r   	   s   † òò&!õ1r   r   c                   ó   • \ rS rSrSrS rSrg)ÚFactorBaseElemé$   z7This class stores an element of the `factor_base`.
    c                 óR   • Xl         X l        X0l        SU l        SU l        SU l        g)zÇ
Initialization of factor_base_elem.

Parameters
==========

prime : prime number of the factor_base
tmem_p : Integer square root of x**2 = n mod prime
log_p : Compute Natural Logarithm of the prime
N)ÚprimeÚtmem_pÚlog_pÚsoln1Úsoln2Úb_ainv)r   r0   r1   r2   s       r   r   ÚFactorBaseElem.__init__'   s*   € ð Œ
ØŒØŒ
ð ˆŒ
ØˆŒ
Øˆ�r   )r5   r2   r0   r3   r4   r1   N)r&   r'   r(   r)   Ú__doc__r   r*   r+   r   r   r-   r-   $   s   † ñõr   r-   c                 ób  • SSK Jn  / nSu  pEUR                  SU 5       HŠ  n[        XS-
  S-  U5      S:X  d  M  US:”  a  Uc  [	        U5      S-
  nUS:”  a  Uc  [	        U5      S-
  n[        XS5      S   n[        [        U5      S-  5      nUR                  [        XgU5      5        MŒ     XEU4$ )	a¿  Generate `factor_base` for Quadratic Sieve. The `factor_base`
consists of all the points whose ``legendre_symbol(n, p) == 1``
and ``p < num_primes``. Along with the prime `factor_base` also stores
natural logarithm of prime and the residue n modulo p.
It also returns the of primes numbers in the `factor_base` which are
close to 1000 and 5000.

Parameters
==========

prime_bound : upper prime bound of the factor_base
n : integer to be factored
r   )Úsieve)NNé   r   iè  iˆ  é   )
Úsympy.ntheory.generater9   Ú
primerangeÚpowÚlenr   Úroundr   Úappendr-   )	Úprime_boundÚnr9   Úfactor_baseÚidx_1000Úidx_5000r0   Úresiduer2   s	            r   Ú_generate_factor_baserH   <   s¿   € õ -Ø€KØ#Ñ€HØ×!Ñ! ! [Ö1ˆÜˆq˜1‘9 Ñ" EÓ*¨aÕ/Ø�t‹| Ñ 0Ü˜{Ó+¨aÑ/�Ø�t‹| Ñ 0Ü˜{Ó+¨aÑ/�Ü+¨A°aÓ8¸Ñ;ˆGÜœ#˜e›* UÑ*Ó+ˆEØ×Ñœ~¨e¸eÓDÖEñ 2ð ˜{Ð*Ð*r   c              #   óZ  #   • [        SU -  5      S-  [        U5      -
  nU=(       d    SnU=(       d    [        U5      S-
  n Su  pšn[        S5       H¯  nSn/ n[        U5      U:  aY  SnUS:X  d  Xþ;   a  U" Xx5      nUS:X  a  M  Xþ;   a  M  X/   R                  nUU-  nUR	                  U5        [        U5      U:  a  MY  [        [        U5      U-
  5      nUb   [        US-
  5      [        US-
  5      :  d  M©  Un
Un	UnM±     U	nU
n/ nU HY  nUU   R                  nUU   R                  [        UU-  U5      -  U-  nSU-  U:”  a  UU-
  nUR	                  UU-  U-  5        M[     [        U5      n[        UUU 5      nU H©  nUUR                  -  S:X  a	  SUl        M  [        UUR                  5      nU Vs/ s H  nSU-  U-  UR                  -  PM     snUl        UUR                  U-
  -  UR                  -  Ul        UUR                  * U-
  -  UR                  -  Ul        M«     Uv •  [        SS[        U5      S-
  -  5       HÎ  n[        U5      nSUUS-   -	  S-  -  S-
  nUR                  SU-  UU   -  -   nUR                   n[        UUU 5      nU Ht  nUR                  c  M  UR                  UUR                  U   -  -
  UR                  -  Ul        UR                  UUR                  U   -  -
  UR                  -  Ul        Mv     Uv •  MÐ     GMã  s  snf 7f)a  Generate sieve polynomials indefinitely.
Information such as `soln1` in the `factor_base` associated with
the polynomial is modified in place.

Parameters
==========

N : Number to be factored
M : sieve interval
factor_base : factor_base primes
idx_1000 : index of prime number in the factor_base near 1000
idx_5000 : index of prime number in the factor_base near to 5000
randint : A callable that takes two integers (a, b) and returns a random integer
          n such that a <= n <= b, similar to `random.randint`.
r   r   r:   )NNNé2   N)r   r?   Úranger0   rA   r   Úabsr1   r   Úsumr   r3   r5   r4   r   r   r   )r   ÚMrD   rE   rF   ÚrandintÚ
approx_valÚstartÚendÚbest_aÚbest_qÚ
best_ratioÚ_r   ÚqÚrand_pÚpÚratioÚBÚvalÚq_lÚgammar   ÚgÚfbÚa_invÚb_elemÚiÚvÚneg_pows                                 r   Ú_generate_polynomialrf   Y   s$  é € ô  �Q�q‘S“˜!‘œc !›fÑ$€JØ�M˜€EØ
×
,”s˜;Ó'¨!Ñ+€CØ
à%5Ñ"ˆ˜
Ü�r–ˆAØˆAØˆAÜ�a“&˜:Ó%Ø�Ø “k V£[Ù$ UÓ0�Fð  •k V¥[àÑ'×-Ñ-�Ø�Q‘�Ø—‘˜Ô ô �a“&˜:Õ%ô œ˜A› Ñ+Ó,ˆEØÑ!¤S¨°©£^´c¸*Àq¹.Ó6IÕ%IØ�Ø�Ø"’
ñ ð" ˆØˆØˆÛˆCØ˜cÑ"×(Ñ(ˆCØ Ñ$×+Ñ+¬f°Q¸#±X¸sÓ.CÑCÀcÑIˆEØ�‰w˜‹}Ø˜e™�Ø�H‰H�Q˜‘V˜E‘\Ö"ñ ô �‹FˆÜ˜A˜q !Ó$ˆÛˆBØ�2—8‘8‰|˜qÓ Ø�”ÙÜ˜1˜bŸh™hÓ'ˆEÙABÓCÂ°v˜˜6™ %™¨"¯(©(Ô2ÁÑCˆBŒIØ˜rŸy™y¨1™}Ñ-°·±Ñ9ˆBŒHØ §	¡	˜z¨A™~Ñ.°"·(±(Ñ:ˆBŽHñ ð Šô �q˜!œc !›f Q™h™-Ö(ˆAÜ˜!“ˆAØ˜!  A¡™,¨!Ñ+Ñ,¨qÑ0ˆGØ—‘�a˜‘i  !¡‘nÑ$ˆAØ—‘ˆAÜ  1 aÓ(ˆAÛ!�Ø—8‘8Ñ#ÙØŸH™H w¨r¯y©y¸©|Ñ';Ñ;¸r¿x¹xÑG�”ØŸH™H w¨r¯y©y¸©|Ñ';Ñ;¸r¿x¹xÑG�–ñ	 "ð
 ŒGñ )òU ùòH Dùs,   ‚BL+ÂL+Â3L+Ã6L+Ã<CL+Æ>L&ÇEL+c                 ó²  • S/SU -  S-   -  nU HÄ  nUR                   c  M  [        XR                   -   UR                  -  SU -  UR                  5       H  nX$==   UR                  -  ss'   M     UR                  S:X  a  Mt  [        XR                  -   UR                  -  SU -  UR                  5       H  nX$==   UR                  -  ss'   M     MÆ     U$ )a„  Sieve Stage of the Quadratic Sieve. For every prime in the factor_base
that does not divide the coefficient `a` we add log_p over the sieve_array
such that ``-M <= soln1 + i*p <=  M`` and ``-M <= soln2 + i*p <=  M`` where `i`
is an integer. When p = 2 then log_p is only added using
``-M <= soln1 + i*p <=  M``.

Parameters
==========

M : sieve interval
factor_base : factor_base primes
r   r   r:   )r3   rK   r0   r2   r4   )rN   rD   Úsieve_arrayÚfactorÚidxs        r   Ú_gen_sieve_arrayrk   ¤   sÁ   € ð �#�q˜‘s˜Q‘w‘-€KÛˆØ�<‰<ÑÙÜ˜!Ÿl™lÑ*¨f¯l©lÑ:¸A¸a¹CÀÇÁÖNˆCØÓ §¡Ñ,Õñ Oà�<‰<˜1ÓÙä˜!Ÿl™lÑ*¨f¯l©lÑ:¸A¸a¹CÀÇÁÖNˆCØÓ §¡Ñ,Õó Oñ ð Ðr   c                 ó6  • U S:  a  U S-  n SnOSn[        US5       Hw  u  p4XR                  -  (       a  M  SnXR                  -  n XR                  -  S:X  a'  US-  nXR                  -  n XR                  -  S:X  a  M'  US-  (       d  Mo  USU-  -  nMy     X 4$ )zÑCheck if `num` is smooth with respect to the given `factor_base`
and compute its factorization vector.

Parameters
==========

num : integer whose smootheness is to be checked
factor_base : factor_base primes
r   éÿÿÿÿr:   r   )Ú	enumerater0   )ÚnumrD   Úvecrc   r`   Úes         r   Ú_check_smoothnessrr   ¿   s¢   € ð ˆQƒwØˆr‰	ˆØ‰àˆÜ˜;¨Ö*‰ˆØ—‘�>ÙØˆØ—‘ÑˆØ—H‘H‰n Ó!Ø�‰FˆAØ—H‘HÑˆCð —H‘H‰n Õ!ð ˆq�5‰5Ø�1˜‘6‰MŠCñ +ð ˆ8€Or   c                 óˆ  • [        U5      [        U 5      S-  -   U-
  S-  n/ n[        5       n	SUS   R                  -  n
[        X1* 5       Hò  u  p¼XÇ:  a  M  UR	                  U5      n[        XÒ5      u  pïUS:X  a$  UR                  UR                  U5      XÞ45        MT  Xú:  d  M[  [        U5      (       d  Mm  X-  S:X  a  U	R                  U5        Mˆ  UR                  U5      nXõ;   aN  UR                  U5      u  nnnUU-  [        Xð5      -  U -  nUU-  US-  -  nUU-  nUR                  UXÞ45        Mì  UXÞ4X_'   Mô     X‰4$ )aÝ  Trial division stage. Here we trial divide the values generetated
by sieve_poly in the sieve interval and if it is a smooth number then
it is stored in `smooth_relations`. Moreover, if we find two partial relations
with same large prime then they are combined to form a smooth relation.
First we iterate over sieve array and look for values which are greater
than accumulated_val, as these values have a high chance of being smooth
number. Then using these values we find smooth relations.
In general, let ``t**2 = u*p modN`` and ``r**2 = v*p modN`` be two partial relations
with the same large prime p. Then they can be combined ``(t*r/p)**2 = u*v modN``
to form a smooth relation.

Parameters
==========

N : Number to be factored
M : sieve interval
factor_base : factor_base primes
sieve_array : stores log_p values
sieve_poly : polynomial from which we find smooth relations
partial_relations : stores partial relations with one large prime
ERROR_TERM : error term for accumulated_val
r   r;   é€   rm   r:   r   )r   Úsetr0   rn   r$   rr   rA   r!   r   ÚaddÚpopr   )r   rN   rD   rh   Ú
sieve_polyÚpartial_relationsÚ
ERROR_TERMÚaccumulated_valÚsmooth_relationsÚproper_factorÚpartial_relation_upper_boundr    r\   rd   rp   ro   ÚuÚu_prevÚv_prevÚvec_prevs                       r   Ú_trial_division_stagerƒ   Û   sT  € ô. ˜1“v¤ A£ q¡Ñ(¨:Ñ5¸Ñ>€OØÐÜ“E€MØ#& {°2¡×'<Ñ'<Ñ#<Ð Ü˜K¨Ö,‰ˆØÓ ÙØ×Ñ˜aÓ ˆÜ$ QÓ4‰ˆØ�!‹8Ø×#Ñ# Z×%6Ñ%6°qÓ%9¸1Ð$BÖCØÕ/´G¸C·L³LØ‰w˜!‹|Ø×!Ñ! #Ô&ÙØ×!Ñ! !Ó$ˆAØÓ'Ø+<×+@Ñ+@ÀÓ+EÑ(�˜ Ø�f‘HœV C›^Ñ+¨aÑ/�Ø�f‘H  Q¡Ñ&�Ø�x‘�Ø ×'Ñ'¨¨A¨Ö4à*+¨Q¨Ð!Ó&ñ' -ð( Ð*Ð*r   c              #   ó~  #   • U Vs/ s H  o3S   PM	     nn[        U5      nS/U-  n[        U5       Hj  nSU-  n[        U5       HS  n	XI   U-  =n
(       d  M  X¤U	   -  nX„U	'   SXi'   [        U	S-   U5       H  nXL   U-  (       d  M  XL==   U-  ss'   M       Mh     Ml     [        XdU5       H†  u  p�nU(       a  M  US   US   nn[        XdU5       H,  u  nnnU(       d  M  UU-  (       d  M  UUS   -  nUUS   -  nM.     [        U5      nS[	        UU-
  U 5      =ns=:  a  U :  d  M~  O  M‚  Uv •  Mˆ     gs  snf 7f)ao  Finds proper factor of N using fast gaussian reduction for modulo 2 matrix.

Parameters
==========

N : Number to be factored
smooth_relations : Smooth relations vectors matrix
col : Number of columns in the matrix

Reference
==========

.. [1] A fast algorithm for gaussian elimination over GF(2) and
its implementation on the GAPP. Cetin K.Koc, Sarath N.Arachchige
r   Fr:   Tr   N)r?   rK   ÚzipÚisqrtr   )r   r|   ÚcolÚ
s_relationÚmatrixÚrowÚmarkÚposÚmrc   rY   Úadd_colÚjÚmatÚrelr   rd   Úm1Úmat1Úrel1r_   s                        r   Ú_find_factorr•     sW  é € ñ  /?Ó?Ò.> 
˜ŒmÑ.>€FÐ?Ü
ˆf‹+€CØˆ7�S‰=€DÜ�SŽzˆØ�‰HˆÜ�s–ˆAØ‘I ‘MÐ!ˆq×!Ø Q™i™-�Ø�q‘	Ø�‘Ü˜q 1™u cÖ*�AØ‘y 1—}‘}Ø›	 WÑ,�	ñ +ò ó ñ ô ˜4Ð)9Ö:‰ˆ�ÞÙØ�1‰v�s˜1‘vˆ1ˆÜ! $Ð0@ÖA‰NˆB��dßˆr�c˜D—j‘jØ�T˜!‘W‘�Ø�T˜!‘W‘’ñ Bô
 �!‹HˆØ”S˜˜Q™ “]Ð"�Õ' a×'Ñ'ØŒGò ;ùò @ùs/   ‚D=‡D8•A D=Á+D=ÂAD=Ã"D=Ã.9D=Ä+D=c           	      ó.   • [        [        XX#U5      5      $ )a  Performs factorization using Self-Initializing Quadratic Sieve.
In SIQS, let N be a number to be factored, and this N should not be a
perfect power. If we find two integers such that ``X**2 = Y**2 modN`` and
``X != +-Y modN``, then `gcd(X + Y, N)` will reveal a proper factor of N.
In order to find these integers X and Y we try to find relations of form
t**2 = u modN where u is a product of small primes. If we have enough of
these relations then we can form ``(t1*t2...ti)**2 = u1*u2...ui modN`` such that
the right hand side is a square, thus we found a relation of ``X**2 = Y**2 modN``.

Here, several optimizations are done like using multiple polynomials for
sieving, fast changing between polynomials and using partial relations.
The use of partial relations can speeds up the factoring by 2 times.

Parameters
==========

N : Number to be Factored
prime_bound : upper bound for primes in the factor base
M : Sieve Interval
ERROR_TERM : Error term for checking smoothness
seed : seed of random number generator

Returns
=======

set(int) : A set of factors of N without considering multiplicity.
           Returns ``{N}`` if factorization fails.

Examples
========

>>> from sympy.ntheory import qs
>>> qs(25645121643901801, 2000, 10000)
{5394769, 4753701529}
>>> qs(9804659461513846513, 2000, 10000)
{4641991, 2112166839943}

See Also
========

qs_factor

References
==========

.. [1] https://pdfs.semanticscholar.org/5c52/8a975c1405bd35c65993abf5a4edb667c1db.pdf
.. [2] https://www.rieselprime.de/ziki/Self-initializing_quadratic_sieve
)ru   Ú	qs_factor)r   rB   rN   rz   Úseeds        r   Úqsr™   :  s   € ôb Œy˜¨¸Ó=Ó>Ð>r   c           
      óJ  • U S:  a  [        S5      e0 n/ n0 nU S-  S:X  a)  SnU S-  n U S-  S:X  a  U S-  n US-  nU S-  S:X  a  M  X…S'   [        U 5      (       a  SXP'   U$ [        U S5      =n	(       a
  U	u  p¨X…U
'   U$ U n[        U5      n[	        X5      u  pÞn[        U5      S-  S-  n[        XXýXì5       Ht  n[        X/5      n[        XUUUXs5      u  nnUU-  nU H8  nUU-  (       a  M  SnUU-  nUU-  S:X  a  UU-  nUS-  nUU-  S:X  a  M  X…U'   M:     U[        U5      ::  d  Mt    O   [        X[        U5      S-   5       HO  nUU-  S:X  d  M  SnUU-  nUU-  S:X  a  UU-  nUS-  nUU-  S:X  a  M  X…U'   US:X  d  [        U5      (       d  MO    O   US:w  a  SX['   U$ )aU  Performs factorization using Self-Initializing Quadratic Sieve.

Parameters
==========

N : Number to be Factored
prime_bound : upper bound for primes in the factor base
M : Sieve Interval
ERROR_TERM : Error term for checking smoothness
seed : seed of random number generator

Returns
=======

dict[int, int] : Factors of N.
                 Returns ``{N: 1}`` if factorization fails.
                 Note that the key is not always a prime number.

Examples
========

>>> from sympy.ntheory import qs_factor
>>> qs_factor(1009 * 100003, 2000, 10000)
{1009: 1, 100003: 1}

See Also
========

qs

r   zN should be greater than 1r   r:   é   éi   éd   )
Ú
ValueErrorr   r
   r   rH   r?   rf   rk   rƒ   r•   )r   rB   rN   rz   r˜   Úfactorsr|   ry   rq   ÚresultrC   ÚN_copyrO   rE   rF   rD   Ú	thresholdr_   rh   Ús_relÚp_frY   ri   s                          r   r—   r—   n  s   € ð@ 	ˆ1ƒuÜÐ5Ó6Ð6Ø€GØÐØÐð 	ˆ1�u�ƒzØˆØ	ˆa‰ˆØ�!‰e�q‹jØ�!‰GˆAØ�‰FˆAð �!‰e�q�jð �‰
Üˆq‡z�zØˆ‰
ØˆÜ  1Ó%Ð%€vÕ%Ø‰ˆØ�‰
ØˆØ€FÜ�t‹n€GÜ&;¸KÓ&KÑ#€H˜Ü�KÓ  3Ñ&¨Ñ+€IÜ! !¨¸xÖQˆÜ& qÓ6ˆÜ*¨1°¸kÈ1ÐN_Ól‰
ˆˆsØ˜EÑ!ÐÛˆAØ˜�zÙØˆAØ�q‰LˆFØ˜1‘* “/Ø˜1‘�Ø�Q‘�ð ˜1‘* •/ð �A‹Jñ ð œÐ,Ó-Õ-Ùñ Rô  ˜q´C¸Ó4DÀqÑ4HÖIˆØ�F‰?˜aÕØˆAØ�vÑˆFØ˜6‘/ QÓ&Ø˜6Ñ!�Ø�Q‘�ð ˜6‘/ QÕ&ð  �F‰OØ˜‹{œg fŸo›oÙñ Jð �ƒ{Øˆ‰Ø€Nr   N)é   iÒ  )Úmathr   r   Úsympy.core.randomr   Úsympy.external.gmpyr   r   r   r	   r†   Úsympy.ntheory.factor_r
   Úsympy.ntheory.primetestr   Úsympy.ntheory.residue_ntheoryr   r   r-   rH   rf   rk   rr   rƒ   r•   r™   r—   r+   r   r   Ú<module>r¬      s\   ðß Ý &ß EÓ EÝ 0Ý +Ý ?÷1ñ 1÷6ñ ò0+ò:HòVò6ò8/+òd*ôZ1?õhUr   