mirror of
https://github.com/elseif/MikroTikPatch.git
synced 2025-01-23 21:44:59 +03:00
133 lines
4.1 KiB
Python
133 lines
4.1 KiB
Python
|
#
|
||
|
# 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>
|
||
|
#
|
||
|
|
||
|
import math
|
||
|
|
||
|
from .FieldElement import FieldElement
|
||
|
from .PointOps import PointOpEDDSAEncoding, PointOpCurveConversion, PointOpNaiveOrderCalculation, PointOpSerialization, PointOpScalarMultiplicationXOnly
|
||
|
|
||
|
class AffineCurvePoint(PointOpEDDSAEncoding, PointOpCurveConversion, PointOpNaiveOrderCalculation, PointOpSerialization, PointOpScalarMultiplicationXOnly):
|
||
|
"""Represents a point on a curve in affine (x, y) representation."""
|
||
|
|
||
|
def __init__(self, x, y, curve):
|
||
|
"""Generate a curve point (x, y) on the curve 'curve'. x and y have to
|
||
|
be integers. If the neutral element of the group O (for some curves,
|
||
|
this is a point at infinity) should be created, use the static method
|
||
|
'neutral', since representations of O differ on various curves (e.g. in
|
||
|
short Weierstrass curves, they have no explicit notation in affine
|
||
|
space while on twisted Edwards curves they do."""
|
||
|
# Either x and y are None (Point at Infty) or both are defined
|
||
|
assert(((x is None) and (y is None)) or ((x is not None) and (y is not None)))
|
||
|
assert((x is None) or isinstance(x, int))
|
||
|
assert((y is None) or isinstance(y, int))
|
||
|
if x is None:
|
||
|
# Point at infinity
|
||
|
self._x = None
|
||
|
self._y = None
|
||
|
else:
|
||
|
self._x = FieldElement(x, curve.p)
|
||
|
self._y = FieldElement(y, curve.p)
|
||
|
self._curve = curve
|
||
|
|
||
|
@staticmethod
|
||
|
def neutral(curve):
|
||
|
"""Returns the neutral element of the curve group."""
|
||
|
return curve.neutral()
|
||
|
|
||
|
@property
|
||
|
def is_neutral(self):
|
||
|
"""Indicates if the point is the neutral element O of the curve (point
|
||
|
at infinity for some curves)."""
|
||
|
return self.curve.is_neutral(self)
|
||
|
|
||
|
@property
|
||
|
def x(self):
|
||
|
"""Affine X component of the point, field element of p."""
|
||
|
return self._x
|
||
|
|
||
|
@property
|
||
|
def y(self):
|
||
|
"""Affine Y component of the point, field element of p."""
|
||
|
return self._y
|
||
|
|
||
|
@property
|
||
|
def curve(self):
|
||
|
"""Curve that the point is located on."""
|
||
|
return self._curve
|
||
|
|
||
|
def __add__(self, other):
|
||
|
"""Returns the point addition."""
|
||
|
assert(isinstance(other, AffineCurvePoint))
|
||
|
return self.curve.point_addition(self, other)
|
||
|
|
||
|
def __rmul__(self, other):
|
||
|
return self * other
|
||
|
|
||
|
def __neg__(self):
|
||
|
"""Returns the conjugated point."""
|
||
|
return self.curve.point_conjugate(self)
|
||
|
|
||
|
def __mul__(self, scalar):
|
||
|
"""Returns the scalar point multiplication. The scalar needs to be an
|
||
|
integer value."""
|
||
|
assert(isinstance(scalar, int))
|
||
|
assert(scalar >= 0)
|
||
|
|
||
|
result = self.curve.neutral()
|
||
|
n = self
|
||
|
if scalar > 0:
|
||
|
for bit in range(scalar.bit_length()):
|
||
|
if (scalar & (1 << bit)):
|
||
|
result = result + n
|
||
|
n = n + n
|
||
|
#assert(result.oncurve())
|
||
|
return result
|
||
|
|
||
|
def __eq__(self, other):
|
||
|
return (self.x, self.y) == (other.x, other.y)
|
||
|
|
||
|
def __ne__(self, other):
|
||
|
return not (self == other)
|
||
|
|
||
|
def __hash__(self):
|
||
|
return hash((self.x, self.y))
|
||
|
|
||
|
def oncurve(self):
|
||
|
"""Indicates if the given point is satisfying the curve equation (i.e.
|
||
|
if it is a point on the curve)."""
|
||
|
return self.curve.oncurve(self)
|
||
|
|
||
|
def compress(self):
|
||
|
"""Returns the compressed point format (if this is possible on the
|
||
|
given curve)."""
|
||
|
return self.curve.compress(self)
|
||
|
|
||
|
def __repr__(self):
|
||
|
return str(self)
|
||
|
|
||
|
def __str__(self):
|
||
|
if self.is_neutral:
|
||
|
return "(neutral)"
|
||
|
else:
|
||
|
return "(0x%x, 0x%x)" % (int(self.x), int(self.y))
|