Bitcoin ABC 0.32.7
P2P Digital Currency
field_10x26_impl.h
Go to the documentation of this file.
1/***********************************************************************
2 * Copyright (c) 2013, 2014 Pieter Wuille *
3 * Distributed under the MIT software license, see the accompanying *
4 * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5 ***********************************************************************/
6
7#ifndef SECP256K1_FIELD_REPR_IMPL_H
8#define SECP256K1_FIELD_REPR_IMPL_H
9
10#include "util.h"
11#include "field.h"
12#include "modinv32_impl.h"
13
23#ifdef VERIFY
24static void secp256k1_fe_verify(const secp256k1_fe *a) {
25 const uint32_t *d = a->n;
26 int m = a->normalized ? 1 : 2 * a->magnitude, r = 1;
27 r &= (d[0] <= 0x3FFFFFFUL * m);
28 r &= (d[1] <= 0x3FFFFFFUL * m);
29 r &= (d[2] <= 0x3FFFFFFUL * m);
30 r &= (d[3] <= 0x3FFFFFFUL * m);
31 r &= (d[4] <= 0x3FFFFFFUL * m);
32 r &= (d[5] <= 0x3FFFFFFUL * m);
33 r &= (d[6] <= 0x3FFFFFFUL * m);
34 r &= (d[7] <= 0x3FFFFFFUL * m);
35 r &= (d[8] <= 0x3FFFFFFUL * m);
36 r &= (d[9] <= 0x03FFFFFUL * m);
37 r &= (a->magnitude >= 0);
38 r &= (a->magnitude <= 32);
39 if (a->normalized) {
40 r &= (a->magnitude <= 1);
41 if (r && (d[9] == 0x03FFFFFUL)) {
42 uint32_t mid = d[8] & d[7] & d[6] & d[5] & d[4] & d[3] & d[2];
43 if (mid == 0x3FFFFFFUL) {
44 r &= ((d[1] + 0x40UL + ((d[0] + 0x3D1UL) >> 26)) <= 0x3FFFFFFUL);
45 }
46 }
47 }
48 VERIFY_CHECK(r == 1);
49}
50#endif
51
53 uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
54 t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
55
56 /* Reduce t9 at the start so there will be at most a single carry from the first pass */
57 uint32_t m;
58 uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
59
60 /* The first pass ensures the magnitude is 1, ... */
61 t0 += x * 0x3D1UL; t1 += (x << 6);
62 t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
63 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
64 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2;
65 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3;
66 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4;
67 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5;
68 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6;
69 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7;
70 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8;
71
72 /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
73 VERIFY_CHECK(t9 >> 23 == 0);
74
75 /* At most a single final reduction is needed; check if the value is >= the field characteristic */
76 x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL)
77 & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL));
78
79 /* Apply the final reduction (for constant-time behaviour, we do it always) */
80 t0 += x * 0x3D1UL; t1 += (x << 6);
81 t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
82 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
83 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL;
84 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL;
85 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL;
86 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL;
87 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL;
88 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL;
89 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL;
90
91 /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */
92 VERIFY_CHECK(t9 >> 22 == x);
93
94 /* Mask off the possible multiple of 2^256 from the final reduction */
95 t9 &= 0x03FFFFFUL;
96
97 r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
98 r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9;
99
100#ifdef VERIFY
101 r->magnitude = 1;
102 r->normalized = 1;
103 secp256k1_fe_verify(r);
104#endif
105}
106
108 uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
109 t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
110
111 /* Reduce t9 at the start so there will be at most a single carry from the first pass */
112 uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
113
114 /* The first pass ensures the magnitude is 1, ... */
115 t0 += x * 0x3D1UL; t1 += (x << 6);
116 t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
117 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
118 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL;
119 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL;
120 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL;
121 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL;
122 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL;
123 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL;
124 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL;
125
126 /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
127 VERIFY_CHECK(t9 >> 23 == 0);
128
129 r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
130 r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9;
131
132#ifdef VERIFY
133 r->magnitude = 1;
134 secp256k1_fe_verify(r);
135#endif
136}
137
139 uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
140 t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
141
142 /* Reduce t9 at the start so there will be at most a single carry from the first pass */
143 uint32_t m;
144 uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
145
146 /* The first pass ensures the magnitude is 1, ... */
147 t0 += x * 0x3D1UL; t1 += (x << 6);
148 t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
149 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
150 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2;
151 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3;
152 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4;
153 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5;
154 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6;
155 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7;
156 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8;
157
158 /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
159 VERIFY_CHECK(t9 >> 23 == 0);
160
161 /* At most a single final reduction is needed; check if the value is >= the field characteristic */
162 x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL)
163 & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL));
164
165 if (x) {
166 t0 += 0x3D1UL; t1 += (x << 6);
167 t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
168 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
169 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL;
170 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL;
171 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL;
172 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL;
173 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL;
174 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL;
175 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL;
176
177 /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */
178 VERIFY_CHECK(t9 >> 22 == x);
179
180 /* Mask off the possible multiple of 2^256 from the final reduction */
181 t9 &= 0x03FFFFFUL;
182 }
183
184 r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
185 r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9;
186
187#ifdef VERIFY
188 r->magnitude = 1;
189 r->normalized = 1;
190 secp256k1_fe_verify(r);
191#endif
192}
193
195 uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
196 t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
197
198 /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
199 uint32_t z0, z1;
200
201 /* Reduce t9 at the start so there will be at most a single carry from the first pass */
202 uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
203
204 /* The first pass ensures the magnitude is 1, ... */
205 t0 += x * 0x3D1UL; t1 += (x << 6);
206 t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; z0 = t0; z1 = t0 ^ 0x3D0UL;
207 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL;
208 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2;
209 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3;
210 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4;
211 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5;
212 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6;
213 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7;
214 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8;
215 z0 |= t9; z1 &= t9 ^ 0x3C00000UL;
216
217 /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
218 VERIFY_CHECK(t9 >> 23 == 0);
219
220 return (z0 == 0) | (z1 == 0x3FFFFFFUL);
221}
222
224 uint32_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
225 uint32_t z0, z1;
226 uint32_t x;
227
228 t0 = r->n[0];
229 t9 = r->n[9];
230
231 /* Reduce t9 at the start so there will be at most a single carry from the first pass */
232 x = t9 >> 22;
233
234 /* The first pass ensures the magnitude is 1, ... */
235 t0 += x * 0x3D1UL;
236
237 /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
238 z0 = t0 & 0x3FFFFFFUL;
239 z1 = z0 ^ 0x3D0UL;
240
241 /* Fast return path should catch the majority of cases */
242 if ((z0 != 0UL) & (z1 != 0x3FFFFFFUL)) {
243 return 0;
244 }
245
246 t1 = r->n[1];
247 t2 = r->n[2];
248 t3 = r->n[3];
249 t4 = r->n[4];
250 t5 = r->n[5];
251 t6 = r->n[6];
252 t7 = r->n[7];
253 t8 = r->n[8];
254
255 t9 &= 0x03FFFFFUL;
256 t1 += (x << 6);
257
258 t1 += (t0 >> 26);
259 t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL;
260 t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2;
261 t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3;
262 t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4;
263 t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5;
264 t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6;
265 t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7;
266 t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8;
267 z0 |= t9; z1 &= t9 ^ 0x3C00000UL;
268
269 /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
270 VERIFY_CHECK(t9 >> 23 == 0);
271
272 return (z0 == 0) | (z1 == 0x3FFFFFFUL);
273}
274
276 VERIFY_CHECK(0 <= a && a <= 0x7FFF);
277 r->n[0] = a;
278 r->n[1] = r->n[2] = r->n[3] = r->n[4] = r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0;
279#ifdef VERIFY
280 r->magnitude = (a != 0);
281 r->normalized = 1;
282 secp256k1_fe_verify(r);
283#endif
284}
285
287 const uint32_t *t = a->n;
288#ifdef VERIFY
289 VERIFY_CHECK(a->normalized);
290 secp256k1_fe_verify(a);
291#endif
292 return (t[0] | t[1] | t[2] | t[3] | t[4] | t[5] | t[6] | t[7] | t[8] | t[9]) == 0;
293}
294
296#ifdef VERIFY
297 VERIFY_CHECK(a->normalized);
298 secp256k1_fe_verify(a);
299#endif
300 return a->n[0] & 1;
301}
302
304 int i;
305#ifdef VERIFY
306 a->magnitude = 0;
307 a->normalized = 1;
308#endif
309 for (i=0; i<10; i++) {
310 a->n[i] = 0;
311 }
312}
313
314static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) {
315 int i;
316#ifdef VERIFY
317 VERIFY_CHECK(a->normalized);
318 VERIFY_CHECK(b->normalized);
319 secp256k1_fe_verify(a);
320 secp256k1_fe_verify(b);
321#endif
322 for (i = 9; i >= 0; i--) {
323 if (a->n[i] > b->n[i]) {
324 return 1;
325 }
326 if (a->n[i] < b->n[i]) {
327 return -1;
328 }
329 }
330 return 0;
331}
332
333static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) {
334 int ret;
335 r->n[0] = (uint32_t)a[31] | ((uint32_t)a[30] << 8) | ((uint32_t)a[29] << 16) | ((uint32_t)(a[28] & 0x3) << 24);
336 r->n[1] = (uint32_t)((a[28] >> 2) & 0x3f) | ((uint32_t)a[27] << 6) | ((uint32_t)a[26] << 14) | ((uint32_t)(a[25] & 0xf) << 22);
337 r->n[2] = (uint32_t)((a[25] >> 4) & 0xf) | ((uint32_t)a[24] << 4) | ((uint32_t)a[23] << 12) | ((uint32_t)(a[22] & 0x3f) << 20);
338 r->n[3] = (uint32_t)((a[22] >> 6) & 0x3) | ((uint32_t)a[21] << 2) | ((uint32_t)a[20] << 10) | ((uint32_t)a[19] << 18);
339 r->n[4] = (uint32_t)a[18] | ((uint32_t)a[17] << 8) | ((uint32_t)a[16] << 16) | ((uint32_t)(a[15] & 0x3) << 24);
340 r->n[5] = (uint32_t)((a[15] >> 2) & 0x3f) | ((uint32_t)a[14] << 6) | ((uint32_t)a[13] << 14) | ((uint32_t)(a[12] & 0xf) << 22);
341 r->n[6] = (uint32_t)((a[12] >> 4) & 0xf) | ((uint32_t)a[11] << 4) | ((uint32_t)a[10] << 12) | ((uint32_t)(a[9] & 0x3f) << 20);
342 r->n[7] = (uint32_t)((a[9] >> 6) & 0x3) | ((uint32_t)a[8] << 2) | ((uint32_t)a[7] << 10) | ((uint32_t)a[6] << 18);
343 r->n[8] = (uint32_t)a[5] | ((uint32_t)a[4] << 8) | ((uint32_t)a[3] << 16) | ((uint32_t)(a[2] & 0x3) << 24);
344 r->n[9] = (uint32_t)((a[2] >> 2) & 0x3f) | ((uint32_t)a[1] << 6) | ((uint32_t)a[0] << 14);
345
346 ret = !((r->n[9] == 0x3FFFFFUL) & ((r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL) & ((r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL));
347#ifdef VERIFY
348 r->magnitude = 1;
349 if (ret) {
350 r->normalized = 1;
351 secp256k1_fe_verify(r);
352 } else {
353 r->normalized = 0;
354 }
355#endif
356 return ret;
357}
358
360static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) {
361#ifdef VERIFY
362 VERIFY_CHECK(a->normalized);
363 secp256k1_fe_verify(a);
364#endif
365 r[0] = (a->n[9] >> 14) & 0xff;
366 r[1] = (a->n[9] >> 6) & 0xff;
367 r[2] = ((a->n[9] & 0x3F) << 2) | ((a->n[8] >> 24) & 0x3);
368 r[3] = (a->n[8] >> 16) & 0xff;
369 r[4] = (a->n[8] >> 8) & 0xff;
370 r[5] = a->n[8] & 0xff;
371 r[6] = (a->n[7] >> 18) & 0xff;
372 r[7] = (a->n[7] >> 10) & 0xff;
373 r[8] = (a->n[7] >> 2) & 0xff;
374 r[9] = ((a->n[7] & 0x3) << 6) | ((a->n[6] >> 20) & 0x3f);
375 r[10] = (a->n[6] >> 12) & 0xff;
376 r[11] = (a->n[6] >> 4) & 0xff;
377 r[12] = ((a->n[6] & 0xf) << 4) | ((a->n[5] >> 22) & 0xf);
378 r[13] = (a->n[5] >> 14) & 0xff;
379 r[14] = (a->n[5] >> 6) & 0xff;
380 r[15] = ((a->n[5] & 0x3f) << 2) | ((a->n[4] >> 24) & 0x3);
381 r[16] = (a->n[4] >> 16) & 0xff;
382 r[17] = (a->n[4] >> 8) & 0xff;
383 r[18] = a->n[4] & 0xff;
384 r[19] = (a->n[3] >> 18) & 0xff;
385 r[20] = (a->n[3] >> 10) & 0xff;
386 r[21] = (a->n[3] >> 2) & 0xff;
387 r[22] = ((a->n[3] & 0x3) << 6) | ((a->n[2] >> 20) & 0x3f);
388 r[23] = (a->n[2] >> 12) & 0xff;
389 r[24] = (a->n[2] >> 4) & 0xff;
390 r[25] = ((a->n[2] & 0xf) << 4) | ((a->n[1] >> 22) & 0xf);
391 r[26] = (a->n[1] >> 14) & 0xff;
392 r[27] = (a->n[1] >> 6) & 0xff;
393 r[28] = ((a->n[1] & 0x3f) << 2) | ((a->n[0] >> 24) & 0x3);
394 r[29] = (a->n[0] >> 16) & 0xff;
395 r[30] = (a->n[0] >> 8) & 0xff;
396 r[31] = a->n[0] & 0xff;
397}
398
400#ifdef VERIFY
401 VERIFY_CHECK(a->magnitude <= m);
402 secp256k1_fe_verify(a);
403 VERIFY_CHECK(0x3FFFC2FUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m);
404 VERIFY_CHECK(0x3FFFFBFUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m);
405 VERIFY_CHECK(0x3FFFFFFUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m);
406 VERIFY_CHECK(0x03FFFFFUL * 2 * (m + 1) >= 0x03FFFFFUL * 2 * m);
407#endif
408 r->n[0] = 0x3FFFC2FUL * 2 * (m + 1) - a->n[0];
409 r->n[1] = 0x3FFFFBFUL * 2 * (m + 1) - a->n[1];
410 r->n[2] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[2];
411 r->n[3] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[3];
412 r->n[4] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[4];
413 r->n[5] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[5];
414 r->n[6] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[6];
415 r->n[7] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[7];
416 r->n[8] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[8];
417 r->n[9] = 0x03FFFFFUL * 2 * (m + 1) - a->n[9];
418#ifdef VERIFY
419 r->magnitude = m + 1;
420 r->normalized = 0;
421 secp256k1_fe_verify(r);
422#endif
423}
424
426 r->n[0] *= a;
427 r->n[1] *= a;
428 r->n[2] *= a;
429 r->n[3] *= a;
430 r->n[4] *= a;
431 r->n[5] *= a;
432 r->n[6] *= a;
433 r->n[7] *= a;
434 r->n[8] *= a;
435 r->n[9] *= a;
436#ifdef VERIFY
437 r->magnitude *= a;
438 r->normalized = 0;
439 secp256k1_fe_verify(r);
440#endif
441}
442
444#ifdef VERIFY
445 secp256k1_fe_verify(a);
446#endif
447 r->n[0] += a->n[0];
448 r->n[1] += a->n[1];
449 r->n[2] += a->n[2];
450 r->n[3] += a->n[3];
451 r->n[4] += a->n[4];
452 r->n[5] += a->n[5];
453 r->n[6] += a->n[6];
454 r->n[7] += a->n[7];
455 r->n[8] += a->n[8];
456 r->n[9] += a->n[9];
457#ifdef VERIFY
458 r->magnitude += a->magnitude;
459 r->normalized = 0;
460 secp256k1_fe_verify(r);
461#endif
462}
463
464#if defined(USE_EXTERNAL_ASM)
465
466/* External assembler implementation */
467void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b);
468void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a);
469
470#else
471
472#ifdef VERIFY
473#define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0)
474#else
475#define VERIFY_BITS(x, n) do { } while(0)
476#endif
477
478SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b) {
479 uint64_t c, d;
480 uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8;
481 uint32_t t9, t1, t0, t2, t3, t4, t5, t6, t7;
482 const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL;
483
484 VERIFY_BITS(a[0], 30);
485 VERIFY_BITS(a[1], 30);
486 VERIFY_BITS(a[2], 30);
487 VERIFY_BITS(a[3], 30);
488 VERIFY_BITS(a[4], 30);
489 VERIFY_BITS(a[5], 30);
490 VERIFY_BITS(a[6], 30);
491 VERIFY_BITS(a[7], 30);
492 VERIFY_BITS(a[8], 30);
493 VERIFY_BITS(a[9], 26);
494 VERIFY_BITS(b[0], 30);
495 VERIFY_BITS(b[1], 30);
496 VERIFY_BITS(b[2], 30);
497 VERIFY_BITS(b[3], 30);
498 VERIFY_BITS(b[4], 30);
499 VERIFY_BITS(b[5], 30);
500 VERIFY_BITS(b[6], 30);
501 VERIFY_BITS(b[7], 30);
502 VERIFY_BITS(b[8], 30);
503 VERIFY_BITS(b[9], 26);
504
511 d = (uint64_t)a[0] * b[9]
512 + (uint64_t)a[1] * b[8]
513 + (uint64_t)a[2] * b[7]
514 + (uint64_t)a[3] * b[6]
515 + (uint64_t)a[4] * b[5]
516 + (uint64_t)a[5] * b[4]
517 + (uint64_t)a[6] * b[3]
518 + (uint64_t)a[7] * b[2]
519 + (uint64_t)a[8] * b[1]
520 + (uint64_t)a[9] * b[0];
521 /* VERIFY_BITS(d, 64); */
522 /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */
523 t9 = d & M; d >>= 26;
524 VERIFY_BITS(t9, 26);
525 VERIFY_BITS(d, 38);
526 /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */
527
528 c = (uint64_t)a[0] * b[0];
529 VERIFY_BITS(c, 60);
530 /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */
531 d += (uint64_t)a[1] * b[9]
532 + (uint64_t)a[2] * b[8]
533 + (uint64_t)a[3] * b[7]
534 + (uint64_t)a[4] * b[6]
535 + (uint64_t)a[5] * b[5]
536 + (uint64_t)a[6] * b[4]
537 + (uint64_t)a[7] * b[3]
538 + (uint64_t)a[8] * b[2]
539 + (uint64_t)a[9] * b[1];
540 VERIFY_BITS(d, 63);
541 /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
542 u0 = d & M; d >>= 26; c += u0 * R0;
543 VERIFY_BITS(u0, 26);
544 VERIFY_BITS(d, 37);
545 VERIFY_BITS(c, 61);
546 /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
547 t0 = c & M; c >>= 26; c += u0 * R1;
548 VERIFY_BITS(t0, 26);
549 VERIFY_BITS(c, 37);
550 /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
551 /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
552
553 c += (uint64_t)a[0] * b[1]
554 + (uint64_t)a[1] * b[0];
555 VERIFY_BITS(c, 62);
556 /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */
557 d += (uint64_t)a[2] * b[9]
558 + (uint64_t)a[3] * b[8]
559 + (uint64_t)a[4] * b[7]
560 + (uint64_t)a[5] * b[6]
561 + (uint64_t)a[6] * b[5]
562 + (uint64_t)a[7] * b[4]
563 + (uint64_t)a[8] * b[3]
564 + (uint64_t)a[9] * b[2];
565 VERIFY_BITS(d, 63);
566 /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
567 u1 = d & M; d >>= 26; c += u1 * R0;
568 VERIFY_BITS(u1, 26);
569 VERIFY_BITS(d, 37);
570 VERIFY_BITS(c, 63);
571 /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
572 t1 = c & M; c >>= 26; c += u1 * R1;
573 VERIFY_BITS(t1, 26);
574 VERIFY_BITS(c, 38);
575 /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
576 /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
577
578 c += (uint64_t)a[0] * b[2]
579 + (uint64_t)a[1] * b[1]
580 + (uint64_t)a[2] * b[0];
581 VERIFY_BITS(c, 62);
582 /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
583 d += (uint64_t)a[3] * b[9]
584 + (uint64_t)a[4] * b[8]
585 + (uint64_t)a[5] * b[7]
586 + (uint64_t)a[6] * b[6]
587 + (uint64_t)a[7] * b[5]
588 + (uint64_t)a[8] * b[4]
589 + (uint64_t)a[9] * b[3];
590 VERIFY_BITS(d, 63);
591 /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
592 u2 = d & M; d >>= 26; c += u2 * R0;
593 VERIFY_BITS(u2, 26);
594 VERIFY_BITS(d, 37);
595 VERIFY_BITS(c, 63);
596 /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
597 t2 = c & M; c >>= 26; c += u2 * R1;
598 VERIFY_BITS(t2, 26);
599 VERIFY_BITS(c, 38);
600 /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
601 /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
602
603 c += (uint64_t)a[0] * b[3]
604 + (uint64_t)a[1] * b[2]
605 + (uint64_t)a[2] * b[1]
606 + (uint64_t)a[3] * b[0];
607 VERIFY_BITS(c, 63);
608 /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
609 d += (uint64_t)a[4] * b[9]
610 + (uint64_t)a[5] * b[8]
611 + (uint64_t)a[6] * b[7]
612 + (uint64_t)a[7] * b[6]
613 + (uint64_t)a[8] * b[5]
614 + (uint64_t)a[9] * b[4];
615 VERIFY_BITS(d, 63);
616 /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
617 u3 = d & M; d >>= 26; c += u3 * R0;
618 VERIFY_BITS(u3, 26);
619 VERIFY_BITS(d, 37);
620 /* VERIFY_BITS(c, 64); */
621 /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
622 t3 = c & M; c >>= 26; c += u3 * R1;
623 VERIFY_BITS(t3, 26);
624 VERIFY_BITS(c, 39);
625 /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
626 /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
627
628 c += (uint64_t)a[0] * b[4]
629 + (uint64_t)a[1] * b[3]
630 + (uint64_t)a[2] * b[2]
631 + (uint64_t)a[3] * b[1]
632 + (uint64_t)a[4] * b[0];
633 VERIFY_BITS(c, 63);
634 /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
635 d += (uint64_t)a[5] * b[9]
636 + (uint64_t)a[6] * b[8]
637 + (uint64_t)a[7] * b[7]
638 + (uint64_t)a[8] * b[6]
639 + (uint64_t)a[9] * b[5];
640 VERIFY_BITS(d, 62);
641 /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
642 u4 = d & M; d >>= 26; c += u4 * R0;
643 VERIFY_BITS(u4, 26);
644 VERIFY_BITS(d, 36);
645 /* VERIFY_BITS(c, 64); */
646 /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
647 t4 = c & M; c >>= 26; c += u4 * R1;
648 VERIFY_BITS(t4, 26);
649 VERIFY_BITS(c, 39);
650 /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
651 /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
652
653 c += (uint64_t)a[0] * b[5]
654 + (uint64_t)a[1] * b[4]
655 + (uint64_t)a[2] * b[3]
656 + (uint64_t)a[3] * b[2]
657 + (uint64_t)a[4] * b[1]
658 + (uint64_t)a[5] * b[0];
659 VERIFY_BITS(c, 63);
660 /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
661 d += (uint64_t)a[6] * b[9]
662 + (uint64_t)a[7] * b[8]
663 + (uint64_t)a[8] * b[7]
664 + (uint64_t)a[9] * b[6];
665 VERIFY_BITS(d, 62);
666 /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
667 u5 = d & M; d >>= 26; c += u5 * R0;
668 VERIFY_BITS(u5, 26);
669 VERIFY_BITS(d, 36);
670 /* VERIFY_BITS(c, 64); */
671 /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
672 t5 = c & M; c >>= 26; c += u5 * R1;
673 VERIFY_BITS(t5, 26);
674 VERIFY_BITS(c, 39);
675 /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
676 /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
677
678 c += (uint64_t)a[0] * b[6]
679 + (uint64_t)a[1] * b[5]
680 + (uint64_t)a[2] * b[4]
681 + (uint64_t)a[3] * b[3]
682 + (uint64_t)a[4] * b[2]
683 + (uint64_t)a[5] * b[1]
684 + (uint64_t)a[6] * b[0];
685 VERIFY_BITS(c, 63);
686 /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
687 d += (uint64_t)a[7] * b[9]
688 + (uint64_t)a[8] * b[8]
689 + (uint64_t)a[9] * b[7];
690 VERIFY_BITS(d, 61);
691 /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
692 u6 = d & M; d >>= 26; c += u6 * R0;
693 VERIFY_BITS(u6, 26);
694 VERIFY_BITS(d, 35);
695 /* VERIFY_BITS(c, 64); */
696 /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
697 t6 = c & M; c >>= 26; c += u6 * R1;
698 VERIFY_BITS(t6, 26);
699 VERIFY_BITS(c, 39);
700 /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
701 /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
702
703 c += (uint64_t)a[0] * b[7]
704 + (uint64_t)a[1] * b[6]
705 + (uint64_t)a[2] * b[5]
706 + (uint64_t)a[3] * b[4]
707 + (uint64_t)a[4] * b[3]
708 + (uint64_t)a[5] * b[2]
709 + (uint64_t)a[6] * b[1]
710 + (uint64_t)a[7] * b[0];
711 /* VERIFY_BITS(c, 64); */
712 VERIFY_CHECK(c <= 0x8000007C00000007ULL);
713 /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
714 d += (uint64_t)a[8] * b[9]
715 + (uint64_t)a[9] * b[8];
716 VERIFY_BITS(d, 58);
717 /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
718 u7 = d & M; d >>= 26; c += u7 * R0;
719 VERIFY_BITS(u7, 26);
720 VERIFY_BITS(d, 32);
721 /* VERIFY_BITS(c, 64); */
722 VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL);
723 /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
724 t7 = c & M; c >>= 26; c += u7 * R1;
725 VERIFY_BITS(t7, 26);
726 VERIFY_BITS(c, 38);
727 /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
728 /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
729
730 c += (uint64_t)a[0] * b[8]
731 + (uint64_t)a[1] * b[7]
732 + (uint64_t)a[2] * b[6]
733 + (uint64_t)a[3] * b[5]
734 + (uint64_t)a[4] * b[4]
735 + (uint64_t)a[5] * b[3]
736 + (uint64_t)a[6] * b[2]
737 + (uint64_t)a[7] * b[1]
738 + (uint64_t)a[8] * b[0];
739 /* VERIFY_BITS(c, 64); */
740 VERIFY_CHECK(c <= 0x9000007B80000008ULL);
741 /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
742 d += (uint64_t)a[9] * b[9];
743 VERIFY_BITS(d, 57);
744 /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
745 u8 = d & M; d >>= 26; c += u8 * R0;
746 VERIFY_BITS(u8, 26);
747 VERIFY_BITS(d, 31);
748 /* VERIFY_BITS(c, 64); */
749 VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL);
750 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
751
752 r[3] = t3;
753 VERIFY_BITS(r[3], 26);
754 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
755 r[4] = t4;
756 VERIFY_BITS(r[4], 26);
757 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
758 r[5] = t5;
759 VERIFY_BITS(r[5], 26);
760 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
761 r[6] = t6;
762 VERIFY_BITS(r[6], 26);
763 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
764 r[7] = t7;
765 VERIFY_BITS(r[7], 26);
766 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
767
768 r[8] = c & M; c >>= 26; c += u8 * R1;
769 VERIFY_BITS(r[8], 26);
770 VERIFY_BITS(c, 39);
771 /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
772 /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
773 c += d * R0 + t9;
774 VERIFY_BITS(c, 45);
775 /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
776 r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4);
777 VERIFY_BITS(r[9], 22);
778 VERIFY_BITS(c, 46);
779 /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
780 /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
781 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
782
783 d = c * (R0 >> 4) + t0;
784 VERIFY_BITS(d, 56);
785 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
786 r[0] = d & M; d >>= 26;
787 VERIFY_BITS(r[0], 26);
788 VERIFY_BITS(d, 30);
789 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
790 d += c * (R1 >> 4) + t1;
791 VERIFY_BITS(d, 53);
792 VERIFY_CHECK(d <= 0x10000003FFFFBFULL);
793 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
794 /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
795 r[1] = d & M; d >>= 26;
796 VERIFY_BITS(r[1], 26);
797 VERIFY_BITS(d, 27);
798 VERIFY_CHECK(d <= 0x4000000ULL);
799 /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
800 d += t2;
801 VERIFY_BITS(d, 27);
802 /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
803 r[2] = d;
804 VERIFY_BITS(r[2], 27);
805 /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
806}
807
808SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a) {
809 uint64_t c, d;
810 uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8;
811 uint32_t t9, t0, t1, t2, t3, t4, t5, t6, t7;
812 const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL;
813
814 VERIFY_BITS(a[0], 30);
815 VERIFY_BITS(a[1], 30);
816 VERIFY_BITS(a[2], 30);
817 VERIFY_BITS(a[3], 30);
818 VERIFY_BITS(a[4], 30);
819 VERIFY_BITS(a[5], 30);
820 VERIFY_BITS(a[6], 30);
821 VERIFY_BITS(a[7], 30);
822 VERIFY_BITS(a[8], 30);
823 VERIFY_BITS(a[9], 26);
824
830 d = (uint64_t)(a[0]*2) * a[9]
831 + (uint64_t)(a[1]*2) * a[8]
832 + (uint64_t)(a[2]*2) * a[7]
833 + (uint64_t)(a[3]*2) * a[6]
834 + (uint64_t)(a[4]*2) * a[5];
835 /* VERIFY_BITS(d, 64); */
836 /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */
837 t9 = d & M; d >>= 26;
838 VERIFY_BITS(t9, 26);
839 VERIFY_BITS(d, 38);
840 /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */
841
842 c = (uint64_t)a[0] * a[0];
843 VERIFY_BITS(c, 60);
844 /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */
845 d += (uint64_t)(a[1]*2) * a[9]
846 + (uint64_t)(a[2]*2) * a[8]
847 + (uint64_t)(a[3]*2) * a[7]
848 + (uint64_t)(a[4]*2) * a[6]
849 + (uint64_t)a[5] * a[5];
850 VERIFY_BITS(d, 63);
851 /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
852 u0 = d & M; d >>= 26; c += u0 * R0;
853 VERIFY_BITS(u0, 26);
854 VERIFY_BITS(d, 37);
855 VERIFY_BITS(c, 61);
856 /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
857 t0 = c & M; c >>= 26; c += u0 * R1;
858 VERIFY_BITS(t0, 26);
859 VERIFY_BITS(c, 37);
860 /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
861 /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
862
863 c += (uint64_t)(a[0]*2) * a[1];
864 VERIFY_BITS(c, 62);
865 /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */
866 d += (uint64_t)(a[2]*2) * a[9]
867 + (uint64_t)(a[3]*2) * a[8]
868 + (uint64_t)(a[4]*2) * a[7]
869 + (uint64_t)(a[5]*2) * a[6];
870 VERIFY_BITS(d, 63);
871 /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
872 u1 = d & M; d >>= 26; c += u1 * R0;
873 VERIFY_BITS(u1, 26);
874 VERIFY_BITS(d, 37);
875 VERIFY_BITS(c, 63);
876 /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
877 t1 = c & M; c >>= 26; c += u1 * R1;
878 VERIFY_BITS(t1, 26);
879 VERIFY_BITS(c, 38);
880 /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
881 /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
882
883 c += (uint64_t)(a[0]*2) * a[2]
884 + (uint64_t)a[1] * a[1];
885 VERIFY_BITS(c, 62);
886 /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
887 d += (uint64_t)(a[3]*2) * a[9]
888 + (uint64_t)(a[4]*2) * a[8]
889 + (uint64_t)(a[5]*2) * a[7]
890 + (uint64_t)a[6] * a[6];
891 VERIFY_BITS(d, 63);
892 /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
893 u2 = d & M; d >>= 26; c += u2 * R0;
894 VERIFY_BITS(u2, 26);
895 VERIFY_BITS(d, 37);
896 VERIFY_BITS(c, 63);
897 /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
898 t2 = c & M; c >>= 26; c += u2 * R1;
899 VERIFY_BITS(t2, 26);
900 VERIFY_BITS(c, 38);
901 /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
902 /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
903
904 c += (uint64_t)(a[0]*2) * a[3]
905 + (uint64_t)(a[1]*2) * a[2];
906 VERIFY_BITS(c, 63);
907 /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
908 d += (uint64_t)(a[4]*2) * a[9]
909 + (uint64_t)(a[5]*2) * a[8]
910 + (uint64_t)(a[6]*2) * a[7];
911 VERIFY_BITS(d, 63);
912 /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
913 u3 = d & M; d >>= 26; c += u3 * R0;
914 VERIFY_BITS(u3, 26);
915 VERIFY_BITS(d, 37);
916 /* VERIFY_BITS(c, 64); */
917 /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
918 t3 = c & M; c >>= 26; c += u3 * R1;
919 VERIFY_BITS(t3, 26);
920 VERIFY_BITS(c, 39);
921 /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
922 /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
923
924 c += (uint64_t)(a[0]*2) * a[4]
925 + (uint64_t)(a[1]*2) * a[3]
926 + (uint64_t)a[2] * a[2];
927 VERIFY_BITS(c, 63);
928 /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
929 d += (uint64_t)(a[5]*2) * a[9]
930 + (uint64_t)(a[6]*2) * a[8]
931 + (uint64_t)a[7] * a[7];
932 VERIFY_BITS(d, 62);
933 /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
934 u4 = d & M; d >>= 26; c += u4 * R0;
935 VERIFY_BITS(u4, 26);
936 VERIFY_BITS(d, 36);
937 /* VERIFY_BITS(c, 64); */
938 /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
939 t4 = c & M; c >>= 26; c += u4 * R1;
940 VERIFY_BITS(t4, 26);
941 VERIFY_BITS(c, 39);
942 /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
943 /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
944
945 c += (uint64_t)(a[0]*2) * a[5]
946 + (uint64_t)(a[1]*2) * a[4]
947 + (uint64_t)(a[2]*2) * a[3];
948 VERIFY_BITS(c, 63);
949 /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
950 d += (uint64_t)(a[6]*2) * a[9]
951 + (uint64_t)(a[7]*2) * a[8];
952 VERIFY_BITS(d, 62);
953 /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
954 u5 = d & M; d >>= 26; c += u5 * R0;
955 VERIFY_BITS(u5, 26);
956 VERIFY_BITS(d, 36);
957 /* VERIFY_BITS(c, 64); */
958 /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
959 t5 = c & M; c >>= 26; c += u5 * R1;
960 VERIFY_BITS(t5, 26);
961 VERIFY_BITS(c, 39);
962 /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
963 /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
964
965 c += (uint64_t)(a[0]*2) * a[6]
966 + (uint64_t)(a[1]*2) * a[5]
967 + (uint64_t)(a[2]*2) * a[4]
968 + (uint64_t)a[3] * a[3];
969 VERIFY_BITS(c, 63);
970 /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
971 d += (uint64_t)(a[7]*2) * a[9]
972 + (uint64_t)a[8] * a[8];
973 VERIFY_BITS(d, 61);
974 /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
975 u6 = d & M; d >>= 26; c += u6 * R0;
976 VERIFY_BITS(u6, 26);
977 VERIFY_BITS(d, 35);
978 /* VERIFY_BITS(c, 64); */
979 /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
980 t6 = c & M; c >>= 26; c += u6 * R1;
981 VERIFY_BITS(t6, 26);
982 VERIFY_BITS(c, 39);
983 /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
984 /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
985
986 c += (uint64_t)(a[0]*2) * a[7]
987 + (uint64_t)(a[1]*2) * a[6]
988 + (uint64_t)(a[2]*2) * a[5]
989 + (uint64_t)(a[3]*2) * a[4];
990 /* VERIFY_BITS(c, 64); */
991 VERIFY_CHECK(c <= 0x8000007C00000007ULL);
992 /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
993 d += (uint64_t)(a[8]*2) * a[9];
994 VERIFY_BITS(d, 58);
995 /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
996 u7 = d & M; d >>= 26; c += u7 * R0;
997 VERIFY_BITS(u7, 26);
998 VERIFY_BITS(d, 32);
999 /* VERIFY_BITS(c, 64); */
1000 VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL);
1001 /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
1002 t7 = c & M; c >>= 26; c += u7 * R1;
1003 VERIFY_BITS(t7, 26);
1004 VERIFY_BITS(c, 38);
1005 /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
1006 /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
1007
1008 c += (uint64_t)(a[0]*2) * a[8]
1009 + (uint64_t)(a[1]*2) * a[7]
1010 + (uint64_t)(a[2]*2) * a[6]
1011 + (uint64_t)(a[3]*2) * a[5]
1012 + (uint64_t)a[4] * a[4];
1013 /* VERIFY_BITS(c, 64); */
1014 VERIFY_CHECK(c <= 0x9000007B80000008ULL);
1015 /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1016 d += (uint64_t)a[9] * a[9];
1017 VERIFY_BITS(d, 57);
1018 /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1019 u8 = d & M; d >>= 26; c += u8 * R0;
1020 VERIFY_BITS(u8, 26);
1021 VERIFY_BITS(d, 31);
1022 /* VERIFY_BITS(c, 64); */
1023 VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL);
1024 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1025
1026 r[3] = t3;
1027 VERIFY_BITS(r[3], 26);
1028 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1029 r[4] = t4;
1030 VERIFY_BITS(r[4], 26);
1031 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1032 r[5] = t5;
1033 VERIFY_BITS(r[5], 26);
1034 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1035 r[6] = t6;
1036 VERIFY_BITS(r[6], 26);
1037 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1038 r[7] = t7;
1039 VERIFY_BITS(r[7], 26);
1040 /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1041
1042 r[8] = c & M; c >>= 26; c += u8 * R1;
1043 VERIFY_BITS(r[8], 26);
1044 VERIFY_BITS(c, 39);
1045 /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1046 /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1047 c += d * R0 + t9;
1048 VERIFY_BITS(c, 45);
1049 /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1050 r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4);
1051 VERIFY_BITS(r[9], 22);
1052 VERIFY_BITS(c, 46);
1053 /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1054 /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1055 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1056
1057 d = c * (R0 >> 4) + t0;
1058 VERIFY_BITS(d, 56);
1059 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1060 r[0] = d & M; d >>= 26;
1061 VERIFY_BITS(r[0], 26);
1062 VERIFY_BITS(d, 30);
1063 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1064 d += c * (R1 >> 4) + t1;
1065 VERIFY_BITS(d, 53);
1066 VERIFY_CHECK(d <= 0x10000003FFFFBFULL);
1067 /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1068 /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1069 r[1] = d & M; d >>= 26;
1070 VERIFY_BITS(r[1], 26);
1071 VERIFY_BITS(d, 27);
1072 VERIFY_CHECK(d <= 0x4000000ULL);
1073 /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1074 d += t2;
1075 VERIFY_BITS(d, 27);
1076 /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1077 r[2] = d;
1078 VERIFY_BITS(r[2], 27);
1079 /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
1080}
1081#endif
1082
1084#ifdef VERIFY
1085 VERIFY_CHECK(a->magnitude <= 8);
1086 VERIFY_CHECK(b->magnitude <= 8);
1087 secp256k1_fe_verify(a);
1088 secp256k1_fe_verify(b);
1089 VERIFY_CHECK(r != b);
1090 VERIFY_CHECK(a != b);
1091#endif
1092 secp256k1_fe_mul_inner(r->n, a->n, b->n);
1093#ifdef VERIFY
1094 r->magnitude = 1;
1095 r->normalized = 0;
1096 secp256k1_fe_verify(r);
1097#endif
1098}
1099
1100static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) {
1101#ifdef VERIFY
1102 VERIFY_CHECK(a->magnitude <= 8);
1103 secp256k1_fe_verify(a);
1104#endif
1105 secp256k1_fe_sqr_inner(r->n, a->n);
1106#ifdef VERIFY
1107 r->magnitude = 1;
1108 r->normalized = 0;
1109 secp256k1_fe_verify(r);
1110#endif
1111}
1112
1114 uint32_t mask0, mask1;
1115 volatile int vflag = flag;
1116 VG_CHECK_VERIFY(r->n, sizeof(r->n));
1117 mask0 = vflag + ~((uint32_t)0);
1118 mask1 = ~mask0;
1119 r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
1120 r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
1121 r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
1122 r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
1123 r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1);
1124 r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1);
1125 r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1);
1126 r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1);
1127 r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1);
1128 r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1);
1129#ifdef VERIFY
1130 if (flag) {
1131 r->magnitude = a->magnitude;
1132 r->normalized = a->normalized;
1133 }
1134#endif
1135}
1136
1138 uint32_t mask0, mask1;
1139 volatile int vflag = flag;
1140 VG_CHECK_VERIFY(r->n, sizeof(r->n));
1141 mask0 = vflag + ~((uint32_t)0);
1142 mask1 = ~mask0;
1143 r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
1144 r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
1145 r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
1146 r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
1147 r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1);
1148 r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1);
1149 r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1);
1150 r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1);
1151}
1152
1154#ifdef VERIFY
1155 VERIFY_CHECK(a->normalized);
1156#endif
1157 r->n[0] = a->n[0] | a->n[1] << 26;
1158 r->n[1] = a->n[1] >> 6 | a->n[2] << 20;
1159 r->n[2] = a->n[2] >> 12 | a->n[3] << 14;
1160 r->n[3] = a->n[3] >> 18 | a->n[4] << 8;
1161 r->n[4] = a->n[4] >> 24 | a->n[5] << 2 | a->n[6] << 28;
1162 r->n[5] = a->n[6] >> 4 | a->n[7] << 22;
1163 r->n[6] = a->n[7] >> 10 | a->n[8] << 16;
1164 r->n[7] = a->n[8] >> 16 | a->n[9] << 10;
1165}
1166
1168 r->n[0] = a->n[0] & 0x3FFFFFFUL;
1169 r->n[1] = a->n[0] >> 26 | ((a->n[1] << 6) & 0x3FFFFFFUL);
1170 r->n[2] = a->n[1] >> 20 | ((a->n[2] << 12) & 0x3FFFFFFUL);
1171 r->n[3] = a->n[2] >> 14 | ((a->n[3] << 18) & 0x3FFFFFFUL);
1172 r->n[4] = a->n[3] >> 8 | ((a->n[4] << 24) & 0x3FFFFFFUL);
1173 r->n[5] = (a->n[4] >> 2) & 0x3FFFFFFUL;
1174 r->n[6] = a->n[4] >> 28 | ((a->n[5] << 4) & 0x3FFFFFFUL);
1175 r->n[7] = a->n[5] >> 22 | ((a->n[6] << 10) & 0x3FFFFFFUL);
1176 r->n[8] = a->n[6] >> 16 | ((a->n[7] << 16) & 0x3FFFFFFUL);
1177 r->n[9] = a->n[7] >> 10;
1178#ifdef VERIFY
1179 r->magnitude = 1;
1180 r->normalized = 1;
1181 secp256k1_fe_verify(r);
1182#endif
1183}
1184
1186 const uint32_t M26 = UINT32_MAX >> 6;
1187 const uint32_t a0 = a->v[0], a1 = a->v[1], a2 = a->v[2], a3 = a->v[3], a4 = a->v[4],
1188 a5 = a->v[5], a6 = a->v[6], a7 = a->v[7], a8 = a->v[8];
1189
1190 /* The output from secp256k1_modinv32{_var} should be normalized to range [0,modulus), and
1191 * have limbs in [0,2^30). The modulus is < 2^256, so the top limb must be below 2^(256-30*8).
1192 */
1193 VERIFY_CHECK(a0 >> 30 == 0);
1194 VERIFY_CHECK(a1 >> 30 == 0);
1195 VERIFY_CHECK(a2 >> 30 == 0);
1196 VERIFY_CHECK(a3 >> 30 == 0);
1197 VERIFY_CHECK(a4 >> 30 == 0);
1198 VERIFY_CHECK(a5 >> 30 == 0);
1199 VERIFY_CHECK(a6 >> 30 == 0);
1200 VERIFY_CHECK(a7 >> 30 == 0);
1201 VERIFY_CHECK(a8 >> 16 == 0);
1202
1203 r->n[0] = a0 & M26;
1204 r->n[1] = (a0 >> 26 | a1 << 4) & M26;
1205 r->n[2] = (a1 >> 22 | a2 << 8) & M26;
1206 r->n[3] = (a2 >> 18 | a3 << 12) & M26;
1207 r->n[4] = (a3 >> 14 | a4 << 16) & M26;
1208 r->n[5] = (a4 >> 10 | a5 << 20) & M26;
1209 r->n[6] = (a5 >> 6 | a6 << 24) & M26;
1210 r->n[7] = (a6 >> 2 ) & M26;
1211 r->n[8] = (a6 >> 28 | a7 << 2) & M26;
1212 r->n[9] = (a7 >> 24 | a8 << 6);
1213
1214#ifdef VERIFY
1215 r->magnitude = 1;
1216 r->normalized = 1;
1217 secp256k1_fe_verify(r);
1218#endif
1219}
1220
1222 const uint32_t M30 = UINT32_MAX >> 2;
1223 const uint64_t a0 = a->n[0], a1 = a->n[1], a2 = a->n[2], a3 = a->n[3], a4 = a->n[4],
1224 a5 = a->n[5], a6 = a->n[6], a7 = a->n[7], a8 = a->n[8], a9 = a->n[9];
1225
1226#ifdef VERIFY
1227 VERIFY_CHECK(a->normalized);
1228#endif
1229
1230 r->v[0] = (a0 | a1 << 26) & M30;
1231 r->v[1] = (a1 >> 4 | a2 << 22) & M30;
1232 r->v[2] = (a2 >> 8 | a3 << 18) & M30;
1233 r->v[3] = (a3 >> 12 | a4 << 14) & M30;
1234 r->v[4] = (a4 >> 16 | a5 << 10) & M30;
1235 r->v[5] = (a5 >> 20 | a6 << 6) & M30;
1236 r->v[6] = (a6 >> 24 | a7 << 2
1237 | a8 << 28) & M30;
1238 r->v[7] = (a8 >> 2 | a9 << 24) & M30;
1239 r->v[8] = a9 >> 6;
1240}
1241
1243 {{-0x3D1, -4, 0, 0, 0, 0, 0, 0, 65536}},
1244 0x2DDACACFL
1245};
1246
1247static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *x) {
1248 secp256k1_fe tmp;
1250
1251 tmp = *x;
1253 secp256k1_fe_to_signed30(&s, &tmp);
1256
1258}
1259
1261 secp256k1_fe tmp;
1263
1264 tmp = *x;
1266 secp256k1_fe_to_signed30(&s, &tmp);
1269
1271}
1272
1273#endif /* SECP256K1_FIELD_REPR_IMPL_H */
static int secp256k1_fe_normalizes_to_zero_var(const secp256k1_fe *r)
static SECP256K1_INLINE void secp256k1_fe_set_int(secp256k1_fe *r, int a)
static void secp256k1_fe_normalize_weak(secp256k1_fe *r)
static SECP256K1_INLINE void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a)
static const secp256k1_modinv32_modinfo secp256k1_const_modinfo_fe
static SECP256K1_INLINE int secp256k1_fe_is_zero(const secp256k1_fe *a)
static void secp256k1_fe_normalize_var(secp256k1_fe *r)
static SECP256K1_INLINE void secp256k1_fe_mul_int(secp256k1_fe *r, int a)
static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe *SECP256K1_RESTRICT b)
static SECP256K1_INLINE void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t *SECP256K1_RESTRICT b)
static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a)
static void secp256k1_fe_from_signed30(secp256k1_fe *r, const secp256k1_modinv32_signed30 *a)
static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag)
static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a)
static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag)
static int secp256k1_fe_normalizes_to_zero(const secp256k1_fe *r)
static SECP256K1_INLINE void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m)
static void secp256k1_fe_normalize(secp256k1_fe *r)
See the comment at the top of field_5x52_impl.h for more details.
#define VERIFY_BITS(x, n)
static SECP256K1_INLINE int secp256k1_fe_is_odd(const secp256k1_fe *a)
static SECP256K1_INLINE void secp256k1_fe_clear(secp256k1_fe *a)
static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a)
static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a)
static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a)
Convert a field element to a 32-byte big endian value.
static SECP256K1_INLINE void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a)
static void secp256k1_fe_to_signed30(secp256k1_modinv32_signed30 *r, const secp256k1_fe *a)
static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b)
static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *x)
static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x)
static void secp256k1_modinv32_var(secp256k1_modinv32_signed30 *x, const secp256k1_modinv32_modinfo *modinfo)
static void secp256k1_modinv32(secp256k1_modinv32_signed30 *x, const secp256k1_modinv32_modinfo *modinfo)
#define VG_CHECK_VERIFY(x, y)
Definition: util.h:115
#define VERIFY_CHECK(cond)
Definition: util.h:95
#define SECP256K1_RESTRICT
Definition: util.h:155
#define SECP256K1_INLINE
Definition: secp256k1.h:127
uint32_t n[10]
Definition: field_10x26.h:16