diff options
| -rw-r--r-- | pyecsca/ec/context.py | 11 | ||||
| -rw-r--r-- | pyecsca/ec/formula.py | 7 | ||||
| -rw-r--r-- | pyecsca/ec/op.py | 38 |
3 files changed, 47 insertions, 9 deletions
diff --git a/pyecsca/ec/context.py b/pyecsca/ec/context.py index e691184..7fafadc 100644 --- a/pyecsca/ec/context.py +++ b/pyecsca/ec/context.py @@ -24,13 +24,10 @@ class Context(object): for coord, value in point.coords.items(): coords[coord + str(i + 1)] = value locals = {**coords, **params} - previous_locals = set(locals.keys()) - for line in formula.code: - exec(compile(line, "", mode="exec"), {}, locals) - diff = set(locals.keys()).difference(previous_locals) - previous_locals = set(locals.keys()) - for key in diff: - self.intermediates.append((key, locals[key])) + for op in formula.code: + op_result = op(**locals) + self.intermediates.append((op.result, op_result)) + locals[op.result] = op_result result = [] for i in range(formula.num_outputs): ind = str(i + 3) diff --git a/pyecsca/ec/formula.py b/pyecsca/ec/formula.py index fd58a31..9b9c213 100644 --- a/pyecsca/ec/formula.py +++ b/pyecsca/ec/formula.py @@ -3,6 +3,8 @@ from pkg_resources import resource_stream from public import public from typing import List, Any +from .op import Op, CodeOp + class Formula(object): name: str @@ -10,7 +12,7 @@ class Formula(object): source: str parameters: List[str] assumptions: List[Expression] - code: List[Module] + code: List[Op] _inputs: int _outputs: int @@ -42,7 +44,8 @@ class Formula(object): def __read_op3_file(self, path): with resource_stream(__name__, path) as f: for line in f.readlines(): - self.code.append(parse(line.decode("ascii").replace("^", "**"), path, mode="exec")) + code_module = parse(line.decode("ascii").replace("^", "**"), path, mode="exec") + self.code.append(CodeOp(code_module)) @property def num_inputs(self): diff --git a/pyecsca/ec/op.py b/pyecsca/ec/op.py new file mode 100644 index 0000000..b366617 --- /dev/null +++ b/pyecsca/ec/op.py @@ -0,0 +1,38 @@ +from ast import Module, walk, Name +from typing import FrozenSet + +from .mod import Mod + + +class Op(object): + result: str + parameters: FrozenSet[str] + variables: FrozenSet[str] + + def __call__(self, *args, **kwargs) -> Mod: + raise NotImplementedError + + +class CodeOp(Op): + code: Module + + def __init__(self, code: Module): + self.code = code + assign = code.body[0] + self.result = assign.targets[0].id + params = set() + variables = set() + for node in walk(assign.value): + if isinstance(node, Name): + name = node.id + if name.isupper(): + variables.add(name) + else: + params.add(name) + self.parameters = frozenset(params) + self.variables = frozenset(variables) + + def __call__(self, *args, **kwargs) -> Mod: + loc = dict(kwargs) + exec(compile(self.code, "", mode="exec"), {}, loc) + return loc[self.result] |
