aboutsummaryrefslogtreecommitdiffhomepage
path: root/pyecsca
diff options
context:
space:
mode:
authorJ08nY2024-07-11 15:45:54 +0200
committerJ08nY2024-07-11 15:45:54 +0200
commit43e105655bd2de6b64ddb3c4ddf4b965bc196e6b (patch)
tree0cdb44eba00cad7d2e87a41e6c202f33578ae92a /pyecsca
parentb85ebefb35e2661e87a8c1be16a222bb6eae6a1f (diff)
downloadpyecsca-43e105655bd2de6b64ddb3c4ddf4b965bc196e6b.tar.gz
pyecsca-43e105655bd2de6b64ddb3c4ddf4b965bc196e6b.tar.zst
pyecsca-43e105655bd2de6b64ddb3c4ddf4b965bc196e6b.zip
Fix issues from new sympy flint use.
Diffstat (limited to 'pyecsca')
-rw-r--r--pyecsca/ec/curve.py4
-rw-r--r--pyecsca/ec/formula/base.py32
-rw-r--r--pyecsca/ec/mod.py41
-rw-r--r--pyecsca/ec/params.py7
-rw-r--r--pyecsca/sca/re/zvp.py2
5 files changed, 25 insertions, 61 deletions
diff --git a/pyecsca/ec/curve.py b/pyecsca/ec/curve.py
index 957aafc..fb3e763 100644
--- a/pyecsca/ec/curve.py
+++ b/pyecsca/ec/curve.py
@@ -120,12 +120,12 @@ class EllipticCurve:
lhs, rhs = assumption_string.split(" = ")
expr = sympify(f"{rhs} - {lhs}")
for curve_param, value in self.parameters.items():
- expr = expr.subs(curve_param, k(value))
+ expr = expr.subs(curve_param, value)
if len(expr.free_symbols) > 0:
raise ValueError(
f"Missing necessary coordinate model parameter ({assumption_string})."
)
- if k(expr) != 0:
+ if k.from_sympy(expr) != 0:
raise_unsatisified_assumption(
getconfig().ec.unsatisfied_coordinate_assumption_action,
f"Coordinate model {self.coordinate_model} has an unsatisifed assumption on the {param} parameter (0 = {expr})."
diff --git a/pyecsca/ec/formula/base.py b/pyecsca/ec/formula/base.py
index 704ba11..faccd97 100644
--- a/pyecsca/ec/formula/base.py
+++ b/pyecsca/ec/formula/base.py
@@ -8,7 +8,7 @@ from astunparse import unparse
from typing import List, Any, ClassVar, MutableMapping, Tuple, Union, Dict
from public import public
-from sympy import FF, symbols, Poly, Rational
+from sympy import FF, symbols, Poly, parse_expr
from pyecsca.ec.context import ResultAction
from pyecsca.ec import context
@@ -178,22 +178,20 @@ class Formula(ABC):
)
elif lhs in self.parameters and is_symbolic:
# Handle a symbolic assignment to a new parameter.
- k = FF(field)
expr = sympify(rhs, evaluate=False)
for curve_param, value in params.items():
if isinstance(value, SymbolicMod):
expr = expr.subs(curve_param, value.x)
else:
- expr = expr.subs(curve_param, k(value))
+ expr = expr.subs(curve_param, int(value))
params[lhs] = SymbolicMod(expr, field)
else:
- k = FF(field)
expr = sympify(f"{rhs} - {lhs}", evaluate=False)
for curve_param, value in params.items():
if isinstance(value, SymbolicMod):
expr = expr.subs(curve_param, value.x)
else:
- expr = expr.subs(curve_param, k(value))
+ expr = expr.subs(curve_param, int(value))
if (
len(expr.free_symbols) > 1
or (param := str(expr.free_symbols.pop())) not in self.parameters
@@ -201,31 +199,17 @@ class Formula(ABC):
raise ValueError(
f"This formula couldn't be executed due to an unsupported assumption ({assumption_string})."
)
-
- def resolve(expression, k):
- if not expression.args:
- return expression
- args = []
- for arg in expression.args:
- if isinstance(arg, Rational):
- a = arg.p
- b = arg.q
- res = k(a) / k(b)
- else:
- res = resolve(arg, k)
- args.append(res)
- return expression.func(*args)
-
- expr = resolve(simplify(expr), k)
- poly = Poly(expr, symbols(param), domain=k)
+ numerator, denominator = expr.as_numer_denom()
+ domain = FF(field)
+ poly = Poly(numerator, symbols(param), domain=domain)
roots = poly.ground_roots()
for root in roots:
- params[param] = Mod(int(root), field)
+ params[param] = Mod(int(domain.from_sympy(root)), field)
break
else:
raise UnsatisfiedAssumptionError(
f"Unsatisfied assumption in the formula ({assumption_string}).\n"
- f"'{expr}' has no roots in the base field {k}."
+ f"'{expr}' has no roots in the base field GF({field})."
)
def __call__(self, field: int, *points: Any, **params: Mod) -> Tuple[Any, ...]:
diff --git a/pyecsca/ec/mod.py b/pyecsca/ec/mod.py
index 07b2734..2aa4bdd 100644
--- a/pyecsca/ec/mod.py
+++ b/pyecsca/ec/mod.py
@@ -457,27 +457,6 @@ class Undefined(Mod):
return NotImplemented
-@lru_cache
-def __ff_cache(n):
- return FF(n)
-
-
-def _symbolic_check(func):
- @wraps(func)
- def method(self, other):
- if type(self) is not type(other):
- if type(other) is int:
- other = self.__class__(__ff_cache(self.n)(other), self.n)
- else:
- other = self.__class__(other, self.n)
- else:
- if self.n != other.n:
- raise ValueError
- return func(self, other)
-
- return method
-
-
@public
class SymbolicMod(Mod):
"""A symbolic element x of ℤₙ (implemented using sympy)."""
@@ -493,19 +472,19 @@ class SymbolicMod(Mod):
self.x = x
self.n = n
- @_symbolic_check
+ @_check
def __add__(self, other) -> "SymbolicMod":
return self.__class__((self.x + other.x), self.n)
- @_symbolic_check
+ @_check
def __radd__(self, other) -> "SymbolicMod":
return self + other
- @_symbolic_check
+ @_check
def __sub__(self, other) -> "SymbolicMod":
return self.__class__((self.x - other.x), self.n)
- @_symbolic_check
+ @_check
def __rsub__(self, other) -> "SymbolicMod":
return -self + other
@@ -527,27 +506,27 @@ class SymbolicMod(Mod):
def __invert__(self) -> "SymbolicMod":
return self.inverse()
- @_symbolic_check
+ @_check
def __mul__(self, other) -> "SymbolicMod":
return self.__class__(self.x * other.x, self.n)
- @_symbolic_check
+ @_check
def __rmul__(self, other) -> "SymbolicMod":
return self * other
- @_symbolic_check
+ @_check
def __truediv__(self, other) -> "SymbolicMod":
return self * ~other
- @_symbolic_check
+ @_check
def __rtruediv__(self, other) -> "SymbolicMod":
return ~self * other
- @_symbolic_check
+ @_check
def __floordiv__(self, other) -> "SymbolicMod":
return self * ~other
- @_symbolic_check
+ @_check
def __rfloordiv__(self, other) -> "SymbolicMod":
return ~self * other
diff --git a/pyecsca/ec/params.py b/pyecsca/ec/params.py
index d9e05e5..d5477b6 100644
--- a/pyecsca/ec/params.py
+++ b/pyecsca/ec/params.py
@@ -220,7 +220,7 @@ def _create_params(curve, coords, infty):
lhs, rhs = assumption_string.split(" = ")
expr = sympify(f"{rhs} - {lhs}")
for curve_param, value in params.items():
- expr = expr.subs(curve_param, k(value))
+ expr = expr.subs(curve_param, value)
if (
len(expr.free_symbols) > 1
or (param := str(expr.free_symbols.pop()))
@@ -229,10 +229,11 @@ def _create_params(curve, coords, infty):
raise ValueError(
f"This coordinate model couldn't be loaded due to an unsupported assumption ({assumption_string})."
)
- poly = Poly(expr, symbols(param), domain=k)
+ numerator, denominator = expr.as_numer_denom()
+ poly = Poly(numerator, symbols(param), domain=k)
roots = poly.ground_roots()
for root in roots:
- params[param] = Mod(int(root), field)
+ params[param] = Mod(int(k.from_sympy(root)), field)
break
else:
raise_unsatisified_assumption(
diff --git a/pyecsca/sca/re/zvp.py b/pyecsca/sca/re/zvp.py
index a697388..8005382 100644
--- a/pyecsca/sca/re/zvp.py
+++ b/pyecsca/sca/re/zvp.py
@@ -180,7 +180,7 @@ def compute_factor_set(
# Go over all the factors of the intermediate, forget the power
for factor, power in factor_list:
# Remove unnecessary variables from the Poly
- reduced = factor.exclude()
+ reduced = factor.exclude() if not factor.is_univariate else factor
# If there are only curve parameters, we do not care about the polynomial
if set(reduced.gens).issubset(curve_params): # type: ignore[attr-defined]
continue