1 package fp448
2
3 import (
4 "encoding/binary"
5 "math/bits"
6 )
7
8 func cmovGeneric(x, y *Elt, n uint) {
9 m := -uint64(n & 0x1)
10 x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
11 x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
12 x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
13 x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
14 x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
15 x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
16 x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
17
18 y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
19 y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
20 y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
21 y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
22 y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
23 y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
24 y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
25
26 x0 = (x0 &^ m) | (y0 & m)
27 x1 = (x1 &^ m) | (y1 & m)
28 x2 = (x2 &^ m) | (y2 & m)
29 x3 = (x3 &^ m) | (y3 & m)
30 x4 = (x4 &^ m) | (y4 & m)
31 x5 = (x5 &^ m) | (y5 & m)
32 x6 = (x6 &^ m) | (y6 & m)
33
34 binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
35 binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
36 binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
37 binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
38 binary.LittleEndian.PutUint64(x[4*8:5*8], x4)
39 binary.LittleEndian.PutUint64(x[5*8:6*8], x5)
40 binary.LittleEndian.PutUint64(x[6*8:7*8], x6)
41 }
42
43 func cswapGeneric(x, y *Elt, n uint) {
44 m := -uint64(n & 0x1)
45 x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
46 x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
47 x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
48 x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
49 x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
50 x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
51 x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
52
53 y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
54 y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
55 y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
56 y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
57 y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
58 y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
59 y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
60
61 t0 := m & (x0 ^ y0)
62 t1 := m & (x1 ^ y1)
63 t2 := m & (x2 ^ y2)
64 t3 := m & (x3 ^ y3)
65 t4 := m & (x4 ^ y4)
66 t5 := m & (x5 ^ y5)
67 t6 := m & (x6 ^ y6)
68 x0 ^= t0
69 x1 ^= t1
70 x2 ^= t2
71 x3 ^= t3
72 x4 ^= t4
73 x5 ^= t5
74 x6 ^= t6
75 y0 ^= t0
76 y1 ^= t1
77 y2 ^= t2
78 y3 ^= t3
79 y4 ^= t4
80 y5 ^= t5
81 y6 ^= t6
82
83 binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
84 binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
85 binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
86 binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
87 binary.LittleEndian.PutUint64(x[4*8:5*8], x4)
88 binary.LittleEndian.PutUint64(x[5*8:6*8], x5)
89 binary.LittleEndian.PutUint64(x[6*8:7*8], x6)
90
91 binary.LittleEndian.PutUint64(y[0*8:1*8], y0)
92 binary.LittleEndian.PutUint64(y[1*8:2*8], y1)
93 binary.LittleEndian.PutUint64(y[2*8:3*8], y2)
94 binary.LittleEndian.PutUint64(y[3*8:4*8], y3)
95 binary.LittleEndian.PutUint64(y[4*8:5*8], y4)
96 binary.LittleEndian.PutUint64(y[5*8:6*8], y5)
97 binary.LittleEndian.PutUint64(y[6*8:7*8], y6)
98 }
99
100 func addGeneric(z, x, y *Elt) {
101 x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
102 x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
103 x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
104 x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
105 x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
106 x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
107 x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
108
109 y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
110 y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
111 y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
112 y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
113 y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
114 y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
115 y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
116
117 z0, c0 := bits.Add64(x0, y0, 0)
118 z1, c1 := bits.Add64(x1, y1, c0)
119 z2, c2 := bits.Add64(x2, y2, c1)
120 z3, c3 := bits.Add64(x3, y3, c2)
121 z4, c4 := bits.Add64(x4, y4, c3)
122 z5, c5 := bits.Add64(x5, y5, c4)
123 z6, z7 := bits.Add64(x6, y6, c5)
124
125 z0, c0 = bits.Add64(z0, z7, 0)
126 z1, c1 = bits.Add64(z1, 0, c0)
127 z2, c2 = bits.Add64(z2, 0, c1)
128 z3, c3 = bits.Add64(z3, z7<<32, c2)
129 z4, c4 = bits.Add64(z4, 0, c3)
130 z5, c5 = bits.Add64(z5, 0, c4)
131 z6, z7 = bits.Add64(z6, 0, c5)
132
133 z0, c0 = bits.Add64(z0, z7, 0)
134 z1, c1 = bits.Add64(z1, 0, c0)
135 z2, c2 = bits.Add64(z2, 0, c1)
136 z3, c3 = bits.Add64(z3, z7<<32, c2)
137 z4, c4 = bits.Add64(z4, 0, c3)
138 z5, c5 = bits.Add64(z5, 0, c4)
139 z6, _ = bits.Add64(z6, 0, c5)
140
141 binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
142 binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
143 binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
144 binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
145 binary.LittleEndian.PutUint64(z[4*8:5*8], z4)
146 binary.LittleEndian.PutUint64(z[5*8:6*8], z5)
147 binary.LittleEndian.PutUint64(z[6*8:7*8], z6)
148 }
149
150 func subGeneric(z, x, y *Elt) {
151 x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
152 x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
153 x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
154 x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
155 x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
156 x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
157 x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
158
159 y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
160 y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
161 y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
162 y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
163 y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
164 y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
165 y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
166
167 z0, c0 := bits.Sub64(x0, y0, 0)
168 z1, c1 := bits.Sub64(x1, y1, c0)
169 z2, c2 := bits.Sub64(x2, y2, c1)
170 z3, c3 := bits.Sub64(x3, y3, c2)
171 z4, c4 := bits.Sub64(x4, y4, c3)
172 z5, c5 := bits.Sub64(x5, y5, c4)
173 z6, z7 := bits.Sub64(x6, y6, c5)
174
175 z0, c0 = bits.Sub64(z0, z7, 0)
176 z1, c1 = bits.Sub64(z1, 0, c0)
177 z2, c2 = bits.Sub64(z2, 0, c1)
178 z3, c3 = bits.Sub64(z3, z7<<32, c2)
179 z4, c4 = bits.Sub64(z4, 0, c3)
180 z5, c5 = bits.Sub64(z5, 0, c4)
181 z6, z7 = bits.Sub64(z6, 0, c5)
182
183 z0, c0 = bits.Sub64(z0, z7, 0)
184 z1, c1 = bits.Sub64(z1, 0, c0)
185 z2, c2 = bits.Sub64(z2, 0, c1)
186 z3, c3 = bits.Sub64(z3, z7<<32, c2)
187 z4, c4 = bits.Sub64(z4, 0, c3)
188 z5, c5 = bits.Sub64(z5, 0, c4)
189 z6, _ = bits.Sub64(z6, 0, c5)
190
191 binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
192 binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
193 binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
194 binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
195 binary.LittleEndian.PutUint64(z[4*8:5*8], z4)
196 binary.LittleEndian.PutUint64(z[5*8:6*8], z5)
197 binary.LittleEndian.PutUint64(z[6*8:7*8], z6)
198 }
199
200 func addsubGeneric(x, y *Elt) {
201 z := &Elt{}
202 addGeneric(z, x, y)
203 subGeneric(y, x, y)
204 *x = *z
205 }
206
207 func mulGeneric(z, x, y *Elt) {
208 x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
209 x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
210 x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
211 x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
212 x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
213 x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
214 x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
215
216 y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
217 y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
218 y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
219 y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
220 y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
221 y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
222 y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
223
224 yy := [7]uint64{y0, y1, y2, y3, y4, y5, y6}
225 zz := [7]uint64{}
226
227 yi := yy[0]
228 h0, l0 := bits.Mul64(x0, yi)
229 h1, l1 := bits.Mul64(x1, yi)
230 h2, l2 := bits.Mul64(x2, yi)
231 h3, l3 := bits.Mul64(x3, yi)
232 h4, l4 := bits.Mul64(x4, yi)
233 h5, l5 := bits.Mul64(x5, yi)
234 h6, l6 := bits.Mul64(x6, yi)
235
236 zz[0] = l0
237 a0, c0 := bits.Add64(h0, l1, 0)
238 a1, c1 := bits.Add64(h1, l2, c0)
239 a2, c2 := bits.Add64(h2, l3, c1)
240 a3, c3 := bits.Add64(h3, l4, c2)
241 a4, c4 := bits.Add64(h4, l5, c3)
242 a5, c5 := bits.Add64(h5, l6, c4)
243 a6, _ := bits.Add64(h6, 0, c5)
244
245 for i := 1; i < 7; i++ {
246 yi = yy[i]
247 h0, l0 = bits.Mul64(x0, yi)
248 h1, l1 = bits.Mul64(x1, yi)
249 h2, l2 = bits.Mul64(x2, yi)
250 h3, l3 = bits.Mul64(x3, yi)
251 h4, l4 = bits.Mul64(x4, yi)
252 h5, l5 = bits.Mul64(x5, yi)
253 h6, l6 = bits.Mul64(x6, yi)
254
255 zz[i], c0 = bits.Add64(a0, l0, 0)
256 a0, c1 = bits.Add64(a1, l1, c0)
257 a1, c2 = bits.Add64(a2, l2, c1)
258 a2, c3 = bits.Add64(a3, l3, c2)
259 a3, c4 = bits.Add64(a4, l4, c3)
260 a4, c5 = bits.Add64(a5, l5, c4)
261 a5, a6 = bits.Add64(a6, l6, c5)
262
263 a0, c0 = bits.Add64(a0, h0, 0)
264 a1, c1 = bits.Add64(a1, h1, c0)
265 a2, c2 = bits.Add64(a2, h2, c1)
266 a3, c3 = bits.Add64(a3, h3, c2)
267 a4, c4 = bits.Add64(a4, h4, c3)
268 a5, c5 = bits.Add64(a5, h5, c4)
269 a6, _ = bits.Add64(a6, h6, c5)
270 }
271 red64(z, &zz, &[7]uint64{a0, a1, a2, a3, a4, a5, a6})
272 }
273
274 func sqrGeneric(z, x *Elt) { mulGeneric(z, x, x) }
275
276 func red64(z *Elt, l, h *[7]uint64) {
277
278 h0 := h[0]
279 h1 := h[1]
280 h2 := h[2]
281 h3 := ((h[3] & (0xFFFFFFFF << 32)) << 1) | (h[3] & 0xFFFFFFFF)
282 h4 := (h[3] >> 63) | (h[4] << 1)
283 h5 := (h[4] >> 63) | (h[5] << 1)
284 h6 := (h[5] >> 63) | (h[6] << 1)
285 h7 := (h[6] >> 63)
286
287 l0, c0 := bits.Add64(h0, l[0], 0)
288 l1, c1 := bits.Add64(h1, l[1], c0)
289 l2, c2 := bits.Add64(h2, l[2], c1)
290 l3, c3 := bits.Add64(h3, l[3], c2)
291 l4, c4 := bits.Add64(h4, l[4], c3)
292 l5, c5 := bits.Add64(h5, l[5], c4)
293 l6, c6 := bits.Add64(h6, l[6], c5)
294 l7, _ := bits.Add64(h7, 0, c6)
295
296
297 h0 = (h[3] >> 32) | (h[4] << 32)
298 h1 = (h[4] >> 32) | (h[5] << 32)
299 h2 = (h[5] >> 32) | (h[6] << 32)
300 h3 = (h[6] >> 32) | (h[0] << 32)
301 h4 = (h[0] >> 32) | (h[1] << 32)
302 h5 = (h[1] >> 32) | (h[2] << 32)
303 h6 = (h[2] >> 32) | (h[3] << 32)
304
305 l0, c0 = bits.Add64(l0, h0, 0)
306 l1, c1 = bits.Add64(l1, h1, c0)
307 l2, c2 = bits.Add64(l2, h2, c1)
308 l3, c3 = bits.Add64(l3, h3, c2)
309 l4, c4 = bits.Add64(l4, h4, c3)
310 l5, c5 = bits.Add64(l5, h5, c4)
311 l6, c6 = bits.Add64(l6, h6, c5)
312 l7, _ = bits.Add64(l7, 0, c6)
313
314
315 l0, c0 = bits.Add64(l0, l7, 0)
316 l1, c1 = bits.Add64(l1, 0, c0)
317 l2, c2 = bits.Add64(l2, 0, c1)
318 l3, c3 = bits.Add64(l3, l7<<32, c2)
319 l4, c4 = bits.Add64(l4, 0, c3)
320 l5, c5 = bits.Add64(l5, 0, c4)
321 l6, l7 = bits.Add64(l6, 0, c5)
322
323
324 l0, c0 = bits.Add64(l0, l7, 0)
325 l1, c1 = bits.Add64(l1, 0, c0)
326 l2, c2 = bits.Add64(l2, 0, c1)
327 l3, c3 = bits.Add64(l3, l7<<32, c2)
328 l4, c4 = bits.Add64(l4, 0, c3)
329 l5, c5 = bits.Add64(l5, 0, c4)
330 l6, _ = bits.Add64(l6, 0, c5)
331
332 binary.LittleEndian.PutUint64(z[0*8:1*8], l0)
333 binary.LittleEndian.PutUint64(z[1*8:2*8], l1)
334 binary.LittleEndian.PutUint64(z[2*8:3*8], l2)
335 binary.LittleEndian.PutUint64(z[3*8:4*8], l3)
336 binary.LittleEndian.PutUint64(z[4*8:5*8], l4)
337 binary.LittleEndian.PutUint64(z[5*8:6*8], l5)
338 binary.LittleEndian.PutUint64(z[6*8:7*8], l6)
339 }
340
View as plain text