2025 LitCTF --- Crypto wp

baisc

题目:

from Crypto.Util.number import *
from enc import flag 

m = bytes_to_long(flag)
n = getPrime(1024)
e = 65537
c = pow(m,e,n)
print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")

'''
n = 150624321883406825203208223877379141248303098639178939246561016555984711088281599451642401036059677788491845392145185508483430243280649179231349888108649766320961095732400297052274003269230704890949682836396267905946735114062399402918261536249386889450952744142006299684134049634061774475077472062182860181893
e = 65537
c = 22100249806368901850308057097325161014161983862106732664802709096245890583327581696071722502983688651296445646479399181285406901089342035005663657920475988887735917901540796773387868189853248394801754486142362158369380296905537947192318600838652772655597241004568815762683630267295160272813021037399506007505
'''

n只有一个素因子,则
p h i ( n ) = n − 1 phi(n) = n-1 phi(n)=n1
d = e − 1   m o d   ϕ ( n ) d = e^{-1} \space mod \space \phi(n) d=e1 mod ϕ(n)
m = e d   m o d   n m = e^d \space mod \space n m=ed mod n

exp:

from Crypto.Util.number import *
n = 150624321883406825203208223877379141248303098639178939246561016555984711088281599451642401036059677788491845392145185508483430243280649179231349888108649766320961095732400297052274003269230704890949682836396267905946735114062399402918261536249386889450952744142006299684134049634061774475077472062182860181893
e = 65537
c = 22100249806368901850308057097325161014161983862106732664802709096245890583327581696071722502983688651296445646479399181285406901089342035005663657920475988887735917901540796773387868189853248394801754486142362158369380296905537947192318600838652772655597241004568815762683630267295160272813021037399506007505
phi = n-1
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
flag = long_to_bytes(m)
print(flag)

math

题目:

from Crypto.Util.number import *
from enc import flag

m = bytes_to_long(flag)
e = 65537
p,q = getPrime(1024),getPrime(1024)
n = p*q
noise = getPrime(40)
tmp1 = noise*p+noise*q
tmp2 = noise*noise
hint = p*q+tmp1+tmp2
c = pow(m,e,n)
print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")
print(f"hint = {hint}")
'''
n = 17532490684844499573962335739488728447047570856216948961588440767955512955473651897333925229174151614695264324340730480776786566348862857891246670588649327068340567882240999607182345833441113636475093894425780004013793034622954182148283517822177334733794951622433597634369648913113258689335969565066224724927142875488372745811265526082952677738164529563954987228906850399133238995317510054164641775620492640261304545177255239344267408541100183257566363663184114386155791750269054370153318333985294770328952530538998873255288249682710758780563400912097941615526239960620378046855974566511497666396320752739097426013141
e = 65537
c = 1443781085228809103260687286964643829663045712724558803386592638665188285978095387180863161962724216167963654290035919557593637853286347618612161170407578261345832596144085802169614820425769327958192208423842665197938979924635782828703591528369967294598450115818251812197323674041438116930949452107918727347915177319686431081596379288639254670818653338903424232605790442382455868513646425376462921686391652158186913416425784854067607352211587156772930311563002832095834548323381414409747899386887578746299577314595641345032692386684834362470575165392266454078129135668153486829723593489194729482511596288603515252196
hint = 17532490684844499573962335739488728447047570856216948961588440767955512955473651897333925229174151614695264324340730480776786566348862857891246670588649327068340567882240999607182345833441113636475093894425780004013793034622954182148283517822177334733794951622433597634369648913113258689335969565315879035806034866363781260326863226820493638303543900551786806420978685834963920605455531498816171226961859405498825422799670404315599803610007692517859020686506546933013150302023167306580068646104886750772590407299332549746317286972954245335810093049085813683948329319499796034424103981702702886662008367017860043529164
'''

h i n t = p × q + n o i s e ( p + q ) + n o i s e 2 hint = p\times q+noise(p+q)+noise^2 hint=p×q+noise(p+q)+noise2
化简一下,得到
h i n t − p × q = n o i s e ( p + q + n o i s e ) hint - p\times q = noise(p+q+noise) hintp×q=noise(p+q+noise)
由于noise为一个40Bit的素数
可以通过factordb或者yafu分解 h i n t − n hint-n hintn来找到一个40bit的值得到noise,进而可以构造方程组
{ n = p × q h i n t = ( p + n o i s e ) ( q + n o i s e ) \left\{\begin{matrix} n = p\times q \\hint = (p+noise)(q+noise) \end{matrix}\right. {n=p×qhint=(p+noise)(q+noise)
解方程求出p和q
或者直接计算出p+q
p + q = h i n t − n n o i s e − n o i s e p+q = \frac{hint-n}{noise}-noise p+q=noisehintnnoise

ϕ ( n ) = ( p − 1 ) ( q − 1 ) = n − ( p + q ) + 1 \phi(n) = (p-1)(q-1) = n-(p+q)+1 ϕ(n)=(p1)(q1)=n(p+q)+1
最后直接RSA解密即可得到flag

from Crypto.Util.number import *
import gmpy2
from z3 import *

n = 17532490684844499573962335739488728447047570856216948961588440767955512955473651897333925229174151614695264324340730480776786566348862857891246670588649327068340567882240999607182345833441113636475093894425780004013793034622954182148283517822177334733794951622433597634369648913113258689335969565066224724927142875488372745811265526082952677738164529563954987228906850399133238995317510054164641775620492640261304545177255239344267408541100183257566363663184114386155791750269054370153318333985294770328952530538998873255288249682710758780563400912097941615526239960620378046855974566511497666396320752739097426013141
e = 65537
c = 1443781085228809103260687286964643829663045712724558803386592638665188285978095387180863161962724216167963654290035919557593637853286347618612161170407578261345832596144085802169614820425769327958192208423842665197938979924635782828703591528369967294598450115818251812197323674041438116930949452107918727347915177319686431081596379288639254670818653338903424232605790442382455868513646425376462921686391652158186913416425784854067607352211587156772930311563002832095834548323381414409747899386887578746299577314595641345032692386684834362470575165392266454078129135668153486829723593489194729482511596288603515252196
hint = 17532490684844499573962335739488728447047570856216948961588440767955512955473651897333925229174151614695264324340730480776786566348862857891246670588649327068340567882240999607182345833441113636475093894425780004013793034622954182148283517822177334733794951622433597634369648913113258689335969565315879035806034866363781260326863226820493638303543900551786806420978685834963920605455531498816171226961859405498825422799670404315599803610007692517859020686506546933013150302023167306580068646104886750772590407299332549746317286972954245335810093049085813683948329319499796034424103981702702886662008367017860043529164
noise = 942430120937
p,q = Ints('p q')
s = Solver()
s.add(p*q==n)
s.add((p+noise)*(q+noise)==hint)
if s.check()==sat:
    result = s.model()
    p = result[p].as_long()
    q = result[q].as_long()
    phi = (p-1)*(q-1)
    d = gmpy2.invert(e,phi)
    m = pow(c,d,n)
    flag = long_to_bytes(m)
    print(flag)

leak

题目:

from Crypto.Util.number import *
from enc import flag

m = bytes_to_long(flag)
p,q,e = getPrime(1024),getPrime(1024),getPrime(101)
n = p*q
temp = gmpy2.invert(e,p-1)
c = pow(m,e,n)
hint = temp>>180
print(f"e = {e}")
print(f"n = {n}")
print(f"c = {c}")
print(f"hint = {hint}")
'''
e = 1915595112993511209389477484497
n = 12058282950596489853905564906853910576358068658769384729579819801721022283769030646360180235232443948894906791062870193314816321865741998147649422414431603039299616924238070704766273248012723702232534461910351418959616424998310622248291946154911467931964165973880496792299684212854214808779137819098357856373383337861864983040851365040402759759347175336660743115085194245075677724908400670513472707204162448675189436121439485901172477676082718531655089758822272217352755724670977397896215535981617949681898003148122723643223872440304852939317937912373577272644460885574430666002498233608150431820264832747326321450951
c = 5408361909232088411927098437148101161537011991636129516591281515719880372902772811801912955227544956928232819204513431590526561344301881618680646725398384396780493500649993257687034790300731922993696656726802653808160527651979428360536351980573727547243033796256983447267916371027899350378727589926205722216229710593828255704443872984334145124355391164297338618851078271620401852146006797653957299047860900048265940437555113706268887718422744645438627302494160620008862694047022773311552492738928266138774813855752781598514642890074854185464896060598268009621985230517465300289580941739719020511078726263797913582399
hint = 10818795142327948869191775315599184514916408553660572070587057895748317442312635789407391509205135808872509326739583930473478654752295542349813847128992385262182771143444612586369461112374487380427668276692719788567075889405245844775441364204657098142930
'''

part1:二元copper求dp
∵ e × d p ≡ 1   m o d   ( p − 1 ) \because e\times dp \equiv 1 \space mod \space (p-1) e×dp1 mod (p1)
∴ e ( d p h + d p l ) ≡ 1   m o d   ( p − 1 ) \therefore e(dp_{h}+dp_{l}) \equiv 1 \space mod \space (p-1) e(dph+dpl)1 mod (p1)
等式变换
⇒ e ( d p h + d p l ) = 1 + k ( p − 1 ) \Rightarrow e(dp_{h}+dp_{l}) = 1+k(p-1) e(dph+dpl)=1+k(p1)
⇒ e ( d p h + d p l ) = 1 − k + k p \Rightarrow e(dp_{h}+dp_{l}) = 1-k+kp e(dph+dpl)=1k+kp
⇒ e ( d p h + d p l ) + k − 1 = k p \Rightarrow e(dp_{h}+dp_{l}) +k-1=kp e(dph+dpl)+k1=kp
⇒ e ( d p h + d p l ) + k − 1 ≡ 0   m o d   p \Rightarrow e(dp_{h}+dp_{l}) +k-1 \equiv 0\space mod \space p e(dph+dpl)+k10 mod p
已知 d p l dp_{l} dpl为180bit,且对于1024的p来说算是小根
因此二元copper计算出 d p l dp_{l} dpl,此时dp也就求出来了

part2:dp泄露求p以及计算flag:
d p ≡ d   m o d   ( p − 1 ) d_p \equiv d \space mod \space (p-1) dpd mod (p1)
e d ≡ 1   m o d   ( p − 1 ) ( q − 1 ) ed \equiv 1 \space mod \space (p-1)(q-1) ed1 mod (p1)(q1)
则 m e d p   m o d   n ≡ m e d   m o d   ( p − 1 )   m o d   p 则 m^{edp} \space mod \space n \equiv m^{ed \space mod \space (p-1)} \space mod \space p medp mod nmed mod (p1) mod p
⇒ m e d p   m o d   n ≡ m 1 + k ( p − 1 )   m o d   p \Rightarrow m^{edp} \space mod \space n\equiv m^{1+k(p-1)} \space mod \space p medp mod nm1+k(p1) mod p
根据费马小定理
a p − 1 ≡ 1   m o d   p a^{p-1} \equiv 1 \space mod \space p ap11 mod p
⇒ m 1 + k ( p − 1 )   m o d   p ≡ m   m o d   p \Rightarrow m^{1+k(p-1)} \space mod \space p \equiv m \space mod \space p m1+k(p1) mod pm mod p
⇒ m e d p   m o d   n − m ≡ 0   m o d   p \Rightarrow m^{edp} \space mod \space n -m \equiv 0 \space mod \space p medp mod nm0 mod p
∵ n = p ∗ q , \because n = p*q, n=pq, 那么, m e d p   m o d   n − m 与 n 存在最大公约数 p 那么,m^{edp} \space mod \space n -m与n存在最大公约数p 那么,medp mod nmn存在最大公约数p
p = g c d ( m e d p   m o d   n − m , n ) , m ∈ ( 1 , p ) p = gcd( m^{edp} \space mod \space n -m,n), m\in(1,p) p=gcd(medp mod nm,n)m(1,p)
⇒ p = g c d ( m e d p   m o d   n − m , n ) \Rightarrow p = gcd( m^{edp} \space mod \space n -m,n) p=gcd(medp mod nm,n)
进而得到 q = n / / p q = n//p q=n//p
遍历一下解出来的flag是否包含LitCTF即可
exp:

from Crypto.Util.number import *
import gmpy2
import itertools



def small_roots(f, bounds, m=1, d=None):
    if not d:
        d = f.degree()
        print(d)
    R = f.base_ring()
    N = R.cardinality()
    f /= f.coefficients().pop(0)
    f = f.change_ring(ZZ)
    G = Sequence([], f.parent())
    for i in range(m + 1):
        base = N ^ (m - i) * f ^ i
        for shifts in itertools.product(range(d), repeat=f.nvariables()):
            g = base * prod(map(power, f.variables(), shifts))
            G.append(g)
    B, monomials = G.coefficient_matrix()
    monomials = vector(monomials)
    factors = [monomial(*bounds) for monomial in monomials]
    for i, factor in enumerate(factors):
        B.rescale_col(i, factor)
    B = B.dense_matrix().LLL()
    B = B.change_ring(QQ)
    for i, factor in enumerate(factors):
        B.rescale_col(i, 1 / factor)
    H = Sequence([], f.parent().change_ring(QQ))
    for h in filter(None, B * monomials):
        H.append(h)
        I = H.ideal()
        if I.dimension() == -1:
            H.pop()
        elif I.dimension() == 0:
            roots = []
            for root in I.variety(ring=ZZ):
                root = tuple(R(root[var]) for var in f.variables())
                roots.append(root)
            return roots
    return []

def solve_dp_leak(e,dp,n,c):
    tmp = gmpy2.mpz(pow(5,e*dp,n)-5)
    p = gmpy2.gcd(tmp,n)
    q = n//p
    phi = (p-1)*(q-1)
    try:
        d = gmpy2.invert(e,phi)
        m = pow(c,d,n)
        flag = long_to_bytes(int(m))
        return flag
    except:
        pass
e = 1915595112993511209389477484497
n = 12058282950596489853905564906853910576358068658769384729579819801721022283769030646360180235232443948894906791062870193314816321865741998147649422414431603039299616924238070704766273248012723702232534461910351418959616424998310622248291946154911467931964165973880496792299684212854214808779137819098357856373383337861864983040851365040402759759347175336660743115085194245075677724908400670513472707204162448675189436121439485901172477676082718531655089758822272217352755724670977397896215535981617949681898003148122723643223872440304852939317937912373577272644460885574430666002498233608150431820264832747326321450951
c = 5408361909232088411927098437148101161537011991636129516591281515719880372902772811801912955227544956928232819204513431590526561344301881618680646725398384396780493500649993257687034790300731922993696656726802653808160527651979428360536351980573727547243033796256983447267916371027899350378727589926205722216229710593828255704443872984334145124355391164297338618851078271620401852146006797653957299047860900048265940437555113706268887718422744645438627302494160620008862694047022773311552492738928266138774813855752781598514642890074854185464896060598268009621985230517465300289580941739719020511078726263797913582399
hint = 10818795142327948869191775315599184514916408553660572070587057895748317442312635789407391509205135808872509326739583930473478654752295542349813847128992385262182771143444612586369461112374487380427668276692719788567075889405245844775441364204657098142930
dp_high = hint<<180
R.<k1,k2> = PolynomialRing(Zmod(n))
f = e * (dp_high + k1) + k2 - 1
res = small_roots(f,(2^180,2^101),m=2,d=5)[0]
for dp_low in res:
    dp= dp_high+int(dp_low)
    flag = solve_dp_leak(e,dp,n,c)
    if b'LitCTF' in flag:
        print(flag)
        break

baby

题目:

      
import gmpy2
from Crypto.Util.number import *
from enc import flag


m = bytes_to_long(flag)
g = getPrime(512)
t = getPrime(150)
data = (t * gmpy2.invert(m, g)) % g
print(f'g = {g}')
print(f'data = {data}')
'''
g = 7835965640896798834809247993719156202474265737048568647376673642017466116106914666363462292416077666356578469725971587858259708356557157689066968453881547
data = 2966297990428234518470018601566644093790837230283136733660201036837070852272380968379055636436886428180671888655884680666354402224746495312632530221228498
'''

    

已知data和g,以及存在如下等式
d a t a ≡ t × m − 1   m o d   g data \equiv t\times m^{-1} \space mod \space g datat×m1 mod g
移项
d a t a × m ≡ t   m o d   g data\times m \equiv t \space mod \space g data×mt mod g
t = d a t a × m − k g t = data\times m-kg t=data×mkg
由此我们可以构造格
L = ( 1 d a t a 0 g ) L = \begin{pmatrix} 1&data \\ 0&g \end{pmatrix} L=(10datag)
我们需要求的目标向量为 ( m t ) (m\hspace{0.3cm} t) (mt),则有
( m − k ) ( 1 d a t a 0 g ) = ( m t ) (m\hspace{0.3cm} -k)\begin{pmatrix} 1&data\\ 0&g \end{pmatrix} = (m\hspace{0.3cm} t) (mk)(10datag)=(mt)
此时直接格基规约无法得到预期的目标向量(小卡了一下界),显然未知m的大小大于256bit,此时直接增大格体积从而使得格的行列式大于目标向量的模长即可
我们可以给格中较小的一列乘上一个数D
( m − k ) ( 1 D × d a t a 0 D × g ) = ( m D t ) (m\hspace{0.3cm} -k)\begin{pmatrix} 1&D\times data \\ 0&D\times g \end{pmatrix} = (m\hspace{0.3cm} Dt) (mk)(10D×dataD×g)=(mDt)
在不知道m大小的情况下,我们遍历D即可,直到格基规约出一个值,其开头为LiCTF{,那么该值则为所求的flag

exp:

#sage
from tqdm import *
from Crypto.Util.number import *

g = 7835965640896798834809247993719156202474265737048568647376673642017466116106914666363462292416077666356578469725971587858259708356557157689066968453881547
data = 2966297990428234518470018601566644093790837230283136733660201036837070852272380968379055636436886428180671888655884680666354402224746495312632530221228498
for i in trange(100,400):
    D = 2**i
    M = Matrix(ZZ,[[1,data*D],[0,g*D]])
    res = M.LLL()
    if res:
        m,x = res[0]
        m = abs(m)
        flag = long_to_bytes(m)
        if b'LitCTF{' in flag:
            print(flag)
            break

ez_math

题目:

      
from sage.all import *
from Crypto.Util.number import *
from uuid import uuid4

flag = b'flag{'+ str(uuid4()).encode() + b'}'
flag = bytes_to_long(flag)
len_flag = flag.bit_length()
e = 65537
p = getPrime(512)
P = GF(p)
A = [[flag,                 getPrime(len_flag)],
     [getPrime(len_flag),   getPrime(len_flag)]]
A = matrix(P, A)
B = A ** e

print(f"e = {e}")
print(f"p = {p}")
print(f"B = {list(B)}".replace('(', '[').replace(')', ']'))

# e = 65537
# p = 8147594556101158967571180945694180896742294483544853070485096002084187305007965554901340220135102394516080775084644243545680089670612459698730714507241869
# B = [[2155477851953408309667286450183162647077775173298899672730310990871751073331268840697064969968224381692698267285466913831393859280698670494293432275120170, 4113196339199671283644050914377933292797783829068402678379946926727565560805246629977929420627263995348168282358929186302526949449679561299204123214741547], [3652128051559825585352835887172797117251184204957364197630337114276860638429451378581133662832585442502338145987792778148110514594776496633267082169998598, 2475627430652911131017666156879485088601207383028954405788583206976605890994185119936790889665919339591067412273564551745588770370229650653217822472440992]]

    

一眼顶针是一个二阶矩阵RSA题型,根据论文A Matrix Extension of the RSA Cryptosystem
在这里插入图片描述
可知,该二阶矩阵在模p上的欧拉函数为: ϕ = ( p 2 − 1 ) ( p 2 − p ) \phi = (p^2-1)(p^2-p) ϕ=(p21)(p2p)
然后按照常规的RSA解密流程,计算出d
d = e − 1   m o d   p h i d = e^{-1} \space mod \space phi d=e1 mod phi
A = B d A = B^d A=Bd
最后还原矩阵A即可找到flag

#sage
from Crypto.Util.number import *

e = 65537
p = 8147594556101158967571180945694180896742294483544853070485096002084187305007965554901340220135102394516080775084644243545680089670612459698730714507241869
B = [[2155477851953408309667286450183162647077775173298899672730310990871751073331268840697064969968224381692698267285466913831393859280698670494293432275120170, 4113196339199671283644050914377933292797783829068402678379946926727565560805246629977929420627263995348168282358929186302526949449679561299204123214741547], [3652128051559825585352835887172797117251184204957364197630337114276860638429451378581133662832585442502338145987792778148110514594776496633267082169998598, 2475627430652911131017666156879485088601207383028954405788583206976605890994185119936790889665919339591067412273564551745588770370229650653217822472440992]]
phi = (p^2-1)*(p^2-p)
d = inverse_mod(e,phi)
B_M = matrix(Zmod(p),B)
A = B_M^d
flag = int(A[0][0])
print(long_to_bytes(flag))

new_bag

题目:

from Crypto.Util.number import *
import random
import string
 
def get_flag(length):
    characters = string.ascii_letters + string.digits + '_'
    flag = 'LitCTF{' + ''.join(random.choice(characters) for _ in range(length)) + '}'
    return flag.encode()

flag = get_flag(8)
print(flag)
flag = bin(bytes_to_long(flag))[2:]

p = getPrime(128)
pubkey = [getPrime(128) for i in range(len(flag))]
enc = 0
for i in range(len(flag)):
    enc += pubkey[i] * int(flag[i])
    enc %= p
f = open("output.txt","w")
f.write(f"p = {p}\n")
f.write(f"pubkey = {pubkey}\n")
f.write(f"enc = {enc}\n")
f.close()

output.txt:

p = 173537234562263850990112795836487093439
pubkey = [184316235755254907483728080281053515467, 301753295242660201987730522100674059399, 214746865948159247109907445342727086153, 190710765981032078577562674498245824397, 331594659178887289573546882792969306963, 325241251857446530306000904015122540537, 183138087354043440402018216471847480597, 184024660891182404534278014517267677121, 221852419056451630727726571924370029193, 252122782233143392994310666727549089119, 175886223097788623718858806338121455451, 275410728642596840638045777234465661687, 251664694235514793799312335012668142813, 218645272462591891220065928162159215543, 312223630454310643034351163568776055567, 246969281206041998865813427647656760287, 314861458279166374375088099707870061461, 264293021895772608566300156292334238719, 300802209357110221724717494354120213867, 293825386566202476683406032420716750733, 280164880535680245461599240490036536891, 223138633045675121340315815489781884671, 194958151408670059556476901479795911187, 180523100489259027750075460231138785329, 180425435626797251881104654861163883059, 313871202884226454316190668965524324023, 184833541398593696671625353250714719537, 217497008601504809464374671355532403921, 246589067140439936215888566305171004301, 289015788017956436490096615142465503023, 301775305365100149653555500258867275677, 185893637147914858767269807046039030871, 319328260264390422708186053639594729851, 196198701308135383224057395173059054757, 231185775704496628532348037721799493511, 243973313872552840389840048418558528537, 213140279661565397451805047456032832611, 310386296949148370235845491986451639013, 228492979916155878048849684460007011451, 240557187581619139147592264130657066299, 187388364905654342761169670127101032713, 305292765113810142043496345097024570233, 303823809595161213886303993298011013599, 227663140954563126349665813092551336597, 257833881948992845466919654910838972461, 291249161813309696736659661907363469657, 228470133121759300620143703381920625589, 337912208888617180835513160742872043511, 252639095930536359128379880984347614689, 306613178720695137374121633131944714277, 328627523443531702430603855075960220403, 283995291614222889691668376952473718279, 185992200035693404743830210660606140043, 175575945935802771832062328390060568381, 239709736751531517044198331233711541211, 325191992201185112802734343474281930993, 285825734319916654888050222626163129503, 260820892372814862728958615462018022903, 271109638409686342632742230596810197399, 195432366301516284662210689868561107229, 252351678712166898804432075801905414141, 175869608753229067314866329908981554323, 212291732707466211705141589249474157597, 299891357045144243959903067354676661051, 271237385422923460052644584552894282763, 268702576849722796315440463412052409241, 198273535005705777854651218089804228523, 177684355989910045168511400849036259973, 189237944200991357454773904466163557789, 175427967765368330787115337317676160499, 270446056495616077936737430232108222303, 243318639972702711024520926308402316247, 223872107662231922057872197123261908053, 268995355861070998347238198063073079851, 244478236168888494353493404999149985963, 230731375083676409248450208772518041369, 231630208287176700035265642824425872113, 187649298194887119502654724235771449423, 264924369987111619306245625770849264491, 327092811483332202721992798797117253283, 274967838920225995524024619709213673571, 313836314009366857157961838519499192671, 181860768653760352435352944732117309357, 184011200837375425882494435177626368109, 246455975565763627776562816894916143559, 262208917125258935991543552004318662109, 334006940602786701813813048552124976177, 241119397420390120456580389194328607351, 255370083166310325724283692646412327547, 280056982387584554076672702548437488901, 190822826881447578202544631446213911541, 206119293866065537243159766877834200177, 289535246575130471484249052043282790337, 222004375767927951747133364917437739627, 186041951615746748538744491355290007923, 299120276948597373232905692530626175519, 268645812049699572580085139845553457511, 231990902203442306941381714523426756489, 259677531562170067444672097354970172129, 232573792063456357545735601063504090387, 268451806037215206985127877726665463011, 324266632324016349795115268035757999593, 323952615081869295386415078624753400501, 302316593553669781596237136546083536339, 235576231941572491681115931798290883659, 202271277470197960243533508432663735031, 172391954991101354275650988921310984563, 215333185856183701105529790905068832303, 335916893044781805453250006520700519353, 217268288923298532517983372665872329797, 265455575922780577837866687874732212733, 182194442259001995170676842797322170297, 180222796978664332193987060700843734759, 332629077640484670095070754759241249101, 238815683708676274248277883404136375767, 246167709707533867216616011486975023679, 188375282015595301232040104228085154549, 230675799347049231846866057019582889423, 290911573230654740468234181613682439691, 173178956820933028868714760884278201561, 340087079300305236498945763514358009773, 215775253913162994758086261347636015049, 286306008278685809877266756697807931889, 175231652202310718229276393280541484041, 230887015177563361309867021497576716609, 306478031708687513424095160106047572447, 172289054804425429042492673052057816187]
enc = 82516114905258351634653446232397085739

根据题目名new_bag,显而易见是一个背包问题
先计算一下密度d
d = l e n ( p u b k e y ) l o g 2 m a x ( p u b k e y i ) = 0.9921 > 0.9408 d = \frac{len(pubkey) }{log_2^{max(pubkey_i)}}=0.9921>0.9408 d=log2max(pubkeyi)len(pubkey)=0.9921>0.9408
显然,没办法直接构造格规约得到预取解,但是我们知道flag的格式为LitCTF{xxx}
也就是说,前7个字符和最后1个字符是已知的,那么我们只需要求中间8个字符即可。
这样整个背包的规模也就降下来了,因此新的背包,其密度也在范围内,可以格基规约了。
根据等式
e n c ≡ p u b l i c i × m i   m o d   p enc \equiv public_i\times m_i \space mod \space p encpublici×mi mod p
e n c = p u b l i c i × m i + k p enc =public_i\times m_i +kp enc=publici×mi+kp
0 = p u b l i c i × m i + k p − e n c 0 =public_i\times m_i +kp-enc 0=publici×mi+kpenc
0 = ∑ 0 64 p u b l i c i m i + k p − e n c 0 = \sum_{0}^{64}public_im_i+kp-enc 0=064publicimi+kpenc
构造的格子如下
( 1 0 ⋯ 0 0 p u b k e y 1 0 1 ⋯ 0 0 p u b k e y 2 ⋮ ⋮ ⋱ ⋮ ⋮ ⋮ 0 0 ⋯ 1 0 p u b k e y 64 0 0 ⋯ 0 1 c 0 0 ⋯ 0 0 p ) \begin{pmatrix} 1& 0& \cdots & 0 &0 & pubkey_1\\ 0& 1& \cdots& 0& 0& pubkey_2\\ \vdots &\vdots & \ddots&\vdots &\vdots &\vdots \\ 0& 0& \cdots & 1 & 0& pubkey_{64} \\ 0& 0& \cdots& 0& 1&c \\ 0& 0& \cdots& 0 & 0 &p \end{pmatrix} 10000010000010000010pubkey1pubkey2pubkey64cp
且有如下线性关系
( m 1 m 2 ⋯ m 64 − 1 k ) ( 1 0 ⋯ 0 0 p u b k e y 1 0 1 ⋯ 0 0 p u b k e y 2 ⋮ ⋮ ⋱ ⋮ ⋮ ⋮ 0 0 ⋯ 1 0 p u b k e y 64 0 0 ⋯ 0 1 c 0 0 ⋯ 0 0 p ) = ( m 1 m 2 ⋯ m 64 − 1 0 ) \begin{pmatrix} m_1 &m_2 &\cdots &m_{64} &-1&k \end{pmatrix}\begin{pmatrix} 1& 0& \cdots & 0 &0 & pubkey_1\\ 0& 1& \cdots& 0& 0& pubkey_2\\ \vdots &\vdots & \ddots&\vdots &\vdots &\vdots \\ 0& 0& \cdots & 1 & 0& pubkey_{64} \\ 0& 0& \cdots& 0& 1&c \\ 0& 0& \cdots& 0 & 0 &p \end{pmatrix}=\begin{pmatrix} m_1 &m_2 &\cdots &m_{64} &-1&0 \end{pmatrix} (m1m2m641k) 10000010000010000010pubkey1pubkey2pubkey64cp =(m1m2m6410)
在使用BKZ规约的时候,默认值无法得到预期结果,我们可以把参数block_size 调大(其默认值为10,我设置为30),然后将规约出来的结果进行遍历,直到满足题目的条件为止
exp:

#sage
from Crypto.Util.number import *
import string

flag_dict = string.ascii_letters + string.digits + '_'
p = 173537234562263850990112795836487093439
pubkey = [184316235755254907483728080281053515467, 301753295242660201987730522100674059399, 214746865948159247109907445342727086153, 190710765981032078577562674498245824397, 331594659178887289573546882792969306963, 325241251857446530306000904015122540537, 183138087354043440402018216471847480597, 184024660891182404534278014517267677121, 221852419056451630727726571924370029193, 252122782233143392994310666727549089119, 175886223097788623718858806338121455451, 275410728642596840638045777234465661687, 251664694235514793799312335012668142813, 218645272462591891220065928162159215543, 312223630454310643034351163568776055567, 246969281206041998865813427647656760287, 314861458279166374375088099707870061461, 264293021895772608566300156292334238719, 300802209357110221724717494354120213867, 293825386566202476683406032420716750733, 280164880535680245461599240490036536891, 223138633045675121340315815489781884671, 194958151408670059556476901479795911187, 180523100489259027750075460231138785329, 180425435626797251881104654861163883059, 313871202884226454316190668965524324023, 184833541398593696671625353250714719537, 217497008601504809464374671355532403921, 246589067140439936215888566305171004301, 289015788017956436490096615142465503023, 301775305365100149653555500258867275677, 185893637147914858767269807046039030871, 319328260264390422708186053639594729851, 196198701308135383224057395173059054757, 231185775704496628532348037721799493511, 243973313872552840389840048418558528537, 213140279661565397451805047456032832611, 310386296949148370235845491986451639013, 228492979916155878048849684460007011451, 240557187581619139147592264130657066299, 187388364905654342761169670127101032713, 305292765113810142043496345097024570233, 303823809595161213886303993298011013599, 227663140954563126349665813092551336597, 257833881948992845466919654910838972461, 291249161813309696736659661907363469657, 228470133121759300620143703381920625589, 337912208888617180835513160742872043511, 252639095930536359128379880984347614689, 306613178720695137374121633131944714277, 328627523443531702430603855075960220403, 283995291614222889691668376952473718279, 185992200035693404743830210660606140043, 175575945935802771832062328390060568381, 239709736751531517044198331233711541211, 325191992201185112802734343474281930993, 285825734319916654888050222626163129503, 260820892372814862728958615462018022903, 271109638409686342632742230596810197399, 195432366301516284662210689868561107229, 252351678712166898804432075801905414141, 175869608753229067314866329908981554323, 212291732707466211705141589249474157597, 299891357045144243959903067354676661051, 271237385422923460052644584552894282763, 268702576849722796315440463412052409241, 198273535005705777854651218089804228523, 177684355989910045168511400849036259973, 189237944200991357454773904466163557789, 175427967765368330787115337317676160499, 270446056495616077936737430232108222303, 243318639972702711024520926308402316247, 223872107662231922057872197123261908053, 268995355861070998347238198063073079851, 244478236168888494353493404999149985963, 230731375083676409248450208772518041369, 231630208287176700035265642824425872113, 187649298194887119502654724235771449423, 264924369987111619306245625770849264491, 327092811483332202721992798797117253283, 274967838920225995524024619709213673571, 313836314009366857157961838519499192671, 181860768653760352435352944732117309357, 184011200837375425882494435177626368109, 246455975565763627776562816894916143559, 262208917125258935991543552004318662109, 334006940602786701813813048552124976177, 241119397420390120456580389194328607351, 255370083166310325724283692646412327547, 280056982387584554076672702548437488901, 190822826881447578202544631446213911541, 206119293866065537243159766877834200177, 289535246575130471484249052043282790337, 222004375767927951747133364917437739627, 186041951615746748538744491355290007923, 299120276948597373232905692530626175519, 268645812049699572580085139845553457511, 231990902203442306941381714523426756489, 259677531562170067444672097354970172129, 232573792063456357545735601063504090387, 268451806037215206985127877726665463011, 324266632324016349795115268035757999593, 323952615081869295386415078624753400501, 302316593553669781596237136546083536339, 235576231941572491681115931798290883659, 202271277470197960243533508432663735031, 172391954991101354275650988921310984563, 215333185856183701105529790905068832303, 335916893044781805453250006520700519353, 217268288923298532517983372665872329797, 265455575922780577837866687874732212733, 182194442259001995170676842797322170297, 180222796978664332193987060700843734759, 332629077640484670095070754759241249101, 238815683708676274248277883404136375767, 246167709707533867216616011486975023679, 188375282015595301232040104228085154549, 230675799347049231846866057019582889423, 290911573230654740468234181613682439691, 173178956820933028868714760884278201561, 340087079300305236498945763514358009773, 215775253913162994758086261347636015049, 286306008278685809877266756697807931889, 175231652202310718229276393280541484041, 230887015177563361309867021497576716609, 306478031708687513424095160106047572447, 172289054804425429042492673052057816187]
enc = 82516114905258351634653446232397085739
head = b'LitCTF{'
tail = b'}'
head_bin = bin(bytes_to_long(head))[2:]
tail_bin = bin(bytes_to_long(tail))[2:].zfill(8)
new_pubkey = pubkey[55:119]
n = len(new_pubkey)
for i in range(len(head_bin)):
    enc -= pubkey[i] * int(head_bin[i])
enc = enc%p
for j in range(-8,0):
    enc -= pubkey[j] * int(tail_bin[8+j])
enc = enc%p
M = Matrix(ZZ,n+2,n+2)
for i in range(n):
    M[i,i] = 1
    M[i,-1] = new_pubkey[i]
M[-2,-2] = 1
M[-2,-1] = enc
M[-1,-1] = p
res = M.BKZ(block_size = 30)
for r in res:
    flag_bin=""
    for x in r[:-2]:
        if str(x)=="0":
            flag_bin +="0"
        else:
            flag_bin +="1"
    try:
        flag = long_to_bytes(int(flag_bin,2)).decode()
        if all(i  in flag_dict  for i in flag):
            print('LitCTF{'+flag+'}')
    except:
        pass


完工!!!!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值