diff options
| author | J08nY | 2020-10-06 22:25:51 +0200 |
|---|---|---|
| committer | J08nY | 2020-10-06 22:25:51 +0200 |
| commit | 6a07921cd9ce89e0d4e56dec01a6704ee1553110 (patch) | |
| tree | 83d3e772852f555fa74e009cd76fc8939c4857cf | |
| parent | a2fcccb79a1a148b3409d26c5ea95c637af7b7b1 (diff) | |
| download | pyecsca-6a07921cd9ce89e0d4e56dec01a6704ee1553110.tar.gz pyecsca-6a07921cd9ce89e0d4e56dec01a6704ee1553110.tar.zst pyecsca-6a07921cd9ce89e0d4e56dec01a6704ee1553110.zip | |
Add way of importing parameters from file.
| -rw-r--r-- | pyecsca/ec/params.py | 92 | ||||
| m--------- | pyecsca/ec/std | 0 | ||||
| -rw-r--r-- | pyecsca/sca/trace_set/hdf5.py | 4 | ||||
| -rw-r--r-- | pyecsca/sca/trace_set/pickle.py | 2 | ||||
| -rw-r--r-- | test/data/curve.json | 29 | ||||
| -rw-r--r-- | test/ec/test_params.py | 9 |
6 files changed, 102 insertions, 34 deletions
diff --git a/pyecsca/ec/params.py b/pyecsca/ec/params.py index d938333..fea5988 100644 --- a/pyecsca/ec/params.py +++ b/pyecsca/ec/params.py @@ -1,6 +1,8 @@ import json +from io import RawIOBase, BufferedIOBase from os.path import join -from typing import Optional, Dict, Union +from pathlib import Path +from typing import Optional, Dict, Union, BinaryIO from pkg_resources import resource_listdir, resource_isdir, resource_stream from public import public @@ -56,32 +58,7 @@ class DomainParameters(object): return f"{self.__class__.__name__}({self.curve!r}, {self.generator!r}, {self.order}, {self.cofactor})" -@public -def get_params(category: str, name: str, coords: str, infty: bool = True) -> DomainParameters: - """ - Retrieve a curve from a set of stored parameters. Uses the std-curves database at - https://github.com/J08nY/std-curves. - - :param category: The category of the curve. - :param name: The name of the curve. - :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. - """ - listing = resource_listdir(__name__, "std") - categories = list(entry for entry in listing if resource_isdir(__name__, join("std", entry))) - if category not in categories: - raise ValueError("Category {} not found.".format(category)) - json_path = join("std", category, "curves.json") - with resource_stream(__name__, json_path) as f: - category_json = json.load(f) - for curve in category_json["curves"]: - if curve["name"] == name: - break - else: - raise ValueError("Curve {} not found in category {}.".format(name, category)) - +def _create_params(curve, coords, infty): if curve["field"]["type"] == "Binary": raise ValueError("Binary field curves are currently not supported.") if curve["field"]["type"] == "Extension": @@ -122,7 +99,8 @@ def get_params(category: str, name: str, coords: str, infty: bool = True) -> Dom exec(compiled, None, alocals) for param, value in alocals.items(): if params[param] != value: - raise ValueError(f"Coordinate model {coord_model} has an unsatisifed assumption on the {param} parameter (= {value}).") + raise ValueError( + f"Coordinate model {coord_model} has an unsatisifed assumption on the {param} parameter (= {value}).") # Construct the point at infinity infinity: Point @@ -143,10 +121,64 @@ def get_params(category: str, name: str, coords: str, infty: bool = True) -> Dom infinity_coords[coordinate] = value infinity = Point(coord_model, **infinity_coords) elliptic_curve = EllipticCurve(model, coord_model, field, infinity, params) # type: ignore[arg-type] - affine = Point(AffineCoordinateModel(model), x=Mod(int(curve["generator"]["x"]["raw"], 16), field), + affine = Point(AffineCoordinateModel(model), + x=Mod(int(curve["generator"]["x"]["raw"], 16), field), y=Mod(int(curve["generator"]["y"]["raw"], 16), field)) if not isinstance(coord_model, AffineCoordinateModel): generator = affine.to_model(coord_model, elliptic_curve) else: generator = affine - return DomainParameters(elliptic_curve, generator, order, cofactor, name, category) + return DomainParameters(elliptic_curve, generator, order, cofactor, curve["name"], curve["category"]) + + +@public +def load_params(file: Union[str, Path, BinaryIO], coords: str, infty: bool = True) -> DomainParameters: + """ + + :param input: + :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. + """ + curve = None + if isinstance(file, (str, Path)): + with open(file, "rb") as f: + curve = json.load(f) + elif isinstance(file, (RawIOBase, BufferedIOBase, BinaryIO)): + curve = json.load(file) + if curve["field"]["type"] == "Binary": + raise ValueError("Binary field curves are currently not supported.") + if curve["field"]["type"] == "Extension": + raise ValueError("Extension field curves are currently not supported.") + + return _create_params(curve, coords, infty) + + +@public +def get_params(category: str, name: str, coords: str, infty: bool = True) -> DomainParameters: + """ + Retrieve a curve from a set of stored parameters. Uses the std-curves database at + https://github.com/J08nY/std-curves. + + :param category: The category of the curve. + :param name: The name of the curve. + :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. + """ + listing = resource_listdir(__name__, "std") + categories = list(entry for entry in listing if resource_isdir(__name__, join("std", entry))) + if category not in categories: + raise ValueError("Category {} not found.".format(category)) + json_path = join("std", category, "curves.json") + with resource_stream(__name__, json_path) as f: + category_json = json.load(f) + for curve in category_json["curves"]: + if curve["name"] == name: + break + else: + raise ValueError("Curve {} not found in category {}.".format(name, category)) + + return _create_params(curve, coords, infty) diff --git a/pyecsca/ec/std b/pyecsca/ec/std -Subproject d94f7b9e38af8318eda186e6d7acabea57b6d85 +Subproject 867e7aeafda3304fb802588d887ef35f2523f0f diff --git a/pyecsca/sca/trace_set/hdf5.py b/pyecsca/sca/trace_set/hdf5.py index 7eeeaf9..0a45e01 100644 --- a/pyecsca/sca/trace_set/hdf5.py +++ b/pyecsca/sca/trace_set/hdf5.py @@ -1,9 +1,9 @@ import pickle import uuid from collections import MutableMapping -from io import RawIOBase, BufferedIOBase, IOBase +from io import RawIOBase, BufferedIOBase from pathlib import Path -from typing import Union, Optional, Dict, Any, List, BinaryIO +from typing import Union, Optional, List, BinaryIO import h5py import numpy as np diff --git a/pyecsca/sca/trace_set/pickle.py b/pyecsca/sca/trace_set/pickle.py index f754bbf..29b5dd2 100644 --- a/pyecsca/sca/trace_set/pickle.py +++ b/pyecsca/sca/trace_set/pickle.py @@ -1,5 +1,5 @@ import pickle -from io import BufferedIOBase, RawIOBase, IOBase +from io import BufferedIOBase, RawIOBase from pathlib import Path from typing import Union, BinaryIO diff --git a/test/data/curve.json b/test/data/curve.json new file mode 100644 index 0000000..98d9ae7 --- /dev/null +++ b/test/data/curve.json @@ -0,0 +1,29 @@ +{ + "name": "small", + "category": "test", + "desc": "A small prime order test curve.", + "field": { + "type": "Prime", + "p": "0xc5f5cd5e4a0beb9a445bd3b824e46d8b", + "bits": 128 + }, + "form": "Weierstrass", + "params": { + "a": { + "raw": "0x307c28b1209bb670e6b44f5ff6ee8118" + }, + "b": { + "raw": "0xa3206b2b16fa6dd383acc084e649782a" + } + }, + "generator": { + "x": { + "raw": "0xb805e6ee5f3cd8a9c103c3978b688391" + }, + "y": { + "raw": "0x74b0a63b1cc5aa501a9e2101c16d9939" + } + }, + "order": "0xc5f5cd5e4a0beb9b5515cd2847c4051d", + "cofactor": "0x01" +}
\ No newline at end of file diff --git a/test/ec/test_params.py b/test/ec/test_params.py index 9de813b..2873a17 100644 --- a/test/ec/test_params.py +++ b/test/ec/test_params.py @@ -3,7 +3,7 @@ from unittest import TestCase from parameterized import parameterized from pyecsca.ec.coordinates import AffineCoordinateModel -from pyecsca.ec.params import get_params +from pyecsca.ec.params import get_params, load_params class DomainParameterTests(TestCase): @@ -36,6 +36,13 @@ class DomainParameterTests(TestCase): except NotImplementedError: pass + def test_load_params(self): + params = load_params("test/data/curve.json", "projective") + try: + assert params.curve.is_on_curve(params.generator) + except NotImplementedError: + pass + @parameterized.expand([ ("no_category/some", "else"), ("secg/no_curve", "else"), |
