diff options
| -rw-r--r-- | Makefile | 16 | ||||
| -rw-r--r-- | pyecsca/ec/formula.py | 35 | ||||
| -rw-r--r-- | pyecsca/ec/op.py | 34 | ||||
| -rw-r--r-- | test/ec/test_mult.py | 2 | ||||
| -rw-r--r-- | test/ec/test_point.py | 2 |
5 files changed, 77 insertions, 12 deletions
@@ -1,13 +1,21 @@ +EC_TESTS = ec.test_context ec.test_curve ec.test_group ec.test_key_agreement ec.test_mod ec.test_model \ +ec.test_mult ec.test_naf ec.test_point ec.test_signature + +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_test sca.test_trace sca.test_traceset + +TESTS = ${EC_TESTS} ${SCA_TESTS} + test: - nose2 -A !slow -C -v + nose2 -s test -A !slow -C -v ${TESTS} test-plots: - env PYECSCA_TEST_PLOTS=1 nose2 -A !slow -C -v + env PYECSCA_TEST_PLOTS=1 nose2 -s test -A !slow -C -v ${TESTS} test-all: - nose2 -C -v + nose2 -s test -C -v ${TESTS} typecheck: - mypy -p pyecsca --ignore-missing-imports + mypy pyecsca --ignore-missing-imports .PHONY: test test-plots test-all typecheck
\ No newline at end of file diff --git a/pyecsca/ec/formula.py b/pyecsca/ec/formula.py index f80e9fa..5f4c7cb 100644 --- a/pyecsca/ec/formula.py +++ b/pyecsca/ec/formula.py @@ -1,5 +1,6 @@ from ast import parse, Expression -from typing import List, Any, ClassVar, MutableMapping +from typing import List, Set, Any, ClassVar, MutableMapping +from itertools import product from pkg_resources import resource_stream from public import public @@ -22,10 +23,22 @@ class Formula(object): return f"{self.__class__.__name__}({self.name} for {self.coordinate_model})" @property - def output_index(cls): + def input_index(self): + raise NotImplementedError + + @property + def output_index(self) -> int: """The starting index where this formula stores its outputs.""" raise NotImplementedError + @property + def inputs(self) -> Set[str]: + raise NotImplementedError + + @property + def outputs(self) -> Set[str]: + raise NotImplementedError + class EFDFormula(Formula): @@ -60,8 +73,22 @@ class EFDFormula(Formula): self.code.append(CodeOp(code_module)) @property - def output_index(cls): - return max(cls.num_inputs + 1, 3) + def input_index(self): + return 1 + + @property + def output_index(self): + return max(self.num_inputs + 1, 3) + + @property + def inputs(self): + return set(var + str(i) for var, i in product(self.coordinate_model.variables, + range(1, 1 + self.num_inputs))) + + @property + def outputs(self): + return set(var + str(i) for var, i in product(self.coordinate_model.variables, + range(self.output_index, self.output_index + self.num_outputs))) def __eq__(self, other): if not isinstance(other, EFDFormula): diff --git a/pyecsca/ec/op.py b/pyecsca/ec/op.py index 169f3bb..11c3079 100644 --- a/pyecsca/ec/op.py +++ b/pyecsca/ec/op.py @@ -1,4 +1,4 @@ -from ast import Module, walk, Name, BinOp, operator +from ast import Module, walk, Name, BinOp, Constant, operator, Mult, Div, Add, Sub, Pow from types import CodeType from typing import FrozenSet, Optional @@ -26,6 +26,7 @@ class CodeOp(Op): self.result = assign.targets[0].id params = set() variables = set() + constants = set() op = None for node in walk(assign.value): if isinstance(node, Name): @@ -34,15 +35,44 @@ class CodeOp(Op): variables.add(name) else: params.add(name) + elif isinstance(node, Constant): + constants.add(node.value) elif isinstance(node, BinOp): op = node.op + self.left = self.__to_name(node.left) + self.right = self.__to_name(node.right) self.operator = op self.parameters = frozenset(params) self.variables = frozenset(variables) + self.constants = frozenset(constants) self.compiled = compile(self.code, "", mode="exec") + def __to_name(self, node): + if isinstance(node, Name): + return node.id + elif isinstance(node, Constant): + return node.value + else: + return None + + def __to_opsymbol(self, op): + if isinstance(op, Mult): + return "*" + elif isinstance(op, Div): + return "/" + elif isinstance(op, Add): + return "+" + elif isinstance(op, Sub): + return "-" + elif isinstance(op, Pow): + return "^" + return "" + + def __str__(self): + return f"{self.result} = {self.left}{self.__to_opsymbol(self.operator)}{self.right}" + def __repr__(self): - return f"CodeOp({self.result} = f(params={self.parameters}, vars={self.variables}))" + return f"CodeOp({self.result} = f(params={self.parameters}, vars={self.variables}, consts={self.constants}))" def __call__(self, *args, **kwargs: Mod) -> Mod: loc = dict(kwargs) diff --git a/test/ec/test_mult.py b/test/ec/test_mult.py index 2d167f3..c72f370 100644 --- a/test/ec/test_mult.py +++ b/test/ec/test_mult.py @@ -3,7 +3,7 @@ from unittest import TestCase from pyecsca.ec.mult import (LTRMultiplier, RTLMultiplier, LadderMultiplier, BinaryNAFMultiplier, WindowNAFMultiplier, SimpleLadderMultiplier, CoronMultiplier) from pyecsca.ec.point import InfinityPoint -from test.ec.curves import get_secp128r1, get_curve25519 +from .curves import get_secp128r1, get_curve25519 class ScalarMultiplierTests(TestCase): diff --git a/test/ec/test_point.py b/test/ec/test_point.py index d85ed4a..c80d4cc 100644 --- a/test/ec/test_point.py +++ b/test/ec/test_point.py @@ -4,7 +4,7 @@ from pyecsca.ec.coordinates import AffineCoordinateModel from pyecsca.ec.mod import Mod from pyecsca.ec.model import ShortWeierstrassModel, MontgomeryModel from pyecsca.ec.point import Point, InfinityPoint -from test.ec.curves import get_secp128r1 +from .curves import get_secp128r1 class PointTests(TestCase): |
