• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.math.raw;
2 
3 import java.math.BigInteger;
4 
5 import org.bouncycastle.util.Pack;
6 
7 public abstract class Nat256
8 {
9     private static final long M = 0xFFFFFFFFL;
10 
add(int[] x, int[] y, int[] z)11     public static int add(int[] x, int[] y, int[] z)
12     {
13         long c = 0;
14         c += (x[0] & M) + (y[0] & M);
15         z[0] = (int)c;
16         c >>>= 32;
17         c += (x[1] & M) + (y[1] & M);
18         z[1] = (int)c;
19         c >>>= 32;
20         c += (x[2] & M) + (y[2] & M);
21         z[2] = (int)c;
22         c >>>= 32;
23         c += (x[3] & M) + (y[3] & M);
24         z[3] = (int)c;
25         c >>>= 32;
26         c += (x[4] & M) + (y[4] & M);
27         z[4] = (int)c;
28         c >>>= 32;
29         c += (x[5] & M) + (y[5] & M);
30         z[5] = (int)c;
31         c >>>= 32;
32         c += (x[6] & M) + (y[6] & M);
33         z[6] = (int)c;
34         c >>>= 32;
35         c += (x[7] & M) + (y[7] & M);
36         z[7] = (int)c;
37         c >>>= 32;
38         return (int)c;
39     }
40 
add(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)41     public static int add(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
42     {
43         long c = 0;
44         c += (x[xOff + 0] & M) + (y[yOff + 0] & M);
45         z[zOff + 0] = (int)c;
46         c >>>= 32;
47         c += (x[xOff + 1] & M) + (y[yOff + 1] & M);
48         z[zOff + 1] = (int)c;
49         c >>>= 32;
50         c += (x[xOff + 2] & M) + (y[yOff + 2] & M);
51         z[zOff + 2] = (int)c;
52         c >>>= 32;
53         c += (x[xOff + 3] & M) + (y[yOff + 3] & M);
54         z[zOff + 3] = (int)c;
55         c >>>= 32;
56         c += (x[xOff + 4] & M) + (y[yOff + 4] & M);
57         z[zOff + 4] = (int)c;
58         c >>>= 32;
59         c += (x[xOff + 5] & M) + (y[yOff + 5] & M);
60         z[zOff + 5] = (int)c;
61         c >>>= 32;
62         c += (x[xOff + 6] & M) + (y[yOff + 6] & M);
63         z[zOff + 6] = (int)c;
64         c >>>= 32;
65         c += (x[xOff + 7] & M) + (y[yOff + 7] & M);
66         z[zOff + 7] = (int)c;
67         c >>>= 32;
68         return (int)c;
69     }
70 
addBothTo(int[] x, int[] y, int[] z)71     public static int addBothTo(int[] x, int[] y, int[] z)
72     {
73         long c = 0;
74         c += (x[0] & M) + (y[0] & M) + (z[0] & M);
75         z[0] = (int)c;
76         c >>>= 32;
77         c += (x[1] & M) + (y[1] & M) + (z[1] & M);
78         z[1] = (int)c;
79         c >>>= 32;
80         c += (x[2] & M) + (y[2] & M) + (z[2] & M);
81         z[2] = (int)c;
82         c >>>= 32;
83         c += (x[3] & M) + (y[3] & M) + (z[3] & M);
84         z[3] = (int)c;
85         c >>>= 32;
86         c += (x[4] & M) + (y[4] & M) + (z[4] & M);
87         z[4] = (int)c;
88         c >>>= 32;
89         c += (x[5] & M) + (y[5] & M) + (z[5] & M);
90         z[5] = (int)c;
91         c >>>= 32;
92         c += (x[6] & M) + (y[6] & M) + (z[6] & M);
93         z[6] = (int)c;
94         c >>>= 32;
95         c += (x[7] & M) + (y[7] & M) + (z[7] & M);
96         z[7] = (int)c;
97         c >>>= 32;
98         return (int)c;
99     }
100 
addBothTo(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)101     public static int addBothTo(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
102     {
103         long c = 0;
104         c += (x[xOff + 0] & M) + (y[yOff + 0] & M) + (z[zOff + 0] & M);
105         z[zOff + 0] = (int)c;
106         c >>>= 32;
107         c += (x[xOff + 1] & M) + (y[yOff + 1] & M) + (z[zOff + 1] & M);
108         z[zOff + 1] = (int)c;
109         c >>>= 32;
110         c += (x[xOff + 2] & M) + (y[yOff + 2] & M) + (z[zOff + 2] & M);
111         z[zOff + 2] = (int)c;
112         c >>>= 32;
113         c += (x[xOff + 3] & M) + (y[yOff + 3] & M) + (z[zOff + 3] & M);
114         z[zOff + 3] = (int)c;
115         c >>>= 32;
116         c += (x[xOff + 4] & M) + (y[yOff + 4] & M) + (z[zOff + 4] & M);
117         z[zOff + 4] = (int)c;
118         c >>>= 32;
119         c += (x[xOff + 5] & M) + (y[yOff + 5] & M) + (z[zOff + 5] & M);
120         z[zOff + 5] = (int)c;
121         c >>>= 32;
122         c += (x[xOff + 6] & M) + (y[yOff + 6] & M) + (z[zOff + 6] & M);
123         z[zOff + 6] = (int)c;
124         c >>>= 32;
125         c += (x[xOff + 7] & M) + (y[yOff + 7] & M) + (z[zOff + 7] & M);
126         z[zOff + 7] = (int)c;
127         c >>>= 32;
128         return (int)c;
129     }
130 
addTo(int[] x, int[] z)131     public static int addTo(int[] x, int[] z)
132     {
133         long c = 0;
134         c += (x[0] & M) + (z[0] & M);
135         z[0] = (int)c;
136         c >>>= 32;
137         c += (x[1] & M) + (z[1] & M);
138         z[1] = (int)c;
139         c >>>= 32;
140         c += (x[2] & M) + (z[2] & M);
141         z[2] = (int)c;
142         c >>>= 32;
143         c += (x[3] & M) + (z[3] & M);
144         z[3] = (int)c;
145         c >>>= 32;
146         c += (x[4] & M) + (z[4] & M);
147         z[4] = (int)c;
148         c >>>= 32;
149         c += (x[5] & M) + (z[5] & M);
150         z[5] = (int)c;
151         c >>>= 32;
152         c += (x[6] & M) + (z[6] & M);
153         z[6] = (int)c;
154         c >>>= 32;
155         c += (x[7] & M) + (z[7] & M);
156         z[7] = (int)c;
157         c >>>= 32;
158         return (int)c;
159     }
160 
addTo(int[] x, int xOff, int[] z, int zOff, int cIn)161     public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
162     {
163         long c = cIn & M;
164         c += (x[xOff + 0] & M) + (z[zOff + 0] & M);
165         z[zOff + 0] = (int)c;
166         c >>>= 32;
167         c += (x[xOff + 1] & M) + (z[zOff + 1] & M);
168         z[zOff + 1] = (int)c;
169         c >>>= 32;
170         c += (x[xOff + 2] & M) + (z[zOff + 2] & M);
171         z[zOff + 2] = (int)c;
172         c >>>= 32;
173         c += (x[xOff + 3] & M) + (z[zOff + 3] & M);
174         z[zOff + 3] = (int)c;
175         c >>>= 32;
176         c += (x[xOff + 4] & M) + (z[zOff + 4] & M);
177         z[zOff + 4] = (int)c;
178         c >>>= 32;
179         c += (x[xOff + 5] & M) + (z[zOff + 5] & M);
180         z[zOff + 5] = (int)c;
181         c >>>= 32;
182         c += (x[xOff + 6] & M) + (z[zOff + 6] & M);
183         z[zOff + 6] = (int)c;
184         c >>>= 32;
185         c += (x[xOff + 7] & M) + (z[zOff + 7] & M);
186         z[zOff + 7] = (int)c;
187         c >>>= 32;
188         return (int)c;
189     }
190 
addToEachOther(int[] u, int uOff, int[] v, int vOff)191     public static int addToEachOther(int[] u, int uOff, int[] v, int vOff)
192     {
193         long c = 0;
194         c += (u[uOff + 0] & M) + (v[vOff + 0] & M);
195         u[uOff + 0] = (int)c;
196         v[vOff + 0] = (int)c;
197         c >>>= 32;
198         c += (u[uOff + 1] & M) + (v[vOff + 1] & M);
199         u[uOff + 1] = (int)c;
200         v[vOff + 1] = (int)c;
201         c >>>= 32;
202         c += (u[uOff + 2] & M) + (v[vOff + 2] & M);
203         u[uOff + 2] = (int)c;
204         v[vOff + 2] = (int)c;
205         c >>>= 32;
206         c += (u[uOff + 3] & M) + (v[vOff + 3] & M);
207         u[uOff + 3] = (int)c;
208         v[vOff + 3] = (int)c;
209         c >>>= 32;
210         c += (u[uOff + 4] & M) + (v[vOff + 4] & M);
211         u[uOff + 4] = (int)c;
212         v[vOff + 4] = (int)c;
213         c >>>= 32;
214         c += (u[uOff + 5] & M) + (v[vOff + 5] & M);
215         u[uOff + 5] = (int)c;
216         v[vOff + 5] = (int)c;
217         c >>>= 32;
218         c += (u[uOff + 6] & M) + (v[vOff + 6] & M);
219         u[uOff + 6] = (int)c;
220         v[vOff + 6] = (int)c;
221         c >>>= 32;
222         c += (u[uOff + 7] & M) + (v[vOff + 7] & M);
223         u[uOff + 7] = (int)c;
224         v[vOff + 7] = (int)c;
225         c >>>= 32;
226         return (int)c;
227     }
228 
copy(int[] x, int[] z)229     public static void copy(int[] x, int[] z)
230     {
231         z[0] = x[0];
232         z[1] = x[1];
233         z[2] = x[2];
234         z[3] = x[3];
235         z[4] = x[4];
236         z[5] = x[5];
237         z[6] = x[6];
238         z[7] = x[7];
239     }
240 
copy64(long[] x, long[] z)241     public static void copy64(long[] x, long[] z)
242     {
243         z[0] = x[0];
244         z[1] = x[1];
245         z[2] = x[2];
246         z[3] = x[3];
247     }
248 
create()249     public static int[] create()
250     {
251         return new int[8];
252     }
253 
create64()254     public static long[] create64()
255     {
256         return new long[4];
257     }
258 
createExt()259     public static int[] createExt()
260     {
261         return new int[16];
262     }
263 
createExt64()264     public static long[] createExt64()
265     {
266         return new long[8];
267     }
268 
diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)269     public static boolean diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
270     {
271         boolean pos = gte(x, xOff, y, yOff);
272         if (pos)
273         {
274             sub(x, xOff, y, yOff, z, zOff);
275         }
276         else
277         {
278             sub(y, yOff, x, xOff, z, zOff);
279         }
280         return pos;
281     }
282 
eq(int[] x, int[] y)283     public static boolean eq(int[] x, int[] y)
284     {
285         for (int i = 7; i >= 0; --i)
286         {
287             if (x[i] != y[i])
288             {
289                 return false;
290             }
291         }
292         return true;
293     }
294 
eq64(long[] x, long[] y)295     public static boolean eq64(long[] x, long[] y)
296     {
297         for (int i = 3; i >= 0; --i)
298         {
299             if (x[i] != y[i])
300             {
301                 return false;
302             }
303         }
304         return true;
305     }
306 
fromBigInteger(BigInteger x)307     public static int[] fromBigInteger(BigInteger x)
308     {
309         if (x.signum() < 0 || x.bitLength() > 256)
310         {
311             throw new IllegalArgumentException();
312         }
313 
314         int[] z = create();
315         int i = 0;
316         while (x.signum() != 0)
317         {
318             z[i++] = x.intValue();
319             x = x.shiftRight(32);
320         }
321         return z;
322     }
323 
fromBigInteger64(BigInteger x)324     public static long[] fromBigInteger64(BigInteger x)
325     {
326         if (x.signum() < 0 || x.bitLength() > 256)
327         {
328             throw new IllegalArgumentException();
329         }
330 
331         long[] z = create64();
332         int i = 0;
333         while (x.signum() != 0)
334         {
335             z[i++] = x.longValue();
336             x = x.shiftRight(64);
337         }
338         return z;
339     }
340 
getBit(int[] x, int bit)341     public static int getBit(int[] x, int bit)
342     {
343         if (bit == 0)
344         {
345             return x[0] & 1;
346         }
347         if ((bit & 255) != bit)
348         {
349             return 0;
350         }
351         int w = bit >>> 5;
352         int b = bit & 31;
353         return (x[w] >>> b) & 1;
354     }
355 
gte(int[] x, int[] y)356     public static boolean gte(int[] x, int[] y)
357     {
358         for (int i = 7; i >= 0; --i)
359         {
360             int x_i = x[i] ^ Integer.MIN_VALUE;
361             int y_i = y[i] ^ Integer.MIN_VALUE;
362             if (x_i < y_i)
363                 return false;
364             if (x_i > y_i)
365                 return true;
366         }
367         return true;
368     }
369 
gte(int[] x, int xOff, int[] y, int yOff)370     public static boolean gte(int[] x, int xOff, int[] y, int yOff)
371     {
372         for (int i = 7; i >= 0; --i)
373         {
374             int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
375             int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
376             if (x_i < y_i)
377                 return false;
378             if (x_i > y_i)
379                 return true;
380         }
381         return true;
382     }
383 
isOne(int[] x)384     public static boolean isOne(int[] x)
385     {
386         if (x[0] != 1)
387         {
388             return false;
389         }
390         for (int i = 1; i < 8; ++i)
391         {
392             if (x[i] != 0)
393             {
394                 return false;
395             }
396         }
397         return true;
398     }
399 
isOne64(long[] x)400     public static boolean isOne64(long[] x)
401     {
402         if (x[0] != 1L)
403         {
404             return false;
405         }
406         for (int i = 1; i < 4; ++i)
407         {
408             if (x[i] != 0L)
409             {
410                 return false;
411             }
412         }
413         return true;
414     }
415 
isZero(int[] x)416     public static boolean isZero(int[] x)
417     {
418         for (int i = 0; i < 8; ++i)
419         {
420             if (x[i] != 0)
421             {
422                 return false;
423             }
424         }
425         return true;
426     }
427 
isZero64(long[] x)428     public static boolean isZero64(long[] x)
429     {
430         for (int i = 0; i < 4; ++i)
431         {
432             if (x[i] != 0L)
433             {
434                 return false;
435             }
436         }
437         return true;
438     }
439 
mul(int[] x, int[] y, int[] zz)440     public static void mul(int[] x, int[] y, int[] zz)
441     {
442         long y_0 = y[0] & M;
443         long y_1 = y[1] & M;
444         long y_2 = y[2] & M;
445         long y_3 = y[3] & M;
446         long y_4 = y[4] & M;
447         long y_5 = y[5] & M;
448         long y_6 = y[6] & M;
449         long y_7 = y[7] & M;
450 
451         {
452             long c = 0, x_0 = x[0] & M;
453             c += x_0 * y_0;
454             zz[0] = (int)c;
455             c >>>= 32;
456             c += x_0 * y_1;
457             zz[1] = (int)c;
458             c >>>= 32;
459             c += x_0 * y_2;
460             zz[2] = (int)c;
461             c >>>= 32;
462             c += x_0 * y_3;
463             zz[3] = (int)c;
464             c >>>= 32;
465             c += x_0 * y_4;
466             zz[4] = (int)c;
467             c >>>= 32;
468             c += x_0 * y_5;
469             zz[5] = (int)c;
470             c >>>= 32;
471             c += x_0 * y_6;
472             zz[6] = (int)c;
473             c >>>= 32;
474             c += x_0 * y_7;
475             zz[7] = (int)c;
476             c >>>= 32;
477             zz[8] = (int)c;
478         }
479 
480         for (int i = 1; i < 8; ++i)
481         {
482             long c = 0, x_i = x[i] & M;
483             c += x_i * y_0 + (zz[i + 0] & M);
484             zz[i + 0] = (int)c;
485             c >>>= 32;
486             c += x_i * y_1 + (zz[i + 1] & M);
487             zz[i + 1] = (int)c;
488             c >>>= 32;
489             c += x_i * y_2 + (zz[i + 2] & M);
490             zz[i + 2] = (int)c;
491             c >>>= 32;
492             c += x_i * y_3 + (zz[i + 3] & M);
493             zz[i + 3] = (int)c;
494             c >>>= 32;
495             c += x_i * y_4 + (zz[i + 4] & M);
496             zz[i + 4] = (int)c;
497             c >>>= 32;
498             c += x_i * y_5 + (zz[i + 5] & M);
499             zz[i + 5] = (int)c;
500             c >>>= 32;
501             c += x_i * y_6 + (zz[i + 6] & M);
502             zz[i + 6] = (int)c;
503             c >>>= 32;
504             c += x_i * y_7 + (zz[i + 7] & M);
505             zz[i + 7] = (int)c;
506             c >>>= 32;
507             zz[i + 8] = (int)c;
508         }
509     }
510 
mul(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)511     public static void mul(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
512     {
513         long y_0 = y[yOff + 0] & M;
514         long y_1 = y[yOff + 1] & M;
515         long y_2 = y[yOff + 2] & M;
516         long y_3 = y[yOff + 3] & M;
517         long y_4 = y[yOff + 4] & M;
518         long y_5 = y[yOff + 5] & M;
519         long y_6 = y[yOff + 6] & M;
520         long y_7 = y[yOff + 7] & M;
521 
522         {
523             long c = 0, x_0 = x[xOff + 0] & M;
524             c += x_0 * y_0;
525             zz[zzOff + 0] = (int)c;
526             c >>>= 32;
527             c += x_0 * y_1;
528             zz[zzOff + 1] = (int)c;
529             c >>>= 32;
530             c += x_0 * y_2;
531             zz[zzOff + 2] = (int)c;
532             c >>>= 32;
533             c += x_0 * y_3;
534             zz[zzOff + 3] = (int)c;
535             c >>>= 32;
536             c += x_0 * y_4;
537             zz[zzOff + 4] = (int)c;
538             c >>>= 32;
539             c += x_0 * y_5;
540             zz[zzOff + 5] = (int)c;
541             c >>>= 32;
542             c += x_0 * y_6;
543             zz[zzOff + 6] = (int)c;
544             c >>>= 32;
545             c += x_0 * y_7;
546             zz[zzOff + 7] = (int)c;
547             c >>>= 32;
548             zz[zzOff + 8] = (int)c;
549         }
550 
551         for (int i = 1; i < 8; ++i)
552         {
553             ++zzOff;
554             long c = 0, x_i = x[xOff + i] & M;
555             c += x_i * y_0 + (zz[zzOff + 0] & M);
556             zz[zzOff + 0] = (int)c;
557             c >>>= 32;
558             c += x_i * y_1 + (zz[zzOff + 1] & M);
559             zz[zzOff + 1] = (int)c;
560             c >>>= 32;
561             c += x_i * y_2 + (zz[zzOff + 2] & M);
562             zz[zzOff + 2] = (int)c;
563             c >>>= 32;
564             c += x_i * y_3 + (zz[zzOff + 3] & M);
565             zz[zzOff + 3] = (int)c;
566             c >>>= 32;
567             c += x_i * y_4 + (zz[zzOff + 4] & M);
568             zz[zzOff + 4] = (int)c;
569             c >>>= 32;
570             c += x_i * y_5 + (zz[zzOff + 5] & M);
571             zz[zzOff + 5] = (int)c;
572             c >>>= 32;
573             c += x_i * y_6 + (zz[zzOff + 6] & M);
574             zz[zzOff + 6] = (int)c;
575             c >>>= 32;
576             c += x_i * y_7 + (zz[zzOff + 7] & M);
577             zz[zzOff + 7] = (int)c;
578             c >>>= 32;
579             zz[zzOff + 8] = (int)c;
580         }
581     }
582 
mulAddTo(int[] x, int[] y, int[] zz)583     public static int mulAddTo(int[] x, int[] y, int[] zz)
584     {
585         long y_0 = y[0] & M;
586         long y_1 = y[1] & M;
587         long y_2 = y[2] & M;
588         long y_3 = y[3] & M;
589         long y_4 = y[4] & M;
590         long y_5 = y[5] & M;
591         long y_6 = y[6] & M;
592         long y_7 = y[7] & M;
593 
594         long zc = 0;
595         for (int i = 0; i < 8; ++i)
596         {
597             long c = 0, x_i = x[i] & M;
598             c += x_i * y_0 + (zz[i + 0] & M);
599             zz[i + 0] = (int)c;
600             c >>>= 32;
601             c += x_i * y_1 + (zz[i + 1] & M);
602             zz[i + 1] = (int)c;
603             c >>>= 32;
604             c += x_i * y_2 + (zz[i + 2] & M);
605             zz[i + 2] = (int)c;
606             c >>>= 32;
607             c += x_i * y_3 + (zz[i + 3] & M);
608             zz[i + 3] = (int)c;
609             c >>>= 32;
610             c += x_i * y_4 + (zz[i + 4] & M);
611             zz[i + 4] = (int)c;
612             c >>>= 32;
613             c += x_i * y_5 + (zz[i + 5] & M);
614             zz[i + 5] = (int)c;
615             c >>>= 32;
616             c += x_i * y_6 + (zz[i + 6] & M);
617             zz[i + 6] = (int)c;
618             c >>>= 32;
619             c += x_i * y_7 + (zz[i + 7] & M);
620             zz[i + 7] = (int)c;
621             c >>>= 32;
622             c += zc + (zz[i + 8] & M);
623             zz[i + 8] = (int)c;
624             zc = c >>> 32;
625         }
626         return (int)zc;
627     }
628 
mulAddTo(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)629     public static int mulAddTo(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
630     {
631         long y_0 = y[yOff + 0] & M;
632         long y_1 = y[yOff + 1] & M;
633         long y_2 = y[yOff + 2] & M;
634         long y_3 = y[yOff + 3] & M;
635         long y_4 = y[yOff + 4] & M;
636         long y_5 = y[yOff + 5] & M;
637         long y_6 = y[yOff + 6] & M;
638         long y_7 = y[yOff + 7] & M;
639 
640         long zc = 0;
641         for (int i = 0; i < 8; ++i)
642         {
643             long c = 0, x_i = x[xOff + i] & M;
644             c += x_i * y_0 + (zz[zzOff + 0] & M);
645             zz[zzOff + 0] = (int)c;
646             c >>>= 32;
647             c += x_i * y_1 + (zz[zzOff + 1] & M);
648             zz[zzOff + 1] = (int)c;
649             c >>>= 32;
650             c += x_i * y_2 + (zz[zzOff + 2] & M);
651             zz[zzOff + 2] = (int)c;
652             c >>>= 32;
653             c += x_i * y_3 + (zz[zzOff + 3] & M);
654             zz[zzOff + 3] = (int)c;
655             c >>>= 32;
656             c += x_i * y_4 + (zz[zzOff + 4] & M);
657             zz[zzOff + 4] = (int)c;
658             c >>>= 32;
659             c += x_i * y_5 + (zz[zzOff + 5] & M);
660             zz[zzOff + 5] = (int)c;
661             c >>>= 32;
662             c += x_i * y_6 + (zz[zzOff + 6] & M);
663             zz[zzOff + 6] = (int)c;
664             c >>>= 32;
665             c += x_i * y_7 + (zz[zzOff + 7] & M);
666             zz[zzOff + 7] = (int)c;
667             c >>>= 32;
668             c += zc + (zz[zzOff + 8] & M);
669             zz[zzOff + 8] = (int)c;
670             zc = c >>> 32;
671             ++zzOff;
672         }
673         return (int)zc;
674     }
675 
mul33Add(int w, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)676     public static long mul33Add(int w, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
677     {
678         // assert w >>> 31 == 0;
679 
680         long c = 0, wVal = w & M;
681         long x0 = x[xOff + 0] & M;
682         c += wVal * x0 + (y[yOff + 0] & M);
683         z[zOff + 0] = (int)c;
684         c >>>= 32;
685         long x1 = x[xOff + 1] & M;
686         c += wVal * x1 + x0 + (y[yOff + 1] & M);
687         z[zOff + 1] = (int)c;
688         c >>>= 32;
689         long x2 = x[xOff + 2] & M;
690         c += wVal * x2 + x1 + (y[yOff + 2] & M);
691         z[zOff + 2] = (int)c;
692         c >>>= 32;
693         long x3 = x[xOff + 3] & M;
694         c += wVal * x3 + x2 + (y[yOff + 3] & M);
695         z[zOff + 3] = (int)c;
696         c >>>= 32;
697         long x4 = x[xOff + 4] & M;
698         c += wVal * x4 + x3 + (y[yOff + 4] & M);
699         z[zOff + 4] = (int)c;
700         c >>>= 32;
701         long x5 = x[xOff + 5] & M;
702         c += wVal * x5 + x4 + (y[yOff + 5] & M);
703         z[zOff + 5] = (int)c;
704         c >>>= 32;
705         long x6 = x[xOff + 6] & M;
706         c += wVal * x6 + x5 + (y[yOff + 6] & M);
707         z[zOff + 6] = (int)c;
708         c >>>= 32;
709         long x7 = x[xOff + 7] & M;
710         c += wVal * x7 + x6 + (y[yOff + 7] & M);
711         z[zOff + 7] = (int)c;
712         c >>>= 32;
713         c += x7;
714         return c;
715     }
716 
mulByWord(int x, int[] z)717     public static int mulByWord(int x, int[] z)
718     {
719         long c = 0, xVal = x & M;
720         c += xVal * (z[0] & M);
721         z[0] = (int)c;
722         c >>>= 32;
723         c += xVal * (z[1] & M);
724         z[1] = (int)c;
725         c >>>= 32;
726         c += xVal * (z[2] & M);
727         z[2] = (int)c;
728         c >>>= 32;
729         c += xVal * (z[3] & M);
730         z[3] = (int)c;
731         c >>>= 32;
732         c += xVal * (z[4] & M);
733         z[4] = (int)c;
734         c >>>= 32;
735         c += xVal * (z[5] & M);
736         z[5] = (int)c;
737         c >>>= 32;
738         c += xVal * (z[6] & M);
739         z[6] = (int)c;
740         c >>>= 32;
741         c += xVal * (z[7] & M);
742         z[7] = (int)c;
743         c >>>= 32;
744         return (int)c;
745     }
746 
mulByWordAddTo(int x, int[] y, int[] z)747     public static int mulByWordAddTo(int x, int[] y, int[] z)
748     {
749         long c = 0, xVal = x & M;
750         c += xVal * (z[0] & M) + (y[0] & M);
751         z[0] = (int)c;
752         c >>>= 32;
753         c += xVal * (z[1] & M) + (y[1] & M);
754         z[1] = (int)c;
755         c >>>= 32;
756         c += xVal * (z[2] & M) + (y[2] & M);
757         z[2] = (int)c;
758         c >>>= 32;
759         c += xVal * (z[3] & M) + (y[3] & M);
760         z[3] = (int)c;
761         c >>>= 32;
762         c += xVal * (z[4] & M) + (y[4] & M);
763         z[4] = (int)c;
764         c >>>= 32;
765         c += xVal * (z[5] & M) + (y[5] & M);
766         z[5] = (int)c;
767         c >>>= 32;
768         c += xVal * (z[6] & M) + (y[6] & M);
769         z[6] = (int)c;
770         c >>>= 32;
771         c += xVal * (z[7] & M) + (y[7] & M);
772         z[7] = (int)c;
773         c >>>= 32;
774         return (int)c;
775     }
776 
mulWordAddTo(int x, int[] y, int yOff, int[] z, int zOff)777     public static int mulWordAddTo(int x, int[] y, int yOff, int[] z, int zOff)
778     {
779         long c = 0, xVal = x & M;
780         c += xVal * (y[yOff + 0] & M) + (z[zOff + 0] & M);
781         z[zOff + 0] = (int)c;
782         c >>>= 32;
783         c += xVal * (y[yOff + 1] & M) + (z[zOff + 1] & M);
784         z[zOff + 1] = (int)c;
785         c >>>= 32;
786         c += xVal * (y[yOff + 2] & M) + (z[zOff + 2] & M);
787         z[zOff + 2] = (int)c;
788         c >>>= 32;
789         c += xVal * (y[yOff + 3] & M) + (z[zOff + 3] & M);
790         z[zOff + 3] = (int)c;
791         c >>>= 32;
792         c += xVal * (y[yOff + 4] & M) + (z[zOff + 4] & M);
793         z[zOff + 4] = (int)c;
794         c >>>= 32;
795         c += xVal * (y[yOff + 5] & M) + (z[zOff + 5] & M);
796         z[zOff + 5] = (int)c;
797         c >>>= 32;
798         c += xVal * (y[yOff + 6] & M) + (z[zOff + 6] & M);
799         z[zOff + 6] = (int)c;
800         c >>>= 32;
801         c += xVal * (y[yOff + 7] & M) + (z[zOff + 7] & M);
802         z[zOff + 7] = (int)c;
803         c >>>= 32;
804         return (int)c;
805     }
806 
mul33DWordAdd(int x, long y, int[] z, int zOff)807     public static int mul33DWordAdd(int x, long y, int[] z, int zOff)
808     {
809         // assert x >>> 31 == 0;
810         // assert zOff <= 4;
811 
812         long c = 0, xVal = x & M;
813         long y00 = y & M;
814         c += xVal * y00 + (z[zOff + 0] & M);
815         z[zOff + 0] = (int)c;
816         c >>>= 32;
817         long y01 = y >>> 32;
818         c += xVal * y01 + y00 + (z[zOff + 1] & M);
819         z[zOff + 1] = (int)c;
820         c >>>= 32;
821         c += y01 + (z[zOff + 2] & M);
822         z[zOff + 2] = (int)c;
823         c >>>= 32;
824         c += (z[zOff + 3] & M);
825         z[zOff + 3] = (int)c;
826         c >>>= 32;
827         return c == 0 ? 0 : Nat.incAt(8, z, zOff, 4);
828     }
829 
mul33WordAdd(int x, int y, int[] z, int zOff)830     public static int mul33WordAdd(int x, int y, int[] z, int zOff)
831     {
832         // assert x >>> 31 == 0;
833         // assert zOff <= 5;
834 
835         long c = 0, xVal = x & M, yVal = y & M;
836         c += yVal * xVal + (z[zOff + 0] & M);
837         z[zOff + 0] = (int)c;
838         c >>>= 32;
839         c += yVal + (z[zOff + 1] & M);
840         z[zOff + 1] = (int)c;
841         c >>>= 32;
842         c += (z[zOff + 2] & M);
843         z[zOff + 2] = (int)c;
844         c >>>= 32;
845         return c == 0 ? 0 : Nat.incAt(8, z, zOff, 3);
846     }
847 
mulWordDwordAdd(int x, long y, int[] z, int zOff)848     public static int mulWordDwordAdd(int x, long y, int[] z, int zOff)
849     {
850         // assert zOff <= 5;
851         long c = 0, xVal = x & M;
852         c += xVal * (y & M) + (z[zOff + 0] & M);
853         z[zOff + 0] = (int)c;
854         c >>>= 32;
855         c += xVal * (y >>> 32) + (z[zOff + 1] & M);
856         z[zOff + 1] = (int)c;
857         c >>>= 32;
858         c += (z[zOff + 2] & M);
859         z[zOff + 2] = (int)c;
860         c >>>= 32;
861         return c == 0 ? 0 : Nat.incAt(8, z, zOff, 3);
862     }
863 
mulWord(int x, int[] y, int[] z, int zOff)864     public static int mulWord(int x, int[] y, int[] z, int zOff)
865     {
866         long c = 0, xVal = x & M;
867         int i = 0;
868         do
869         {
870             c += xVal * (y[i] & M);
871             z[zOff + i] = (int)c;
872             c >>>= 32;
873         }
874         while (++i < 8);
875         return (int)c;
876     }
877 
square(int[] x, int[] zz)878     public static void square(int[] x, int[] zz)
879     {
880         long x_0 = x[0] & M;
881         long zz_1;
882 
883         int c = 0, w;
884         {
885             int i = 7, j = 16;
886             do
887             {
888                 long xVal = (x[i--] & M);
889                 long p = xVal * xVal;
890                 zz[--j] = (c << 31) | (int)(p >>> 33);
891                 zz[--j] = (int)(p >>> 1);
892                 c = (int)p;
893             }
894             while (i > 0);
895 
896             {
897                 long p = x_0 * x_0;
898                 zz_1 = ((c << 31) & M) | (p >>> 33);
899                 zz[0] = (int)p;
900                 c = (int)(p >>> 32) & 1;
901             }
902         }
903 
904         long x_1 = x[1] & M;
905         long zz_2 = zz[2] & M;
906 
907         {
908             zz_1 += x_1 * x_0;
909             w = (int)zz_1;
910             zz[1] = (w << 1) | c;
911             c = w >>> 31;
912             zz_2 += zz_1 >>> 32;
913         }
914 
915         long x_2 = x[2] & M;
916         long zz_3 = zz[3] & M;
917         long zz_4 = zz[4] & M;
918         {
919             zz_2 += x_2 * x_0;
920             w = (int)zz_2;
921             zz[2] = (w << 1) | c;
922             c = w >>> 31;
923             zz_3 += (zz_2 >>> 32) + x_2 * x_1;
924             zz_4 += zz_3 >>> 32;
925             zz_3 &= M;
926         }
927 
928         long x_3 = x[3] & M;
929         long zz_5 = (zz[5] & M) + (zz_4 >>> 32); zz_4 &= M;
930         long zz_6 = (zz[6] & M) + (zz_5 >>> 32); zz_5 &= M;
931         {
932             zz_3 += x_3 * x_0;
933             w = (int)zz_3;
934             zz[3] = (w << 1) | c;
935             c = w >>> 31;
936             zz_4 += (zz_3 >>> 32) + x_3 * x_1;
937             zz_5 += (zz_4 >>> 32) + x_3 * x_2;
938             zz_4 &= M;
939             zz_6 += zz_5 >>> 32;
940             zz_5 &= M;
941         }
942 
943         long x_4 = x[4] & M;
944         long zz_7 = (zz[7] & M) + (zz_6 >>> 32); zz_6 &= M;
945         long zz_8 = (zz[8] & M) + (zz_7 >>> 32); zz_7 &= M;
946         {
947             zz_4 += x_4 * x_0;
948             w = (int)zz_4;
949             zz[4] = (w << 1) | c;
950             c = w >>> 31;
951             zz_5 += (zz_4 >>> 32) + x_4 * x_1;
952             zz_6 += (zz_5 >>> 32) + x_4 * x_2;
953             zz_5 &= M;
954             zz_7 += (zz_6 >>> 32) + x_4 * x_3;
955             zz_6 &= M;
956             zz_8 += zz_7 >>> 32;
957             zz_7 &= M;
958         }
959 
960         long x_5 = x[5] & M;
961         long zz_9 = (zz[9] & M) + (zz_8 >>> 32); zz_8 &= M;
962         long zz_10 = (zz[10] & M) + (zz_9 >>> 32); zz_9 &= M;
963         {
964             zz_5 += x_5 * x_0;
965             w = (int)zz_5;
966             zz[5] = (w << 1) | c;
967             c = w >>> 31;
968             zz_6 += (zz_5 >>> 32) + x_5 * x_1;
969             zz_7 += (zz_6 >>> 32) + x_5 * x_2;
970             zz_6 &= M;
971             zz_8 += (zz_7 >>> 32) + x_5 * x_3;
972             zz_7 &= M;
973             zz_9 += (zz_8 >>> 32) + x_5 * x_4;
974             zz_8 &= M;
975             zz_10 += zz_9 >>> 32;
976             zz_9 &= M;
977         }
978 
979         long x_6 = x[6] & M;
980         long zz_11 = (zz[11] & M) + (zz_10 >>> 32); zz_10 &= M;
981         long zz_12 = (zz[12] & M) + (zz_11 >>> 32); zz_11 &= M;
982         {
983             zz_6 += x_6 * x_0;
984             w = (int)zz_6;
985             zz[6] = (w << 1) | c;
986             c = w >>> 31;
987             zz_7 += (zz_6 >>> 32) + x_6 * x_1;
988             zz_8 += (zz_7 >>> 32) + x_6 * x_2;
989             zz_7 &= M;
990             zz_9 += (zz_8 >>> 32) + x_6 * x_3;
991             zz_8 &= M;
992             zz_10 += (zz_9 >>> 32) + x_6 * x_4;
993             zz_9 &= M;
994             zz_11 += (zz_10 >>> 32) + x_6 * x_5;
995             zz_10 &= M;
996             zz_12 += zz_11 >>> 32;
997             zz_11 &= M;
998         }
999 
1000         long x_7 = x[7] & M;
1001         long zz_13 = (zz[13] & M) + (zz_12 >>> 32); zz_12 &= M;
1002         long zz_14 = (zz[14] & M) + (zz_13 >>> 32); zz_13 &= M;
1003         {
1004             zz_7 += x_7 * x_0;
1005             w = (int)zz_7;
1006             zz[7] = (w << 1) | c;
1007             c = w >>> 31;
1008             zz_8 += (zz_7 >>> 32) + x_7 * x_1;
1009             zz_9 += (zz_8 >>> 32) + x_7 * x_2;
1010             zz_10 += (zz_9 >>> 32) + x_7 * x_3;
1011             zz_11 += (zz_10 >>> 32) + x_7 * x_4;
1012             zz_12 += (zz_11 >>> 32) + x_7 * x_5;
1013             zz_13 += (zz_12 >>> 32) + x_7 * x_6;
1014             zz_14 += zz_13 >>> 32;
1015         }
1016 
1017         w = (int)zz_8;
1018         zz[8] = (w << 1) | c;
1019         c = w >>> 31;
1020         w = (int)zz_9;
1021         zz[9] = (w << 1) | c;
1022         c = w >>> 31;
1023         w = (int)zz_10;
1024         zz[10] = (w << 1) | c;
1025         c = w >>> 31;
1026         w = (int)zz_11;
1027         zz[11] = (w << 1) | c;
1028         c = w >>> 31;
1029         w = (int)zz_12;
1030         zz[12] = (w << 1) | c;
1031         c = w >>> 31;
1032         w = (int)zz_13;
1033         zz[13] = (w << 1) | c;
1034         c = w >>> 31;
1035         w = (int)zz_14;
1036         zz[14] = (w << 1) | c;
1037         c = w >>> 31;
1038         w = zz[15] + (int)(zz_14 >>> 32);
1039         zz[15] = (w << 1) | c;
1040     }
1041 
square(int[] x, int xOff, int[] zz, int zzOff)1042     public static void square(int[] x, int xOff, int[] zz, int zzOff)
1043     {
1044         long x_0 = x[xOff + 0] & M;
1045         long zz_1;
1046 
1047         int c = 0, w;
1048         {
1049             int i = 7, j = 16;
1050             do
1051             {
1052                 long xVal = (x[xOff + i--] & M);
1053                 long p = xVal * xVal;
1054                 zz[zzOff + --j] = (c << 31) | (int)(p >>> 33);
1055                 zz[zzOff + --j] = (int)(p >>> 1);
1056                 c = (int)p;
1057             }
1058             while (i > 0);
1059 
1060             {
1061                 long p = x_0 * x_0;
1062                 zz_1 = ((c << 31) & M) | (p >>> 33);
1063                 zz[zzOff + 0] = (int)p;
1064                 c = (int)(p >>> 32) & 1;
1065             }
1066         }
1067 
1068         long x_1 = x[xOff + 1] & M;
1069         long zz_2 = zz[zzOff + 2] & M;
1070 
1071         {
1072             zz_1 += x_1 * x_0;
1073             w = (int)zz_1;
1074             zz[zzOff + 1] = (w << 1) | c;
1075             c = w >>> 31;
1076             zz_2 += zz_1 >>> 32;
1077         }
1078 
1079         long x_2 = x[xOff + 2] & M;
1080         long zz_3 = zz[zzOff + 3] & M;
1081         long zz_4 = zz[zzOff + 4] & M;
1082         {
1083             zz_2 += x_2 * x_0;
1084             w = (int)zz_2;
1085             zz[zzOff + 2] = (w << 1) | c;
1086             c = w >>> 31;
1087             zz_3 += (zz_2 >>> 32) + x_2 * x_1;
1088             zz_4 += zz_3 >>> 32;
1089             zz_3 &= M;
1090         }
1091 
1092         long x_3 = x[xOff + 3] & M;
1093         long zz_5 = (zz[zzOff + 5] & M) + (zz_4 >>> 32); zz_4 &= M;
1094         long zz_6 = (zz[zzOff + 6] & M) + (zz_5 >>> 32); zz_5 &= M;
1095         {
1096             zz_3 += x_3 * x_0;
1097             w = (int)zz_3;
1098             zz[zzOff + 3] = (w << 1) | c;
1099             c = w >>> 31;
1100             zz_4 += (zz_3 >>> 32) + x_3 * x_1;
1101             zz_5 += (zz_4 >>> 32) + x_3 * x_2;
1102             zz_4 &= M;
1103             zz_6 += zz_5 >>> 32;
1104             zz_5 &= M;
1105         }
1106 
1107         long x_4 = x[xOff + 4] & M;
1108         long zz_7 = (zz[zzOff + 7] & M) + (zz_6 >>> 32); zz_6 &= M;
1109         long zz_8 = (zz[zzOff + 8] & M) + (zz_7 >>> 32); zz_7 &= M;
1110         {
1111             zz_4 += x_4 * x_0;
1112             w = (int)zz_4;
1113             zz[zzOff + 4] = (w << 1) | c;
1114             c = w >>> 31;
1115             zz_5 += (zz_4 >>> 32) + x_4 * x_1;
1116             zz_6 += (zz_5 >>> 32) + x_4 * x_2;
1117             zz_5 &= M;
1118             zz_7 += (zz_6 >>> 32) + x_4 * x_3;
1119             zz_6 &= M;
1120             zz_8 += zz_7 >>> 32;
1121             zz_7 &= M;
1122         }
1123 
1124         long x_5 = x[xOff + 5] & M;
1125         long zz_9 = (zz[zzOff + 9] & M) + (zz_8 >>> 32); zz_8 &= M;
1126         long zz_10 = (zz[zzOff + 10] & M) + (zz_9 >>> 32); zz_9 &= M;
1127         {
1128             zz_5 += x_5 * x_0;
1129             w = (int)zz_5;
1130             zz[zzOff + 5] = (w << 1) | c;
1131             c = w >>> 31;
1132             zz_6 += (zz_5 >>> 32) + x_5 * x_1;
1133             zz_7 += (zz_6 >>> 32) + x_5 * x_2;
1134             zz_6 &= M;
1135             zz_8 += (zz_7 >>> 32) + x_5 * x_3;
1136             zz_7 &= M;
1137             zz_9 += (zz_8 >>> 32) + x_5 * x_4;
1138             zz_8 &= M;
1139             zz_10 += zz_9 >>> 32;
1140             zz_9 &= M;
1141         }
1142 
1143         long x_6 = x[xOff + 6] & M;
1144         long zz_11 = (zz[zzOff + 11] & M) + (zz_10 >>> 32); zz_10 &= M;
1145         long zz_12 = (zz[zzOff + 12] & M) + (zz_11 >>> 32); zz_11 &= M;
1146         {
1147             zz_6 += x_6 * x_0;
1148             w = (int)zz_6;
1149             zz[zzOff + 6] = (w << 1) | c;
1150             c = w >>> 31;
1151             zz_7 += (zz_6 >>> 32) + x_6 * x_1;
1152             zz_8 += (zz_7 >>> 32) + x_6 * x_2;
1153             zz_7 &= M;
1154             zz_9 += (zz_8 >>> 32) + x_6 * x_3;
1155             zz_8 &= M;
1156             zz_10 += (zz_9 >>> 32) + x_6 * x_4;
1157             zz_9 &= M;
1158             zz_11 += (zz_10 >>> 32) + x_6 * x_5;
1159             zz_10 &= M;
1160             zz_12 += zz_11 >>> 32;
1161             zz_11 &= M;
1162         }
1163 
1164         long x_7 = x[xOff + 7] & M;
1165         long zz_13 = (zz[zzOff + 13] & M) + (zz_12 >>> 32); zz_12 &= M;
1166         long zz_14 = (zz[zzOff + 14] & M) + (zz_13 >>> 32); zz_13 &= M;
1167         {
1168             zz_7 += x_7 * x_0;
1169             w = (int)zz_7;
1170             zz[zzOff + 7] = (w << 1) | c;
1171             c = w >>> 31;
1172             zz_8 += (zz_7 >>> 32) + x_7 * x_1;
1173             zz_9 += (zz_8 >>> 32) + x_7 * x_2;
1174             zz_10 += (zz_9 >>> 32) + x_7 * x_3;
1175             zz_11 += (zz_10 >>> 32) + x_7 * x_4;
1176             zz_12 += (zz_11 >>> 32) + x_7 * x_5;
1177             zz_13 += (zz_12 >>> 32) + x_7 * x_6;
1178             zz_14 += zz_13 >>> 32;
1179         }
1180 
1181         w = (int)zz_8;
1182         zz[zzOff + 8] = (w << 1) | c;
1183         c = w >>> 31;
1184         w = (int)zz_9;
1185         zz[zzOff + 9] = (w << 1) | c;
1186         c = w >>> 31;
1187         w = (int)zz_10;
1188         zz[zzOff + 10] = (w << 1) | c;
1189         c = w >>> 31;
1190         w = (int)zz_11;
1191         zz[zzOff + 11] = (w << 1) | c;
1192         c = w >>> 31;
1193         w = (int)zz_12;
1194         zz[zzOff + 12] = (w << 1) | c;
1195         c = w >>> 31;
1196         w = (int)zz_13;
1197         zz[zzOff + 13] = (w << 1) | c;
1198         c = w >>> 31;
1199         w = (int)zz_14;
1200         zz[zzOff + 14] = (w << 1) | c;
1201         c = w >>> 31;
1202         w = zz[zzOff + 15] + (int)(zz_14 >>> 32);
1203         zz[zzOff + 15] = (w << 1) | c;
1204     }
1205 
sub(int[] x, int[] y, int[] z)1206     public static int sub(int[] x, int[] y, int[] z)
1207     {
1208         long c = 0;
1209         c += (x[0] & M) - (y[0] & M);
1210         z[0] = (int)c;
1211         c >>= 32;
1212         c += (x[1] & M) - (y[1] & M);
1213         z[1] = (int)c;
1214         c >>= 32;
1215         c += (x[2] & M) - (y[2] & M);
1216         z[2] = (int)c;
1217         c >>= 32;
1218         c += (x[3] & M) - (y[3] & M);
1219         z[3] = (int)c;
1220         c >>= 32;
1221         c += (x[4] & M) - (y[4] & M);
1222         z[4] = (int)c;
1223         c >>= 32;
1224         c += (x[5] & M) - (y[5] & M);
1225         z[5] = (int)c;
1226         c >>= 32;
1227         c += (x[6] & M) - (y[6] & M);
1228         z[6] = (int)c;
1229         c >>= 32;
1230         c += (x[7] & M) - (y[7] & M);
1231         z[7] = (int)c;
1232         c >>= 32;
1233         return (int)c;
1234     }
1235 
sub(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)1236     public static int sub(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
1237     {
1238         long c = 0;
1239         c += (x[xOff + 0] & M) - (y[yOff + 0] & M);
1240         z[zOff + 0] = (int)c;
1241         c >>= 32;
1242         c += (x[xOff + 1] & M) - (y[yOff + 1] & M);
1243         z[zOff + 1] = (int)c;
1244         c >>= 32;
1245         c += (x[xOff + 2] & M) - (y[yOff + 2] & M);
1246         z[zOff + 2] = (int)c;
1247         c >>= 32;
1248         c += (x[xOff + 3] & M) - (y[yOff + 3] & M);
1249         z[zOff + 3] = (int)c;
1250         c >>= 32;
1251         c += (x[xOff + 4] & M) - (y[yOff + 4] & M);
1252         z[zOff + 4] = (int)c;
1253         c >>= 32;
1254         c += (x[xOff + 5] & M) - (y[yOff + 5] & M);
1255         z[zOff + 5] = (int)c;
1256         c >>= 32;
1257         c += (x[xOff + 6] & M) - (y[yOff + 6] & M);
1258         z[zOff + 6] = (int)c;
1259         c >>= 32;
1260         c += (x[xOff + 7] & M) - (y[yOff + 7] & M);
1261         z[zOff + 7] = (int)c;
1262         c >>= 32;
1263         return (int)c;
1264     }
1265 
subBothFrom(int[] x, int[] y, int[] z)1266     public static int subBothFrom(int[] x, int[] y, int[] z)
1267     {
1268         long c = 0;
1269         c += (z[0] & M) - (x[0] & M) - (y[0] & M);
1270         z[0] = (int)c;
1271         c >>= 32;
1272         c += (z[1] & M) - (x[1] & M) - (y[1] & M);
1273         z[1] = (int)c;
1274         c >>= 32;
1275         c += (z[2] & M) - (x[2] & M) - (y[2] & M);
1276         z[2] = (int)c;
1277         c >>= 32;
1278         c += (z[3] & M) - (x[3] & M) - (y[3] & M);
1279         z[3] = (int)c;
1280         c >>= 32;
1281         c += (z[4] & M) - (x[4] & M) - (y[4] & M);
1282         z[4] = (int)c;
1283         c >>= 32;
1284         c += (z[5] & M) - (x[5] & M) - (y[5] & M);
1285         z[5] = (int)c;
1286         c >>= 32;
1287         c += (z[6] & M) - (x[6] & M) - (y[6] & M);
1288         z[6] = (int)c;
1289         c >>= 32;
1290         c += (z[7] & M) - (x[7] & M) - (y[7] & M);
1291         z[7] = (int)c;
1292         c >>= 32;
1293         return (int)c;
1294     }
1295 
subFrom(int[] x, int[] z)1296     public static int subFrom(int[] x, int[] z)
1297     {
1298         long c = 0;
1299         c += (z[0] & M) - (x[0] & M);
1300         z[0] = (int)c;
1301         c >>= 32;
1302         c += (z[1] & M) - (x[1] & M);
1303         z[1] = (int)c;
1304         c >>= 32;
1305         c += (z[2] & M) - (x[2] & M);
1306         z[2] = (int)c;
1307         c >>= 32;
1308         c += (z[3] & M) - (x[3] & M);
1309         z[3] = (int)c;
1310         c >>= 32;
1311         c += (z[4] & M) - (x[4] & M);
1312         z[4] = (int)c;
1313         c >>= 32;
1314         c += (z[5] & M) - (x[5] & M);
1315         z[5] = (int)c;
1316         c >>= 32;
1317         c += (z[6] & M) - (x[6] & M);
1318         z[6] = (int)c;
1319         c >>= 32;
1320         c += (z[7] & M) - (x[7] & M);
1321         z[7] = (int)c;
1322         c >>= 32;
1323         return (int)c;
1324     }
1325 
subFrom(int[] x, int xOff, int[] z, int zOff)1326     public static int subFrom(int[] x, int xOff, int[] z, int zOff)
1327     {
1328         long c = 0;
1329         c += (z[zOff + 0] & M) - (x[xOff + 0] & M);
1330         z[zOff + 0] = (int)c;
1331         c >>= 32;
1332         c += (z[zOff + 1] & M) - (x[xOff + 1] & M);
1333         z[zOff + 1] = (int)c;
1334         c >>= 32;
1335         c += (z[zOff + 2] & M) - (x[xOff + 2] & M);
1336         z[zOff + 2] = (int)c;
1337         c >>= 32;
1338         c += (z[zOff + 3] & M) - (x[xOff + 3] & M);
1339         z[zOff + 3] = (int)c;
1340         c >>= 32;
1341         c += (z[zOff + 4] & M) - (x[xOff + 4] & M);
1342         z[zOff + 4] = (int)c;
1343         c >>= 32;
1344         c += (z[zOff + 5] & M) - (x[xOff + 5] & M);
1345         z[zOff + 5] = (int)c;
1346         c >>= 32;
1347         c += (z[zOff + 6] & M) - (x[xOff + 6] & M);
1348         z[zOff + 6] = (int)c;
1349         c >>= 32;
1350         c += (z[zOff + 7] & M) - (x[xOff + 7] & M);
1351         z[zOff + 7] = (int)c;
1352         c >>= 32;
1353         return (int)c;
1354     }
1355 
toBigInteger(int[] x)1356     public static BigInteger toBigInteger(int[] x)
1357     {
1358         byte[] bs = new byte[32];
1359         for (int i = 0; i < 8; ++i)
1360         {
1361             int x_i = x[i];
1362             if (x_i != 0)
1363             {
1364                 Pack.intToBigEndian(x_i, bs, (7 - i) << 2);
1365             }
1366         }
1367         return new BigInteger(1, bs);
1368     }
1369 
toBigInteger64(long[] x)1370     public static BigInteger toBigInteger64(long[] x)
1371     {
1372         byte[] bs = new byte[32];
1373         for (int i = 0; i < 4; ++i)
1374         {
1375             long x_i = x[i];
1376             if (x_i != 0L)
1377             {
1378                 Pack.longToBigEndian(x_i, bs, (3 - i) << 3);
1379             }
1380         }
1381         return new BigInteger(1, bs);
1382     }
1383 
zero(int[] z)1384     public static void zero(int[] z)
1385     {
1386         z[0] = 0;
1387         z[1] = 0;
1388         z[2] = 0;
1389         z[3] = 0;
1390         z[4] = 0;
1391         z[5] = 0;
1392         z[6] = 0;
1393         z[7] = 0;
1394     }
1395 }
1396