diff options
| -rw-r--r-- | pyecsca/ec/params.py | 2 | ||||
| -rw-r--r-- | pyecsca/ec/point.py | 49 | ||||
| -rw-r--r-- | test/ec/test_point.py | 14 | ||||
| -rw-r--r-- | test/sca/test_target.py | 10 |
4 files changed, 43 insertions, 32 deletions
diff --git a/pyecsca/ec/params.py b/pyecsca/ec/params.py index 9f1865f..abe716a 100644 --- a/pyecsca/ec/params.py +++ b/pyecsca/ec/params.py @@ -143,7 +143,7 @@ def get_params(category: str, name: str, coords: str, infty: bool = True) -> Dom affine = Point(AffineCoordinateModel(model), x=Mod(int(curve["generator"]["x"], 16), field), y=Mod(int(curve["generator"]["y"], 16), field)) if not isinstance(coord_model, AffineCoordinateModel): - generator = Point.from_affine(coord_model, affine) + generator = affine.to_model(coord_model, elliptic_curve) else: generator = affine return DomainParameters(elliptic_curve, generator, order, cofactor, name, category) diff --git a/pyecsca/ec/point.py b/pyecsca/ec/point.py index 4484626..2f9c29a 100644 --- a/pyecsca/ec/point.py +++ b/pyecsca/ec/point.py @@ -51,7 +51,7 @@ class Point(object): with CoordinateMappingAction(self.coordinate_model, affine_model, self) as action: if isinstance(self.coordinate_model, AffineCoordinateModel): return action.exit(copy(self)) - ops = list() + ops = [] for s in self.coordinate_model.satisfying: try: ops.append(CodeOp(s)) @@ -61,36 +61,48 @@ class Point(object): if not result_variables.issuperset(affine_model.variables): raise NotImplementedError result = {} - locals = {**self.coords} + locls = {**self.coords} for op in ops: try: - locals[op.result] = op(**locals) + locls[op.result] = op(**locls) except NameError as e: if op.result in affine_model.variables: raise e else: continue if op.result in affine_model.variables: - result[op.result] = locals[op.result] + result[op.result] = locls[op.result] return action.exit(Point(affine_model, **result)) - @staticmethod - def from_affine(coordinate_model: CoordinateModel, affine_point: "Point") -> "Point": + def to_model(self, coordinate_model: CoordinateModel, curve: "EllipticCurve") -> "Point": """Convert an affine point into a given coordinate model, if possible.""" - with CoordinateMappingAction(affine_point.coordinate_model, coordinate_model, affine_point) as action: - if not isinstance(affine_point.coordinate_model, AffineCoordinateModel): - raise ValueError + if not isinstance(self.coordinate_model, AffineCoordinateModel): + raise ValueError + with CoordinateMappingAction(self.coordinate_model, coordinate_model, self) as action: + ops = [] + for s in coordinate_model.satisfying: + try: + ops.append(CodeOp(s)) + except Exception: + pass + locls = {**self.coords, **curve.parameters, "Z": Mod(1, curve.prime)} + for op in ops: + try: + locls[op.result] = op(**locls) + except: + continue 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"] + for var in coordinate_model.variables: + if var in locls: # Try this first. + result[var] = locls[var] + elif var == "X": # XXX: This just works for the stuff currently in EFD. + result[var] = self.coords["x"] elif var == "Y": - result[var] = affine_point.coords["y"] + result[var] = self.coords["y"] elif var.startswith("Z"): - result[var] = Mod(1, n) + result[var] = Mod(1, curve.prime) elif var == "T": - result[var] = Mod(int(affine_point.coords["x"] * affine_point.coords["y"]), n) + result[var] = Mod(int(affine_point.coords["x"] * affine_point.coords["y"]), curve.prime) else: raise NotImplementedError return action.exit(Point(coordinate_model, **result)) @@ -138,9 +150,8 @@ class InfinityPoint(Point): def to_affine(self) -> "InfinityPoint": return InfinityPoint(AffineCoordinateModel(self.coordinate_model.curve_model)) - @staticmethod - def from_affine(coordinate_model: CoordinateModel, affine_point: "Point") -> "InfinityPoint": - raise NotImplementedError + def to_model(self, coordinate_model: CoordinateModel, curve: "EllipticCurve") -> "InfinityPoint": + return InfinityPoint(coordinate_model) def equals(self, other) -> bool: return self == other diff --git a/test/ec/test_point.py b/test/ec/test_point.py index 936d4e9..2fc4ca4 100644 --- a/test/ec/test_point.py +++ b/test/ec/test_point.py @@ -34,11 +34,11 @@ class PointTests(TestCase): affine = InfinityPoint(self.coords).to_affine() self.assertIsInstance(affine, InfinityPoint) - def test_from_affine(self): + def test_to_model(self): affine = Point(self.affine, x=Mod(0xabcd, self.secp128r1.curve.prime), y=Mod(0xef, self.secp128r1.curve.prime)) projective_model = self.coords - other = Point.from_affine(projective_model, affine) + other = affine.to_model(projective_model, self.secp128r1.curve) self.assertEqual(other.coordinate_model, projective_model) self.assertSetEqual(set(other.coords.keys()), set(projective_model.variables)) @@ -46,17 +46,19 @@ class PointTests(TestCase): self.assertEqual(other.coords["Y"], affine.coords["y"]) self.assertEqual(other.coords["Z"], Mod(1, self.secp128r1.curve.prime)) - with self.assertRaises(NotImplementedError): - InfinityPoint.from_affine(self.coords, affine) + infty = InfinityPoint(AffineCoordinateModel(self.secp128r1.curve.model)) + other_infty = infty.to_model(self.coords, self.secp128r1.curve) + self.assertIsInstance(other_infty, InfinityPoint) + with self.assertRaises(ValueError): - Point.from_affine(self.coords, self.base) + self.base.to_model(self.coords, self.secp128r1.curve) def test_to_from_affine(self): pt = Point(self.coords, X=Mod(0x161ff7528b899b2d0c28607ca52c5b86, self.secp128r1.curve.prime), Y=Mod(0xcf5ac8395bafeb13c02da292dded7a83, self.secp128r1.curve.prime), Z=Mod(1, self.secp128r1.curve.prime)) - other = Point.from_affine(self.coords, pt.to_affine()) + other = pt.to_affine().to_model(self.coords, self.secp128r1.curve) self.assertEqual(pt, other) def test_equals(self): diff --git a/test/sca/test_target.py b/test/sca/test_target.py index 3652309..d31da69 100644 --- a/test/sca/test_target.py +++ b/test/sca/test_target.py @@ -207,8 +207,8 @@ class ECTesterTargetTests(TestCase): privkey = Mod(int.from_bytes( export_privkey_resp.get_param(KeypairEnum.KEYPAIR_REMOTE, ParameterEnum.S), "big"), self.secp256r1.curve.prime) - pubkey_projective = Point.from_affine(self.secp256r1_projective.curve.coordinate_model, - pubkey) + pubkey_projective = pubkey.to_model(self.secp256r1_projective.curve.coordinate_model, self.secp256r1.curve) + mult = LTRMultiplier( self.secp256r1_projective.curve.coordinate_model.formulas["add-2016-rcb"], self.secp256r1_projective.curve.coordinate_model.formulas["dbl-2016-rcb"]) @@ -257,8 +257,7 @@ class ECTesterTargetTests(TestCase): ParameterEnum.W) pubkey_bytes = export_public_resp.get_param(KeypairEnum.KEYPAIR_LOCAL, ParameterEnum.W) pubkey = self.secp256r1.curve.decode_point(pubkey_bytes) - pubkey_projective = Point.from_affine(self.secp256r1_projective.curve.coordinate_model, - pubkey) + pubkey_projective = pubkey.to_model(self.secp256r1_projective.curve.coordinate_model, self.secp256r1.curve) sig = SignatureResult.from_DER(ecdsa_resp.signature) mult = LTRMultiplier( @@ -284,8 +283,7 @@ class ECTesterTargetTests(TestCase): ParameterEnum.W) pubkey_bytes = export_public_resp.get_param(KeypairEnum.KEYPAIR_LOCAL, ParameterEnum.W) pubkey = self.secp256r1.curve.decode_point(pubkey_bytes) - pubkey_projective = Point.from_affine(self.secp256r1_projective.curve.coordinate_model, - pubkey) + pubkey_projective = pubkey.to_model(self.secp256r1_projective.curve.coordinate_model, self.secp256r1.curve) sig = SignatureResult.from_DER(ecdsa_resp.signature) mult = LTRMultiplier( |
