• 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 Nat192
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         return (int)c;
33     }
34 
addBothTo(int[] x, int[] y, int[] z)35     public static int addBothTo(int[] x, int[] y, int[] z)
36     {
37         long c = 0;
38         c += (x[0] & M) + (y[0] & M) + (z[0] & M);
39         z[0] = (int)c;
40         c >>>= 32;
41         c += (x[1] & M) + (y[1] & M) + (z[1] & M);
42         z[1] = (int)c;
43         c >>>= 32;
44         c += (x[2] & M) + (y[2] & M) + (z[2] & M);
45         z[2] = (int)c;
46         c >>>= 32;
47         c += (x[3] & M) + (y[3] & M) + (z[3] & M);
48         z[3] = (int)c;
49         c >>>= 32;
50         c += (x[4] & M) + (y[4] & M) + (z[4] & M);
51         z[4] = (int)c;
52         c >>>= 32;
53         c += (x[5] & M) + (y[5] & M) + (z[5] & M);
54         z[5] = (int)c;
55         c >>>= 32;
56         return (int)c;
57     }
58 
addTo(int[] x, int[] z)59     public static int addTo(int[] x, int[] z)
60     {
61         long c = 0;
62         c += (x[0] & M) + (z[0] & M);
63         z[0] = (int)c;
64         c >>>= 32;
65         c += (x[1] & M) + (z[1] & M);
66         z[1] = (int)c;
67         c >>>= 32;
68         c += (x[2] & M) + (z[2] & M);
69         z[2] = (int)c;
70         c >>>= 32;
71         c += (x[3] & M) + (z[3] & M);
72         z[3] = (int)c;
73         c >>>= 32;
74         c += (x[4] & M) + (z[4] & M);
75         z[4] = (int)c;
76         c >>>= 32;
77         c += (x[5] & M) + (z[5] & M);
78         z[5] = (int)c;
79         c >>>= 32;
80         return (int)c;
81     }
82 
addTo(int[] x, int xOff, int[] z, int zOff, int cIn)83     public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
84     {
85         long c = cIn & M;
86         c += (x[xOff + 0] & M) + (z[zOff + 0] & M);
87         z[zOff + 0] = (int)c;
88         c >>>= 32;
89         c += (x[xOff + 1] & M) + (z[zOff + 1] & M);
90         z[zOff + 1] = (int)c;
91         c >>>= 32;
92         c += (x[xOff + 2] & M) + (z[zOff + 2] & M);
93         z[zOff + 2] = (int)c;
94         c >>>= 32;
95         c += (x[xOff + 3] & M) + (z[zOff + 3] & M);
96         z[zOff + 3] = (int)c;
97         c >>>= 32;
98         c += (x[xOff + 4] & M) + (z[zOff + 4] & M);
99         z[zOff + 4] = (int)c;
100         c >>>= 32;
101         c += (x[xOff + 5] & M) + (z[zOff + 5] & M);
102         z[zOff + 5] = (int)c;
103         c >>>= 32;
104         return (int)c;
105     }
106 
addToEachOther(int[] u, int uOff, int[] v, int vOff)107     public static int addToEachOther(int[] u, int uOff, int[] v, int vOff)
108     {
109         long c = 0;
110         c += (u[uOff + 0] & M) + (v[vOff + 0] & M);
111         u[uOff + 0] = (int)c;
112         v[vOff + 0] = (int)c;
113         c >>>= 32;
114         c += (u[uOff + 1] & M) + (v[vOff + 1] & M);
115         u[uOff + 1] = (int)c;
116         v[vOff + 1] = (int)c;
117         c >>>= 32;
118         c += (u[uOff + 2] & M) + (v[vOff + 2] & M);
119         u[uOff + 2] = (int)c;
120         v[vOff + 2] = (int)c;
121         c >>>= 32;
122         c += (u[uOff + 3] & M) + (v[vOff + 3] & M);
123         u[uOff + 3] = (int)c;
124         v[vOff + 3] = (int)c;
125         c >>>= 32;
126         c += (u[uOff + 4] & M) + (v[vOff + 4] & M);
127         u[uOff + 4] = (int)c;
128         v[vOff + 4] = (int)c;
129         c >>>= 32;
130         c += (u[uOff + 5] & M) + (v[vOff + 5] & M);
131         u[uOff + 5] = (int)c;
132         v[vOff + 5] = (int)c;
133         c >>>= 32;
134         return (int)c;
135     }
136 
copy(int[] x, int[] z)137     public static void copy(int[] x, int[] z)
138     {
139         z[0] = x[0];
140         z[1] = x[1];
141         z[2] = x[2];
142         z[3] = x[3];
143         z[4] = x[4];
144         z[5] = x[5];
145     }
146 
copy64(long[] x, long[] z)147     public static void copy64(long[] x, long[] z)
148     {
149         z[0] = x[0];
150         z[1] = x[1];
151         z[2] = x[2];
152     }
153 
create()154     public static int[] create()
155     {
156         return new int[6];
157     }
158 
create64()159     public static long[] create64()
160     {
161         return new long[3];
162     }
163 
createExt()164     public static int[] createExt()
165     {
166         return new int[12];
167     }
168 
createExt64()169     public static long[] createExt64()
170     {
171         return new long[6];
172     }
173 
diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)174     public static boolean diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
175     {
176         boolean pos = gte(x, xOff, y, yOff);
177         if (pos)
178         {
179             sub(x, xOff, y, yOff, z, zOff);
180         }
181         else
182         {
183             sub(y, yOff, x, xOff, z, zOff);
184         }
185         return pos;
186     }
187 
eq(int[] x, int[] y)188     public static boolean eq(int[] x, int[] y)
189     {
190         for (int i = 5; i >= 0; --i)
191         {
192             if (x[i] != y[i])
193             {
194                 return false;
195             }
196         }
197         return true;
198     }
199 
eq64(long[] x, long[] y)200     public static boolean eq64(long[] x, long[] y)
201     {
202         for (int i = 2; i >= 0; --i)
203         {
204             if (x[i] != y[i])
205             {
206                 return false;
207             }
208         }
209         return true;
210     }
211 
fromBigInteger(BigInteger x)212     public static int[] fromBigInteger(BigInteger x)
213     {
214         if (x.signum() < 0 || x.bitLength() > 192)
215         {
216             throw new IllegalArgumentException();
217         }
218 
219         int[] z = create();
220         int i = 0;
221         while (x.signum() != 0)
222         {
223             z[i++] = x.intValue();
224             x = x.shiftRight(32);
225         }
226         return z;
227     }
228 
fromBigInteger64(BigInteger x)229     public static long[] fromBigInteger64(BigInteger x)
230     {
231         if (x.signum() < 0 || x.bitLength() > 192)
232         {
233             throw new IllegalArgumentException();
234         }
235 
236         long[] z = create64();
237         int i = 0;
238         while (x.signum() != 0)
239         {
240             z[i++] = x.longValue();
241             x = x.shiftRight(64);
242         }
243         return z;
244     }
245 
getBit(int[] x, int bit)246     public static int getBit(int[] x, int bit)
247     {
248         if (bit == 0)
249         {
250             return x[0] & 1;
251         }
252         int w = bit >> 5;
253         if (w < 0 || w >= 6)
254         {
255             return 0;
256         }
257         int b = bit & 31;
258         return (x[w] >>> b) & 1;
259     }
260 
gte(int[] x, int[] y)261     public static boolean gte(int[] x, int[] y)
262     {
263         for (int i = 5; i >= 0; --i)
264         {
265             int x_i = x[i] ^ Integer.MIN_VALUE;
266             int y_i = y[i] ^ Integer.MIN_VALUE;
267             if (x_i < y_i)
268                 return false;
269             if (x_i > y_i)
270                 return true;
271         }
272         return true;
273     }
274 
gte(int[] x, int xOff, int[] y, int yOff)275     public static boolean gte(int[] x, int xOff, int[] y, int yOff)
276     {
277         for (int i = 5; i >= 0; --i)
278         {
279             int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
280             int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
281             if (x_i < y_i)
282                 return false;
283             if (x_i > y_i)
284                 return true;
285         }
286         return true;
287     }
288 
isOne(int[] x)289     public static boolean isOne(int[] x)
290     {
291         if (x[0] != 1)
292         {
293             return false;
294         }
295         for (int i = 1; i < 6; ++i)
296         {
297             if (x[i] != 0)
298             {
299                 return false;
300             }
301         }
302         return true;
303     }
304 
isOne64(long[] x)305     public static boolean isOne64(long[] x)
306     {
307         if (x[0] != 1L)
308         {
309             return false;
310         }
311         for (int i = 1; i < 3; ++i)
312         {
313             if (x[i] != 0L)
314             {
315                 return false;
316             }
317         }
318         return true;
319     }
320 
isZero(int[] x)321     public static boolean isZero(int[] x)
322     {
323         for (int i = 0; i < 6; ++i)
324         {
325             if (x[i] != 0)
326             {
327                 return false;
328             }
329         }
330         return true;
331     }
332 
isZero64(long[] x)333     public static boolean isZero64(long[] x)
334     {
335         for (int i = 0; i < 3; ++i)
336         {
337             if (x[i] != 0L)
338             {
339                 return false;
340             }
341         }
342         return true;
343     }
344 
mul(int[] x, int[] y, int[] zz)345     public static void mul(int[] x, int[] y, int[] zz)
346     {
347         long y_0 = y[0] & M;
348         long y_1 = y[1] & M;
349         long y_2 = y[2] & M;
350         long y_3 = y[3] & M;
351         long y_4 = y[4] & M;
352         long y_5 = y[5] & M;
353 
354         {
355             long c = 0, x_0 = x[0] & M;
356             c += x_0 * y_0;
357             zz[0] = (int)c;
358             c >>>= 32;
359             c += x_0 * y_1;
360             zz[1] = (int)c;
361             c >>>= 32;
362             c += x_0 * y_2;
363             zz[2] = (int)c;
364             c >>>= 32;
365             c += x_0 * y_3;
366             zz[3] = (int)c;
367             c >>>= 32;
368             c += x_0 * y_4;
369             zz[4] = (int)c;
370             c >>>= 32;
371             c += x_0 * y_5;
372             zz[5] = (int)c;
373             c >>>= 32;
374             zz[6] = (int)c;
375         }
376 
377         for (int i = 1; i < 6; ++i)
378         {
379             long c = 0, x_i = x[i] & M;
380             c += x_i * y_0 + (zz[i + 0] & M);
381             zz[i + 0] = (int)c;
382             c >>>= 32;
383             c += x_i * y_1 + (zz[i + 1] & M);
384             zz[i + 1] = (int)c;
385             c >>>= 32;
386             c += x_i * y_2 + (zz[i + 2] & M);
387             zz[i + 2] = (int)c;
388             c >>>= 32;
389             c += x_i * y_3 + (zz[i + 3] & M);
390             zz[i + 3] = (int)c;
391             c >>>= 32;
392             c += x_i * y_4 + (zz[i + 4] & M);
393             zz[i + 4] = (int)c;
394             c >>>= 32;
395             c += x_i * y_5 + (zz[i + 5] & M);
396             zz[i + 5] = (int)c;
397             c >>>= 32;
398             zz[i + 6] = (int)c;
399         }
400     }
401 
mul(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)402     public static void mul(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
403     {
404         long y_0 = y[yOff + 0] & M;
405         long y_1 = y[yOff + 1] & M;
406         long y_2 = y[yOff + 2] & M;
407         long y_3 = y[yOff + 3] & M;
408         long y_4 = y[yOff + 4] & M;
409         long y_5 = y[yOff + 5] & M;
410 
411         {
412             long c = 0, x_0 = x[xOff + 0] & M;
413             c += x_0 * y_0;
414             zz[zzOff + 0] = (int)c;
415             c >>>= 32;
416             c += x_0 * y_1;
417             zz[zzOff + 1] = (int)c;
418             c >>>= 32;
419             c += x_0 * y_2;
420             zz[zzOff + 2] = (int)c;
421             c >>>= 32;
422             c += x_0 * y_3;
423             zz[zzOff + 3] = (int)c;
424             c >>>= 32;
425             c += x_0 * y_4;
426             zz[zzOff + 4] = (int)c;
427             c >>>= 32;
428             c += x_0 * y_5;
429             zz[zzOff + 5] = (int)c;
430             c >>>= 32;
431             zz[zzOff + 6] = (int)c;
432         }
433 
434         for (int i = 1; i < 6; ++i)
435         {
436             ++zzOff;
437             long c = 0, x_i = x[xOff + i] & M;
438             c += x_i * y_0 + (zz[zzOff + 0] & M);
439             zz[zzOff + 0] = (int)c;
440             c >>>= 32;
441             c += x_i * y_1 + (zz[zzOff + 1] & M);
442             zz[zzOff + 1] = (int)c;
443             c >>>= 32;
444             c += x_i * y_2 + (zz[zzOff + 2] & M);
445             zz[zzOff + 2] = (int)c;
446             c >>>= 32;
447             c += x_i * y_3 + (zz[zzOff + 3] & M);
448             zz[zzOff + 3] = (int)c;
449             c >>>= 32;
450             c += x_i * y_4 + (zz[zzOff + 4] & M);
451             zz[zzOff + 4] = (int)c;
452             c >>>= 32;
453             c += x_i * y_5 + (zz[zzOff + 5] & M);
454             zz[zzOff + 5] = (int)c;
455             c >>>= 32;
456             zz[zzOff + 6] = (int)c;
457         }
458     }
459 
mulAddTo(int[] x, int[] y, int[] zz)460     public static int mulAddTo(int[] x, int[] y, int[] zz)
461     {
462         long y_0 = y[0] & M;
463         long y_1 = y[1] & M;
464         long y_2 = y[2] & M;
465         long y_3 = y[3] & M;
466         long y_4 = y[4] & M;
467         long y_5 = y[5] & M;
468 
469         long zc = 0;
470         for (int i = 0; i < 6; ++i)
471         {
472             long c = 0, x_i = x[i] & M;
473             c += x_i * y_0 + (zz[i + 0] & M);
474             zz[i + 0] = (int)c;
475             c >>>= 32;
476             c += x_i * y_1 + (zz[i + 1] & M);
477             zz[i + 1] = (int)c;
478             c >>>= 32;
479             c += x_i * y_2 + (zz[i + 2] & M);
480             zz[i + 2] = (int)c;
481             c >>>= 32;
482             c += x_i * y_3 + (zz[i + 3] & M);
483             zz[i + 3] = (int)c;
484             c >>>= 32;
485             c += x_i * y_4 + (zz[i + 4] & M);
486             zz[i + 4] = (int)c;
487             c >>>= 32;
488             c += x_i * y_5 + (zz[i + 5] & M);
489             zz[i + 5] = (int)c;
490             c >>>= 32;
491             c += zc + (zz[i + 6] & M);
492             zz[i + 6] = (int)c;
493             zc = c >>> 32;
494         }
495         return (int)zc;
496     }
497 
mulAddTo(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)498     public static int mulAddTo(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
499     {
500         long y_0 = y[yOff + 0] & M;
501         long y_1 = y[yOff + 1] & M;
502         long y_2 = y[yOff + 2] & M;
503         long y_3 = y[yOff + 3] & M;
504         long y_4 = y[yOff + 4] & M;
505         long y_5 = y[yOff + 5] & M;
506 
507         long zc = 0;
508         for (int i = 0; i < 6; ++i)
509         {
510             long c = 0, x_i = x[xOff + i] & M;
511             c += x_i * y_0 + (zz[zzOff + 0] & M);
512             zz[zzOff + 0] = (int)c;
513             c >>>= 32;
514             c += x_i * y_1 + (zz[zzOff + 1] & M);
515             zz[zzOff + 1] = (int)c;
516             c >>>= 32;
517             c += x_i * y_2 + (zz[zzOff + 2] & M);
518             zz[zzOff + 2] = (int)c;
519             c >>>= 32;
520             c += x_i * y_3 + (zz[zzOff + 3] & M);
521             zz[zzOff + 3] = (int)c;
522             c >>>= 32;
523             c += x_i * y_4 + (zz[zzOff + 4] & M);
524             zz[zzOff + 4] = (int)c;
525             c >>>= 32;
526             c += x_i * y_5 + (zz[zzOff + 5] & M);
527             zz[zzOff + 5] = (int)c;
528             c >>>= 32;
529             c += zc + (zz[zzOff + 6] & M);
530             zz[zzOff + 6] = (int)c;
531             zc = c >>> 32;
532             ++zzOff;
533         }
534         return (int)zc;
535     }
536 
mul33Add(int w, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)537     public static long mul33Add(int w, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
538     {
539         // assert w >>> 31 == 0;
540 
541         long c = 0, wVal = w & M;
542         long x0 = x[xOff + 0] & M;
543         c += wVal * x0 + (y[yOff + 0] & M);
544         z[zOff + 0] = (int)c;
545         c >>>= 32;
546         long x1 = x[xOff + 1] & M;
547         c += wVal * x1 + x0 + (y[yOff + 1] & M);
548         z[zOff + 1] = (int)c;
549         c >>>= 32;
550         long x2 = x[xOff + 2] & M;
551         c += wVal * x2 + x1 + (y[yOff + 2] & M);
552         z[zOff + 2] = (int)c;
553         c >>>= 32;
554         long x3 = x[xOff + 3] & M;
555         c += wVal * x3 + x2 + (y[yOff + 3] & M);
556         z[zOff + 3] = (int)c;
557         c >>>= 32;
558         long x4 = x[xOff + 4] & M;
559         c += wVal * x4 + x3 + (y[yOff + 4] & M);
560         z[zOff + 4] = (int)c;
561         c >>>= 32;
562         long x5 = x[xOff + 5] & M;
563         c += wVal * x5 + x4 + (y[yOff + 5] & M);
564         z[zOff + 5] = (int)c;
565         c >>>= 32;
566         c += x5;
567         return c;
568     }
569 
mulWordAddExt(int x, int[] yy, int yyOff, int[] zz, int zzOff)570     public static int mulWordAddExt(int x, int[] yy, int yyOff, int[] zz, int zzOff)
571     {
572         // assert yyOff <= 6;
573         // assert zzOff <= 6;
574         long c = 0, xVal = x & M;
575         c += xVal * (yy[yyOff + 0] & M) + (zz[zzOff + 0] & M);
576         zz[zzOff + 0] = (int)c;
577         c >>>= 32;
578         c += xVal * (yy[yyOff + 1] & M) + (zz[zzOff + 1] & M);
579         zz[zzOff + 1] = (int)c;
580         c >>>= 32;
581         c += xVal * (yy[yyOff + 2] & M) + (zz[zzOff + 2] & M);
582         zz[zzOff + 2] = (int)c;
583         c >>>= 32;
584         c += xVal * (yy[yyOff + 3] & M) + (zz[zzOff + 3] & M);
585         zz[zzOff + 3] = (int)c;
586         c >>>= 32;
587         c += xVal * (yy[yyOff + 4] & M) + (zz[zzOff + 4] & M);
588         zz[zzOff + 4] = (int)c;
589         c >>>= 32;
590         c += xVal * (yy[yyOff + 5] & M) + (zz[zzOff + 5] & M);
591         zz[zzOff + 5] = (int)c;
592         c >>>= 32;
593         return (int)c;
594     }
595 
mul33DWordAdd(int x, long y, int[] z, int zOff)596     public static int mul33DWordAdd(int x, long y, int[] z, int zOff)
597     {
598         // assert x >>> 31 == 0;
599         // assert zOff <= 2;
600 
601         long c = 0, xVal = x & M;
602         long y00 = y & M;
603         c += xVal * y00 + (z[zOff + 0] & M);
604         z[zOff + 0] = (int)c;
605         c >>>= 32;
606         long y01 = y >>> 32;
607         c += xVal * y01 + y00 + (z[zOff + 1] & M);
608         z[zOff + 1] = (int)c;
609         c >>>= 32;
610         c += y01 + (z[zOff + 2] & M);
611         z[zOff + 2] = (int)c;
612         c >>>= 32;
613         c += (z[zOff + 3] & M);
614         z[zOff + 3] = (int)c;
615         c >>>= 32;
616         return c == 0 ? 0 : Nat.incAt(6, z, zOff, 4);
617     }
618 
mul33WordAdd(int x, int y, int[] z, int zOff)619     public static int mul33WordAdd(int x, int y, int[] z, int zOff)
620     {
621         // assert x >>> 31 == 0;
622         // assert zOff <= 3;
623 
624         long c = 0, xVal = x & M, yVal = y & M;
625         c += yVal * xVal + (z[zOff + 0] & M);
626         z[zOff + 0] = (int)c;
627         c >>>= 32;
628         c += yVal + (z[zOff + 1] & M);
629         z[zOff + 1] = (int)c;
630         c >>>= 32;
631         c += (z[zOff + 2] & M);
632         z[zOff + 2] = (int)c;
633         c >>>= 32;
634         return c == 0 ? 0 : Nat.incAt(6, z, zOff, 3);
635     }
636 
mulWordDwordAdd(int x, long y, int[] z, int zOff)637     public static int mulWordDwordAdd(int x, long y, int[] z, int zOff)
638     {
639         // assert zOff <= 3;
640         long c = 0, xVal = x & M;
641         c += xVal * (y & M) + (z[zOff + 0] & M);
642         z[zOff + 0] = (int)c;
643         c >>>= 32;
644         c += xVal * (y >>> 32) + (z[zOff + 1] & M);
645         z[zOff + 1] = (int)c;
646         c >>>= 32;
647         c += (z[zOff + 2] & M);
648         z[zOff + 2] = (int)c;
649         c >>>= 32;
650         return c == 0 ? 0 : Nat.incAt(6, z, zOff, 3);
651     }
652 
mulWord(int x, int[] y, int[] z, int zOff)653     public static int mulWord(int x, int[] y, int[] z, int zOff)
654     {
655         long c = 0, xVal = x & M;
656         int i = 0;
657         do
658         {
659             c += xVal * (y[i] & M);
660             z[zOff + i] = (int)c;
661             c >>>= 32;
662         }
663         while (++i < 6);
664         return (int)c;
665     }
666 
square(int[] x, int[] zz)667     public static void square(int[] x, int[] zz)
668     {
669         long x_0 = x[0] & M;
670         long zz_1;
671 
672         int c = 0, w;
673         {
674             int i = 5, j = 12;
675             do
676             {
677                 long xVal = (x[i--] & M);
678                 long p = xVal * xVal;
679                 zz[--j] = (c << 31) | (int)(p >>> 33);
680                 zz[--j] = (int)(p >>> 1);
681                 c = (int)p;
682             }
683             while (i > 0);
684 
685             {
686                 long p = x_0 * x_0;
687                 zz_1 = ((c << 31) & M) | (p >>> 33);
688                 zz[0] = (int)p;
689                 c = (int)(p >>> 32) & 1;
690             }
691         }
692 
693         long x_1 = x[1] & M;
694         long zz_2 = zz[2] & M;
695 
696         {
697             zz_1 += x_1 * x_0;
698             w = (int)zz_1;
699             zz[1] = (w << 1) | c;
700             c = w >>> 31;
701             zz_2 += zz_1 >>> 32;
702         }
703 
704         long x_2 = x[2] & M;
705         long zz_3 = zz[3] & M;
706         long zz_4 = zz[4] & M;
707         {
708             zz_2 += x_2 * x_0;
709             w = (int)zz_2;
710             zz[2] = (w << 1) | c;
711             c = w >>> 31;
712             zz_3 += (zz_2 >>> 32) + x_2 * x_1;
713             zz_4 += zz_3 >>> 32;
714             zz_3 &= M;
715         }
716 
717         long x_3 = x[3] & M;
718         long zz_5 = (zz[5] & M) + (zz_4 >>> 32); zz_4 &= M;
719         long zz_6 = (zz[6] & M) + (zz_5 >>> 32); zz_5 &= M;
720         {
721             zz_3 += x_3 * x_0;
722             w = (int)zz_3;
723             zz[3] = (w << 1) | c;
724             c = w >>> 31;
725             zz_4 += (zz_3 >>> 32) + x_3 * x_1;
726             zz_5 += (zz_4 >>> 32) + x_3 * x_2;
727             zz_4 &= M;
728             zz_6 += zz_5 >>> 32;
729             zz_5 &= M;
730         }
731 
732         long x_4 = x[4] & M;
733         long zz_7 = (zz[7] & M) + (zz_6 >>> 32); zz_6 &= M;
734         long zz_8 = (zz[8] & M) + (zz_7 >>> 32); zz_7 &= M;
735         {
736             zz_4 += x_4 * x_0;
737             w = (int)zz_4;
738             zz[4] = (w << 1) | c;
739             c = w >>> 31;
740             zz_5 += (zz_4 >>> 32) + x_4 * x_1;
741             zz_6 += (zz_5 >>> 32) + x_4 * x_2;
742             zz_5 &= M;
743             zz_7 += (zz_6 >>> 32) + x_4 * x_3;
744             zz_6 &= M;
745             zz_8 += zz_7 >>> 32;
746             zz_7 &= M;
747         }
748 
749         long x_5 = x[5] & M;
750         long zz_9 = (zz[9] & M) + (zz_8 >>> 32); zz_8 &= M;
751         long zz_10 = (zz[10] & M) + (zz_9 >>> 32); zz_9 &= M;
752         {
753             zz_5 += x_5 * x_0;
754             w = (int)zz_5;
755             zz[5] = (w << 1) | c;
756             c = w >>> 31;
757             zz_6 += (zz_5 >>> 32) + x_5 * x_1;
758             zz_7 += (zz_6 >>> 32) + x_5 * x_2;
759             zz_8 += (zz_7 >>> 32) + x_5 * x_3;
760             zz_9 += (zz_8 >>> 32) + x_5 * x_4;
761             zz_10 += zz_9 >>> 32;
762         }
763 
764         w = (int)zz_6;
765         zz[6] = (w << 1) | c;
766         c = w >>> 31;
767         w = (int)zz_7;
768         zz[7] = (w << 1) | c;
769         c = w >>> 31;
770         w = (int)zz_8;
771         zz[8] = (w << 1) | c;
772         c = w >>> 31;
773         w = (int)zz_9;
774         zz[9] = (w << 1) | c;
775         c = w >>> 31;
776         w = (int)zz_10;
777         zz[10] = (w << 1) | c;
778         c = w >>> 31;
779         w = zz[11] + (int)(zz_10 >>> 32);
780         zz[11] = (w << 1) | c;
781     }
782 
square(int[] x, int xOff, int[] zz, int zzOff)783     public static void square(int[] x, int xOff, int[] zz, int zzOff)
784     {
785         long x_0 = x[xOff + 0] & M;
786         long zz_1;
787 
788         int c = 0, w;
789         {
790             int i = 5, j = 12;
791             do
792             {
793                 long xVal = (x[xOff + i--] & M);
794                 long p = xVal * xVal;
795                 zz[zzOff + --j] = (c << 31) | (int)(p >>> 33);
796                 zz[zzOff + --j] = (int)(p >>> 1);
797                 c = (int)p;
798             }
799             while (i > 0);
800 
801             {
802                 long p = x_0 * x_0;
803                 zz_1 = ((c << 31) & M) | (p >>> 33);
804                 zz[zzOff + 0] = (int)p;
805                 c = (int)(p >>> 32) & 1;
806             }
807         }
808 
809         long x_1 = x[xOff + 1] & M;
810         long zz_2 = zz[zzOff + 2] & M;
811 
812         {
813             zz_1 += x_1 * x_0;
814             w = (int)zz_1;
815             zz[zzOff + 1] = (w << 1) | c;
816             c = w >>> 31;
817             zz_2 += zz_1 >>> 32;
818         }
819 
820         long x_2 = x[xOff + 2] & M;
821         long zz_3 = zz[zzOff + 3] & M;
822         long zz_4 = zz[zzOff + 4] & M;
823         {
824             zz_2 += x_2 * x_0;
825             w = (int)zz_2;
826             zz[zzOff + 2] = (w << 1) | c;
827             c = w >>> 31;
828             zz_3 += (zz_2 >>> 32) + x_2 * x_1;
829             zz_4 += zz_3 >>> 32;
830             zz_3 &= M;
831         }
832 
833         long x_3 = x[xOff + 3] & M;
834         long zz_5 = (zz[zzOff + 5] & M) + (zz_4 >>> 32); zz_4 &= M;
835         long zz_6 = (zz[zzOff + 6] & M) + (zz_5 >>> 32); zz_5 &= M;
836         {
837             zz_3 += x_3 * x_0;
838             w = (int)zz_3;
839             zz[zzOff + 3] = (w << 1) | c;
840             c = w >>> 31;
841             zz_4 += (zz_3 >>> 32) + x_3 * x_1;
842             zz_5 += (zz_4 >>> 32) + x_3 * x_2;
843             zz_4 &= M;
844             zz_6 += zz_5 >>> 32;
845             zz_5 &= M;
846         }
847 
848         long x_4 = x[xOff + 4] & M;
849         long zz_7 = (zz[zzOff + 7] & M) + (zz_6 >>> 32); zz_6 &= M;
850         long zz_8 = (zz[zzOff + 8] & M) + (zz_7 >>> 32); zz_7 &= M;
851         {
852             zz_4 += x_4 * x_0;
853             w = (int)zz_4;
854             zz[zzOff + 4] = (w << 1) | c;
855             c = w >>> 31;
856             zz_5 += (zz_4 >>> 32) + x_4 * x_1;
857             zz_6 += (zz_5 >>> 32) + x_4 * x_2;
858             zz_5 &= M;
859             zz_7 += (zz_6 >>> 32) + x_4 * x_3;
860             zz_6 &= M;
861             zz_8 += zz_7 >>> 32;
862             zz_7 &= M;
863         }
864 
865         long x_5 = x[xOff + 5] & M;
866         long zz_9 = (zz[zzOff + 9] & M) + (zz_8 >>> 32); zz_8 &= M;
867         long zz_10 = (zz[zzOff + 10] & M) + (zz_9 >>> 32); zz_9 &= M;
868         {
869             zz_5 += x_5 * x_0;
870             w = (int)zz_5;
871             zz[zzOff + 5] = (w << 1) | c;
872             c = w >>> 31;
873             zz_6 += (zz_5 >>> 32) + x_5 * x_1;
874             zz_7 += (zz_6 >>> 32) + x_5 * x_2;
875             zz_8 += (zz_7 >>> 32) + x_5 * x_3;
876             zz_9 += (zz_8 >>> 32) + x_5 * x_4;
877             zz_10 += zz_9 >>> 32;
878         }
879 
880         w = (int)zz_6;
881         zz[zzOff + 6] = (w << 1) | c;
882         c = w >>> 31;
883         w = (int)zz_7;
884         zz[zzOff + 7] = (w << 1) | c;
885         c = w >>> 31;
886         w = (int)zz_8;
887         zz[zzOff + 8] = (w << 1) | c;
888         c = w >>> 31;
889         w = (int)zz_9;
890         zz[zzOff + 9] = (w << 1) | c;
891         c = w >>> 31;
892         w = (int)zz_10;
893         zz[zzOff + 10] = (w << 1) | c;
894         c = w >>> 31;
895         w = zz[zzOff + 11] + (int)(zz_10 >>> 32);
896         zz[zzOff + 11] = (w << 1) | c;
897     }
898 
sub(int[] x, int[] y, int[] z)899     public static int sub(int[] x, int[] y, int[] z)
900     {
901         long c = 0;
902         c += (x[0] & M) - (y[0] & M);
903         z[0] = (int)c;
904         c >>= 32;
905         c += (x[1] & M) - (y[1] & M);
906         z[1] = (int)c;
907         c >>= 32;
908         c += (x[2] & M) - (y[2] & M);
909         z[2] = (int)c;
910         c >>= 32;
911         c += (x[3] & M) - (y[3] & M);
912         z[3] = (int)c;
913         c >>= 32;
914         c += (x[4] & M) - (y[4] & M);
915         z[4] = (int)c;
916         c >>= 32;
917         c += (x[5] & M) - (y[5] & M);
918         z[5] = (int)c;
919         c >>= 32;
920         return (int)c;
921     }
922 
sub(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)923     public static int sub(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
924     {
925         long c = 0;
926         c += (x[xOff + 0] & M) - (y[yOff + 0] & M);
927         z[zOff + 0] = (int)c;
928         c >>= 32;
929         c += (x[xOff + 1] & M) - (y[yOff + 1] & M);
930         z[zOff + 1] = (int)c;
931         c >>= 32;
932         c += (x[xOff + 2] & M) - (y[yOff + 2] & M);
933         z[zOff + 2] = (int)c;
934         c >>= 32;
935         c += (x[xOff + 3] & M) - (y[yOff + 3] & M);
936         z[zOff + 3] = (int)c;
937         c >>= 32;
938         c += (x[xOff + 4] & M) - (y[yOff + 4] & M);
939         z[zOff + 4] = (int)c;
940         c >>= 32;
941         c += (x[xOff + 5] & M) - (y[yOff + 5] & M);
942         z[zOff + 5] = (int)c;
943         c >>= 32;
944         return (int)c;
945     }
946 
subBothFrom(int[] x, int[] y, int[] z)947     public static int subBothFrom(int[] x, int[] y, int[] z)
948     {
949         long c = 0;
950         c += (z[0] & M) - (x[0] & M) - (y[0] & M);
951         z[0] = (int)c;
952         c >>= 32;
953         c += (z[1] & M) - (x[1] & M) - (y[1] & M);
954         z[1] = (int)c;
955         c >>= 32;
956         c += (z[2] & M) - (x[2] & M) - (y[2] & M);
957         z[2] = (int)c;
958         c >>= 32;
959         c += (z[3] & M) - (x[3] & M) - (y[3] & M);
960         z[3] = (int)c;
961         c >>= 32;
962         c += (z[4] & M) - (x[4] & M) - (y[4] & M);
963         z[4] = (int)c;
964         c >>= 32;
965         c += (z[5] & M) - (x[5] & M) - (y[5] & M);
966         z[5] = (int)c;
967         c >>= 32;
968         return (int)c;
969     }
970 
subFrom(int[] x, int[] z)971     public static int subFrom(int[] x, int[] z)
972     {
973         long c = 0;
974         c += (z[0] & M) - (x[0] & M);
975         z[0] = (int)c;
976         c >>= 32;
977         c += (z[1] & M) - (x[1] & M);
978         z[1] = (int)c;
979         c >>= 32;
980         c += (z[2] & M) - (x[2] & M);
981         z[2] = (int)c;
982         c >>= 32;
983         c += (z[3] & M) - (x[3] & M);
984         z[3] = (int)c;
985         c >>= 32;
986         c += (z[4] & M) - (x[4] & M);
987         z[4] = (int)c;
988         c >>= 32;
989         c += (z[5] & M) - (x[5] & M);
990         z[5] = (int)c;
991         c >>= 32;
992         return (int)c;
993     }
994 
subFrom(int[] x, int xOff, int[] z, int zOff)995     public static int subFrom(int[] x, int xOff, int[] z, int zOff)
996     {
997         long c = 0;
998         c += (z[zOff + 0] & M) - (x[xOff + 0] & M);
999         z[zOff + 0] = (int)c;
1000         c >>= 32;
1001         c += (z[zOff + 1] & M) - (x[xOff + 1] & M);
1002         z[zOff + 1] = (int)c;
1003         c >>= 32;
1004         c += (z[zOff + 2] & M) - (x[xOff + 2] & M);
1005         z[zOff + 2] = (int)c;
1006         c >>= 32;
1007         c += (z[zOff + 3] & M) - (x[xOff + 3] & M);
1008         z[zOff + 3] = (int)c;
1009         c >>= 32;
1010         c += (z[zOff + 4] & M) - (x[xOff + 4] & M);
1011         z[zOff + 4] = (int)c;
1012         c >>= 32;
1013         c += (z[zOff + 5] & M) - (x[xOff + 5] & M);
1014         z[zOff + 5] = (int)c;
1015         c >>= 32;
1016         return (int)c;
1017     }
1018 
toBigInteger(int[] x)1019     public static BigInteger toBigInteger(int[] x)
1020     {
1021         byte[] bs = new byte[24];
1022         for (int i = 0; i < 6; ++i)
1023         {
1024             int x_i = x[i];
1025             if (x_i != 0)
1026             {
1027                 Pack.intToBigEndian(x_i, bs, (5 - i) << 2);
1028             }
1029         }
1030         return new BigInteger(1, bs);
1031     }
1032 
toBigInteger64(long[] x)1033     public static BigInteger toBigInteger64(long[] x)
1034     {
1035         byte[] bs = new byte[24];
1036         for (int i = 0; i < 3; ++i)
1037         {
1038             long x_i = x[i];
1039             if (x_i != 0L)
1040             {
1041                 Pack.longToBigEndian(x_i, bs, (2 - i) << 3);
1042             }
1043         }
1044         return new BigInteger(1, bs);
1045     }
1046 
zero(int[] z)1047     public static void zero(int[] z)
1048     {
1049         z[0] = 0;
1050         z[1] = 0;
1051         z[2] = 0;
1052         z[3] = 0;
1053         z[4] = 0;
1054         z[5] = 0;
1055     }
1056 }
1057