aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2020-03-16 20:44:22 +0100
committerJ08nY2020-03-16 20:44:22 +0100
commitc2b75500aa3dbcb0d2367439e29d33440bf77688 (patch)
treeb91c1b3fe8efb085aed14e51600fa88a35b15772
parent9d4d881d6d847b044959b3c080dac1c9488445e8 (diff)
downloadpyecsca-c2b75500aa3dbcb0d2367439e29d33440bf77688.tar.gz
pyecsca-c2b75500aa3dbcb0d2367439e29d33440bf77688.tar.bz2
pyecsca-c2b75500aa3dbcb0d2367439e29d33440bf77688.zip
Add curve transformations M2SW and M2TE.
-rw-r--r--Makefile2
-rw-r--r--pyecsca/ec/transformations.py71
-rw-r--r--test/ec/test_transformations.py18
3 files changed, 90 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index bd30ab1..5aeb2ed 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
EC_TESTS = ec.test_context ec.test_configuration ec.test_curve ec.test_formula \
ec.test_params ec.test_key_agreement ec.test_key_generation ec.test_mod ec.test_model \
-ec.test_mult ec.test_naf ec.test_op ec.test_point ec.test_signature
+ec.test_mult ec.test_naf ec.test_op ec.test_point ec.test_signature ec.test_transformations
SCA_TESTS = sca.test_align sca.test_combine sca.test_edit sca.test_filter sca.test_match sca.test_process \
sca.test_sampling sca.test_target sca.test_test sca.test_trace sca.test_traceset sca.test_plot
diff --git a/pyecsca/ec/transformations.py b/pyecsca/ec/transformations.py
new file mode 100644
index 0000000..1363483
--- /dev/null
+++ b/pyecsca/ec/transformations.py
@@ -0,0 +1,71 @@
+from public import public
+
+from .coordinates import AffineCoordinateModel
+from .curve import EllipticCurve
+from .model import ShortWeierstrassModel, MontgomeryModel, TwistedEdwardsModel
+from .params import DomainParameters
+from .point import InfinityPoint, Point
+
+
+def __M_map(params, map_parameters, map_point, model):
+ A = params.curve.parameters["a"]
+ B = params.curve.parameters["b"]
+ parameters = map_parameters(A, B)
+ aff = AffineCoordinateModel(model)
+ if isinstance(params.curve.neutral, InfinityPoint):
+ neutral = InfinityPoint(aff)
+ else:
+ neutral = map_point(A, B, params.curve.neutral, aff)
+ curve = EllipticCurve(model, aff, params.curve.prime, neutral, parameters)
+ return DomainParameters(curve, map_point(A, B, params.generator, aff), params.order,
+ params.cofactor)
+
+
+@public
+def M2SW(params: DomainParameters) -> DomainParameters:
+ """
+ Convert a Montgomery curve to ShortWeierstrass.
+
+ :param params: The domain parameters to convert.
+ :return: The converted domain parameters.
+ """
+ if not isinstance(params.curve.model, MontgomeryModel) or not isinstance(
+ params.curve.coordinate_model, AffineCoordinateModel):
+ raise ValueError
+
+ def map_parameters(A, B):
+ a = (3 - A ** 2) / (3 * B ** 2)
+ b = (2 * A ** 3 - 9 * A) / (27 * B ** 3)
+ return {"a": a, "b": b}
+
+ def map_point(A, B, pt, aff):
+ u = pt.x / B + A / (3 * B)
+ v = pt.y / B
+ return Point(aff, x=u, y=v)
+
+ return __M_map(params, map_parameters, map_point, ShortWeierstrassModel())
+
+
+@public
+def M2TE(params: DomainParameters) -> DomainParameters:
+ """
+ Convert a Montgomery curve to TwistedEdwards.
+
+ :param params: The domain parameters to convert.
+ :return: The converted domain parameters.
+ """
+ if not isinstance(params.curve.model, MontgomeryModel) or not isinstance(
+ params.curve.coordinate_model, AffineCoordinateModel):
+ raise ValueError
+
+ def map_parameters(A, B):
+ a = (A + 2) / B
+ d = (A - 2) / B
+ return {"a": a, "d": d}
+
+ def map_point(A, B, pt, aff):
+ u = pt.x / pt.y
+ v = (pt.x - 1) / (pt.x + 1)
+ return Point(aff, x=u, y=v)
+
+ return __M_map(params, map_parameters, map_point, TwistedEdwardsModel())
diff --git a/test/ec/test_transformations.py b/test/ec/test_transformations.py
new file mode 100644
index 0000000..2f2383c
--- /dev/null
+++ b/test/ec/test_transformations.py
@@ -0,0 +1,18 @@
+from unittest import TestCase
+
+from pyecsca.ec.params import get_params
+from pyecsca.ec.transformations import M2SW, M2TE
+
+
+class TransformationTests(TestCase):
+
+ def test_montgomery(self):
+ curve25519 = get_params("other", "Curve25519", "affine")
+ sw = M2SW(curve25519)
+ self.assertIsNotNone(sw)
+ self.assertTrue(sw.curve.is_on_curve(sw.generator))
+ self.assertTrue(sw.curve.is_neutral(sw.curve.neutral))
+ te = M2TE(curve25519)
+ self.assertIsNotNone(te)
+ self.assertTrue(te.curve.is_on_curve(te.generator))
+ self.assertTrue(te.curve.is_neutral(te.curve.neutral))