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