main
Raw Download raw file
  1package fp448
  2
  3import (
  4	"encoding/binary"
  5	"math/bits"
  6)
  7
  8func 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
 43func 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
100func 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
150func 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
200func addsubGeneric(x, y *Elt) {
201	z := &Elt{}
202	addGeneric(z, x, y)
203	subGeneric(y, x, y)
204	*x = *z
205}
206
207func 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
274func sqrGeneric(z, x *Elt) { mulGeneric(z, x, x) }
275
276func red64(z *Elt, l, h *[7]uint64) {
277	/* (2C13, 2C12, 2C11, 2C10|C10, C9, C8, C7) + (C6,...,C0) */
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	/* (C10C9, C9C8,C8C7,C7C13,C13C12,C12C11,C11C10) + (C6,...,C0) */
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	/* (C7) + (C6,...,C0) */
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	/* (C7) + (C6,...,C0) */
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}