1
2
3
4
5
6
7 package fiat
8
9 import (
10 "crypto/subtle"
11 "errors"
12 )
13
14
15
16
17 type P521Element struct {
18
19
20
21
22
23
24
25 x [9]uint64
26 }
27
28
29 func (e *P521Element) One() *P521Element {
30 *e = P521Element{}
31 e.x[0] = 1
32 return e
33 }
34
35
36 func (e *P521Element) Equal(t *P521Element) int {
37 eBytes := e.Bytes()
38 tBytes := t.Bytes()
39 return subtle.ConstantTimeCompare(eBytes, tBytes)
40 }
41
42 var p521ZeroEncoding = new(P521Element).Bytes()
43
44
45 func (e *P521Element) IsZero() int {
46 eBytes := e.Bytes()
47 return subtle.ConstantTimeCompare(eBytes, p521ZeroEncoding)
48 }
49
50
51 func (e *P521Element) Set(t *P521Element) *P521Element {
52 e.x = t.x
53 return e
54 }
55
56
57 func (e *P521Element) Bytes() []byte {
58
59
60 var out [66]byte
61 p521ToBytes(&out, &e.x)
62 return out[:]
63 }
64
65
66
67
68 func (e *P521Element) SetBytes(v []byte) (*P521Element, error) {
69 if len(v) != 66 || v[65] > 1 {
70 return nil, errors.New("invalid P-521 field encoding")
71 }
72 var in [66]byte
73 copy(in[:], v)
74 p521FromBytes(&e.x, &in)
75 return e, nil
76 }
77
78
79 func (e *P521Element) Add(t1, t2 *P521Element) *P521Element {
80 p521Add(&e.x, &t1.x, &t2.x)
81 p521Carry(&e.x, &e.x)
82 return e
83 }
84
85
86 func (e *P521Element) Sub(t1, t2 *P521Element) *P521Element {
87 p521Sub(&e.x, &t1.x, &t2.x)
88 p521Carry(&e.x, &e.x)
89 return e
90 }
91
92
93 func (e *P521Element) Mul(t1, t2 *P521Element) *P521Element {
94 p521CarryMul(&e.x, &t1.x, &t2.x)
95 return e
96 }
97
98
99 func (e *P521Element) Square(t *P521Element) *P521Element {
100 p521CarrySquare(&e.x, &t.x)
101 return e
102 }
103
104
105 func (v *P521Element) Select(a, b *P521Element, cond int) *P521Element {
106 p521Selectznz(&v.x, p521Uint1(cond), &b.x, &a.x)
107 return v
108 }
109
110
111
112
113 func (e *P521Element) Invert(t *P521Element) *P521Element {
114
115
116
117
118 var t1, t2 = new(P521Element), new(P521Element)
119
120
121 t1.Square(t)
122
123
124 t1.Mul(t, t1)
125
126
127 t2.Square(t1)
128 t2.Square(t2)
129
130
131 t1.Mul(t1, t2)
132
133
134 t2.Square(t1)
135 for i := 0; i < 3; i++ {
136 t2.Square(t2)
137 }
138
139
140 t1.Mul(t1, t2)
141
142
143 t2.Square(t1)
144 for i := 0; i < 7; i++ {
145 t2.Square(t2)
146 }
147 t1.Mul(t1, t2)
148
149
150 t2.Square(t1)
151 for i := 0; i < 15; i++ {
152 t2.Square(t2)
153 }
154 t1.Mul(t1, t2)
155
156
157 t2.Square(t1)
158 for i := 0; i < 31; i++ {
159 t2.Square(t2)
160 }
161 t1.Mul(t1, t2)
162
163
164 t2.Square(t1)
165 t2.Mul(t2, t)
166
167
168 for i := 0; i < 64; i++ {
169 t2.Square(t2)
170 }
171 t1.Mul(t1, t2)
172
173
174 t2.Square(t1)
175 t2.Mul(t2, t)
176
177
178 for i := 0; i < 129; i++ {
179 t2.Square(t2)
180 }
181 t1.Mul(t1, t2)
182
183
184 t2.Square(t1)
185 t2.Mul(t2, t)
186
187
188 for i := 0; i < 259; i++ {
189 t2.Square(t2)
190 }
191 t1.Mul(t1, t2)
192
193
194 t1.Square(t1)
195 t1.Square(t1)
196 return e.Mul(t1, t)
197 }
198
View as plain text