常用工具 古典密码
gmpy2 1 2 3 4 5 6 7 8 9 10 from gmpy2 import *mpz(n) mpfr(x) d = invert(e,n) c = powmod(m,e,n) is_prime(n) gcd(a,b) gcdext(a,b) iroot(x,n)
sympy 1 2 3 4 5 6 7 8 from sympy import *prime(n) isprime(n) primepi(n) nextprime(n) prevprime(n) nthroot_mod(c,e,p,all_roots=True )
Sage 定义
1 2 3 4 5 6 7 8 9 R.<X> = PolynomialRing(Zmod(n)) R.<M> = PolynomialRing(MatrixSpace(Zmod(n),3 ,3 ))
数论
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 prime_pi(n) divisors(n) number_of_divisors(n) factor(n) euler_phi(n) two_squares(n) three_squares(n) four_squares(n) x.nth_root(n, truncate_mode=True ) mod(x,p).nth_root(n) def mod_nth_root (x, e, n ): r, z = pari(f"r = sqrtn(Mod({x} , {n} ), {e} , &z); [lift(r), lift(z)]" ) r, z = int (r), int (z) roots = [r] t = r while (t := (t*z) % n) != r: roots.append(t) return roots
多项式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 f.subs({x:x1}) f.univariate_polynomial() f.univariate_polynomial().roots() f.coefficients() f.padded_list(n) f.list () f.monic() f.sub(x,x-1 ) f.factor() x = PolynomialRing(RationalField(), 'x' ).gen() f = (x^3 - 1 )^2 -(x^2 -1 )^2 f.factor() x, y = PolynomialRing(RationalField(), 2 , ['x' ,'y' ]).gens() f = (9 *y^6 - 9 *x^2 *y^5 - 18 *x^3 *y^4 - 9 *x^5 *y^4 + 9 *x^6 *y^2 + 9 *x^7 *y^3 + 18 *x^8 *y^2 - 9 *x^11 ) f.factor() x = PolynomialRing(RationalField(), 'x' ).gen() f = 3 *x^3 + x g = 9 *x*(x+1 ) f.gcd(g) R.<x,y,z> = PolynomialRing(RationalField(), order='lex' ) f = 3 *x^2 *(x+y) g = 9 *x*(y^2 - x^2 ) f.gcd(g) PR = PolynomialRing(GF(2 ),'x' ) R.<x> = GF(2 ^2049 ) pc = R.fetch_int(xx) xx = R(PR(pc)).integer_representation() PR = PolynomialRing(Zmod(p), 'x' ) f = PR.lagrange_polynomial(points)
矩阵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A = matrix(ZZ, [[1 ,1 ],[0 ,4 ]]) A.nrows() A.ncols() A.transpose() A.inverse() 或 A^(-1 ) A.rank() A.det() A.stack(vector([1 ,2 ])) A.augment(vector([1 ,2 ])) A.insert_row(1 , vector([1 ,2 ])) A.change_ring(QQ) A.solve_left(B) 或 A/B A.solve_right(B) 或 A\B A.left_kernel() A.right_kernel() A.LLL() A.multiplicative_order() matrix.zero(2 ,3 ) / zero_matrix(2 ,3 ) matrix.identity(2 ) / identity_matrix(2 ) block_matrix(QQ,[[A,zero_matrix(n,1 )],[matrix(b),matrix([1e-16 ])]])
解方程
$\begin{cases} x+y=10 \\ xy=21 \end{cases} $
1 2 var('x y' ) solve([x+y==10 ,x*y==21 ],[x,y])
解线性方程组
$AX=B$
1 2 3 4 5 6 A = Matrix([[1 ,2 ,3 ],[3 ,2 ,1 ],[1 ,1 ,1 ]]) Y = vector([0 ,-4 ,-1 ]) X = A.solve_right(Y) A \ Y
求逆元
$ed=1\pmod {\varphi(n)}$
扩展欧几里得算法
1 2 d,u,v=xgcd(20 ,30 ) print ("d:{0} u:{1} v:{2}" .format (d,u,v))
CRT(中国剩余定理)
$\begin{cases} x\equiv2\pmod3 \\ x\equiv3\pmod5 \\ x\equiv2\pmod7 \end{cases} $
1 2 3 4 5 6 7 8 9 def chinese_remainder (modulus, remainders ): Sum = 0 prod = reduce(lambda a, b: a*b, modulus) for m_i, r_i in zip (modulus, remainders): p = prod // m_i Sum += r_i * (inverse_mod(p,m_i)*p) return Sum % prod chinese_remainder([3 ,5 ,7 ],[2 ,3 ,2 ])
离散对数
$a^x \equiv b \pmod {n}$
1 2 3 4 5 6 7 8 9 10 11 x = discrete_log(mod(b,n),mod(a,n)) R = Integers(99 ) a = R(4 ) b = a^9 b.log(a) x = int (pari(f"znlog({int (b)} ,Mod({int (a)} ,{int (n)} ))" )) x = gp.znlog(b, gp.Mod(a, n))
欧拉函数
$\varphi(x)=x\prod\limits_{i=1}^n(1-\frac{1}{p_i})$
整数域椭圆曲线
$y^2=x^3+a_4x+a_6$
输出所有整数点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 F = GF(7 ) print (F.order())E = EllipticCurve(F,[0 ,0 ,0 ,2 ,3 ]) G = E.gens()[0 ] q = E.order() allPoints = E.points() P = E(2 ,1 ) P.xy() Q = k*P Q.division_points(k)
曲线
1 2 3 4 5 6 7 8 9 10 11 12 13 x, y = ZZ['x, y' ].gens() eq = x ^ 3 + y ^ 3 + 1 - d * x * y Curve(eq).genus() R.<xx,yy,zz> = Zmod(p)[] cubic = xx^3 + yy^3 + zz^3 - d * xx * yy * zz EC = EllipticCurve_from_cubic(cubic, morphism=False ) mf = EllipticCurve_from_cubic(cubic, morphism=True ) P = PP = mf(P)
解模方程
$ax^2+bx+c \equiv d \pmod p$
1 2 3 4 P.<x> = PolynomialRing(Zmod(p)) f = a * x^2 + b * x + c - d x = f.monic().roots() print (x)
解方程组
$\begin{cases} N=pq \\ \varphi = (p-1)(q-1) \end{cases} $
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 P.<p, q> = PolynomialRing(ZZ) def solve (f1, f2 ): g = f1.resultant(f2, q) roots = g.univariate_polynomial().roots() if len (roots) == 0 : return False p_ = abs (roots[0 ][0 ]) q_ = abs (roots[1 ][0 ]) return (min (p_, q_), max (p_, q_)) N = phi = f1 = (N + 1 ) - phi - p - q f2 = N - p*q p, q = solve(f1, f2) (p, q)
参考:
https://jayxv.github.io/2020/05/20/sage%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/
结式
1 2 3 4 5 6 7 8 9 10 11 12 13 from sage.matrix.matrix2 import Matrixdef resultant (f1, f2, var ): return Matrix.determinant(f1.sylvester_matrix(f2, var)) n = P.<k,t2,t3,d> = PolynomialRing(Integers(n)) f1 = s1*k - h - r*d f2 = s2*(k+t2) - h - r*d f3 = s3*(k+t3) - h - r*d h1 = resultant(f1, f2, d) h2 = resultant(f1, f3, d) g1 = resultant(h1, h2, k) roots = g1.univariate_polynomial().roots()