-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfields.py
130 lines (88 loc) · 3.58 KB
/
fields.py
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
from utils.fields import Field
# This is the basefield(modulus) assosciated with the bandersnatch curve
BASE_FIELD = 52435875175126190479447740508185965837690552500527637822603658699938581184513
# This is the scalar field(order) assosciated with the bandersnatch curve
SCALAR_FIELD = 13108968793781547619861935127046491459309155893440570251786403306729687672801
# (p-1)/2
Q_MIN_ONE_DIV_2_BASE_FIELD = (BASE_FIELD - 1) // 2
# (p-1)/2
Q_MIN_ONE_DIV_2_SCALAR_FIELD = (SCALAR_FIELD - 1) // 2
BYTE_LEN = 32
class Fp(Field):
"""
A generic implementation of a finite field over the modulus of the bandersnatch curve
"""
def __init__(self, value=None, generic_field=None) -> None:
if generic_field is not None:
assert generic_field.modulus == BASE_FIELD
super().__init__(generic_field.value, BASE_FIELD)
return
super().__init__(value, BASE_FIELD)
def zero() -> 'Fp':
return Fp(None, Field.zero(BASE_FIELD))
def one() -> 'Fp':
return Fp(None, Field.one(BASE_FIELD))
def from_bytes(bytes) -> 'Fp':
return Fp(None, Field.from_bytes(bytes, BASE_FIELD))
def from_bytes_reduce(bytes) -> 'Fp':
return Fp(None, Field.from_bytes_reduce(bytes, BASE_FIELD))
def to_bytes(self) -> bytes:
return super().to_bytes(BYTE_LEN)
def lexographically_largest(self) -> bool:
return super().lexographically_largest(Q_MIN_ONE_DIV_2_BASE_FIELD)
def multi_inv(values) -> list['Fp']:
result = []
inverses = Field.multi_inv(values)
for inv in inverses:
result.append(Fp(None, inv))
return result
# Method overloads
def __add__(self, other):
return Fp(None, super().__add__(other))
def __sub__(self, other):
return Fp(None, super().__sub__(other))
def __mul__(self, other):
return Fp(None, super().__mul__(other))
def __neg__(self):
return Fp(None, super().__neg__())
def __truediv__(self, other):
return Fp(None, super().__truediv__(other))
class Fr(Field):
"""
A generic implementation of a finite field over the order of the bandersnatch curve
"""
def __init__(self, value=None, generic_field=None) -> None:
if generic_field is not None:
assert generic_field.modulus == SCALAR_FIELD
super().__init__(generic_field.value, SCALAR_FIELD)
return
super().__init__(value, SCALAR_FIELD)
def zero() -> 'Fr':
return Fr(None, Field.zero(SCALAR_FIELD))
def one() -> 'Fr':
return Fr(None, Field.one(SCALAR_FIELD))
def from_bytes(bytes) -> 'Fr':
return Fr(None, Field.from_bytes(bytes, SCALAR_FIELD))
def from_bytes_reduce(bytes) -> 'Fr':
return Fr(None, Field.from_bytes_reduce(bytes, SCALAR_FIELD))
def to_bytes(self) -> 'Fr':
return super().to_bytes(BYTE_LEN)
def lexographically_largest(self) -> bool:
return super().lexographically_largest(Q_MIN_ONE_DIV_2_SCALAR_FIELD)
def multi_inv(values) -> list['Fr']:
result = []
inverses = Field.multi_inv(values)
for inv in inverses:
result.append(Fr(None, inv))
return result
# Method Overloads
def __add__(self, other):
return Fr(None, super().__add__(other))
def __sub__(self, other):
return Fr(None, super().__sub__(other))
def __mul__(self, other):
return Fr(None, super().__mul__(other))
def __neg__(self):
return Fr(None, super().__neg__())
def __truediv__(self, other):
return Fr(None, super().__truediv__(other))