2023 nkctf crypto wp
Crypto
baby_RSA
解题思路
dp的板子解P Q,然后推式子
解上面这个模多项式即可
exp:
n = 114101396033690088275999670914803472451228154227614098210572767821433470213124900655723605426526569384342101959232900145334500170690603208327913698128445002527020347955300595384752458477749198178791196660625870659540794807018881780680683388008090434114437818447523471527878292741702348454486217652394664664641
N = 1159977299277711167607914893426674454199208605107323826176606074354449015203832606569051328721360397610665453513201486235549374869954501563523028914285006850687275382822302821825953121223999268058107278346499657597050468069712686559045712946025472616754027552629008516489090871415609098178522863027127254404804829735621706042266140637592206366042515190385496909533329383212542170504864473944657824502882014292528444918055958758310544435120502872883857209880723535754528096143707324179005292445100655695427777453144657819474805882956064292780031599790769618615908501966912635232746588639924772530057835864082951499028
dP = 33967356791272818610254738927769774016289590226681637441101504040121743937150259930712897925893431093938385216227201268238374281750681609796883676743311872905933219290266120756315613501614208779063819499785817502677885240656957036398336462000771885589364702443157120609506628895933862241269347200444629283263
e=65537
P=0
e=65537
temp=dP*e
for i in range(1,e):
if(temp-1)%i==0:
x=(temp-1)//i+1
y=N%x
if y==0:
P=x
break
#print(P)
P=37269067352457630263351774206178494913957088859822110344334922741582406663357663275001777826744534556652993452577088773275825539553907027527722045884489297259984687894496505265384077983882580247333972954704644517469999916574893996324149548980338301147983367163067556434434982470623587914250041142380667816331
Q=N//P
#sage
Q,P=(31124398373258967647259273958463995255448332282733968391096762136494537693158180734634142626374694999391960402681114664140356232930100613919064790135723294710984789809295862966052914533841176463683069225072916170624016363164528353386087305805869313783193076760778433672011918504199905552973276891160558444988, 37269067352457630263351774206178494913957088859822110344334922741582406663357663275001777826744534556652993452577088773275825539553907027527722045884489297259984687894496505265384077983882580247333972954704644517469999916574893996324149548980338301147983367163067556434434982470623587914250041142380667816331)
n = 114101396033690088275999670914803472451228154227614098210572767821433470213124900655723605426526569384342101959232900145334500170690603208327913698128445002527020347955300595384752458477749198178791196660625870659540794807018881780680683388008090434114437818447523471527878292741702348454486217652394664664641
R.<m>=Zmod(n)[]
f=m**2-(P+Q)*m+P*Q
m=f.monic().small_roots()
m=152099310694956022622926857538598513541723670773227126074246760446874272165452073476477
print(long_to_bytes(m))
ez_polynomial
解题思路
多项式RSA的板子
exp:
p = 40031
P = PolynomialRing(Zmod(p), name = 'x')
x = P.gen()
n=24096*x^93 + 38785*x^92 + 17489*x^91 + 9067*x^90 + 1034*x^89 + 6534*x^88 + 35818*x^87 + 22046*x^86 + 12887*x^85 + 445*x^84 + 26322*x^83 + 37045*x^82 + 4486*x^81 + 3503*x^80 + 1184*x^79 + 38471*x^78 + 8012*x^77 + 36561*x^76 + 19429*x^75 + 35227*x^74 + 10813*x^73 + 26341*x^72 + 29474*x^71 + 2059*x^70 + 16068*x^69 + 31597*x^68 + 14685*x^67 + 9266*x^66 + 31019*x^65 + 6171*x^64 + 385*x^63 + 28986*x^62 + 9912*x^61 + 10632*x^60 + 33741*x^59 + 12634*x^58 + 21179*x^57 + 35548*x^56 + 17894*x^55 + 7152*x^54 + 9440*x^53 + 4004*x^52 + 2600*x^51 + 12281*x^50 + 22*x^49 + 17314*x^48 + 32694*x^47 + 7693*x^46 + 6567*x^45 + 19897*x^44 + 27329*x^43 + 8799*x^42 + 36348*x^41 + 33963*x^40 + 23730*x^39 + 27685*x^38 + 29037*x^37 + 14622*x^36 + 29608*x^35 + 39588*x^34 + 23294*x^33 + 757*x^32 + 20140*x^31 + 19511*x^30 + 1469*x^29 + 3898*x^28 + 6630*x^27 + 19610*x^26 + 11631*x^25 + 7188*x^24 + 11683*x^23 + 35611*x^22 + 37286*x^21 + 32139*x^20 + 20296*x^19 + 36426*x^18 + 25340*x^17 + 36204*x^16 + 37787*x^15 + 31256*x^14 + 505*x^13 + 27508*x^12 + 20885*x^11 + 32037*x^10 + 31236*x^9 + 7929*x^8 + 27195*x^7 + 28980*x^6 + 11863*x^5 + 16025*x^4 + 16389*x^3 + 570*x^2 + 36547*x + 10451
c=3552*x^92 + 6082*x^91 + 25295*x^90 + 35988*x^89 + 26052*x^88 + 16987*x^87 + 12854*x^86 + 25117*x^85 + 25800*x^84 + 30297*x^83 + 5589*x^82 + 23233*x^81 + 14449*x^80 + 4712*x^79 + 35719*x^78 + 1696*x^77 + 35653*x^76 + 13995*x^75 + 13715*x^74 + 4578*x^73 + 37366*x^72 + 25260*x^71 + 28865*x^70 + 36120*x^69 + 7047*x^68 + 10497*x^67 + 19160*x^66 + 17939*x^65 + 14850*x^64 + 6705*x^63 + 17805*x^62 + 30083*x^61 + 2400*x^60 + 10685*x^59 + 15272*x^58 + 2225*x^57 + 13194*x^56 + 14251*x^55 + 31016*x^54 + 10189*x^53 + 35040*x^52 + 7042*x^51 + 29206*x^50 + 39363*x^49 + 32608*x^48 + 38614*x^47 + 5528*x^46 + 20119*x^45 + 13439*x^44 + 25468*x^43 + 30056*x^42 + 19720*x^41 + 21808*x^40 + 3712*x^39 + 25243*x^38 + 10606*x^37 + 16247*x^36 + 36106*x^35 + 17287*x^34 + 36276*x^33 + 1407*x^32 + 28839*x^31 + 8459*x^30 + 38863*x^29 + 435*x^28 + 913*x^27 + 36619*x^26 + 15572*x^25 + 9363*x^24 + 36837*x^23 + 17925*x^22 + 38567*x^21 + 38709*x^20 + 13582*x^19 + 35038*x^18 + 31121*x^17 + 8933*x^16 + 1666*x^15 + 21940*x^14 + 25585*x^13 + 840*x^12 + 21938*x^11 + 20143*x^10 + 28507*x^9 + 5947*x^8 + 20289*x^7 + 32196*x^6 + 924*x^5 + 370*x^4 + 14849*x^3 + 10780*x^2 + 14035*x + 15327
e=65537
q1, q2 = n.factor()
q1, q2 = q1[0], q2[0]
phi = (p**q1.degree() - 1) * (p**q2.degree() - 1)
assert gcd(e, phi) == 1
d = inverse_mod(e, phi)
m = pow(c,d,n)
flag = bytes(m.coefficients())
print("Flag: ", flag.decode())
#NKCTF{We_HaV3_n0th1ng_But_dr3amS}
ezrsa
解题思路
m1 根据这个板子打https://github.com/jvdsn/crypto-attacks/blob/master/attacks/factorization/known_phi.py
m2 同babyrsa
from math import gcd
from math import isqrt
from random import randrange
def factorize(N, phi):
"""
Recovers the prime factors from a modulus if Euler's totient is known.
This method only works for a modulus consisting of 2 primes!
:param N: the modulus
:param phi: Euler's totient, the order of the multiplicative group modulo N
:return: a tuple containing the prime factors, or None if the factors were not found
"""
s = N + 1 - phi
d = s ** 2 - 4 * N
p = int(s - isqrt(d)) // 2
q = int(s + isqrt(d)) // 2
return p, q
def factorize_multi_prime(N, phi):
"""
Recovers the prime factors from a modulus if Euler's totient is known.
This method works for a modulus consisting of any number of primes, but is considerably be slower than factorize.
More information: Hinek M. J., Low M. K., Teske E., "On Some Attacks on Multi-prime RSA" (Section 3)
:param N: the modulus
:param phi: Euler's totient, the order of the multiplicative group modulo N
:return: a tuple containing the prime factors
"""
prime_factors = set()
factors = [N]
while len(factors) > 0:
# Element to factorize.
N = factors[0]
w = randrange(2, N - 1)
i = 1
while phi % (2 ** i) == 0:
sqrt_1 = pow(w, phi // (2 ** i), N)
if sqrt_1 > 1 and sqrt_1 != N - 1:
# We can remove the element to factorize now, because we have a factorization.
factors = factors[1:]
p = gcd(N, sqrt_1 + 1)
q = N // p
if isPrime(p):
prime_factors.add(p)
elif p > 1:
factors.append(p)
if isPrime(q):
prime_factors.add(q)
elif q > 1:
factors.append(q)
# Continue in the outer loop
break
i += 1
return tuple(prime_factors)
n = 8836130216343708623415307573630337110573363595188748983290313549413242332143945452914800845282478216810685733227137911630239808895196748125078747600505626165666334675100147790578546682128517668100858766784733351894480181877144793496927464058323582165412552970999921215333509253052644024478417393146000490808639363681195799826541558906527985336104761974023394438549055804234997654701266967731137282297623426318212701157416397999108259257077847307874122736921265599854976855949680133804464839768470200425669609996841568545945133611190979810786943246285103031363790663362165522662820344917056587244701635831061853354597
phi = 8836130216343708623415307573630337110573363595188748983290313549413242332143945452914800845282478216810685733227137911630239808895196748125078747600505622503351461565956106005118029537938273153581675065762015952483687057805462728186901563990429998916382820576211887477098611684072561849314986341226981300596338314989867731725668312057134075244816223120038573374383949718714549930261073576391501671722900294331289082826058292599838631513746370889828026039555245672195833927609280773258978856664434349221972568651378808050580665443131001632395175205804045958846124475183825589672204752895252723130454951830966138888560
c1 = 78327207863361017953496121356221173288422862370301396867341957979087627011991738176024643637029313969241151622985226595093079857523487726626882109114134910056673489916408854152274726721451884257677533593174371742411008169082367666168983943358876017521749198218529804830864940274185360506199116451280975188409
e=65537
prime_list=sorted(factorize_multi_prime(n,phi))
p,q,r,t=prime_list[0],prime_list[3],prime_list[1],prime_list[2]
d=gmpy2.invert(e,(p-1)*(q-1))
m1=pow(c1,d,p*q)
#print(m1.bit_length())
#215
#print(long_to_bytes(m1))
#b'NKCTF{it_i5_e45y_th4t_Kn0wn'
N = 157202814866563156513184271957553223260772141845129283711146204376449001653397810781717934720804041916333174673656579086498762693983380365527400604554663873045166444369504886603233275868192688995284322277504050322927511160583280269073338415758019142878016084536129741435221345599028001581385308324407324725353
c2 = 63355788175487221030596314921407476078592001060627033831694843409637965350474955727383434406640075122932939559532216639739294413008164038257338675094324172634789610307227365830016457714456293397466445820352804725466971828172010276387616894829328491068298742711984800900411277550023220538443014162710037992032
c3 = 9266334096866207047544089419994475379619964393206968260875878305040712629590906330073542575719856965053269812924808810766674072615270535207284077081944428011398767330973702305174973148018082513467080087706443512285098600431136743009829009567065760786940706627087366702015319792328141978938111501345426931078
R.<m>=Zmod(N)[]
f=m^2-(c2+c3)*m+c2*c3
m2=f.small_roots(X=2^4312beta=0.4,epsilon=0.01)
m2=4134704395865052635910135198384991632904826868184178486449854532897025132606910716694129086727413635889097150181468673789907726717
print(long_to_bytes(m2))
#b'_phi_4nd_N_dec0mp0ses_N_w1th_th3_s4m3_c0mm0n_n_but_pq}'
ezmath
解题思路
寻找具有相同底数,且结果为平方关系的数据,推式子:
多打几组数据,求公约数
exp:
n = 369520637995317866367336688225182965061898803879373674073832046072914710171302486913303917853881549637806426191970292829598855375370563396182543413674021955181862907847280705741114636854238746612618069619482248639049407507041667720977392421249242597197448360531895206645794505182208390084734779667749657408715621
c = 324131338592233305486487416176106472248153652884280898177125443926549710357763331715045582842045967830200123100144721322509500306940560917086108978796500145618443920020112366546853892387011738997522207752873944151628204886591075864677988865335625452099668804529484866900390927644093597772065285222172136374562043
e=65537
e1=[
170559914324671769117535654836487226009685359320636182075960576764702323732727088502920021993271666209903403463612731506055433486417625242935904916789051793747298593847158174830184596554822038310041512771676833824200302666130102306284852931958549925702330464987955245647072909056824574486147965487598401928881026,
163378867981477210016607618217525067516899896304907822758749135410592905658324027908854458465871295591148114728316034699358213461728042658497873130073105697195541220650688132150216266657024774867846925219967805863946774978900772828496605795631400777090954141000078238226487076065753781167791598816872139973922682,
21606807968454766520529084107175158062623274703294799705984925156349373997035743632649715867216648159433730630939058861636582120303338699113498645592338621228070481894445156769437351313971471061779425442129487317917630554305634797690296919992201174927956121524640438775183413288101169580705360562693274958339416
]
e2=[
156359509651684605051402965560382969488421316701585527115005130492947292379802933549188085059602557600903593831240316597311439285149968787780538126741092612405335349622445040578126369183536683733294143156965518222696624206221060030916594302284630706642066420353822195108928341123726471513256217857861184609387726,
141997416965295486849546892322458652502850390670128808480582247784728456230996812361056958004801816363393016360646922983916999235770803618904474553309200419301820603229504955218189709387942156848904968053547462302189568831762401075340100029630332409419313772378068180267756675141584884876543484516408660699471038,
43213615936909533041058168214350316125246549406589599411969850312698747994071487265299431734433296318867461261878117723273164240606677398226997291184677242456140963788890313538874702627942942123558850884258974635835261108611269595380593839984402349855912243049280877550366826576202339161410721125386549916678832
]
temp=[]
for i in range(3):
temp.append(2*e1[i]-e2[i])
phi=GCD(temp[0],temp[1])
phi=GCD(phi,temp[2])
d=gmpy2.invert(e,phi)
m=pow(c,d,n)
print(long_to_bytes(m))
#b'NKCTF{d15cr373_L0g_15_R3DuC710n_f0R_f4C70r1nG}'
eZ_Bl⊕ck
解题思路
Feistal的板子
exp:
from Crypto.Util.number import *
from Crypto.Util.strxor import strxor as xor
r = b"t\xf7\xaa\xac\x9d\x88\xa4\x8b\x1f+pA\x84\xacHg'\x07{\xcc\x06\xc4i\xdd)\xda\xc9\xad\xa9\xe8\x1fi"
rxorkey = b"'{<z}\x91\xda\xc5\xd5S\x8b\xfa\x9f~]J\x0f\xf4\x9a\x1e\xe0\xef\x129N\xe7a\x928+\xe0\xee"
mxorkey = b'8\x1f"\x83B4\x86)\xce\xebq3\x06\xa0w\x16U\x04M/w\xa1\x8f;)M\xdd~\x11:\xe3\xb3'
a = r[:16]
b = r[16:]
key1 = xor(rxorkey[:16], b)
key2 = xor(rxorkey[16:], xor(a, b))
m2 = xor(key1, mxorkey[:16])
m1xorm2 = xor(key2, mxorkey[16:])
m1 = xor(m2, m1xorm2)
m = m1 + m2
print(m)
fake_MT
解题思路
常见的MT19937板子
指路亲学长的blog:浅析MT19937伪随机数生成算法-安全客 - 安全资讯平台 (anquanke.com)
from pwn import *
from randcrack import RandCrack
from random import Random
import gmpy2
p=remote("node2.yuzhian.com.cn",34236)
def StrToList(s):
l = s[s.find('[') + 1:s.find(']')].replace(' ','').replace('L','')
nums = []
for n in l.split(','):
nums.append(int(n))
return nums
# right shift inverse
def inverse_right(res,shift,bits=32):
tmp = res
for i in range(bits//shift):
tmp = res ^ tmp >> shift
return tmp
# right shift with mask inverse
def inverse_right_mask(res,shift,mask,bits=32):
tmp = res
for i in range(bits//shift):
tmp = res ^ tmp>>shift & mask
return tmp
# left shift inverse
def inverse_left(res,shift,bits=32):
tmp = res
for i in range(bits//shift):
tmp = res ^ tmp << shift
return tmp
# left shift with mask inverse
def inverse_left_mask(res,shift,mask,bits=32):
tmp = res
for i in range(bits//shift):
tmp = res ^ tmp << shift & mask
return tmp
def backtrace(cur):
high = 0x80000000
low = 0x7fffffff
mask = 0x9908b0df
state = cur
for i in range(3,-1,-1):
tmp = state[i+624]^state[i+397]
# recover Y,tmp = Y
if tmp & high == high:
tmp ^= mask
tmp <<= 1
tmp |= 1
else:
tmp <<=1
# recover highest bit
res = tmp&high
# recover other 31 bits,when i =0,it just use the method again it so beautiful!!!!
tmp = state[i-1+624]^state[i+396]
# recover Y,tmp = Y
if tmp & high == high:
tmp ^= mask
tmp <<= 1
tmp |= 1
else:
tmp <<=1
res |= (tmp)&low
state[i] = res
return state
def recover_state(out):
state = []
for i in out:
i = inverse_right(i,18)
i = inverse_left_mask(i,15,0xefc60000)
i = inverse_left_mask(i,7,0x9d2c5680)
i = inverse_right(i,11)
state.append(i)
return state
def _int32(x):
return int(0xFFFFFFFF & x)
def init(seed):
mt = [0] * 624
mt[0] = seed
for i in range(1, 624):
mt[i] = _int32(1812433253 * (mt[i - 1] ^ mt[i - 1] >> 30) + i)
return mt
def invert_right(res,shift):
tmp = res
for i in range(32//shift):
res = tmp^res>>shift
return _int32(res)
def init_recover(last):
n = 1<<32
inv = gmpy2.invert(1812433253,n)
for i in range(623,0,-1):
last = ((last-i)*inv)%n
last = invert_right(last,30)
return last
def extract_number(y):
y = y ^ y >> 11
y = y ^ y << 7 & 2636928640
y = y ^ y << 15 & 4022730752
y = y ^ y >> 18
return y&0xffffffff
def extract_recover(y):
y = inverse_right(y,18)
y = inverse_left_mask(y,15,4022730752)
y = inverse_left_mask(y,7,2636928640)
y = inverse_right(y,11)
return y&0xffffffff
p.recvuntil("\n", drop=True)
for k in range(20):
p.recvuntil("\n", drop=True)
s1=p.recvuntil("\n", drop=True).decode()
#print(s1)
if "random" in s1:
randoms=StrToList(s1)
if len(randoms)==208:
Rand = RandCrack()
for i in range(208):
Rand.submit(randoms[i]-((randoms[i]>>32)<<32))
randoms[i]=randoms[i]>>32
Rand.submit(randoms[i]-((randoms[i]>>32)<<32))
randoms[i]=randoms[i]>>32
Rand.submit(randoms[i]-((randoms[i]>>32)<<32))
ret=Rand.predict_getrandbits(96)
p.sendline(str(ret))
elif len(randoms)==627:
partS = recover_state(randoms)
state = backtrace([0]*3+partS)[:624]
prng = Random()
prng.setstate((3,tuple(state+[0]),None))
ret=prng.getrandbits(96)
p.sendline(str(ret))
elif "extract" in s1:
extract_number = int(s1[17:])
ret=extract_recover(extract_number)
p.sendline(str(ret))
elif "last" in s1:
last_number=int(s1[14:])
ret=init_recover(last_number)
p.sendline(str(ret))
p.recvuntil("\n", drop=True)
print(k)
a=p.recvuntil("\n", drop=True)
print(a)
real_MT
解题思路
跟上个题一样,执行20次for循环之前多加两行
baby_classical
解题思路
先爆破key
import numpy as np
from tqdm import trange
table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
a = np.array([[13, 37, 10], [15, 17, 41], [13, 0, 10]])
for x in range(64):
for y in range(64):
for z in range(64):
data = np.array([x, y, z])
res = np.mod(np.dot(data, a), 64)
dataa = np.array([xx, xx, xx])
if res[0] == dataa[0] and res[1] == dataa[1] and res[2] == dataa[2]:
print(data)
得到key:W3ar3N0wayBack
然后爆破得到处理后的fir1
import string
import re
# import numpy as np
# flag = ''
# print('flag length:', len(flag))
dic = string.ascii_uppercase+string.ascii_lowercase+string.digits+'+/'
def f1nd(x): return dic.find(x)
# class KeyEncryption:
# def __init__(self, m: int, fillchar: str = "z", key: np.ndarray = None):
# self.m = m
# self.key = key
# self.dicn2s = {i: dic[i] for i in range(64)}
# self.dics2n = dict(zip(self.dicn2s.values(), self.dicn2s.keys()))
# self.fillchar = self.dics2n[fillchar]
# def setM(self, m: int) -> None:
# assert m > 0
# self.m = m
# def setKey(self, key: np.ndarray = None) -> None:
# if key is None:
# while key is None or KeyEncryption.modInv(np.linalg.det(key)) == -1:
# key = np.random.randint(0, 65, size=(self.m, self.m))
# print("random matrix:\n", key)
# else:
# assert KeyEncryption.modInv(np.linalg.det(key)) != -1
# self.key = key
# @staticmethod
# #求出逆元.
# def modInv(x: int):
# y = 0
# while y < 64:
# y += 1
# if (x * y) % 64 == 1:
# return y
# return -1
# ##
# def _loopCrypt(self, long: np.ndarray, K: np.ndarray) -> np.ndarray:
# ans = np.array([])
# ## 3个一组.
# '''
# [[13 37 10]
# [15 17 41]
# [13 0 10]]
# '''
# for i in range(long.shape[0] // self.m):
# ans = np.mod(np.hstack((
# ans,
# np.dot(long[i*self.m:i*self.m+self.m], K)
# )), 64)
# return ans.astype(np.int64)
# def encrypt(self, plaintext: np.ndarray):
# assert self.m != None and self.key is not None
# if plaintext.shape[0] % self.m:
# plaintext = np.hstack((
# plaintext,
# [self.fillchar] * (self.m - plaintext.shape[0] % self.m)
# ))
# return self._loopCrypt(plaintext, self.key)
# def translate(self, s, to: str):
# if to == "text":
# return "".join([self.dicn2s[si] for si in s])
# elif to == "num":
# s = s.replace(" ", "")
# return np.array([self.dics2n[si] for si in s])
# def getKey(key):
# he = KeyEncryption(m=3)
# he.setKey()
# nums = he.translate(key, "num")
# res = he.encrypt(nums)
# enkey = ''.join(dic[i] for i in res.tolist())
# print('Encrypt key:', enkey)
# return enkey
key = 'W3ar3N0wayBack'
ciphertext = "1k2Pe{24seBl4_a6Ot_fp7O1_eHk_Plg3EF_g/JtIonut4/}"
_enkey = [f1nd(i) for i in key]
j = 0
for f in range(len(ciphertext)):
enc = None
for c in range(128):
if f1nd(chr(c)) >= 0:
enc = dic[(f1nd(chr(c)) + _enkey[f % len(_enkey)]) % 64]
else:
enc = chr(c)
if enc == ciphertext[f]:
print(chr(c),end='')
j += 1
# if __name__ == '__main__':
# fir1 = ' '.join(
# map(lambda _: _[::-1], re.split("[ { _ } ]", flag.swapcase())))
# ciphertext1 = ''
# key = ""
# enkey = getKey(key)
# _enkey = [f1nd(i) for i in key]
# print('key lengeh:', len(_enkey))
# j = 0
# for i in fir1:
# if f1nd(i) >= 0:
# ciphertext1 += dic[(f1nd(i) + _enkey[j % len(_enkey)]) % 64]
# else:
# ciphertext1 += i
# j += 1
# ciphertext = ciphertext1.replace(' ', '_')
# print('ciphertext:%s{%s}' % (ciphertext[0:5], ciphertext[6:-1]))
# def fuck(nums):
# m1 = [nums]
# m2 = [
# [13 ,37 ,10],
# [15 ,17, 41],
# [13 ,0, 10]
# ]
# result = [[0,0,0]]
# for i in range(1):
# for j in range(3):
# s = 0
# for k in range(3):
# s += m1[i][k] * m2[k][j]
# result[i][j] = s % 64
# if result[0][0] == f1nd('p') and result[0][1] == f1nd('V') and result[0][2] == f1nd('v'):
# for c in result[0]:
# print(chr(c))
# exit(0)
# for i in range(128):
# for j in range(128):
# for k in range(128):
# fuck([i,j,k])
'''
flag length: 48
random matrix:
[[13 37 10]
[15 17 41]
[13 0 10]]
Encrypt key: pVvRe/G08rLhfwa
key lengeh: 14
ciphertext:1k2Pe{24seBl4_a6Ot_fp7O1_eHk_Plg3EF_g/JtIonut4/}
'''
ftckn{CISsALc_ED0C_S1L0D_ErA_YL1A3R_GNITsER3TNI}
再重新转一下就可以得到flag
easy_high
根据p的混淆过程,p0的低444位bit与p的低444bit相同,且高位也相同,coppersmith打中间未知位数即可(一定少于400bit)
import gmpy2
c= 4881545863615247924697512170011400857004555681758106351259776881249360423774694437921554056529064037535796844084045263140567168171628832384672612945806728465127954937293787045302307135365408938448006548465000663247116917564500525499976139556325841597810084111303039525833367199565266613007333465332710833102978756654324956219855687611590278570749890543277201538208370370097424105751568285050703167350889953331829275262932104042040526209179357770495596739361176548337593674366015027648541293309465113202672923556991818236011769228078267484362980348613669012975963468592763463397575879215173972436831753615524193609612
e=65537
p0=149263925308155304734002881595820602641174737629551638146384199378753884153459661375931646716325020758837194837271581361322079811468970876532640273110966545339040194118880506352109559900553776706613338890047890747811129988585025948270181264314668772556874718178868209009192010129918138140332707080927643141811
p_low=p0-((p0>>444)<<444)
#x2=1334253747547840746415857267903616575302774928674671706690814
p_high=p0>>844
N= 17192509201635459965397076685948071839556595198733884616568925970608227408244870123644193452116734188924766414178232653941867668088060274364830452998991993756231372252367134508712447410029668020439498980619263308413952840568602285764163331028384281840387206878673090608323292785024372223569438874557728414737773416206032540038861064700108597448191546413236875600906013508022023794395360001242071569785940215873854748631691555516626235191098174739613181230094797844414203694879874212340812119576042962565179579136753839946922829803044355134086779223242080575811804564731938746051591474236147749401914216734714709281349
R.<x>=Zmod(N)[]
f=(p_high<<844)+(2**444)*x+p_low
#print(f.monic().small_roots(X=2^400,beta=0.4,epsilon=0.02))
x=457059623926073775857892840020564848132449188556215293131445434977604996233933273879513826534412214327905055289700606386
p=(p_high<<844)+(2**444)*x+p_low
#print(p)
assert isPrime(p)
q=N//p
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
m=pow(c,d,n)
print(long_to_bytes(m))
#b'NKCTF{F10wrs_hVe_r3strDay}'
complex_matrix
解题思路
直接打拓展维纳的板子
import gmpy2
N=71841248095369087024928175623295380241516644434969868335504061065977014103487197287619667598363486210886674500469383623511906399909335989202774281795855975972913438448899231650449810696539722877903606541112937729384851506921675290984316325565141178015123381439392534417225128922398194700511937668809140024838070124095703585627058463137549632965723304713166804084673075651182998654091113119667582720831809458721072371364839503563819080226784026253
e1=65128799196671634905309494529154568614228788035735808211836905142007976099865571126946706559109393187772126407982007858423859147772762638898854472065889939549916077695303157760259717113616428849798058080633047516455513870697383339784816006154279428812359241282979297285283850338964993773227397528608557211742425548651971558377656644211835094019462699301650412862894391885325969143805924684662849869947172175608502179438901337558870349697233790535
e2=58756559706647121529575085912021603170286163639572075337348109911506627489265537716060463072086480156516641723700802217411122982693536541892986623158818442274840863016647800896033363360822503445344748132842451806511693779600370832206455202293028402486647422212959763287987847280322100701242139127654031151565924132562837893975505159702015125483479126108892709063135006366792197127007229210558758401679638300464111782814561428899998471531067163715
e3=34828685390969672139784723764579499920301439564705391196519314224159563070870933754477650614819514127121146216049444888554338415587165719098661141454627820126445291802801256297252654045398330613075575527685542980264993711077876535643646746742646371967302159565887123638001580042027272379341650995728849759541960087953160211696369079708787543303742132161742979856720539914370868829868891655221361545648778590685232034703220732697083024449894197969
e4=26717968456600556973167180286909817773394160817933525240720067057464671317174201540556176814203780603153696663101158205367554829261808020426363683474848952397963507069306452835776851274959389849223566030857588019845781623271395012194869024566879791449466064832273531795430185178486425688475688634844530106740480643866537205900809400383304665727460014210405339697947582657505028211149470787536144302545259243549176816653560626044921521516818788487
c=39297018404565022956251803918747154798377576057123078716166221329195959669756819453426741569480551313085435037629493881038383709458043802420338889323233368852331387845200216275712388921820794980987541224782392553528127093154957890356084331463340193478391679540506421250562554424770350351514435220782124981277580072039637811543914983033300225131364246910828188727043248991987332274929827173923543187017105236008487756190002204169623313222748976369
for i in range(1000):
alpha2 = i/1000
M1 = int(gmpy2.mpz(N)**(3./2))
M2 = int( gmpy2.mpz(N) )
M3 = int(gmpy2.mpz(N)**(3./2 + alpha2))
M4 = int( gmpy2.mpz(N)**(0.5) )
M5 = int( gmpy2.mpz(N)**(3./2 + alpha2) )
M6 = int( gmpy2.mpz(N)**(1.+alpha2) )
M7 = int( gmpy2.mpz(N)**(1.+alpha2) )
D = diagonal_matrix(ZZ, [M1, M2, M3, M4, M5, M6, M7, 1])
B = Matrix(ZZ, [ [1, -N, 0, N**2, 0, 0, 0, -N**3],
[0, e1, -e1, -e1*N, -e1, 0, e1*N, e1*N**2],
[0, 0, e2, -e2*N, 0, e2*N, 0, e2*N**2],
[0, 0, 0, e1*e2, 0, -e1*e2, -e1*e2, -e1*e2*N],
[0, 0, 0, 0, e3, -e3*N, -e3*N, e3*N**2],
[0, 0, 0, 0, 0, e1*e3, 0, -e1*e3*N],
[0, 0, 0, 0, 0, 0, e2*e3, -e2*e3*N],
[0, 0, 0, 0, 0, 0, 0, e1*e2*e3] ]) * D
L = B.LLL()
v = Matrix(ZZ, L[0])
x = v * B**(-1)
phi_ = (e1*x[0,1]/x[0,0]).floor()
try:
d = inverse_mod(65537, phi_)
m = hex(power_mod(c, d, N))[2:]
m = bytes.fromhex(hex(power_mod(c, d, N))[2:])
if(b'NKCTF'in m):
print(m)
break
except:
pass
ez_LargeCG
解题思路
n1 n2分别为p-1 p+1 光滑,直接调库分解
接着对三阶递推序列写矩阵快速幂,构造:
于是求逆矩阵的pow(6,666)次幂打就行了(注意p q大小关系,debug de了两个小时,,,本就不富裕的解题时间雪上加霜,Raven没调出来!)
exp:
q2=106481130516780473105954611077340189174861459077145246394800660809527032990637
p2=288551157776490110472645044398395422160196115791981535735903775378294599329633
p1=427721675251610827084310512123962488210068003845592404231631542730839819224381
q1=92946439027877993602295703905130336736159270745389239059083263513478865293549
a=q1
b=p1
c=q2
d=p2
x = 6085327340671394838391386566774092636784105046872311226269065664501131836034666722102264842236327898770287752026397099940098916322051606027565395747098434
y = 1385551782355619987198268805270109182589006873371541520953112424858566073422289235930944613836387546298080386848159955053303343649615385527645536504580787
z = 2529291156468264643335767070801583140819639532551726975314270127875306069067016825677707064451364791677536138503947465612206191051563106705150921639560469
r = 7948275435515074902473978567170931671982245044864706132834233483354166398627204583162848756424199888842910697874390403881343013872330344844971750121043493
v=matrix(Zmod(r),[x,y,z,1])
v1=[0,0,a,0]
v2=[1,0,b,0]
v3=[0,1,c,0]
v4=[0,0,d,1]
m=[]
m.append(v1)
m.append(v2)
m.append(v3)
m.append(v4)
M=matrix(Zmod(r),m)
inv_M=M^(-1)
print(v*(inv_M^(6**666)))
temp=718268686893438084080386300782696916434605242000201123193568557324202508308322958959518435405441886593296740
print(long_to_bytes(temp-2023))
Raven
大抵是个lwe,可惜赛题太多了,还前前后后耽误了大半天,手调了几个格子,效果都差一些,赛后做完来补上
Ending
全队一共没几个没出的题,crypto差了俩,,,向队友磕头并感谢带飞