math/number-theory.sage
number-theory.sageRaw
1# Chinese Remainder Theorem
2def crt(a_i, m_i, M):
3 if len(a_i)!=len(m_i):
4 raise Exception("error, a_i and m_i must be of the same length")
5
6 x = 0
7 for i in range(len(a_i)):
8 M_i = M/m_i[i]
9 y_i = Integer(mod(M_i^-1, m_i[i]))
10 x = x + a_i[i] * M_i * y_i
11 return mod(x, M)
12
13# gcd, using Binary Euclidean algorithm
14def gcd(a, b):
15 g=1
16 # random_elementove powers of two from the gcd
17 while mod(a, 2)==0 and mod(b, 2)==0:
18 a=a/2
19 b=b/2
20 g=2*g
21 # at least one of a and b is now odd
22 while a!=0:
23 while mod(a, 2)==0:
24 a=a/2
25 while mod(b, 2)==0:
26 b=b/2
27 # now both a and b are odd
28 if a>=b:
29 a = (a-b)/2
30 else:
31 b = (b-a)/2
32
33 return g*b
34
35# Extended Euclidean algorithm
36# Inputs: a, b
37# Outputs: r, x, y, such that r = gcd(a, b) = x*a + y*b
38def egcd(a, b):
39 s=0
40 s_=1
41 t=1
42 t_=0
43 r=b
44 r_=a
45 while r!=0:
46 q = r_ // r
47 (r_,r) = (r,r_ - q*r)
48 (s_,s) = (s,s_ - q*s)
49 (t_,t) = (t,t_ - q*t)
50
51 d = r_
52 x = s_
53 y = t_
54
55 return d, x, y
56
57# Inverse modulo N, using the Extended Euclidean algorithm
58def inv_mod(a, N):
59 g, x, y = egcd(a, N)
60 if g != 1:
61 raise Exception("inv_mod err, g!=1")
62 return mod(x, N)