0x00 前言
CTF 加解密合集:CTF 加解密合集
0x01 题目
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!")
0x02 Write Up
这道题实际上是考察对于数论的理解程度,首先看到结果,首先看到
pow(g, s, p) == t * pow(y, c, p) % p
并且y = pow(g, k, p)
然后进行化简
pow(g, s, p) == pow(y, c, p)
等价于
pow(g, s, p) == pow(pow(g, k, p), c, p)
等价于
pow(g, s, p) == pow(g, k * c, p)
等价于
s = k * c
那么就是说我们只要知道了k和c就知道了结果。
c是已知的,只需要算k即可。
s = (r + c*k) % (p - 1) 此时c为0的时候,可以得到s的值,并且可以计算出r的值。
得到r的值之后,再代入即可得到:
k=p-1+s-r
最终可得到答案:
以上