aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pyecsca/ec/context.py11
-rw-r--r--pyecsca/ec/formula.py7
-rw-r--r--pyecsca/ec/op.py38
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]