aboutsummaryrefslogtreecommitdiffhomepage
path: root/pyecsca/ec/params.py
diff options
context:
space:
mode:
Diffstat (limited to 'pyecsca/ec/params.py')
-rw-r--r--pyecsca/ec/params.py155
1 files changed, 133 insertions, 22 deletions
diff --git a/pyecsca/ec/params.py b/pyecsca/ec/params.py
index 8344901..82a42bd 100644
--- a/pyecsca/ec/params.py
+++ b/pyecsca/ec/params.py
@@ -4,6 +4,7 @@ Provides functions for obtaining domain parameters from the `std-curves <https:/
It also provides a domain parameter class and a class for a whole category of domain parameters.
"""
import json
+import csv
from sympy import Poly, FF, symbols, sympify
from astunparse import unparse
from io import RawIOBase, BufferedIOBase
@@ -41,13 +42,13 @@ class DomainParameters:
category: Optional[str]
def __init__(
- self,
- curve: EllipticCurve,
- generator: Point,
- order: int,
- cofactor: int,
- name: Optional[str] = None,
- category: Optional[str] = None,
+ self,
+ curve: EllipticCurve,
+ generator: Point,
+ order: int,
+ cofactor: int,
+ name: Optional[str] = None,
+ category: Optional[str] = None,
):
self.curve = curve
self.generator = generator
@@ -60,10 +61,10 @@ class DomainParameters:
if not isinstance(other, DomainParameters):
return False
return (
- self.curve == other.curve
- and self.generator == other.generator
- and self.order == other.order
- and self.cofactor == other.cofactor
+ self.curve == other.curve
+ and self.generator == other.generator
+ and self.order == other.order
+ and self.cofactor == other.cofactor
)
def __hash__(self):
@@ -176,9 +177,9 @@ def _create_params(curve, coords, infty):
for curve_param, value in params.items():
expr = expr.subs(curve_param, k(value))
if (
- len(expr.free_symbols) > 1
- or (param := str(expr.free_symbols.pop()))
- not in coord_model.parameters
+ len(expr.free_symbols) > 1
+ or (param := str(expr.free_symbols.pop()))
+ not in coord_model.parameters
):
raise ValueError(
f"This coordinate model couldn't be loaded due to an unsupported assumption ({assumption_string})."
@@ -230,9 +231,9 @@ def _create_params(curve, coords, infty):
@public
def load_category(
- file: Union[str, Path, BinaryIO, IO[bytes]],
- coords: Union[str, Callable[[str], str]],
- infty: Union[bool, Callable[[str], bool]] = True,
+ file: Union[str, Path, BinaryIO, IO[bytes]],
+ coords: Union[str, Callable[[str], str]],
+ infty: Union[bool, Callable[[str], bool]] = True,
) -> DomainParameterCategory:
"""
Load a category of domain parameters containing several curves from a JSON file.
@@ -268,7 +269,7 @@ def load_category(
@public
def load_params(
- file: Union[str, Path, BinaryIO], coords: str, infty: bool = True
+ file: Union[str, Path, BinaryIO], coords: str, infty: bool = True
) -> DomainParameters:
"""
Load a curve from a JSON file.
@@ -291,10 +292,120 @@ def load_params(
@public
+def load_params_ecgen(
+ file: Union[str, Path, BinaryIO], coords: str, infty: bool = True
+) -> DomainParameters:
+ """
+ Load a curve from a file that is output of `ecgen <https://github.com/J08nY/ecgen>`_.
+
+ :param file: The file to load from.
+ :param coords: The name of the coordinate system to use.
+ :param infty: Whether to use the special :py:class:InfinityPoint (`True`) or try to use the
+ point at infinity of the coordinate system.
+ :return: The curve.
+ """
+ if isinstance(file, (str, Path)):
+ with open(file, "rb") as f:
+ ecgen = json.load(f)
+ elif isinstance(file, (RawIOBase, BufferedIOBase, BinaryIO)):
+ ecgen = json.load(file)
+ else:
+ raise TypeError
+ ecgen = ecgen[0]
+ if "m" in ecgen["field"]:
+ raise ValueError("Binary extension field curves not supported")
+ if len(ecgen["subgroups"]) != 1:
+ raise ValueError("Can not represent curve with two subgroups.")
+ curve_dict = {
+ "form": "Weierstrass",
+ "field": {
+ "type": "Prime",
+ "p": ecgen["field"]["p"]
+ },
+ "order": ecgen["subgroups"][0]["order"], # Take just the first subgroup
+ "cofactor": ecgen["subgroups"][0]["cofactor"],
+ "params": {
+ "a": {
+ "raw": ecgen["a"]
+ },
+ "b": {
+ "raw": ecgen["b"]
+ }
+ },
+ "generator": {
+ "x": {
+ "raw": ecgen["subgroups"][0]["x"]
+ },
+ "y": {
+ "raw": ecgen["subgroups"][0]["y"]
+ }
+ },
+ "name": None,
+ "category": None
+ }
+ return _create_params(curve_dict, coords, infty)
+
+
+@public
+def load_params_ectester(
+ file: Union[str, Path, BinaryIO], coords: str, infty: bool = True
+) -> DomainParameters:
+ """
+ Load a curve from a file that uses the format of `ECTester <https://github.com/crocs-muni/ECTester>`_.
+
+ :param file: The file to load from.
+ :param coords: The name of the coordinate system to use.
+ :param infty: Whether to use the special :py:class:InfinityPoint (`True`) or try to use the
+ point at infinity of the coordinate system.
+ :return: The curve.
+ """
+ if isinstance(file, (str, Path)):
+ with open(file, "r") as f:
+ reader = csv.reader(f)
+ line = next(iter(reader))
+ elif isinstance(file, (RawIOBase, BufferedIOBase, BinaryIO)):
+ reader = csv.reader(list(map(lambda line: line.decode(), file.readlines())))
+ line = next(iter(reader))
+ else:
+ raise TypeError
+ if len(line) != 7:
+ raise ValueError("Binary extension field curves not supported")
+ # line = p,a,b,gx,gy,n,h (all in hex)
+ curve_dict = {
+ "form": "Weierstrass",
+ "field": {
+ "type": "Prime",
+ "p": line[0]
+ },
+ "order": line[5],
+ "cofactor": line[6],
+ "params": {
+ "a": {
+ "raw": line[1]
+ },
+ "b": {
+ "raw": line[2]
+ }
+ },
+ "generator": {
+ "x": {
+ "raw": line[3]
+ },
+ "y": {
+ "raw": line[4]
+ }
+ },
+ "name": None,
+ "category": None
+ }
+ return _create_params(curve_dict, coords, infty)
+
+
+@public
def get_category(
- category: str,
- coords: Union[str, Callable[[str], str]],
- infty: Union[bool, Callable[[str], bool]] = True,
+ category: str,
+ coords: Union[str, Callable[[str], str]],
+ infty: Union[bool, Callable[[str], bool]] = True,
) -> DomainParameterCategory:
"""
Retrieve a category from the std-curves database at https://github.com/J08nY/std-curves.
@@ -320,7 +431,7 @@ def get_category(
@public
def get_params(
- category: str, name: str, coords: str, infty: bool = True
+ category: str, name: str, coords: str, infty: bool = True
) -> DomainParameters:
"""
Retrieve a curve from a set of stored parameters.