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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
class FactorRes(object):
def __init__(self, r=None, c=None, u=None, a=None):
self.r = r
self.c = c
self.u = u
self.a = a
def xgcd(f, g, N):
toswap = False
if f.degree() < g.degree():
toswap = True
f, g = g, f
r_i = f
r_i_plus = g
r_i_plus_plus = f
s_i, s_i_plus = 1, 0
t_i, t_i_plus = 0, 1
while (True):
lc = r_i.lc().lift()
lc *= r_i_plus.lc().lift()
lc *= r_i_plus_plus.lc().lift()
divisor = gcd(lc, N)
if divisor > 1:
return divisor, None, None
q = r_i // r_i_plus
s_i_plus_plus = s_i - q * s_i_plus
t_i_plus_plus = t_i - q * t_i_plus
r_i_plus_plus = r_i - q * r_i_plus
if r_i_plus.degree() <= r_i_plus_plus.degree() or r_i_plus_plus.degree() == -1:
if toswap == True:
return r_i_plus, t_i_plus, s_i_plus
else:
return r_i_plus, s_i_plus, t_i_plus,
r_i, r_i_plus = r_i_plus, r_i_plus_plus
s_i, s_i_plus = s_i_plus, s_i_plus_plus
t_i, t_i_plus = t_i_plus, t_i_plus_plus
def Qinverse (Hx, a, N):
r,s,t = xgcd(a.lift(), Hx, N)
if (s,t) == (None, None):
res = r, 0
else:
rinv = r[0]^(-1)
res = 1, s * rinv
return res
def CMfactor(D, N):
Hx = hilbert_class_polynomial(-D)
res = FactorRes()
ZN = Integers(N)
R.<x> = PolynomialRing(ZN)
Hx = R(Hx)
Q.<j> = QuotientRing(R, R.ideal(Hx))
gcd, inverse = Qinverse(Hx, 1728 - j, N)
if gcd == 1:
a = Q(j * inverse)
return CMfactor_core(N, a, Q, ZN, Hx, res)
def CMfactor_core(N, a, Q, ZN, Hx, res):
for c in [1..10]:
E = EllipticCurve(Q, [0, 0, 0, 3 * a * c ^ 2, 2 * a * c ^ 3])
for u in [1..10]:
rand_elem = ZN.random_element()
res.rand_elem = int(rand_elem)
w = E.division_polynomial(N, Q(rand_elem), two_torsion_multiplicity=0)
poly_gcd = xgcd(w.lift(), Hx, N)[0]
r = gcd(ZZ(poly_gcd), N)
res.c = c
res.u = u
if r > 1 and r != N:
return r, N//r
def main():
sys.setrecursionlimit(50000)
#####################################INPUTS####################################
d = 427
n = ...
c = ...
e = 65537
#####################################INPUTS####################################
p, q = CMfactor(d, n)
phi = (p - 1) * (q - 1)
d = pow(e, -1, phi)
flag = int(pow(c, d, n))
print(flag.to_bytes((flag.bit_length() + 7) // 8, 'big').decode())
if __name__ == "__main__":
main()
|