aboutsummaryrefslogtreecommitdiff
path: root/pyecsca/ec/coordinates.py
blob: d1b7870d710e5ae442de9260d139f6c560f8437d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from ast import parse, Expression
from pkg_resources import resource_listdir, resource_isdir, resource_stream
from typing import List, Any, MutableMapping

from .formula import Formula, AdditionFormula, DoublingFormula, TriplingFormula, DifferentialAdditionFormula, LadderFormula, ScalingFormula

class CoordinateModel(object):
    name: str
    full_name: str
    curve_model: Any
    variables: List[str]
    satisfying: List[Expression]
    parameters: List[str]
    assumptions: List[Expression]
    formulas: MutableMapping[str, Formula]

    def __init__(self, dir_path: str, name: str, curve_model: Any):
        self.name = name
        self.curve_model = curve_model
        self.variables = []
        self.satisfying = []
        self.parameters = []
        self.assumptions = []
        self.formulas = {}
        for fname in resource_listdir(__name__, dir_path):
            file_path = dir_path + "/" + fname
            if resource_isdir(__name__, file_path):
                self.__read_formula_dir(file_path, fname)
            else:
                self.__read_coordinates_file(file_path)

    def __read_formula_dir(self, dir_path, formula_type):
        for fname in resource_listdir(__name__, dir_path):
            if fname.endswith(".op3"):
                continue
            if formula_type == "addition":
                cls = AdditionFormula
            elif formula_type == "doubling":
                cls = DoublingFormula
            elif formula_type == "tripling":
                cls = TriplingFormula
            elif formula_type == "diffadd":
                cls = DifferentialAdditionFormula
            elif formula_type == "ladder":
                cls = LadderFormula
            elif formula_type == "scaling":
                cls = ScalingFormula
            else:
                cls = Formula
            self.formulas[fname] = cls(dir_path + "/" + fname, fname, self)

    def __read_coordinates_file(self, file_path):
        with resource_stream(__name__, file_path) as f:
            line = f.readline().decode("ascii")
            while line:
                line = line[:-1]
                if line.startswith("name"):
                    self.full_name = line[5:]
                elif line.startswith("variable"):
                    self.variables.append(line[9:])
                elif line.startswith("satisfying"):
                    self.satisfying.append(parse(line[11:].replace("=", "==").replace("^", "**"), mode="eval"))
                elif line.startswith("parameter"):
                    self.parameters.append(line[10:])
                elif line.startswith("assume"):
                    self.assumptions.append(
                        parse(line[7:].replace("=", "==").replace("^", "**"), mode="eval"))
                line = f.readline().decode("ascii")

    def __repr__(self):
        return "CoordinateModel(\"{}\" on {})".format(self.name, self.curve_model.name)