[GUET-CTF2019]Uncle Sam

写这题的时侯迷迷糊糊才写出来的,不过不知道为什么看到这题给出的式子很容易就想到了费马定理(大概是印象太深刻了吧,昨天也是一道要用到费马定理的题)。

[GUET-CTF2019]Uncle Sam

pubkey可以进行因式分解得到p,q。

根据代码有如下公式:
e n c = m p 2 ∗ q ( m o d   p 2 ∗ q ) enc = m^{p^2*q}\quad(mod\ p^2*q) enc=mp2q(mod p2q)
将该公式拆解,再利用费马定理化简:
{ c 1 ≡ e n c ≡ m p 2 ∗ q ≡ m q ( m o d   p ) c 2 ≡ e n c ≡ m p 2 ∗ q ≡ m p 2 ( m o d   q ) \begin {cases} c1 ≡ enc ≡ m^{p^2*q}≡m^q\quad (mod\ p) \\ c2 ≡ enc ≡ m^{p^2*q} ≡ m^{p^{2}}\quad (mod\ q) \end{cases} {c1encmp2qmq(mod p)c2encmp2qmp2(mod q)
因为p,q互质,所以可以通过求逆来解出m1,m2(求出的是m,为了区分两个式子求出的m),然后得到如下式子:
{ m ≡ m 1 ( m o d   p ) m ≡ m 2 ( m o d   q ) \begin{cases} m ≡ m1\quad (mod\ p) \\ m ≡ m2\quad (mod\ q) \end{cases} {mm1(mod p)mm2(mod q)
这不就可以利用中国剩余定理求解m吗?

代码如下:

import gmpy2,libnum
from Crypto.Util.number import *

pubkey =  2188967977749378274223515689363599801320698247938997135947965550196681836543275429767581633044354412195352229175764784503562989045268075431206876726265968368605210824232207290410773979606662689866265612797103853982014198455433380266671856355564273196151136025319624636805659505233975208570409914054916955097594873702395812044506205943671404203774360656553350987491558491176962018842708476009578127303566834534914605109859995649555122751891647040448980718882755855420324482466559223748065037520788159654436293431470164057490350841209872489538460060216015196875136927502162027562546316560342464968237957692873588796640619530455268367136243313422579857823529592167101260779382665832380054690727358197646512896661216090677033395209196007249594394515130315041760988292009930675192749010228592156047159029095406021812884258810889225617544404799863903982758961208187042972047819358256866346758337277473016068375206319837317222523597
privkey = 1430375790065574721602196196929651174572674429040725535698217207301881161695296519567051246290199551982286327831985649037584885137134580625982555634409225551121712376849579015320947279716204424716566222721338735256648873164510429206991141648646869378141312253135997851908862030990576004173514556541317395106924370019574216894560447817319669690140544728277302043783163888037836675290468320723215759693903569878293475447370766682477726453262771004872749335257953507469109966448126634101604029506006038527612917418016783711729800719387298398848370079742790126047329182349899824258355003200173612567191747851669220766603
enc = 1491421391364871767357931639710394622399451019824572362288458431186299231664459957755422474433520889084351841298056066100216440853409346006657723086501921816381226292526490195810903459483318275931326433052468863850690793659405367902593999395060606972100169925074005992478583035226026829214443008941631771292291305226470216430735050944285543542354459162474346521327649934512511202470099020668235115245819634762067338432916012664452035696422865651002305445711778476072004708256200872226475346448360491248823843688268126341094612981308791499434770936360676087490303951728563482686307164877000300082742316368597958297217061375140696272398140310043942637287763946305961019518639745426370821124559939597559475362769382796386720030343305889701616194279058139516811941262747298761646317383112470923295543635754747288259324745583689440061956478083777663996487389553238481759103908588004219390662578446313004404784835263543083088327198
p = 128194403049680759730417456073484146647356572995921713843464320871713147845377732806963342042934962454134027743097600387979308508723555742581738982465486376489529245549008462953454385367577100489297368340937113649234808638010260771764118502798523641102975042512421309736174582209335248607849222488552635035711
q = 133199096697970395010360601752123884484750642911271667153329616708900276095359262125870755605084831227824337829042027891279415798701328111263867626754073487492338827458300240653837593442381578663683707324178792275270673229517518047914128590838435632554611499345291692417044388509949314333019317417383181850957
'''#此部分一开始利用中国剩余定理没解出来,后来才发现m2 = pow(c2,d2,q) 写成了 m2 = pow(c2,d2,q-1),
   #虽然两者的过程有点不同,但思路是一样的
l = (p-1)*(q-1) / gmpy2.gcd(p-1, q-1)
phi = p*(p-1)*(q-1)

d = gmpy2.invert(pubkey//p//p,phi)
m = pow(enc,d,pubkey)#M = m^(p**2)
c1 = m%p
c2 = m%q

m1 = c1
d2 = gmpy2.invert(p**2,q-1)
m2 = pow(c2,d2,q)
print(m1 == m2)#True
print(long_to_bytes(m1))#flag
'''
c1 = enc%p
c2 = enc%q
d1 = gmpy2.invert(q,p-1)
m1 = pow(c1,d1,p)
d2 = gmpy2.invert(p**2,q-1)
m2 = pow(c2,d2,q)
#print(m1,m2)#m1 == m2
#print(long_to_bytes(m1),long_to_bytes(m2))#flag

def broadcast_attack(data):
    def extended_gcd(a,b):
        x,y = 0,1
        lastx,lasty = 1,0
        while b:
            a,(q,b) = b,divmod(a,b)
            x,lastx = lastx-q*x,x
            y,lasty = lasty-q*y,y
        return (lastx,lasty,a)
    def chinese_remaindor_theorem(items):
        N = 1
        for a,n in items:
            N *= n
        result = 0
        for a,n in items:
            m = N//n
            r,s,d = extended_gcd(n,m)
            if d != 1:
                N = N//n
                continue
            result += a*s*m
        return result%N ,N
    x,n = chinese_remaindor_theorem(data)
    #m = int(gmpy2.iroot(x,3)[0])
    return x

data = [(m1,p),(m2,q)]
print(long_to_bytes(broadcast_attack(data)))
#b'flag{61e19444-7afb-11e9-b704-4ccc6adfc6f0}'
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值