根据对ECC的学习知道,我们常用的都是根据Weierstrass方程简化形式的曲线,实际上还存在其他形式的椭圆曲线。

参考:曲线 | Lazzaro (lazzzaro.github.io)

蒙哥马利曲线

蒙哥马利曲线(Montgomery Curves):

系数满足$B(A^2-4)\not =0$。

加法:

蒙哥马利曲线用来构造密码算法的实例是Curve25519。

映射到维尔斯特拉斯曲线:

爱德华曲线

爱德华曲线(Edwards Curves):

一般方程:

加法:

倍乘:

取反:

映射到蒙哥马利曲线:

扭曲爱德华曲线

扭曲爱德华曲线(Twisted Edwards Curves):

一般方程:

加法:

倍乘:

取反:

映射到蒙哥马利曲线:

Huff曲线

一般形式:

加法:

倍乘:

取反:

映射到蒙哥马利曲线:

题目

EdRSA

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
#sagemath
from Crypto.Util.number import *
from secrets import flag

def add(P, Q):
(x1, y1) = P
(x2, y2) = Q

x3 = (x1*y2 + y1*x2) * inverse(1 + d*x1*x2*y1*y2, p) % p
y3 = (y1*y2 - a*x1*x2) * inverse(1 - d*x1*x2*y1*y2, p) % p
return (x3, y3)

def mul(x, P):
Q = (0, 1)
while x > 0:
if x % 2 == 1:
Q = add(Q, P)
P = add(P, P)
x = x >> 1
return Q

p = 64141017538026690847507665744072764126523219720088055136531450296140542176327
a = 362
d = 7
gx=bytes_to_long(flag)
PR.<y>=PolynomialRing(Zmod(p))
f=(d*gx^2-1)*y^2+(1-a*gx^2)
gy=int(f.roots()[0][0])

assert (a*gx^2+gy^2)%p==(1+d*gx^2*gy^2)%p

G=(gx,gy)
e=0x10001
print("eG = {}".format(mul(e, G)))

#eG = (602246821311345089174443402780402388933602410138142480089649941718527311147, 17625197557740535449294773567986004828160284887369041337984750097736030549853)

根据assert (a*gx^2+gy^2)%p==(1+d*gx^2*gy^2)%p可以写出公式:

这是标准的扭曲爱德华曲线。题目加密为:

我们知道了$e,G’$,现在要求解$G$,如果我们能知道$e$在曲线阶下的逆元,那么就可以得到$G$,但是这里的扭曲爱德华曲线我们不能直接表示,所以思考可以通过还原将椭圆曲线映射成常见的椭圆曲线形式,就可以求出阶,并计算逆元得到flag了。

首先先转换为蒙哥马利曲线方程,然后转化为Weierstrass椭圆曲线方程。

利用标准椭圆曲线方程形式,就可以用sage求解椭圆曲线阶,解得原点$G$,再逆变换成Edcurve,横坐标即为flag。

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
# sagemath
from Crypto.Util.number import *

p = 64141017538026690847507665744072764126523219720088055136531450296140542176327
a = 362
d = 7
c = 1
e = 0x10001

eG = (
602246821311345089174443402780402388933602410138142480089649941718527311147,
17625197557740535449294773567986004828160284887369041337984750097736030549853,
)
F = GF(p)

A = (2 * (a + d)) / (a - d)
B = 4 / (a - d)
a = (3 - A ^ 2) / (3 * B ^ 2)
b = (2 * A ^ 3 - 9 * A) / (27 * B ^ 3)


def TEd_to_ECC(x, y):
x1 = F(1 + y) / F(1 - y)
y1 = F(x1) / F(x)
u = F(x1) / F(B) + F(A) / F(3 * B)
v = F(y1) / F(B)
return (u, v)


def ECC_to_TEd(x, y):
x1 = F(B) * F(x) - F(A) / F(3)
y1 = F(B) * F(y)
u = F(x1) / F(y1)
v = (F(x1) - F(1)) / (F(x1) + F(1))
return (u, v)


E = EllipticCurve(F, [a, b])
o = E.order()
eG = E(TEd_to_ECC(eG[0], eG[1]))
t = inverse(e, o)
G = ECC_to_TEd((t * eG)[0], (t * eG)[1])

print(long_to_bytes(int(G[0])))