backdoor++++++++++++++
给了原始签名恶意签名的r,可以看作为p1的x坐标
已知椭圆曲线参数可以恢复p1该点,利用原始签名的p1=k1*G可以计算出恶意签名中的
z = (k1 - w * t) * G + (-a * k1 - b) * Y
= p1 - w * G - a * X * p1 - b * Y
从而绕过k1直接得到z
rsa部分p为k2后第99个素数,q为第100素数,可以得到p,q,但flag为42字节,p*q为320比特,还需要爆破填充一下。
import tqdm
import hashlib
import gmpy2
from Crypto.Util.number import *
a, b, w, X = 751818, 1155982, 908970521, 20391992
message1 = b'It sounds as though you were lamenting,'
message2 = b'a butterfly cooing like a dove.'
hash_message1 = int(hashlib.sha1(message1).hexdigest(), 16)
hash_message2 = int(hashlib.sha1(message2).hexdigest(), 16)
n = 6277101735386680763835789423176059013767194773182842284081
c_a, c_b = -3, 2455155546008943817740293915197451784769108058161191238065
c_p = 6277101735386680763835789423207666416083908700390324961279
E = EllipticCurve(GF(c_p), [c_a, c_b])
G = E(602046282375688656758213480587526111916698976636884684818,
174050332293622031404857552280219410364023488927386650641)
r = 6052579169727414254054653383715281797417510994285530927615
PR.<y> = Zmod(c_p)[]
f = y*y-r**3-c_a*r-c_b
res = f.roots()
for y in res:
k1_G = E(r, y[0])
Y = X * G
z = k1_G - w * G - a * X * k1_G - b * Y
k2 = int(hashlib.sha1(str(z[0]).encode()).hexdigest(), 16)
p = k2
for i in range(99):
p = gmpy2.next_prime(p)
q = gmpy2.next_prime(p)
e = 65537
phi = (p - 1) * (q - 1)
c = 1294716523385880392710224476578009870292343123062352402869702505110652244504101007338338248714943
flag = int(pow(c, inverse_mod(e, phi), p * q))
for i in tqdm.tqdm(range(300000)):
flag += int(p * q)
m = long_to_bytes(int(flag))
if b'flag' in m:
print(m)
break
if len(m) > 42: break
# b'flag{0c75afae-f8ad-4df1-b2d9-a9ca348cb226}'