1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
| from Crypto.Util.number import * from sage.all import * from pwn import remote, process from tqdm import trange
''' step 1''' def solvep(x,y): from functools import reduce
A=[] for i in range(len(x)-2): A.append(abs((x[i+1]-x[i])*(pow(y[i+2],2)-pow(y[i+1],2)-pow(x[i+2],3)+pow(x[i+1],3))-(x[i+2]-x[i+1])*(pow(y[i+1],2)-pow(y[i],2)-pow(x[i+1],3)+pow(x[i],3)))) return reduce(GCD, A)
def solvea(x,y,p): return ((pow(y[1],2)-pow(y[0],2)-pow(x[1],3)+pow(x[0],3))*inverse(x[1]-x[0],p))%p
def solveb(x,y,p,a): return (pow(y[0],2)-pow(x[0],3)-a*x[0])%p
R = [(171819077447104349729775318230128610329, 100881689251479188167408877430920651395), (146159606192758583249716113758919783753, 80533281247513973659122060089873270989), (59017974640689970995344196273079355184, 104746038157191809171185097730819308641), (197595545243296583966922301250921927421, 124928953110104935664793476365310710267), (73968574145300091693338909355207503860, 186652589263761044876849068334695198879), (235827423492689864475083287633450448774, 172913282150535116698543986314403198219), (108003866338161147025654122299627959057, 106135106599969220245633457159754254343), (147930291615697867998498043226133690759, 166883835501879812581658678603301948629)] X = [i[0] for i in R] Y = [i[1] for i in R] p = solvep(X, Y) // 2 assert isPrime(p) a = solvea(X, Y, p) b = solveb(X,Y,p,a)
E = EllipticCurve(GF(p), [a, b]) for i in R: print(E(i))
print(a, b, p) ''' a = 190000065892557574829635621682189530240 b = 5554245539026928962619432281074770856 p = 239475380061526138915008749403622049527 '''
''' step 2'''
a = 190000065892557574829635621682189530240 b = 5554245539026928962619432281074770856 p = 239475380061526138915008749403622049527
E = EllipticCurve(GF(p), [a, b]) P = E.lift_x(Integer(0x1337))
def SmartAttack(P, Q, p): E = P.curve() Eqp = EllipticCurve(Qp(p, 2), [ ZZ(t) + randint(0,p)*p for t in E.a_invariants() ])
P_Qps = Eqp.lift_x(ZZ(P.xy()[0]), all=True) for P_Qp in P_Qps: if GF(p)(P_Qp.xy()[1]) == P.xy()[1]: break
Q_Qps = Eqp.lift_x(ZZ(Q.xy()[0]), all=True) for Q_Qp in Q_Qps: if GF(p)(Q_Qp.xy()[1]) == Q.xy()[1]: break
p_times_P = p*P_Qp p_times_Q = p*Q_Qp
x_P,y_P = p_times_P.xy() x_Q,y_Q = p_times_Q.xy()
phi_P = -(x_P/y_P) phi_Q = -(x_Q/y_Q) k = phi_Q/phi_P return ZZ(k)
while 1: r = remote('node8.anna.nssctf.cn', 26520) out = [] for i in trange(128): r.sendlineafter(b'[?] ', str(2**i)) Q = E(eval(r.recvline().split(b'] ')[-1])) out.append(SmartAttack(P, Q, p))
t = 64 if len(out) != 2 * t: print(f"[!] 错误: 你需要在 'out' 列表中提供 {2*t} 个值。") print(f"[!] 当前列表有 {len(out)} 个值。") exit()
Fp = GF(p) g = Fp(2)
try: v = vector(Fp, [int(val) for val in out]) print(f"[+] 成功加载 {len(v)} 个 oracle 输出值。") except (ValueError, TypeError) as e: print(f"[!] 错误: 无法将 'out' 列表中的值转换为整数。请检查你的输入。") print(f"[!] 原始错误: {e}") exit()
print("[+] 正在构建汉克尔矩阵并求解线性方程组...") M = Matrix(Fp, t, t, lambda i, j: v[i+j])
if M.is_singular(): print("[!] 矩阵 M 不可逆,可能的原因是你的输入数据有误,或者需要更换基数 g。") exit()
b = -vector(Fp, [v[i+t] for i in range(t)]) lambda_coeffs = M.solve_right(b) print("[+] 定位多项式系数求解成功!")
Rz = Fp['z'] z = Rz.gen() Lambda = z**t + sum(lambda_coeffs[i] * z**i for i in range(t))
print("[+] 正在求解定位多项式的根...") roots_m = Lambda.roots(multiplicities=False)
print("[+] 正在通过离散对数恢复指数 B_i...") exponents_B = [log(m, g) for m in roots_m]
print("[+] 正在构建范德蒙德矩阵以求解系数 A_i...") V = Matrix(Fp, t, t, lambda j, i: g**(j * exponents_B[i]))
if V.is_singular(): print("[!] 范德蒙德矩阵 V 不可逆,这通常不应该发生。") exit()
v_sub = v[:t] coeffs_A = V.solve_right(v_sub) print("[+] 所有系数 A_i 恢复成功!")
term_map = {int(B): A for B, A in zip(exponents_B, coeffs_A)} A = [i[1] for i in term_map.items()] t = str(choice(A)).encode() print(t) r.sendlineafter(b"[*]", t) try: flag = r.recvline() if flag: print(flag) break except: r.close() pass
|