aboutsummaryrefslogtreecommitdiff
path: root/pyecsca/ec/point.py
diff options
context:
space:
mode:
Diffstat (limited to 'pyecsca/ec/point.py')
-rw-r--r--pyecsca/ec/point.py88
1 files changed, 54 insertions, 34 deletions
diff --git a/pyecsca/ec/point.py b/pyecsca/ec/point.py
index b5ba10b..2e41606 100644
--- a/pyecsca/ec/point.py
+++ b/pyecsca/ec/point.py
@@ -3,12 +3,30 @@ from typing import Mapping, Any
from public import public
-from .coordinates import CoordinateModel, AffineCoordinateModel
+from .context import Action
+from .coordinates import AffineCoordinateModel, CoordinateModel
from .mod import Mod, Undefined
from .op import CodeOp
@public
+class CoordinateMappingAction(Action):
+ """A mapping of a point from one coordinate system to another one, usually one is an affine one."""
+ model_from: CoordinateModel
+ model_to: CoordinateModel
+ point: "Point"
+
+ def __init__(self, model_from: CoordinateModel, model_to: CoordinateModel, point: "Point"):
+ super().__init__()
+ self.model_from = model_from
+ self.model_to = model_to
+ self.point = point
+
+ def __repr__(self):
+ return f"{self.__class__.__name__}(from={self.model_from}, to={self.model_to}, {self.point})"
+
+
+@public
class Point(object):
"""A point with coordinates in a coordinate model."""
coordinate_model: CoordinateModel
@@ -29,44 +47,46 @@ class Point(object):
def to_affine(self) -> "Point":
"""Convert this point into the affine coordinate model, if possible."""
- if isinstance(self.coordinate_model, AffineCoordinateModel):
- return copy(self)
- ops = set()
- for s in self.coordinate_model.satisfying:
- try:
- ops.add(CodeOp(s))
- except Exception:
- pass
affine_model = AffineCoordinateModel(self.coordinate_model.curve_model)
- 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)
+ with CoordinateMappingAction(self.coordinate_model, affine_model, self):
+ if isinstance(self.coordinate_model, AffineCoordinateModel):
+ return copy(self)
+ ops = set()
+ for s in self.coordinate_model.satisfying:
+ try:
+ ops.add(CodeOp(s))
+ except Exception:
+ pass
+ 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(coordinate_model: CoordinateModel, affine_point: "Point") -> "Point":
"""Convert an affine point into a given coordinate model, if possible."""
- if not isinstance(affine_point.coordinate_model, AffineCoordinateModel):
- raise ValueError
- result = {}
- n = affine_point.coords["x"].n
- for var in coordinate_model.variables: #  XXX: This just works for the stuff currently in EFD.
- 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)
+ with CoordinateMappingAction(affine_point.coordinate_model, coordinate_model, affine_point):
+ if not isinstance(affine_point.coordinate_model, AffineCoordinateModel):
+ raise ValueError
+ result = {}
+ n = affine_point.coords["x"].n
+ for var in coordinate_model.variables: #  XXX: This just works for the stuff currently in EFD.
+ 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: Any) -> bool:
"""Test whether this point is equal to `other` irrespective of the coordinate model (in the affine sense)."""