
    \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)zThis 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       H/var/www/auris/envauris/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    vvax$&&  r   c                 Z    U R                   U-  U R                  -   U-  U R                  -   $ r   )r   r   r   r   s     r   eval_vSievePolynomial.eval_v    s'    	DGG#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q19"E*a/t| 0{+a/t| 0{+a/+Aa8;G#e*U*+E~ee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  pn[        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:   )NNN2   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$      QqS!c!f$JME

,s;'!+C
%5"
rAAAa&:%kV[$U0F kV['--Q  a&:% A+,E!S^c*q.6I%I"
 " Cc"((C$++fQ#Xs.CCcIEw}eHHQVE\"  FAq!$B288|q 1bhh'EABCv6%"((2CBIryy1}-9BH		zA~."((:BH   q!c!fQh-(A!A!A,!+,q0Gai!n$AA1a(A!88#HHwryy|';;rxxGHHwryy|';;rxx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sQw-K<<!ll*fll:AaCNC, O<<1!ll*fll:AaCNC, 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$ )zCheck 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     Qwr	;*>HHn!FAHHC HHn! q5516MC + 8Or   c                    [        U5      [        U 5      S-  -   U-
  S-  n/ n[        5       n	SUS   R                  -  n
[        X1* 5       H  u  pX:  a  M  UR	                  U5      n[        X5      u  pUS:X  a$  UR                  UR                  U5      X4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-  [        X5      -  U -  nUU-  US-  -  nUU-  nUR                  UX45        M  UX4X_'   M     X4$ )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   . 1vAq(:5>OEM#&{2'<'<#< K, a $Q4!8##Z%6%6q%91$BC/GCLLw!|!!#&!!!$A'+<+@+@+E(fHVC^+a/fH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  XU	   -  nXU	'   SXi'   [        U	S-   U5       H  nXL   U-  (       d  M  XL==   U-  ss'   M       Mh     Ml     [        XdU5       H  u  pn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7S=DSzHsAIM!q!Qi-q	q1uc*Ay1}}	W,	 +    4)9:1vs1v1!$0@ANBdrcDjj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  XS'   [        U 5      (       a  SXP'   U$ [        U S5      =n	(       a
  U	u  pXU
'   U$ U n[        U5      n[	        X5      u  pn[        U5      S-  S-  n[        XXX5       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  XU'   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  XU'   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    @ 	1u566G 	1uz	a!eqj!GAFA !eqj 
qzz
1%%v%
FtnG&;K&K#HK 3&+I!!xQ&q6*1k1N_l
sE!AzAqLF1*/1Q 1*/ AJ  ,-- R  qC4Dq4HIF?aAvF6/Q&6!Q 6/Q&  FO{gfoo 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 16 0+:HV68/+d*Z1?hUr   