From c4b98adbb7c9898dc830b9c6f4b1f52890a17632 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 20 Apr 2019 21:41:47 +0200 Subject: Add point conversion. --- README.md | 2 +- pyecsca/ec/point.py | 37 +++++++++++++++++++++++--------- test/ec/test_point.py | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 test/ec/test_point.py diff --git a/README.md b/README.md index 9f53ef0..3c7bd1f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ![](docs/_static/logo_black_small.png) pyecsca [pɪɛtska] -[![Build Status](https://travis-ci.org/J08nY/pyecsca.svg?branch=master)](https://travis-ci.org/J08nY/pyecsca) +[![Build Status](https://travis-ci.org/J08nY/pyecsca.svg?branch=master)](https://travis-ci.org/J08nY/pyecsca) ![License: MIT](https://img.shields.io/github/license/J08nY/pyecsca.svg) **Py**thon **E**lliptic **C**urve cryptography **S**ide-**C**hannel **A**nalysis toolkit. diff --git a/pyecsca/ec/point.py b/pyecsca/ec/point.py index 052165f..b11c3f1 100644 --- a/pyecsca/ec/point.py +++ b/pyecsca/ec/point.py @@ -1,9 +1,10 @@ from copy import copy -from public import public from typing import Mapping +from public import public + from .coordinates import CoordinateModel, AffineCoordinateModel -from .mod import Mod +from .mod import Mod, Undefined from .op import CodeOp @@ -28,18 +29,34 @@ class Point(object): except: pass affine_model = AffineCoordinateModel(self.coordinate_model.curve_model) - # TODO: just fill in with undefined - if not set(map(lambda x: x.result, ops)).issuperset(affine_model.variables): + result_variables = set(map(lambda x: x.result, ops)) + if not result_variables.issuperset(affine_model.variables): raise NotImplementedError result = {} for op in ops: + if op.result not in affine_model.variables: + continue result[op.result] = op(**self.coords) return Point(affine_model, **result) @staticmethod - def from_affine(affine_point): - # TODO - pass + def from_affine(coordinate_model, affine_point): + if not isinstance(affine_point.coordinate_model, AffineCoordinateModel): + return ValueError + result = {} + n = affine_point.coords["x"].n + for var in coordinate_model.variables: + if var == "X": + result[var] = affine_point.coords["x"] + elif var == "Y": + result[var] = affine_point.coords["y"] + elif var.startswith("Z"): + result[var] = Mod(1, n) + elif var == "T": + result[var] = Mod(affine_point.coords["x"] * affine_point.coords["y"], n) + else: + raise NotImplementedError + return Point(coordinate_model, **result) def equals(self, other): if not isinstance(other, Point): @@ -67,14 +84,14 @@ class Point(object): class InfinityPoint(Point): def __init__(self, model: CoordinateModel): - self.coordinate_model = model - self.coords = {} + coords = {key: Undefined() for key in model.variables} + super().__init__(model, **coords) def to_affine(self): return InfinityPoint(AffineCoordinateModel(self.coordinate_model.curve_model)) @staticmethod - def from_affine(affine_point): + def from_affine(coordinate_model, affine_point): raise NotImplementedError def equals(self, other): diff --git a/test/ec/test_point.py b/test/ec/test_point.py new file mode 100644 index 0000000..ea1e79a --- /dev/null +++ b/test/ec/test_point.py @@ -0,0 +1,59 @@ +from unittest import TestCase + +from pyecsca.ec.coordinates import AffineCoordinateModel +from pyecsca.ec.mod import Mod +from pyecsca.ec.model import ShortWeierstrassModel +from pyecsca.ec.point import Point, InfinityPoint +from test.ec.curves import get_secp128r1 + + +class PointTests(TestCase): + def setUp(self): + self.secp128r1, self.base = get_secp128r1() + self.affine = AffineCoordinateModel(ShortWeierstrassModel()) + + def test_to_affine(self): + pt = Point(self.secp128r1.coordinate_model, + X=Mod(0x161ff7528b899b2d0c28607ca52c5b86, self.secp128r1.prime), + Y=Mod(0xcf5ac8395bafeb13c02da292dded7a83, self.secp128r1.prime), + Z=Mod(1, self.secp128r1.prime)) + affine = pt.to_affine() + + self.assertIsInstance(affine.coordinate_model, AffineCoordinateModel) + self.assertSetEqual(set(affine.coords.keys()), set(self.affine.variables)) + self.assertEqual(affine.coords["x"], pt.coords["X"]) + self.assertEqual(affine.coords["y"], pt.coords["Y"]) + + affine = InfinityPoint(self.secp128r1.coordinate_model).to_affine() + self.assertIsInstance(affine, InfinityPoint) + + def test_from_affine(self): + affine = Point(self.affine, x=Mod(0xabcd, self.secp128r1.prime), + y=Mod(0xef, self.secp128r1.prime)) + projective_model = self.secp128r1.coordinate_model + other = Point.from_affine(projective_model, affine) + + self.assertEqual(other.coordinate_model, projective_model) + self.assertSetEqual(set(other.coords.keys()), set(projective_model.variables)) + self.assertEqual(other.coords["X"], affine.coords["x"]) + self.assertEqual(other.coords["Y"], affine.coords["y"]) + self.assertEqual(other.coords["Z"], Mod(1, self.secp128r1.prime)) + + def test_to_from_affine(self): + pt = Point(self.secp128r1.coordinate_model, + X=Mod(0x161ff7528b899b2d0c28607ca52c5b86, self.secp128r1.prime), + Y=Mod(0xcf5ac8395bafeb13c02da292dded7a83, self.secp128r1.prime), + Z=Mod(1, self.secp128r1.prime)) + other = Point.from_affine(self.secp128r1.coordinate_model, pt.to_affine()) + self.assertEqual(pt, other) + + def test_equals(self): + pt = Point(self.secp128r1.coordinate_model, + X=Mod(0x4, self.secp128r1.prime), + Y=Mod(0x6, self.secp128r1.prime), + Z=Mod(2, self.secp128r1.prime)) + other = Point(self.secp128r1.coordinate_model, + X=Mod(0x2, self.secp128r1.prime), + Y=Mod(0x3, self.secp128r1.prime), + Z=Mod(1, self.secp128r1.prime)) + assert pt.equals(other) -- cgit v1.2.3-70-g09d2