task.sage
from Crypto.Util.number import *
import numpy as np
mark = 3**66
def get_random_prime():
total = 0
for i in range(5):
total += mark**i * getRandomNBitInteger(32)
fac = str(factor(total)).split(" * ")
return int(fac[-1])
def get_B(size):
x = np.random.normal(0, 16, size)
return np.rint(x)
p = get_random_prime()
q = get_random_prime()
N = p * q
e = 127
flag = b"N1CTF{************************************}"
secret = np.array(list(flag))
upper = 152989197224467
A = np.random.randint(281474976710655, size=(e, 43))
B = get_B(size=e).astype(np.int64)
linear = (A.dot(secret) + B) % upper
result = []
for l in linear:
result.append(pow(l, e, N))
print(result)
print(N)
np.save("A.npy", A)
代码审计后发现首先要分解N然后还原linear.
从而得到一个LWE问题.(c=a*s+e mod p)
进而尝试解出secret
记第一次得到的随机值为gen_p 第二次得到的随机值为gen_q
易得: g e n p = k 1 ∗ p , g e n q = k 2 ∗ q gen_p=k1*p, gen_q=k2*q genp=k1∗p,genq=k2∗q
记 x = 3 66 x=3^{66} x=366
于是可以得到:
a ∗ b ∗ N = m 8 x 8 + m 7 x 7 + m 6 x 6 + m 5 x 5 + m 4 x 4 + m 3 x 3 + m 2 x 2 + m 1 x + m 0 a * b * N = m_8x^8 + m_7x^7 + m_6x^6 + m_5x^5 + m_4x^4 + m_3x^3 + m_2x^2 + m_1x +m_0 a∗b∗N=m8x8+m7x7+m6x6+m5x5+m4x4+m3x3+m2x2+m1x+m