MikroTikPatch/toyecc/DivisionPolynomial.py

68 lines
2.5 KiB
Python
Raw Permalink Normal View History

2024-06-15 02:18:14 +03:00
#
# toyecc - A small Elliptic Curve Cryptography Demonstration.
# Copyright (C) 2011-2022 Johannes Bauer
#
# This file is part of toyecc.
#
# toyecc is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; this program is ONLY licensed under
# version 3 of the License, later versions are explicitly excluded.
#
# toyecc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with toyecc; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Johannes Bauer <JohannesBauer@gmx.de>
#
from .Polynomial import Polynomial
class DivisionPolynomial(object):
def __init__(self, curve):
"""Creates a division polynomial generator which returns \psi_i for the
given curve in Weierstrass form."""
self._curve = curve
assert(self._curve.curvetype == "shortweierstrass")
self._cache = { }
self._curvepoly = None
self._initcache()
def _initcache(self):
(a, b) = (self.curve.a, self.curve.b)
x = Polynomial(self.curve.p)
self._cache[0] = Polynomial(self.curve.p, 0)
self._cache[1] = Polynomial(self.curve.p, 1)
self._cache[2] = Polynomial(self.curve.p, 2)
self._cache[3] = (3 * x**4) + (6 * a * x**2) + (12 * b * x) - (a**2)
self._cache[4] = 4 * (x**6 + (5 * a * x**4) + (20 * b * x**3) - (5 * a**2 * x**2) - (4 * a * b * x) - (8 * b**2) - (a**3))
self._curvepoly = x**3 + (a * x) + b
@property
def curve(self):
return self._curve
def __getitem__(self, index):
if index not in self._cache:
m = index // 2
if (index % 2) == 1:
# The paper says this would be correct:
# result = (self[m + 2] * self[m]**3) - (self[m - 1] * self[m + 1] ** 3)
# But MIRACL does it differently. Use the MIRACL approach:
if (m % 2) == 0:
result = (self._curvepoly**2 * self[m + 2] * self[m]**3) - (self[m - 1] * self[m + 1]**3)
else:
result = (self[m + 2] * self[m]**3) - (self._curvepoly**2 * self[m - 1] * self[m + 1]**3)
else:
result = (self[m] // 2) * ((self[m + 2] * self[m - 1]**2) - (self[m - 2] * self[m + 1]**2))
self._cache[index] = result
return self._cache[index]
def __str__(self):
return "DivisionPolys<%s, %d cached>" % (str(self.curve), len(self._cache))