Source code for pyecsca.ec.formula.efd
""""""
from copy import copy
from public import public
from importlib_resources.abc import Traversable
from typing import Any
from .code import CodeFormula
from .base import (
Formula,
CodeOp,
AdditionFormula,
DoublingFormula,
TriplingFormula,
NegationFormula,
ScalingFormula,
DifferentialAdditionFormula,
LadderFormula,
)
from ...misc.utils import pexec, peval
class EFDFormula(Formula):
"""Formula from the [EFD]_."""
def __new__(cls, *args, **kwargs):
_, _, name, coordinate_model = args
if name in coordinate_model.formulas:
return coordinate_model.formulas[name]
return object.__new__(cls)
def __init__(
self,
meta_path: Traversable,
op3_path: Traversable,
name: str,
coordinate_model: Any,
):
self.name = name
self.coordinate_model = coordinate_model
self.meta = {}
self.parameters = []
self.assumptions = []
self.code = []
self.unified = False
self.__read_meta_file(meta_path)
self.__read_op3_file(op3_path)
def __read_meta_file(self, path: Traversable):
with path.open("rb") as f:
line = f.readline().decode("ascii").rstrip()
while line:
if line.startswith("source"):
self.meta["source"] = line[7:]
elif line.startswith("parameter"):
self.parameters.append(line[10:])
elif line.startswith("assume"):
self.assumptions.append(
peval(line[7:].replace("=", "==").replace("^", "**"))
)
elif line.startswith("unified"):
self.unified = True
line = f.readline().decode("ascii").rstrip()
def __read_op3_file(self, path: Traversable):
with path.open("rb") as f:
for line in f.readlines():
code_module = pexec(line.decode("ascii").replace("^", "**"))
self.code.append(CodeOp(code_module))
def to_code(self) -> CodeFormula:
for klass in CodeFormula.__subclasses__():
if self.shortname == klass.shortname:
return klass(self.name, copy(self.code), self.coordinate_model, copy(self.parameters), copy(self.assumptions), self.unified)
raise TypeError(f"CodeFormula not found for {self.__class__}.")
def __getnewargs__(self):
return None, None, self.name, self.coordinate_model
def __getstate__(self):
return {}
def __setstate__(self, state):
pass
def __eq__(self, other):
if not isinstance(other, EFDFormula):
return False
return (
self.name == other.name and self.coordinate_model == other.coordinate_model
)
def __hash__(self):
return hash((self.coordinate_model, self.name))