DASCTF X 0psu3十一月挑战赛|越艰巨·越狂热
Crypto
GeneratePrime
原题:
from Crypto.Util.number import getPrime, isPrime, bytes_to_long
import os
def 0psu3_The_best(sz, d):
while True:
p = getPrime(sz)
pp = sum([p**i for i in range(d)])
if isPrime(pp):
return p, pp
p, q = 0psu3_The_best(512, 5)
r = getPrime(512 * 5)
n = p * q * r
e = 65537
flag=open("flag.txt", "rb").read().strip()
flag1=flag+os.urandom(128)
m=bytes_to_long(flag1)
c = pow(m, e, n)
print(f"{n = }")
print(f"{e = }")
print(f"{c = }")
#n=...
#e=65537
#c=...
解题:
根据题目观察n的组成有p、q、r三个参数组成
其中p和q的生成之间掺杂关系
p = getPrime(512)
q = 1 + p + p 2 p^2 p2 + p 3 p^3 p3 + p 4 p^4 p4
r = getPrime(512 * 5)
n = p * q * r
对于q 属于分圆多项式 其次数k=5
脚本来源
所以使用下面exp进行求解:
from Crypto.Util.number import *
P.<x, y> = PolynomialRing(ZZ)
R.<z> = PolynomialRing(ZZ)
z = R.gens()[0]
def calculate_eta_all(eta, aa, bb, m, k):
eta_all = []
for i in range(k):
temp = eta**(aa**i)
add = temp
for _ in range((m-1)//k - 1):
add = add**bb
temp += add
eta_all.append(temp)
return eta_all
def calculate_irreducible_polynomial(eta_all, m):
h = 1
for i in range(k):
h *= (y - eta_all[i].lift())
d = sum([x**i for i in range(m)])
f_irreducible = h % d
return f_irreducible, d
def pad_polynomial_coefficients(f, m):
tmp = f.list()
while len(tmp) < m:
tmp.append(0)
return tmp
def Factoring_with_Cyclotomic_Polynomials(k, n):
if k == 1:
print('k = 1')
a = 2
while True:
print('a =', a)
p = gcd(int(pow(a, n, n)-1), n)
if p > 2**20 and n % p == 0:
return p
a += 1
Phi = cyclotomic_polynomial(k)
Psi = (z**k-1)//(cyclotomic_polynomial(k))
print('Cyclotomic_Polynomials Phi:', Phi)
print('Psi:', Psi)
m = 1
while True:
useful = False
while not useful:
m += k
if not isPrime(m):
continue
aa = primitive_root(m)
ff = x**m - 1
Q = P.quo(ff)
eta = Q.gens()[0]
for bb in range(2, m):
if (bb**((m-1)//k)-1)//(bb-1) % m:
continue
eta_all = calculate_eta_all(eta, aa, bb, m, k)
f_irreducible, d = calculate_irreducible_polynomial(eta_all, m)
if f_irreducible.subs(y=0) in ZZ:
useful = True
break
# print(aa, bb)
# print(m)
eta0 = eta_all[0]
eta0_pow = []
for i in range(2, k):
eta0_pow_i = (eta0**i).lift().subs(x=z)
constant_term = eta0_pow_i.list()[0]
if constant_term != 0:
dd = (d-1).subs(x=z)
eta0_pow_i = eta0_pow_i - constant_term - constant_term * dd
eta0_pow.append(eta0_pow_i)
coefficients = []
for i in range(k):
coefficients.append(pad_polynomial_coefficients(eta_all[i].lift().subs(x=z), m))
A = matrix(QQ, coefficients)
terget = [[-1]*k, [1] + [0]*(k-1)]
for i in range(k-2):
terget.append(A.solve_left(vector(pad_polynomial_coefficients(eta0_pow[i], m))))
B = matrix(QQ, terget)
U.<w> = PolynomialRing(QQ)
w = U.gens()[0]
eta1 = U(list((B**-1)[1]))
f = f_irreducible.subs(y=w)
V = U.quo(f)
eta1 = V(eta1)
C = matrix(QQ, k, k)
C[0, 0] = 1
for i in range(1, k):
tmp = eta1**i
C[i] = pad_polynomial_coefficients(tmp, k)
K.<s> = PolynomialRing(Zmod(n))
f_modulo = f_irreducible.subs(y=s)
K_quo = K.quo(f_modulo)
f_ZZ = f_irreducible.subs(y=z)
try:
sigma = matrix(Zmod(n), C)
except:
continue
while True:
g = R.random_element(k - 1)
try:
kk, _, h = xgcd(f_ZZ, g)
h = inverse_mod(int(kk), n) * h
break
except:
continue
g = g.subs(y=x)
g_Q = K_quo(g)
h_Q = K_quo(h)
assert g_Q * h_Q == 1
Psi_coefficients = Psi.coefficients()
Psi_monomials = Psi.monomials()[::-1]
if Psi_coefficients[0] < 0:
yy = h_Q**(-Psi_coefficients[0])
else:
yy = g_Q**(Psi_coefficients[0])
for i in range(1, len(Psi_monomials)):
if Psi_coefficients[i] < 0:
yy *= K_quo(list(vector(list(h_Q**(-Psi_coefficients[i]))) * Psi_monomials[i](sigma)))
else:
yy *= K_quo(list(vector(list(g_Q**(Psi_coefficients[i]))) * Psi_monomials[i](sigma)))
yy = yy**n
if gcd(yy[1], n) > 2**20:
return gcd(yy[1], n)
if __name__ == "__main__":
k = 5 # the k-th
n=43090231453250894711427929679917165532091051269639380881822679198388872373018031295429558758883298138388596507242928145888959963579111847255588834248367032580980272245414738073179172684104908272069503607376171584936239696444309039211273376010193165083254209608051430794825261116490356392215410064858020176711199543381037420111454942356936721487016187240237683725310306748046587503625096246489043270381153251813360521583717685413070481576320194446237522118380283335294528606720928637529817170809666802598938788405154468683850385277659812316577873886708164549255359514776884765904417881419804464020855420288884972204146588152412816874161445668955639456202226751519881834234916642218078966066353317917939418964763844067220460513388433020071277477619189495465483910271310025371745344364984826481983188861624474015117761898377237745775289039922285111681410319016537270412509750339539020876501534842403407208957382830000761065368861209033791387480377889838737241326116532852335478193204425626487166234964754732945953080086117315162916374952094149599597509405176646068341218684523765974759907645226607364627690026025662221036766148813918691578120023886400197652148214238256715089883892069133754778609710846757189987335827693169644541734443763194942694587436469448973201513131503797898892822373949177030567791519349220158287318717788746060997955057747930375117780320371517616412423571775682868481089431670802944047375824503353609019686495670630728618082254293585479431369645935654024149490741245953271830453426444847467908952699660750809490650479987
pp = Factoring_with_Cyclotomic_Polynomials(k, n)
assert not n % pp
print('factor is found:', pp)
result:
Cyclotomic_Polynomials Phi: x^4 + x^3 + x^2 + x + 1
Psi: z - 1
factor is found: 10223779127743141044678466706179985474302174854457220173103930539918363874691654813758957443858380768641291210108579322612403764648594843444482022290144989
分解成功根据pq的生成规则还原pq
p = 10223779127743141044678466706179985474302174854457220173103930539918363874691654813758957443858380768641291210108579322612403764648594843444482022290144989
pp = sum([p**i for i in range(5)])
print(pp)
n=43090231453250894711427929679917165532091051269639380881822679198388872373018031295429558758883298138388596507242928145888959963579111847255588834248367032580980272245414738073179172684104908272069503607376171584936239696444309039211273376010193165083254209608051430794825261116490356392215410064858020176711199543381037420111454942356936721487016187240237683725310306748046587503625096246489043270381153251813360521583717685413070481576320194446237522118380283335294528606720928637529817170809666802598938788405154468683850385277659812316577873886708164549255359514776884765904417881419804464020855420288884972204146588152412816874161445668955639456202226751519881834234916642218078966066353317917939418964763844067220460513388433020071277477619189495465483910271310025371745344364984826481983188861624474015117761898377237745775289039922285111681410319016537270412509750339539020876501534842403407208957382830000761065368861209033791387480377889838737241326116532852335478193204425626487166234964754732945953080086117315162916374952094149599597509405176646068341218684523765974759907645226607364627690026025662221036766148813918691578120023886400197652148214238256715089883892069133754778609710846757189987335827693169644541734443763194942694587436469448973201513131503797898892822373949177030567791519349220158287318717788746060997955057747930375117780320371517616412423571775682868481089431670802944047375824503353609019686495670630728618082254293585479431369645935654024149490741245953271830453426444847467908952699660750809490650479987
e=65537
c=30862228874892553476569860337345503267926249096036551213683005116620750680365154103242717714230966827288361499342464202425467642950081816675486231250411347472976482409360391136808439034217688010072648722396312121758844966972323513456884732046270240934002095706243044210312663525491282667971502534420245427643076262414036655243117610886157895994101178663474990136516153062956803591842233732498519246731337518545018734984319536536205092573418457928952414660837594265802406473201400259189950484841504227372735345451459452313825309333631615286962304963039625162366186574440146535361888708570569938418676320446653266676364765870547213167058713058609788316647593834008151805692510044158607162858906528913516242904419457446211348504248317409844426309455978985314882123424453618672960876022996245213882467954521212481418830104602302179759479012618982228223244131619557639469872139485197176384683400796204681045965981417650462297978265085323342772310690638049411549216990505001950512428646871875659468885490055363436412364532718888124906227240501145227269727887236864060558999336443165765870556727793253297515155026234234422303238380776900105115890363548589834345888430695886678231459920101695996112312269637459823479947618045447071359886515163416153117176539752947700226596291435270282598638974889205601333097978743387412651687356072223691445472690647184292120882095587563356691450107194982597794937293154289560470269606300576216128045797481404606810315677962659136641943747123985144899464108823536597185386155005111274476874957827391438859327653936
r = n // p // pp
phi = (p-1)*(pp-1)*(r-1)
import gmpy2
d = gmpy2.invert(e,phi)
from Crypto.Util.number import *
print(long_to_bytes(pow(c,d,n)))
result:
b'DASCTF{just_a_very_very_easy_task_with_your_talent_is_not}
我是哈皮,祝您每天嗨皮!我们下期再见~