aboutsummaryrefslogtreecommitdiff
path: root/pyecsca/misc/cfg.py
diff options
context:
space:
mode:
authorJ08nY2020-12-26 18:53:30 +0100
committerJ08nY2020-12-26 18:53:30 +0100
commitb35bb2aea9ea69dac0cba57766f64cb171c8d743 (patch)
tree210af79765218ac4858adf869c2d32003b69b9d9 /pyecsca/misc/cfg.py
parentc2ad6329efa5d0024dc0b281b86738fbadaf7b92 (diff)
downloadpyecsca-b35bb2aea9ea69dac0cba57766f64cb171c8d743.tar.gz
pyecsca-b35bb2aea9ea69dac0cba57766f64cb171c8d743.tar.zst
pyecsca-b35bb2aea9ea69dac0cba57766f64cb171c8d743.zip
Diffstat (limited to 'pyecsca/misc/cfg.py')
-rw-r--r--pyecsca/misc/cfg.py145
1 files changed, 145 insertions, 0 deletions
diff --git a/pyecsca/misc/cfg.py b/pyecsca/misc/cfg.py
new file mode 100644
index 0000000..b1c4007
--- /dev/null
+++ b/pyecsca/misc/cfg.py
@@ -0,0 +1,145 @@
+from copy import deepcopy
+from contextvars import ContextVar, Token
+
+from public import public
+
+
+@public
+class ECConfig(object):
+ """Configuration for the :py:mod:`pyecsca.ec` package."""
+ _no_inverse_action: str = "error"
+ _non_residue_action: str = "error"
+ _unsatisfied_formula_assumption_action: str = "error"
+ _unsatisfied_coordinate_assumption_action: str = "error"
+ _mod_implementation: str = "gmp"
+
+ @property
+ def no_inverse_action(self) -> str:
+ """
+ The action to take when a non-invertible element is to be inverted. One of:
+
+ - `"error"`: Raise :py:class:`pyecsca.ec.error.NonInvertibleError`.
+ - `"warning"`: Raise :py:class:`pyecsca.ec.error.NonInvertibleWarning`.
+ - `"ignore"`: Ignore the event and compute as if nothing happened."""
+ return self._no_inverse_action
+
+ @no_inverse_action.setter
+ def no_inverse_action(self, value: str):
+ if value not in ("error", "warning", "ignore"):
+ raise ValueError("Action has to be one of 'error', 'warning', 'ignore'.")
+ self._no_inverse_action = value
+
+ @property
+ def non_residue_action(self) -> str:
+ """
+ The action to take when a the square-root of a non-residue is to be computed. One of:
+
+ - `"error"`: Raise :py:class:`pyecsca.ec.error.NonResidueError`.
+ - `"warning"`: Raise :py:class:`pyecsca.ec.error.NonResidueWarning`.
+ - `"ignore"`: Ignore the event and compute as if nothing happened."""
+ return self._non_residue_action
+
+ @non_residue_action.setter
+ def non_residue_action(self, value: str):
+ if value not in ("error", "warning", "ignore"):
+ raise ValueError("Action has to be one of 'error', 'warning', 'ignore'.")
+ self._non_residue_action = value
+
+ @property
+ def unsatisfied_formula_assumption_action(self) -> str:
+ """
+ The action to take when a formula assumption is unsatisfied during execution.
+ This works for assumption that can be ignored without a fatal error,
+ which are those that are not used to compute a value of an undefined parameter.
+ For example, things of the form `Z1 = 1`.
+ One of:
+
+ - `"error"`: Raise :py:class:`pyecsca.ec.error.UnsatisfiedAssumptionError`.
+ - `"warning"`: Raise :py:class:`pyecsca.ec.error.UnsatisfiedAssumptionWarning`.
+ - `"ignore"`: Ignore the event and compute as if nothing happened.
+ """
+ return self._unsatisfied_formula_assumption_action
+
+ @unsatisfied_formula_assumption_action.setter
+ def unsatisfied_formula_assumption_action(self, value: str):
+ if value not in ("error", "warning", "ignore"):
+ raise ValueError("Action has to be one of 'error', 'warning', 'ignore'.")
+ self._unsatisfied_formula_assumption_action = value
+
+ @property
+ def unsatisfied_coordinate_assumption_action(self) -> str:
+ """
+ The action to take when a coordinate assumption is unsatisfied during curve creation.
+ This works for assumption that can be ignored without a fatal error,
+ which are those that are not used to compute a value of an undefined parameter.
+ For example, things of the form `a = -1`.
+ One of:
+
+ - `"error"`: Raise :py:class:`pyecsca.ec.error.UnsatisfiedAssumptionError`.
+ - `"warning"`: Raise :py:class:`pyecsca.ec.error.UnsatisfiedAssumptionWarning`.
+ - `"ignore"`: Ignore the event and compute as if nothing happened.
+ """
+ return self._unsatisfied_coordinate_assumption_action
+
+ @unsatisfied_coordinate_assumption_action.setter
+ def unsatisfied_coordinate_assumption_action(self, value: str):
+ if value not in ("error", "warning", "ignore"):
+ raise ValueError("Action has to be one of 'error', 'warning', 'ignore'.")
+ self._unsatisfied_coordinate_assumption_action = value
+
+ @property
+ def mod_implementation(self) -> str:
+ """
+ The selected :py:class:`pyecsca.ec.mod.Mod` implementation. One of:
+
+ - `"gmp"`: Requires the GMP library and `gmpy2` package.
+ - `"python"`: Doesn't require anything.
+ """
+ return self._mod_implementation
+
+ @mod_implementation.setter
+ def mod_implementation(self, value: str):
+ if value not in ("python", "gmp"):
+ raise ValueError(f"Bad Mod implementaiton, can be one of 'python' or 'gmp'.")
+ self._mod_implementation = value
+
+
+@public
+class Config(object):
+ """A runtime configuration for the library."""
+ ec: ECConfig
+ """Configuration for the :py:mod:`pyecsca.ec` package."""
+
+ def __init__(self):
+ self.ec = ECConfig()
+
+
+_config: ContextVar[Config] = ContextVar("config", default=Config())
+
+
+@public
+def getconfig() -> Config:
+ return _config.get()
+
+
+@public
+def setconfig(cfg: Config) -> Token:
+ return _config.set(cfg)
+
+
+@public
+def resetconfig(token: Token):
+ _config.reset(token)
+
+
+@public
+class TemporaryConfig(object):
+ def __init__(self):
+ self.new_config = deepcopy(getconfig())
+
+ def __enter__(self) -> Config:
+ self.token = setconfig(self.new_config)
+ return self.new_config
+
+ def __exit__(self, t, v, tb):
+ resetconfig(self.token) \ No newline at end of file