Tover说不想出题了,我把他上年的防AK题改了一下(逃
随机数生成器就是逊啦,xor yyds!
题目附件:
#sage
from secret import flag
import random
bits = 64
p = random_prime(2^bits)
a = randint(1, bits)
b = randint(1, bits)
E = EllipticCurve(GF(p), [a, b])
g = E.random_element()
x = random_prime(2^16)
pk = x*g
k = randint(1, p-1)
kPoint = k*pk
kp = kPoint.xy()
c = []
for i in range(len(flag)):
c.append( (ord(flag[i]) ^^ int(kp[i%2])) & 0xff )
c = bytes(c).hex()
print(p)
print(a)
print(b)
print(g)
#print(g.order())
print(c)
'''
4698491801183562589
58
59
(2965797230620625775 : 4310564666276679314 : 1)
ac73a774a25bd512d543dc468542c9428141800dd041d043c918d112850dd515d6128214d1138211d71599
'''
大概看下程序逻辑,初始化一条椭圆曲线 E
,然后取随机点,进行随机乘法计算,得到曲线上一个点 kp
包含两个分量。
加密过程很简单,就是将flag中第i个字符与 kp
的两个分量进行异或得到密文。
- 如果i是偶数,则 c i = m i ⨁ k p x c_i=m_i \bigoplus kp_x ci=mi⨁kpx
- 如果i是奇数,则 c i = m i ⨁ k p y c_i=m_i \bigoplus kp_y ci=mi⨁kpy
注意到本题有个特殊条件,flag开头只可能是 HS
或 hs
,于是可以直接枚举出 kp
进行解密。椭圆曲线的条件用不到。
最终exp:
c = 'ac73a774a25bd512d543dc468542c9428141800dd041d043c918d112850dd515d6128214d1138211d71599'
c = bytes.fromhex(c)
# assume HSCTF{... ...}
key = [c[0]^ord('H'), c[1]^ord('S')]
flag = ''
for i in range(len(c)):
flag += chr(c[i] ^ key[i%2])
print(flag)