Skip to content

Commit 9fd7921

Browse files
committed
Add algorithm/monodromy
1 parent f3159af commit 9fd7921

2 files changed

Lines changed: 55 additions & 0 deletions

File tree

algorithm/monodromy/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Montgomery curve における division polynomial と doubling formula の関係
2+
3+
## 結論
4+
Montgomery 曲線 $y^2 = x^3 + Ax^2 + x$ において、doubling formula は division polyomials を尊重する。
5+
6+
7+
## 注意点
8+
9+
`division_polynomial` で division polynomial を計算する際、m が偶数の場合 `two_torsion_multiplicity` に注意すること。
10+
```python
11+
sage: E.division_polynomial(2, two_torsion_multiplicity=0) # division polynomial / (2y)
12+
1
13+
sage: E.division_polynomial(2, two_torsion_multiplicity=1) # 本来の division polynomial
14+
2*y
15+
sage: E.division_polynomial(2, two_torsion_multiplicity=2) # division polynomial * 2y
16+
4*x^3 + 4*a*x^2 + 4*x
17+
```
18+
これは m が偶数の場合に division polynomial が x の多項式にならず y * (x の多項式) になってしまうことの対策と思われる。今回欲しいのは $\psi_n^2$ でありこれは常に x の多項式であるため問題はないが、 `division_polynomial` の呼び出し方には気をつける必要がある。主な対策法は 2 種類ある。
19+
1. 常に `two_torsion_multiplicity=1` で呼び出して計算し、最終的に $y^2 - f(x)$ で割った余りをとる。
20+
2. `two_torsion_multiplicity=2``two_torsion_multiplicity=0` を半々で呼び出し、因子の乗除の影響を取り去りながら x の多項式だけで処理する。
21+
22+
今回は 2. を採用する。
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
R.<x,a> = PolynomialRing(QQ, 'x,a')
2+
3+
def psi2(E, n: int):
4+
return E.division_polynomial(n, x=x, two_torsion_multiplicity=0) \
5+
* E.division_polynomial(n, x=x, two_torsion_multiplicity=2)
6+
7+
def phi(E, n: int):
8+
first = x * psi2(E, n)
9+
second = E.division_polynomial(n + 1, x=x, two_torsion_multiplicity=0) \
10+
* E.division_polynomial(n - 1, x=x, two_torsion_multiplicity=2)
11+
return first - second
12+
13+
14+
if __name__ == "__main__":
15+
E = EllipticCurve([0, a, 0, 1, 0])
16+
for n in range(2, 10):
17+
print(f'{n = }')
18+
if n == 2:
19+
print(' psi_{2*n}^2 =', psi2(E, 2*n))
20+
print(f' phi_{2*n} =', phi(E, 2*n))
21+
phi_n = phi(E, n)
22+
psi_n_2 = psi2(E, n)
23+
if n == 2:
24+
print(f' psi_{n}^2 =', psi_n_2)
25+
print(f' phi_{n} =', phi_n)
26+
dbl_z = 4 * phi_n * (phi_n * phi_n + a * phi_n * psi_n_2 + psi_n_2 ** 2) * psi_n_2
27+
if n == 2:
28+
print(f' DBL_z(phi_{n}, psi_{n}^2) =', dbl_z)
29+
print(f' {psi2(E, 2*n) == dbl_z = }')
30+
dbl_x = (phi_n ** 2 - psi_n_2 ** 2) ** 2
31+
if n == 2:
32+
print(f' DBL_x(phi_{n}, psi_{n}^2) =', dbl_x)
33+
print(f' {phi(E, 2*n) == dbl_x = }')

0 commit comments

Comments
 (0)