2022西湖论剑——Crypto

2022西湖论剑 Crypto writeup

本来以为今年不允许跨校组队竞争不会很激烈,结果一度被各路神仙打到怀疑人生,比国赛还卷...

半个小时能掉十多名(无语住),最后解了一道Crypto起死回生,给sagemath磕一个(

MyErrorLearn | 470.60 points

贴关键代码

def XennyOracle():
    r = getPrime(512)
    d = invert(secret+r, p) - getPrime(246)
    print('> r =', r)
    print('> d =', d)

def task():
    for _ in range(3):
        op = int(input())
        if op == 1:
            XennyOracle()
        elif op == 2:
            ss = int(input())

            if ss == secret:
                print('flag: ', flag)

可以交互得到两组数据,第三次交互进行验证,我们把两次交互生成的246bit素数当成未知量x y,构造二元coppersmith,推式子:

exp:

import gmpy2
import itertools
p = 164080373786132206852380775931971500336857083290389553228887174757214796328346438535803116378472305090487659067728646659982583634731861418341619178768791924712274834673040017690979304857826794311766511469901640021883698738738996653581115332314282398822100428124150204418128338831546311162452521892689129182073
r1 = 7134984614344864225103246570034863069926210673267513316944718274934148599289735273186052653974584216271596602737621871660498103987283844341400426972571891
d1 = 152544591521391846203439186267554491992403311334510313023110235268620693294309269016887418592817274278083545421788274436955307553619583737286551237861043281498130017123063003885702527826356923499696220589392471138164487028460201501759600097070080112819292962902285440734707889440999828315085244717067794932800
r2 = 12727243124710434337174273522608402210307851939803246962307699474234452385393467381259969165114613476185443002941558201759288672528424494270546132132150363
d2 = 128123077977192654363625267794196093807822167226787910517707831000647694482505276949849557468848783716969216000696361713483061913911056125016805756678246997986564096953108078402006190942204043863504411260447094651450959639804706733933715766872031586500081421541895517287106873169535969521415871912603075475717
#coppersmith
def small_roots(f, bounds, m=1, d=None):
    if not d:
        d = f.degree()
    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 []
R.<x,y>=Zmod(p)[]
f=(r1-r2)*(d1+x)*(d2+y)-(d2+y-d1-x)
x,y=small_roots(f,bounds=(2^246,2^246),m=1,d=4)[0]
secret=gmpy2.invert((d1+int(x)),p)-r1
print(secret)

LockByLock | 486.18 points

可以进行两次选择明文的交互,我们传入x与x^2,得到:

这里我们选择x=2,于是n可以通过下式求得:

这里factorb分解数据得到k=19,进而得到n,接下来离散对数解e1 e2,我印象里解离散对数问题的算法中比较良好的时间复杂度是:

这里带入数据上下界计算发现大概是10^7,花一点时间爆破应该刚好够,赛后跟其他师傅交流发现题目数据可能有不稳定的情况,而我跑了2为基底的情况后,感觉4为基底可能跑不完了,以为要遗憾淘汰了,但没想到g=4比g=2跑得快不少,不好说了(

print(discrete_log_lambda(msg11,mod(2,n),(10^14,10^15)))

e1 e2分解完,对flag的加密中:

共模攻击打一下就行了
exp:

msg11 = 1794037065126539344709827513870875601824463909545425363161090181645236962972601439811432804068116011703515479010066178183951543811567858716115397775601696586250751238048836176335563710062720152314952695172552300631634873491965931671234876069710033441874200597286683429309779514509458904025914459619800041221733103482428300283819126277520913231461576549164657206850420066502781169836109064162005584999895062382757986231892718209418618645988441074200197413536767014302312909752065707475461390723400228883379623020412701956953781010203223018442004523236622826528667582151426887075718119174774035860644014470966590975802
msg12 = 13372561492162662490198108768674310528593020119794032419004750985648318116271841964638742062795165047987771933477860152722924718358300878099111447788833579318530393511431217733502561319752865322123610394923539515952525214846801890494210917070938637554111876553082569757121246549241451619467544107379497756610373801717169562817121263686109185668308464756660717815734795273982823479351312529542393714719137768655623407551839578566891271267632749715747148645784769145648927439771323033846873448317209009456173056419039972206607046425995950105861300973064494056156633113411276436952763893418424202249454351546688654404953
msg21 = 6537372108796743816349279970840658262935842164022139282209658791070444542510382929354676384985614343804411272243139839539178609513956638902365607480933797943889490158554458926617628506257409237557027937874515482323685021229385883209703984657658796056895764507943132654011993887202753489902361405859001465320811274631072230080891104069082296590187555228741341339664838135361442915222986838956001015936813236953077436013702003963713581070718377210217171562567530254387567905199893164076312931663080714558456933863524605965385108232444366601662440602673237230688831006119860624257986896698095520364852275559492046629057
msg22 = 14162765263384855609742624396762174520381100032785739072359133120077396671821314891244869283003945049257615016603246461792633213742302834653474340795487606992959184899411054018211252990603284204354922994088758556532196236367171782699679992478575875272289351013057243363547438492400926509046507961218100001713801876052265361314376424580353733897120879549217936681066430064806210705930024240268940817877992717197640628718551890186732611165951739311245358643032160181658660842804068126323060957728930790862859761890035226697903299461558763050427020111561008020777135568233058375223050965002122628643606554254208475607035
n=GCD(msg11*msg11-msg21,msg12*msg12-msg22)//19

from gmpy2 import *
msg1 = 
msg3 = 
e1=197452731399259
e2=235676731995961
c1=msg1
c2=msg3
_, s1, s2 = gmpy2.gcdext(e1, e2)
m = pow(c1, s1, n) * pow(c2, s2, n)
m %= n
m = long_to_bytes(m)
print(m)


最后十分钟出了///

Ending

大起大落的比赛,太抓马了...感谢一起肝了一整天的队友们带我%%%

misc也做了点,wp就不放了,欢迎大家移步友链 https://zysgmzb.club/ ,商业互吹行为!(bushi)

posted @ 2023-02-03 11:49  App1e_Tree  阅读(265)  评论(0编辑  收藏  举报