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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
"""
This module provides a coordinate model class.
"""
from ast import parse, Module
from os.path import join
from typing import List, Any, MutableMapping
from pkg_resources import resource_listdir, resource_isdir, resource_stream
from public import public
from .formula import (Formula, EFDFormula, AdditionEFDFormula, DoublingEFDFormula,
TriplingEFDFormula, DifferentialAdditionEFDFormula, LadderEFDFormula,
ScalingEFDFormula, NegationEFDFormula)
@public
class CoordinateModel(object):
"""A coordinate system for a particular model(form) of an elliptic curve."""
name: str
"""Name of the coordinate model"""
full_name: str
"""Full name."""
curve_model: Any
"""The curve model."""
variables: List[str]
"""Variables that the coordinate model uses."""
satisfying: List[Module]
"""Relationship between the coordinate system and affine coordinates."""
parameters: List[str]
"""Coordinate system parameters."""
assumptions: List[Module]
"""Assumptions that need to hold for the curve to use this coordinate system,
also used to compute the values of the coordinate system parameters."""
neutral: List[Module]
"""Coordinates of the neutral point in the coordinate system, might contain expressions of parameters."""
formulas: MutableMapping[str, Formula]
"""Formulas available on the coordinate system."""
def __repr__(self):
return f"{self.__class__.__name__}(\"{self.name}\" on {self.curve_model.name})"
@public
class AffineCoordinateModel(CoordinateModel):
name = "affine"
full_name = "Affine coordinates"
def __init__(self, curve_model: Any):
self.curve_model = curve_model
self.variables = ["x", "y"]
self.satisfying = []
self.parameters = []
self.assumptions = []
self.neutral = []
self.formulas = {}
def __eq__(self, other):
if not isinstance(other, AffineCoordinateModel):
return False
return self.curve_model == other.curve_model
class EFDCoordinateModel(CoordinateModel):
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.neutral = []
self.formulas = {}
for fname in resource_listdir(__name__, dir_path):
file_path = join(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
formula_types = {
"addition": AdditionEFDFormula,
"doubling": DoublingEFDFormula,
"tripling": TriplingEFDFormula,
"diffadd": DifferentialAdditionEFDFormula,
"ladder": LadderEFDFormula,
"scaling": ScalingEFDFormula,
"negation": NegationEFDFormula
}
cls = formula_types.get(formula_type, EFDFormula)
self.formulas[fname] = cls(join(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").rstrip()
while line:
if line.startswith("name"):
self.full_name = line[5:]
elif line.startswith("variable"):
self.variables.append(line[9:])
elif line.startswith("neutral"):
try:
code = parse(line[8:].replace("^", "**"), mode="exec")
self.neutral.append(code)
except SyntaxError:
pass
elif line.startswith("satisfying"):
try:
code = parse(line[11:].replace("^", "**"), mode="exec")
self.satisfying.append(code)
except SyntaxError:
pass
elif line.startswith("parameter"):
self.parameters.append(line[10:])
elif line.startswith("assume"):
self.assumptions.append(
parse(line[7:].replace("^", "**"), mode="exec"))
line = f.readline().decode("ascii").rstrip()
def __eq__(self, other):
if not isinstance(other, EFDCoordinateModel):
return False
return self.curve_model == other.curve_model and self.name == other.name
def __hash__(self):
return hash(self.curve_model) + hash(self.name)
|