ctfshow crypto 红包四

from secrets import randbelow


g = 2
y = pow(g, k, p)

def gogogo():
    print("Another chance:")
    t = int(input('t = '))
    c = randbelow(p)
    print("Here is my real challenge:")
    print(f'c = {c}')
    print("Give me your answer.")
    s = int(input('s = '))
    return pow(g, s, p) == t * pow(y, c, p) % p

def dododo():
    print("Here is my gift for National's Day!")
    t = pow(g, r, p)
    print(f't = {t}')
    print("What do you want?")
    c = int(input('c = '))
    s = (r + c*k) % (p - 1)
    print("This is another gift:")
    print(f's = {s}')

print("Happy National's Day!")
print("Don't play CTF these days.")
print("Just go out and play~")
print("Don't finish this chall,")
print("although I should tell you that")
print(f"p = {p}")


dododo()

if gogogo():
    print(f"FUIYOH! You can get flag: {flag}")
    print("and then go out and play!")
else:
    print("HAIYAA! You are wrong. Just go out and play!")

 首先看到已知的就有g,p和t了

 其次是输入一个c输出一个s但输出s的等式中有未知量r,k

先令c=0得到

s = r mod (p-1)

p和s已知可求出r=214。再者求k

我们发现不同的c输出的s不同,两次输入不同的c(最简便就是c=1,2)输出不同s得到两条方程

s1=(r+k) mod (p-1)

s2=(r+2*k) mod (p-1)

下来就是解方程的问题

对用同一个k其他量都已知,可以利用

富兰克林-赖特 相关消息攻击

n = 7426377248993167316584923743580751815847513886893496504970559106442393387122038966319447136976391605077588023129643053040905007917383268935927643195922652
s1 = 5054994445577641800727381711603362275848730863034576085807905759367072227717066372846972765594223115536930251313835178715503900402305679456937779756304265
s2 = 2683611642162116284869839679625972735849947839175655666645252412291751068312093779374498394212054625996272479498027304390102792887228089977947916316685664
e = 1

R.<x> = PolynomialRing(Zmod(n))
g1 = (x+214)^e - s1
g2 = (2*x+214)^e - s2

def myGcd(x, y):
    if y == 0:
        return x.monic()
    return myGcd(y, x%y)

v = myGcd(g2, g1)
M = n - v.coefficients()[0]

assert g1(M) == 0
print(hex(M))

 改编于这位大佬的代码,具体可参考:

Coppersmith 攻击 (ruanx.net)

脚本在sage中运行,在线sage网站:

圣人细胞服务器 (sagemath.org)

转10进制得k=5054994445577641800727381711603362275848730863034576085807905759367072227717066372846972765594223115536930251313835178715503900402305679456937779756304051

 另外,我们知道k和p在靶机中是不会改变的

到此我们就求出了y的值

再看到gogogo子函数中,先是输入一个t然后生成一个int型的随机数c

最后输入s然后返回判断等式是否成立,成立则返回flag

return pow(g, s, p) == t * pow(y, c, p) % p

等式中有t和s要我们输入

t影响着s的值,所以令t=1使得运算更简便

这样就有pow(g,s,p)==pow(y,c,p)

而y=pow(g,k,p)

我们利用同余的性质

(g^c%p)^k%p=g^c^k%p

 这样就有:s=c*k

c和k已知

将s在靶机中输入得出flag

ctfshow{41d15e13-2f1a-460e-821c-75327dfc3cde}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sharpery

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值