In the halloween party, we want to half a delicious but small cake!
flag = ASIS{P.x}
#!/usr/bin/env python from fastecdsa.curve import Curve from fastecdsa.point import Point from Crypto.Util.number import * from secret import EC_params, flag, Q p, a, b, q, Px, Py = EC_params C = Curve('halloween', p, a, b, q, Px, Py) P = Point(Px, Py, curve = C) P1 = Point(p + 1, 467996041489418065436268622304855825266338280723, curve = C) P2 = Point(p - 1, 373126988100715326072483107245781156204485119489, curve = C) P3 = Point(p + 3, 245091091146774561796627894715885724307214901148, curve = C) assert ((9<<8>>4<<9<<12<<6>>9>>2<<5>>3>>4>>8<<12>>1>>5>>7<<13>>12>>12) * P).x == Q.x assert bytes_to_long(flag) == P.x assert ((-1) * Q).y == 621803439821606291947646422656643138592770518069
どこからどう見てもEllipticCurveの問題。一瞬sageにみえるけどfastecdsaというライブラリを使っている。P.xを求めるのが目的で、Pの前後のいくつかの点の存在と、Pを何倍かした点Qの存在が明らかになっている。
find parameters
とにかくa, b, pの値くらいは求めないと楕円曲線に辿り着けない。P1, P2, P3から式が立つ。楕円曲線の式はなのでここに変数を当てはめる
適当に開いて で消えるところを消してみる
になるので、 となるはず。というわけで factordb に投げると
がわかる
Find Q
剰余方程式を解くテクを使って (-) Qを求める
Q.x, Q.y には という関係があるので、
の根を求めれば良い。
Find P
あとは 楕円曲線:逆数をかける をやるだけ
from sage.all import * y1 = 467996041489418065436268622304855825266338280723 y2 = 373126988100715326072483107245781156204485119489 y3 = 245091091146774561796627894715885724307214901148 # p = factor(2 * (y1**2) - (y2**2) - (y3**2) + 24) from factordb p = 883097976585278660619269873521314064958923370261 A = (((y1**2) - (y2**2) - 2 ) // 2) % p B = (((y1**2) + (y2**2)) // 2) % p iQy = 621803439821606291947646422656643138592770518069 _, x = PolynomialRing(GF(p), name="x").objgen() f = x**3 + A*x + B - iQy**2 iQx = int(f.roots()[0][0]) EC = EllipticCurve(GF(p), [A, B]) P2 = EC((iQx, iQy)) P = inverse_mod(2, EC.order()) * P2 print(P)
https://blog.bi0s.in/2019/04/23/Crypto/Elliptic-Curves/asis-quals19-halloween-party/