aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pyecsca/ec/context.py33
-rw-r--r--pyecsca/ec/formula/metrics.py4
-rw-r--r--pyecsca/sca/attack/CPA.py2
-rw-r--r--pyecsca/sca/attack/DPA.py2
-rw-r--r--pyecsca/sca/target/leakage.py2
-rw-r--r--test/ec/test_context.py2
-rw-r--r--test/sca/test_leakage_models.py4
7 files changed, 30 insertions, 19 deletions
diff --git a/pyecsca/ec/context.py b/pyecsca/ec/context.py
index 97a64ca..d64cbbc 100644
--- a/pyecsca/ec/context.py
+++ b/pyecsca/ec/context.py
@@ -12,7 +12,7 @@ in the tree.
"""
from abc import abstractmethod, ABC
from copy import deepcopy
-from typing import List, Optional, ContextManager, Any, Tuple, Sequence, Callable
+from typing import List, Optional, ContextManager, Any, Sequence, Callable
from public import public
from anytree import RenderTree, NodeMixin, AbstractStyle, PostOrderIter
@@ -67,6 +67,7 @@ class ResultAction(Action):
@property
def result(self) -> Any:
+ """The result of the action."""
if not self._has_result:
raise AttributeError("No result set")
return self._result
@@ -99,6 +100,7 @@ class Node(NodeMixin):
"""A node in an execution tree."""
action: Action
+ """The action of the node."""
def __init__(self, action: Action, parent=None, children=None):
self.action = action
@@ -176,6 +178,9 @@ class Node(NodeMixin):
def __str__(self):
return self.render()
+ def __repr__(self):
+ return self.render()
+
@public
class Context(ABC):
@@ -212,7 +217,7 @@ class Context(ABC):
@public
class DefaultContext(Context):
"""
- Context that traces executions of actions in a tree.
+ Context that traces executions of actions in a forest.
>>> with local(DefaultContext()) as ctx:
... with Action() as one_action:
@@ -220,28 +225,34 @@ class DefaultContext(Context):
... r = other_action.exit("some result")
... with Action() as yet_another:
... pass
- >>> print(ctx.actions) # doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS
+ >>> print(ctx.actions[0]) # doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS
Action()
├──ResultAction(result='some result')
└──Action()
- >>> for other in ctx.actions.children: # doctest: +ELLIPSIS
+ >>> for other in ctx.actions[0].children: # doctest: +ELLIPSIS
... print(other.action)
ResultAction(result='some result')
Action()
"""
- actions: Optional[Node]
+ actions: List[Node]
+ """A forest of trees."""
current: List[Action]
+ """The path to the current action."""
def __init__(self):
- self.actions = None
+ self.actions = []
self.current = []
def enter_action(self, action: Action) -> None:
- if self.actions is None:
- self.actions = Node(action)
+ if not self.actions:
+ self.actions.append(Node(action))
else:
- Node(action, parent=self.actions.get_by_key(self.current[1:]))
+ if self.current:
+ root = next(filter(lambda node: node.action == self.current[0], self.actions))
+ Node(action, parent=root.get_by_key(self.current[1:]))
+ else:
+ self.actions.append(Node(action))
self.current.append(action)
def exit_action(self, action: Action) -> None:
@@ -250,7 +261,7 @@ class DefaultContext(Context):
self.current.pop()
def __repr__(self):
- return f"{self.__class__.__name__}(actions={self.actions.size if self.actions else 0}, current={self.current!r})"
+ return f"{self.__class__.__name__}(actions={sum(map(lambda action: action.size, self.actions))}, current={self.current!r})"
@public
@@ -322,7 +333,7 @@ def local(ctx: Optional[Context] = None) -> ContextManager:
>>> with local(DefaultContext()) as ctx:
... with Action() as action:
... pass
- >>> ctx.actions.action == action
+ >>> ctx.actions[0].action == action
True
:param ctx: If none, current context is copied.
diff --git a/pyecsca/ec/formula/metrics.py b/pyecsca/ec/formula/metrics.py
index 063a62d..31d0545 100644
--- a/pyecsca/ec/formula/metrics.py
+++ b/pyecsca/ec/formula/metrics.py
@@ -103,13 +103,13 @@ def formula_similarity_fuzz(
inputs = (P, Q, R)[: one.num_inputs]
with local(DefaultContext()) as ctx:
res_one = one(curve.prime, *inputs, **curve.parameters)
- action_one = ctx.actions.action
+ action_one = ctx.actions[0].action
ivs_one = set(
map(attrgetter("value"), sum(action_one.intermediates.values(), []))
)
with local(DefaultContext()) as ctx:
res_other = other(curve.prime, *inputs, **curve.parameters)
- action_other = ctx.actions.action
+ action_other = ctx.actions[0].action
ivs_other = set(
map(attrgetter("value"), sum(action_other.intermediates.values(), []))
)
diff --git a/pyecsca/sca/attack/CPA.py b/pyecsca/sca/attack/CPA.py
index 6efa3b5..efa406c 100644
--- a/pyecsca/sca/attack/CPA.py
+++ b/pyecsca/sca/attack/CPA.py
@@ -55,7 +55,7 @@ class CPA:
action_index += 2
elif bit == "0":
action_index += 1
- result = ctx.actions.get_by_index([action_index]).action
+ result = ctx.actions[0].get_by_index([action_index]).action
return result.output_points[0].X
def compute_correlation_trace(
diff --git a/pyecsca/sca/attack/DPA.py b/pyecsca/sca/attack/DPA.py
index da4ae65..0e6a8cc 100644
--- a/pyecsca/sca/attack/DPA.py
+++ b/pyecsca/sca/attack/DPA.py
@@ -50,7 +50,7 @@ class DPA:
action_index += 2
elif bit == "0":
action_index += 1
- result = ctx.actions.get_by_index([action_index]).action
+ result = ctx.actions[0].get_by_index([action_index]).action
return result.output_points[0]
def split_traces(
diff --git a/pyecsca/sca/target/leakage.py b/pyecsca/sca/target/leakage.py
index e8734fb..74838b8 100644
--- a/pyecsca/sca/target/leakage.py
+++ b/pyecsca/sca/target/leakage.py
@@ -54,7 +54,7 @@ class LeakageTarget(Target):
temp_trace: list[int] = []
if not context.actions:
raise ValueError("Empty context")
- context.actions.walk(callback)
+ context.actions[0].walk(callback)
return Trace(np.array(temp_trace))
def simulate_scalar_mult_traces(
diff --git a/test/ec/test_context.py b/test/ec/test_context.py
index 65053d4..9ad8b52 100644
--- a/test/ec/test_context.py
+++ b/test/ec/test_context.py
@@ -80,7 +80,7 @@ def test_null(mult):
def test_default(mult):
with local(DefaultContext()) as ctx:
result = mult.multiply(59)
- action = ctx.actions.action
+ action = ctx.actions[0].action
assert isinstance(action, ScalarMultiplicationAction)
assert result == action.result
diff --git a/test/sca/test_leakage_models.py b/test/sca/test_leakage_models.py
index 8be5704..592a100 100644
--- a/test/sca/test_leakage_models.py
+++ b/test/sca/test_leakage_models.py
@@ -81,7 +81,7 @@ def test_mult_hw(context):
leak = lm(intermediate.value)
trace.append(leak)
- context.actions.walk(callback)
+ context.actions[0].walk(callback)
assert len(trace) > 0
@@ -97,5 +97,5 @@ def test_mult_hd(context):
leak = lm(*values)
trace.append(leak)
- context.actions.walk(callback)
+ context.actions[0].walk(callback)
assert len(trace) > 0