K iZ:ddlmZmZddlmZddlmZmZmZm Z ddl m Z ddl mZddlmZGddZGd d Zd Zd Zd ZdZdZdZddZddZy))explog)_randint) bit_scan1gcdinvertsqrt)_perfect_power)isprime)_sqrt_mod_prime_powerceZdZdZdZdZy)SievePolynomialch||_||_|dz|_d|z|z|_|dz|z |_y)a4This 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)aba2abb2)selfrrNs V/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/ntheory/qs.py__init__zSievePolynomial.__init__ s;Q$A#a%Q$(c:|j|z|jzSN)rrrxs reval_uzSievePolynomial.eval_usvvax$&&  rcZ|j|z|jz|z|jzSr)rrrrs reval_vzSievePolynomial.eval_v s' DGG#Q&00rN)__name__ __module__ __qualname__rrr!rrrr s&!1rrceZdZdZdZy)FactorBaseElemz7This class stores an element of the `factor_base`. cX||_||_||_d|_d|_d|_y)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)primetmem_plog_psoln1soln2b_ainv)rr)r*r+s rrzFactorBaseElem.__init__'s0      rN)r"r#r$__doc__rr%rrr'r'$s rr'c\ddlm}g}d\}}|jd|D]}t||dz dz|dk(s|dkDr|t |dz }|dkDr|t |dz }t ||dd}t t|dz}|jt||||||fS) aGenerate `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)NNrii) sympy.ntheory.generater1 primerangepowlenr roundrappendr') prime_boundnr1 factor_baseidx_1000idx_5000r)residuer+s r_generate_factor_baser@<s-K#Hh!!![1F q519"E *a /t| 0{+a/t| 0{+a/+Aua8;G#e*U*+E   ~eWeD EF X{ **rc#Ktd|zdz t|z }|xsd}|xst|dz } d\} } } tdD]} d} g}t| |krSd}|dk(s||vr|||}|dk(r||vr||j}| |z} |j |t| |krSt t| |z }| t |dz t | dz ks|} | } |} | } | }g}|D]W}||j}||jt| |z|z|z}d|z|kDr||z }|j | |z|zYt|}t| ||}|D]}| |jzdk(rd|_ t| |j}|Dcgc]}d|z|z|jzc}|_ ||j|z z|jz|_ ||j |z z|jz|_ |tddt|dz zD]}t|}d||dzz dzzdz }|jd|z||zz}|j } t| ||}|D]q}|j|j||j|zz |jz|_ |j||j|zz |jz|_ s|cc}ww)a6 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`. rrr2)NNN2N)rr7ranger)r9rabsr*rsumrr,r.r-rrr)rMr<r=r>randint approx_valstartendbest_abest_q best_ratio_rqrand_ppratioBvalq_lgammargfba_invb_elemivneg_pows r_generate_polynomialr^YsF QqS!c!f$J ME  ,s;'!+C %5" r #AAAa&:%kVq[$UC0FkVq['--Q a&:%A+,E!S^c*q.6I%I"  #"    #Cc"((C$++fQ#Xs.CCcIEw}e  HHQVE\ "  # F Aq! $ ;B288|q 1bhh'EABCv6%"((2CBIryy1}-9BH zA~."((:BH ;q!c!fQh-( A! A!A,!+,q0Gai!n$AA1a(A! H88#HHwryy|';;rxxGHHwryy|';;rxxG  H G U HDs,A6L9L>3L26L)B;L$LELcdgd|zdzz}|D]}|jt||jz|jzd|z|jD]}||xx|jz cc<|jdk(rpt||jz|jzd|z|jD]}||xx|jz cc<|S)aSieve 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 rrr2)r,rCr)r+r-)rFr< sieve_arrayfactoridxs r_gen_sieve_arrayrcs#qsQw-K - <<  !fll*fll:AaCN -C   ,  - <<1  !fll*fll:AaCN -C   ,  - - rc |dkr|dz}d}nd}t|dD]m\}}||jzrd}||jz}||jzdk(r'|dz }||jz}||jzdk(r'|dzsf|d|zz }o||fS)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 rr2r) enumerater))numr<vecr[rXes r_check_smoothnessrjs Qw r ;* 2 >   BHHn! FA BHH CBHHn! q5 16MC  8Orc~t|t|dz z|z dz}g}t} d|djz} t|| D]\} } | |kr |j | } t | |\}}|dk(r$|j |j| | |fU|| ks[t|sg||zdk(r| j||j| }||vrO|j|\}}}||zt||z|z}| |z|dzz} ||z}|j || |f|| |f||<|| fS)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 rr3rer2r) rsetr)rfr!rjr9rr addpopr)rrFr<r` sieve_polypartial_relations ERROR_TERMaccumulated_valsmooth_relations proper_factorpartial_relation_upper_boundrrTr\rhrguu_prevv_prevvec_prevs r_trial_division_stager{su.1vAq(:5>OEM#&{2'<'<#< K!,53     a $Q 4S !8  # #Z%6%6q%91c$B C / /GCL3w!|!!#&!!!$A''+<+@+@+E(fHVC^+a/fHQ&x ''As 4*+Q!#&'5( ] **rc#4K|Dcgc]}|d }}t|}dg|z}t|D]_}d|z}t|D]J} || |zx} s| || z } ||| <d|| <t| dz|D]} || |zs || xx| zcc<_at|||D]o\}} }|r |d|d}}t|||D]\}}}|s | |zs||dz}||dz}!t|}dt ||z |x}cxkr|ksinl|qycc}ww)a 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 rFr2TrN)r7rCzipisqrtr)rrtcol s_relationmatrixrowmarkposmr[rQadd_coljmatrelrwr\m1mat1rel1rWs r _find_factorr sx /? ? jm ?F ? f+C 7S=DSz  Hs A1IM!q!fQi-q Qq1uc*-Aay1}q W, -  4)9:  3 1vs1v1!$0@A NBdcDjT!W T!W   !H SQ]" 'a 'G @s.D D>D,D?A D D7D Dc 2tt|||||S)aPerforms 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 )rm qs_factor)rr:rFrrseeds rqsr:sb yKJ= >>rc |dkr tdi}g}i}|dzdk(r'd}|dz}|dzdk(r|dz}|dz }|dzdk(r||d<t|rd||<|St|dx} r | \} }||| <|S|} t|} t ||\} }}t |dzdz}t |||| || D]k}t||}t|||||||\}}||z }|D]/}| |zr d}| |z} | |zdk(r| |z} |dz }| |zdk(r|||<1|t |ksknt||t |dzD]D}| |zdk(s d}| |z} | |zdk(r| |z} |dz }| |zdk(r|||<| dk(s t| sDn| dk7rd|| <|S)a 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 rzN should be greater than 1rr2id) ValueErrorr r rr@r7r^rcr{r)rr:rFrrrfactorsrtrqriresultr;N_copyrGr=r>r< thresholdrWr`s_relp_frQras rrrnsK@ 1u566G 1uz  a!eqj !GA FA!eqj qz 1%%v%1  FtnG&;K&K#Hh K 3&+I !!Q Xx Q&q+6 *1ak1N_akl sE! AzA qLF1*/1 Q1*/GAJ  ,- -  q"2C 4Dq4HI  F?a A v F6/Q&6!Q6/Q& GFO{gfo { NrN)i)mathrrsympy.core.randomrsympy.external.gmpyrrrr r~sympy.ntheory.factor_r sympy.ntheory.primetestr sympy.ntheory.residue_ntheoryr rr'r@r^rcrjr{rrrr%rrrs\&EE0+?1160+:HV68/+d*Z1?hUr