c = 2023280206852799756188533543726445899210461674882103741449846207085209158128274530066961712554168490693338804965645257201915901430270289914927031884869765066207700835767543832965446328994297771171239554854439801951855734405930228978819264617926307331498279823792404896708489491845814993901912406921233209174052585982422702902921150509799525025006961668679058706680338445147732742087594370544143929344692878849762859325278353499113047627166145064375388330723568647380571912097704007649949039872655521965438358883046062395057460962164069910080794938688401346483471199715397419486956888803799635787660289917216321436075
d = 5325557477974651131933634251521791991925782269036709550928544143247135213750451805876289560548176503358408907072006083232605644148148348426759760165848721826856045819883560475601424759644170039021289236399016340754732526066778542800516887549418899285710399950124543460448926261999153088331976259647327700619342183115011084680629309966651674276478502656272680143227400879298842573111724783827297704483713490258469730037991356794901334012297158591206594636469676973210545148034611453362521846968132369356368152162040634155912080095620977164991291750678677808423018575966921693161165571968455135962605729487885568490033
c = 2023280206852799756188533543726445899210461674882103741449846207085209158128274530066961712554168490693338804965645257201915901430270289914927031884869765066207700835767543832965446328994297771171239554854439801951855734405930228978819264617926307331498279823792404896708489491845814993901912406921233209174052585982422702902921150509799525025006961668679058706680338445147732742087594370544143929344692878849762859325278353499113047627166145064375388330723568647380571912097704007649949039872655521965438358883046062395057460962164069910080794938688401346483471199715397419486956888803799635787660289917216321436075
d = 5325557477974651131933634251521791991925782269036709550928544143247135213750451805876289560548176503358408907072006083232605644148148348426759760165848721826856045819883560475601424759644170039021289236399016340754732526066778542800516887549418899285710399950124543460448926261999153088331976259647327700619342183115011084680629309966651674276478502656272680143227400879298842573111724783827297704483713490258469730037991356794901334012297158591206594636469676973210545148034611453362521846968132369356368152162040634155912080095620977164991291750678677808423018575966921693161165571968455135962605729487885568490033
e = 65537
kphi = e*d - 1
for k in trange(2**13,2**17):
if kphi % k == 0:
phi = kphi // k
p = next_prime(iroot(phi,2)[0])
q = prevprime(iroot(phi,2)[0])
if d == inverse(e,(p-1)*(q-1)):
m = pow(c,d,p*q)
print(long_to_bytes(m))
# SHCTF{53398660-8e40-460d-9f28-2b25b687fbe9}
复制代码
baby_mod
task:
from Crypto.Util.number import *
from enc import flag
m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
r = getPrime(777)
t = getPrime(777)
tmp = getPrime(15)
e = 65537
n = p*q
print(f"c = {pow(m,e,n)}")
print(f"leak = {p*r-q*t-tmp}")
print(f"r = {r}")
print(f"t = {t}")
'''
c = 17937472553998606504669747140789726307439582196963451030969242254157949062129324494114590658920012871180079814675678946453897865233224992985089451278231663618857965418389487647355253063941790618808955858162224234190981820557457655720791346278352310012094147015720264246236621546172323951815149898363856098823
r = 466415729162296733529092458774194130369566652709805609481844599849536821250812719015532685709318199315612306114406654748660375049578603355246845205423401652241172615507957208288364106021726317326899229799053280291178121413651628535023
t = 635316670184189895492730019113841833333699743242997516619486647136468690062607793643684031305893867906907074562340028701514502349937069085426784869269608878466785830130266100418807129895963018317044053909910919832387196116916663544813
c = 17937472553998606504669747140789726307439582196963451030969242254157949062129324494114590658920012871180079814675678946453897865233224992985089451278231663618857965418389487647355253063941790618808955858162224234190981820557457655720791346278352310012094147015720264246236621546172323951815149898363856098823
r = 466415729162296733529092458774194130369566652709805609481844599849536821250812719015532685709318199315612306114406654748660375049578603355246845205423401652241172615507957208288364106021726317326899229799053280291178121413651628535023
t = 635316670184189895492730019113841833333699743242997516619486647136468690062607793643684031305893867906907074562340028701514502349937069085426784869269608878466785830130266100418807129895963018317044053909910919832387196116916663544813
for temp in range(2**14,2**15):
if isPrime(temp):
p = (leak + temp) * inverse(r, t) % t
if isPrime(p):
q = (p * r - leak - temp) // t
if isPrime(q):
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, p * q)
flag = long_to_bytes(m)
print(flag)
break
# SHCTF{0055b9ad-d96a-4d43-a9a9-28ecb08d557e}
复制代码
Week2
worde很大
task:
import gmpy2
from Crypto.Util.number import *
from enc import flag
m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
n = p*q
e = getPrime(200)
d = gmpy2.invert(e,(p-1)*(q-1))
dp = d % (p-1)
c = pow(m,e,n)
print(f"n = {n}")
print(f"c = {c}")
print(f"e = {e}")
print(f"dp = {dp}")
'''
n = 107032957087630288996268413289950221007178661091952415803799204807322719946773789072727097283876411371451855146945178785099365053975022744275499071412639566826876925607457076160736517239727314406122177641305989161650710675377046111659861132320470194374212535258339049977749925125713806268856103059658246838823
c = 13426059268971299890058502967962382039319233826881681062400371816555313938352978412770129453032021159626652883952418968332266876616888219630681123569091893928354304104629165208088101777538952907693381585125393549212184411084081938892612243511190758716729464349148805390375073663394447190303250531328411306179
e = 940179304603814149880259136688231799983345424885109815443153
n = 107032957087630288996268413289950221007178661091952415803799204807322719946773789072727097283876411371451855146945178785099365053975022744275499071412639566826876925607457076160736517239727314406122177641305989161650710675377046111659861132320470194374212535258339049977749925125713806268856103059658246838823
c = 13426059268971299890058502967962382039319233826881681062400371816555313938352978412770129453032021159626652883952418968332266876616888219630681123569091893928354304104629165208088101777538952907693381585125393549212184411084081938892612243511190758716729464349148805390375073663394447190303250531328411306179
e = 940179304603814149880259136688231799983345424885109815443153
n = 75098630616111482769180659620329958045667354926061075208260621193990567410087157843957397740063249813712091785246064471170031967563730722416238514564741845799209165882736179507743810974327683565208643579519017836211681069084365442156637269419638211790587926949896791807497864162801395061736248644788921667789
c = 3638646373008661843144668651345881752890064263891078270562520797735374345440840522319031089914051142881157757879267055752918804376422359639737717683576378097238618841707519724197204326012840131370755503486240820145945437287578597232976614322766435861623599998349726858207129492804638826767780589762299083258
n = 75098630616111482769180659620329958045667354926061075208260621193990567410087157843957397740063249813712091785246064471170031967563730722416238514564741845799209165882736179507743810974327683565208643579519017836211681069084365442156637269419638211790587926949896791807497864162801395061736248644788921667789
c = 3638646373008661843144668651345881752890064263891078270562520797735374345440840522319031089914051142881157757879267055752918804376422359639737717683576378097238618841707519724197204326012840131370755503486240820145945437287578597232976614322766435861623599998349726858207129492804638826767780589762299083258
p = 9799485259524549113003780400336995829253375211044694607315372450399356814285244762186468904824132005209991983177601498069896166228214442123763065076327679
k = 73771953838487511457389800773038323262861649769228176071578897500004883270121
p = 9799485259524549113003780400336995829253375211044694607315372450399356814285244762186468904824132005209991983177601498069896166228214442123763065076327679
k = 73771953838487511457389800773038323262861649769228176071578897500004883270121
C = (2336301464307188733995312208152021176388718095735565422234047912672553316288080052957448196669174030921526180747767251838308335308474037066343018337141276 , 6868888273736103386336636953449998615833854869329393895956720058438723636197866928342387693671211918574357564701700555086194574821628053750572619551290025 )
a = inverse(A1[0]-C[0],p)*((A1[1]**2-A1[0]**3)-(C[1]**2-C[0]**3))% p
b = (C[1]**2-C[0]**3-a*C[0])%p
E = EllipticCurve(Zmod(p),[a,b])
A1 = E(A1)
C = E(C)
M = C-k*A1
mm = (M.xy())[0]
for i in range(292):
m = long_to_bytes(int(mm-i))
if m.endswith(b'}'):
print(m)
复制代码
魔鬼的步伐
task:
from Crypto.Util.number import *
from random import choice
from enc import flag
m = bytes_to_long(flag)
def get_primes(limit):
primes = []
is_prime = [True] * (limit + 1)
for num in range(2, limit + 1):
if is_prime[num]:
primes.append(num)
for multiple in range(num * num, limit + 1, num):
is_prime[multiple] = False
return primes
def get_Prime(bits):
while True:
n = 2
while n.bit_length() < bits:
n *= choice(primes)
if isPrime(n + 1):
return n + 1
e = 65537
primes = get_primes(e)
p = get_Prime(512)
q = get_Prime(512)
n = p*q
c = pow(m,e,n)
print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")
'''
n = 779579301738188606639541475585479048662338414978423162511086618350581959037809676355175033940672838358216296034989613684765924879020007985463372880378958453235938149726732804842653385407460552866449233717559756619739481517089434393605029261842182116054349584175198599481092380973944251651872382058614325364639417
e = 65537
c = 547032040563518540116157223879027303340872416038133089003193905244978422560735616179910978730578423924420033057963791332760379132346877909806353927165538096867865399527460216074519919572776729647581400118345644864260152466704275743378828075020134070702051989890847762735538767329450466068109132805742740564390842
n = 779579301738188606639541475585479048662338414978423162511086618350581959037809676355175033940672838358216296034989613684765924879020007985463372880378958453235938149726732804842653385407460552866449233717559756619739481517089434393605029261842182116054349584175198599481092380973944251651872382058614325364639417
e = 65537
c = 547032040563518540116157223879027303340872416038133089003193905244978422560735616179910978730578423924420033057963791332760379132346877909806353927165538096867865399527460216074519919572776729647581400118345644864260152466704275743378828075020134070702051989890847762735538767329450466068109132805742740564390842
# 初始化生成光滑数的列表get_primes(e)
def get_primes(limit):
primes = []
is_prime = [True] * (limit + 1)
for num in range(2, limit + 1):
if is_prime[num]:
primes.append(num)
for multiple in range(num * num, limit + 1, num):
is_prime[multiple] = False
return primes
# 由于n = p * q ,而p,q分别由一个get_primes生成,所以最终n的列表应该是2*get_primes(e)
primes_value = get_primes(e) + get_primes(e)
# 求解φ(n)
def Solve(n):
counter = 0
for p in primes_value:
if n % p == 0:
counter += 1
return n - counter - 2 # 减去1和n的两种情况
# 取素数2当作最初的a,在φ(n)的范围内不断增大指数寻找GCD(a^{k*φ(n)}-1,n) != 0和 != n
# n = 7120275986401660066259983193598830554385933355254283093021239164350142898387660104515624591378875067038235085428170557400012848874756868985306042421950909
# c = 6803450117490196163076010186755045681029929816618361161925865477601994608941714788803007124967390157378525581080320415602012078322064392991884070073083436
# P = (4143131125485719352848137000299706175276016714942734255688381872061184989156686585992844083387698688432978380177564346382756951426943827434190895490233627 : 3879946878859691332371384275396678851932267609535096278038417524609690721322205780110680003522999409696718745532857001461869452116434787256032366267905519 : 1)
复制代码
analysis: Crypto趣题-剪枝
剪枝: 剪枝是对于树算法类的标题而言的,通过减去已经计算后的树的枝点来缩短算法的时间复杂度。而在这里则是同时找到p和q高位或低位,要是只找p高位和q低位,爆破条件无法判断,这就是为什么这题需要同时用到pxorq的两端.
剪枝已知条件: p 与 q 的反方向二进制的异或值,共256bit,记为p_xor_q
剪枝搜索方式: 1.从两端向中心搜索 2. 每一次搜索,需使用当前 pxorq 两端的bit位。这是因为,pxorq 的当前最高位对应p的最高位及q的最低位,pxorq 的当前最低位对应p的最低位及q的最高位 (其中最高、最低均是对于当前搜索而言) 3.如果当前需搜索的最高位为”1”,则对应两种大概:p该位为1,q对应低位为0;p该位为0,q对应低位为1。剩下依此类推
剪枝条件: 将p、q未搜索到的位全填0,乘积应小于n 将p、q未搜索到的位全填1,乘积应大于n p、q 低 k 位乘积再取低 k 位,应与 n 的低 k 位类似 exp:
第一部门参考鸡块大神的文章。
n = 7120275986401660066259983193598830554385933355254283093021239164350142898387660104515624591378875067038235085428170557400012848874756868985306042421950909
c = 6803450117490196163076010186755045681029929816618361161925865477601994608941714788803007124967390157378525581080320415602012078322064392991884070073083436
P = (4143131125485719352848137000299706175276016714942734255688381872061184989156686585992844083387698688432978380177564346382756951426943827434190895490233627 , 3879946878859691332371384275396678851932267609535096278038417524609690721322205780110680003522999409696718745532857001461869452116434787256032366267905519)
p_xor_q = str(bin(leak)[2:]).zfill(256)
def find(ph, qh, pl, ql):
l = len(ph)
tmp0 = ph + (256 - 2 * l) * "0" + pl
tmp1 = ph + (256 - 2 * l) * "1" + pl
tmq0 = qh + (256 - 2 * l) * "0" + ql
tmq1 = qh + (256 - 2 * l) * "1" + ql
if (int(tmp0, 2) * int(tmq0, 2) > n):
return
if (int(tmp1, 2) * int(tmq1, 2) < n):
return
if (int(pl, 2) * int(ql, 2) % (2 ** (l - 1)) != n % (2 ** (l - 1))):
return
if (l == 128):
pp0 = int(tmp0, 2)
if (n % pp0 == 0):
pf = pp0
qf = n // pp0
print(pf)
print(qf)
phi = (pf - 1) * (qf - 1)
d = inverse(e, phi)
m1 = pow(c, d, n)
print(long_to_bytes(m1))
exit()
else:
if (p_xor_q[l] == "1" and p_xor_q[255 - l] == "1"):
find(ph + "1", qh + "0", "1" + pl, "0" + ql)
find(ph + "0", qh + "0", "1" + pl, "1" + ql)
find(ph + "1", qh + "1", "0" + pl, "0" + ql)
find(ph + "0", qh + "1", "0" + pl, "1" + ql)
elif (p_xor_q[l] == "1" and p_xor_q[255 - l] == "0"):
find(ph + "1", qh + "0", "0" + pl, "0" + ql)
find(ph + "0", qh + "0", "0" + pl, "1" + ql)
find(ph + "1", qh + "1", "1" + pl, "0" + ql)
find(ph + "0", qh + "1", "1" + pl, "1" + ql)
elif (p_xor_q[l] == "0" and p_xor_q[255 - l] == "1"):
find(ph + "0", qh + "0", "1" + pl, "0" + ql)
find(ph + "0", qh + "1", "0" + pl, "0" + ql)
find(ph + "1", qh + "0", "1" + pl, "1" + ql)
find(ph + "1", qh + "1", "0" + pl, "1" + ql)
elif (p_xor_q[l] == "0" and p_xor_q[255 - l] == "0"):
find(ph + "0", qh + "0", "0" + pl, "0" + ql)
find(ph + "1", qh + "0", "0" + pl, "1" + ql)
find(ph + "0", qh + "1", "1" + pl, "0" + ql)
find(ph + "1", qh + "1", "1" + pl, "1" + ql)
find("1", "1", "1", "1")
# p = 64760524083545528318139240449356269097871629401328435356643510319660757701117
n = 7120275986401660066259983193598830554385933355254283093021239164350142898387660104515624591378875067038235085428170557400012848874756868985306042421950909
P = E(4143131125485719352848137000299706175276016714942734255688381872061184989156686585992844083387698688432978380177564346382756951426943827434190895490233627 , 3879946878859691332371384275396678851932267609535096278038417524609690721322205780110680003522999409696718745532857001461869452116434787256032366267905519)