from secrets import randbelow
from nationalsecret import p, r, k, flag
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!")
以上为加密代码,再gogogo这段代码里,只要return的结果为真,也就是
pow(g, s, p) == t * pow(y, c, p) % p 的时候,会返回flag,仔细审题,发现这其实是一道deffie-hellman的现代密码题目
再来回顾一下现代密码,假设有Alice 和 Bob两个人,各自生成一个a和b,求出A=pow(g,a,p)
和B=pow(g,b,p),则key=pow(A,b,p)=pow(B,a,p)
这里看看return后的内容,如果y相当于A,c相当于b,pow(y,c,p)相当于pow(B,a,p)那么前面的pow(g,s,p)就相当于pow(A,b,p)
已知y=pow(g,k,p),根据同余性质可知
所以我们令t=1,s=ck。c给出来了,我们求k
dododo代码块就是让我们来求k的,首先我们让c=0,得到r=224,然后再运行一次这个代码,这一次让c=1,得到r+k=5551628413330011871077674605450526902698282945776482884041995095432548061898021904002453319462057630031351641808008288358761268961670548566575970336145746
得到k=5551628413330011871077674605450526902698282945776482884041995095432548061898021904002453319462057630031351641808008288358761268961670548566575970336145522
s=ck,输进去,得到