aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJ08nY2024-05-30 18:24:43 +0200
committerJ08nY2024-05-30 18:24:43 +0200
commit5222ce8f6989de61a0a4a8ed7fa3dc7c6f575dfb (patch)
tree5fff6b7bd0399811beb95572f010d2ad3338af79
parent5ae20fd1c96b126a71b5f8012b88ecf22661cc2c (diff)
downloadpyecsca-5222ce8f6989de61a0a4a8ed7fa3dc7c6f575dfb.tar.gz
pyecsca-5222ce8f6989de61a0a4a8ed7fa3dc7c6f575dfb.tar.zst
pyecsca-5222ce8f6989de61a0a4a8ed7fa3dc7c6f575dfb.zip
Improve doc coverage and cleanup public functions.
-rw-r--r--pyecsca/ec/formula/code.py11
-rw-r--r--pyecsca/ec/formula/efd.py3
-rw-r--r--pyecsca/ec/formula/expand.py11
-rw-r--r--pyecsca/ec/formula/fake.py6
-rw-r--r--pyecsca/ec/formula/fliparoo.py9
-rw-r--r--pyecsca/ec/formula/graph.py6
-rw-r--r--pyecsca/ec/formula/metrics.py22
-rw-r--r--pyecsca/ec/formula/partitions.py5
-rw-r--r--pyecsca/ec/formula/switch_sign.py2
-rw-r--r--pyecsca/ec/formula/unroll.py2
10 files changed, 74 insertions, 3 deletions
diff --git a/pyecsca/ec/formula/code.py b/pyecsca/ec/formula/code.py
index 9d2d7d6..8309bb8 100644
--- a/pyecsca/ec/formula/code.py
+++ b/pyecsca/ec/formula/code.py
@@ -1,7 +1,8 @@
-"""Provides a concrete class of a formula that has a constructor."""
+"""Provides a concrete class of a formula that has a constructor and some code."""
from typing import List, Any
from ast import Expression
from astunparse import unparse
+from public import public
from .base import (
Formula,
@@ -17,6 +18,7 @@ from ..op import CodeOp
from ...misc.utils import peval
+@public
class CodeFormula(Formula):
"""A basic formula class that can be directly initialized with the code and other attributes."""
@@ -71,29 +73,36 @@ class CodeFormula(Formula):
self.__dict__.update(state)
+@public
class CodeAdditionFormula(AdditionFormula, CodeFormula):
pass
+@public
class CodeDoublingFormula(DoublingFormula, CodeFormula):
pass
+@public
class CodeLadderFormula(LadderFormula, CodeFormula):
pass
+@public
class CodeTriplingFormula(TriplingFormula, CodeFormula):
pass
+@public
class CodeNegationFormula(NegationFormula, CodeFormula):
pass
+@public
class CodeScalingFormula(ScalingFormula, CodeFormula):
pass
+@public
class CodeDifferentialAdditionFormula(DifferentialAdditionFormula, CodeFormula):
pass
diff --git a/pyecsca/ec/formula/efd.py b/pyecsca/ec/formula/efd.py
index 0f2aa98..a56eb47 100644
--- a/pyecsca/ec/formula/efd.py
+++ b/pyecsca/ec/formula/efd.py
@@ -1,4 +1,4 @@
-""""""
+"""Provides formulas wrapping the [EFD]_."""
from copy import copy
from public import public
@@ -22,6 +22,7 @@ from .base import (
from ...misc.utils import pexec, peval
+@public
class EFDFormula(Formula):
"""Formula from the [EFD]_."""
diff --git a/pyecsca/ec/formula/expand.py b/pyecsca/ec/formula/expand.py
index acaf7ea..f3c9a56 100644
--- a/pyecsca/ec/formula/expand.py
+++ b/pyecsca/ec/formula/expand.py
@@ -1,3 +1,4 @@
+"""Provides a formula expansion function."""
from typing import Set, Callable, Any
from public import public
@@ -25,6 +26,16 @@ def reduce_with_similarity(formulas: Set[Formula], norm: Callable[[Formula], Any
def expand_formula_set(
formulas: Set[Formula], norm: Callable[[Formula], Any] = ivs_norm
) -> Set[Formula]:
+ """
+ Expand a set of formulas by using transformations:
+ - Fliparoos
+ - Sign switching
+ - Associativity and Commutativity
+
+ :param formulas:
+ :param norm:
+ :return:
+ """
extended = reduce_with_similarity(formulas, norm)
fliparood: Set[Formula] = set().union(*map(recursive_fliparoo, extended))
diff --git a/pyecsca/ec/formula/fake.py b/pyecsca/ec/formula/fake.py
index cc52740..5c20dfb 100644
--- a/pyecsca/ec/formula/fake.py
+++ b/pyecsca/ec/formula/fake.py
@@ -1,3 +1,4 @@
+"""Provides "fake" formulas."""
from abc import ABC
from typing import Any, Tuple
@@ -18,9 +19,10 @@ from ..mod import Mod, Undefined
from ..point import Point
+@public
class FakeFormula(Formula, ABC):
"""
- No matter what the input point is it just returns the right amount of FakePoints.
+ No matter what the input point is, it just returns the right amount of FakePoints.
Useful for computing with the scalar multipliers without having concrete formulas
and points (for example to get the addition chain via the MultipleContext).
@@ -77,6 +79,8 @@ class FakeLadderFormula(FakeFormula, LadderFormula):
@public
class FakePoint(Point):
+ """Just a fake point."""
+
def __init__(self, model):
coords = {key: Undefined() for key in model.variables}
super().__init__(model, **coords)
diff --git a/pyecsca/ec/formula/fliparoo.py b/pyecsca/ec/formula/fliparoo.py
index 7338b24..6665e1e 100644
--- a/pyecsca/ec/formula/fliparoo.py
+++ b/pyecsca/ec/formula/fliparoo.py
@@ -1,10 +1,13 @@
+"""Provides a way to Fliparoo formulas."""
from ast import parse
from typing import Iterator, List, Type, Optional, Set
+from public import public
from ..op import OpType
from .base import Formula
from .graph import FormulaGraph, Node, CodeOpNode, CodeOp, CodeFormula
+@public
class Fliparoo:
"""
Fliparoo is a chain of nodes N1->N2->...->Nk in FormulaGraph for k>=2 such that:
@@ -79,6 +82,7 @@ class Fliparoo:
return self.__class__(self.nodes[i:j], self.graph)
+@public
class MulFliparoo(Fliparoo):
def __init__(self, chain: List[CodeOpNode], graph: FormulaGraph):
super().__init__(chain, graph)
@@ -88,6 +92,7 @@ class MulFliparoo(Fliparoo):
self.operator = OpType.Mult
+@public
class AddSubFliparoo(Fliparoo):
def __init__(self, chain: List[CodeOpNode], graph: FormulaGraph):
super().__init__(chain, graph)
@@ -96,6 +101,7 @@ class AddSubFliparoo(Fliparoo):
raise BadFliparoo
+@public
class AddFliparoo(Fliparoo):
def __init__(self, chain: List[CodeOpNode], graph: FormulaGraph):
super().__init__(chain, graph)
@@ -105,6 +111,7 @@ class AddFliparoo(Fliparoo):
self.operator = OpType.Add
+@public
class BadFliparoo(Exception):
pass
@@ -238,6 +245,7 @@ class DummyNode(Node):
return None
+@public
def generate_fliparood_formulas(
formula: Formula, rename: bool = True
) -> Iterator[CodeFormula]:
@@ -370,6 +378,7 @@ def combine_signed_nodes(
subgraph.add_node(new_node)
+@public
def recursive_fliparoo(formula: Formula, depth: int = 2) -> Set[Formula]:
all_fliparoos = {0: {formula}}
counter = 0
diff --git a/pyecsca/ec/formula/graph.py b/pyecsca/ec/formula/graph.py
index 59b51dd..c7886bd 100644
--- a/pyecsca/ec/formula/graph.py
+++ b/pyecsca/ec/formula/graph.py
@@ -1,3 +1,4 @@
+"""Provides tools for working with formulas as graphs."""
from .base import Formula
from .code import CodeFormula
from ..op import CodeOp, OpType
@@ -6,9 +7,11 @@ import networkx as nx
from ast import parse, Expression
from typing import Dict, List, Tuple, Set, Optional, MutableMapping, Any
from copy import deepcopy
+from public import public
from abc import ABC, abstractmethod
+@public
class Node(ABC):
def __init__(self):
self.incoming_nodes = []
@@ -75,6 +78,7 @@ class Node(ABC):
destination.outgoing_nodes.append(out)
+@public
class ConstantNode(Node):
color = "#b41f44"
@@ -170,6 +174,7 @@ class CodeOpNode(Node):
return f"Node({self.op})"
+@public
class InputNode(Node):
color = "#b41f44"
@@ -198,6 +203,7 @@ def formula_input_variables(formula: Formula) -> List[str]:
)
+@public
class FormulaGraph:
coordinate_model: Any
name: str
diff --git a/pyecsca/ec/formula/metrics.py b/pyecsca/ec/formula/metrics.py
index 9b521c4..f3c8487 100644
--- a/pyecsca/ec/formula/metrics.py
+++ b/pyecsca/ec/formula/metrics.py
@@ -1,3 +1,4 @@
+"""Provides metrics for comparing formulas."""
from public import public
from .unroll import unroll_formula
from .base import Formula
@@ -26,6 +27,13 @@ def ivs_norm(one: Formula):
@public
def formula_similarity(one: Formula, other: Formula) -> Dict[str, float]:
+ """
+ Formula similarity based on symbolic intermediate value sets.
+
+ :param one:
+ :param other:
+ :return:
+ """
if one.coordinate_model != other.coordinate_model:
warnings.warn("Mismatched coordinate model.")
@@ -41,6 +49,13 @@ def formula_similarity(one: Formula, other: Formula) -> Dict[str, float]:
@public
def formula_similarity_abs(one: Formula, other: Formula) -> Dict[str, float]:
+ """
+ Formula similarity based on symbolic intermediate value sets (absolute value)
+
+ :param one:
+ :param other:
+ :return:
+ """
if one.coordinate_model != other.coordinate_model:
warnings.warn("Mismatched coordinate model.")
@@ -64,6 +79,13 @@ def formula_similarity_abs(one: Formula, other: Formula) -> Dict[str, float]:
def formula_similarity_fuzz(
one: Formula, other: Formula, curve: EllipticCurve, samples: int = 1000
) -> Dict[str, float]:
+ """
+ Formula similarity based on random computation.
+
+ :param one:
+ :param other:
+ :return:
+ """
if one.coordinate_model != other.coordinate_model:
raise ValueError("Mismatched coordinate model.")
diff --git a/pyecsca/ec/formula/partitions.py b/pyecsca/ec/formula/partitions.py
index 4f44631..adfb4f8 100644
--- a/pyecsca/ec/formula/partitions.py
+++ b/pyecsca/ec/formula/partitions.py
@@ -1,5 +1,6 @@
from typing import List, Any, Generator
from ast import parse
+from public import public
from .base import Formula
from ..op import OpType, CodeOp
from .graph import FormulaGraph, CodeOpNode, ConstantNode, Node, CodeFormula
@@ -7,6 +8,7 @@ from .fliparoo import find_fliparoos, AddFliparoo, MulFliparoo
from copy import deepcopy
+@public
def reduce_all_adds(formula: Formula, rename=True) -> CodeFormula:
graph = FormulaGraph(formula, rename=rename)
add_fliparoos = find_single_input_add_fliparoos(graph)
@@ -19,6 +21,7 @@ def reduce_all_adds(formula: Formula, rename=True) -> CodeFormula:
return graph.to_formula("reduce_add")
+@public
def expand_all_muls(formula: Formula, rename=True) -> CodeFormula:
graph = FormulaGraph(formula, rename)
enodes = find_expansion_nodes(graph)
@@ -27,6 +30,7 @@ def expand_all_muls(formula: Formula, rename=True) -> CodeFormula:
return graph.to_formula("expand_mul")
+@public
def expand_all_nopower2_muls(formula: Formula, rename=True) -> CodeFormula:
graph = FormulaGraph(formula, rename)
enodes = find_expansion_nodes(graph, nopower2=True)
@@ -275,6 +279,7 @@ def compute_partitions(n: int) -> List[Partition]:
return result
+@public
def generate_partitioned_formulas(formula: Formula, rename=True):
graph = FormulaGraph(formula, rename)
enodes = find_expansion_nodes(graph)
diff --git a/pyecsca/ec/formula/switch_sign.py b/pyecsca/ec/formula/switch_sign.py
index b0efb56..f860c95 100644
--- a/pyecsca/ec/formula/switch_sign.py
+++ b/pyecsca/ec/formula/switch_sign.py
@@ -1,5 +1,6 @@
from typing import Dict, Iterator, List, Any
from ast import parse
+from public import public
from ..op import OpType, CodeOp
from .base import Formula
from .graph import FormulaGraph, ConstantNode, CodeOpNode, CodeFormula
@@ -8,6 +9,7 @@ from ..point import Point
from ..mod import Mod
+@public
def generate_switched_formulas(
formula: Formula, rename=True
) -> Iterator[CodeFormula]:
diff --git a/pyecsca/ec/formula/unroll.py b/pyecsca/ec/formula/unroll.py
index 84d0901..3b83e96 100644
--- a/pyecsca/ec/formula/unroll.py
+++ b/pyecsca/ec/formula/unroll.py
@@ -1,3 +1,5 @@
+"""Provides functions for unrolling formula intermediate values symvolically."""
+
from typing import List, Tuple
from astunparse import unparse