1package org.bouncycastle.math.raw;
2
3import java.math.BigInteger;
4
5import org.bouncycastle.util.Pack;
6
7public abstract class Nat256
8{
9    private static final long M = 0xFFFFFFFFL;
10
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
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
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
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
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
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
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
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
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
249    public static int[] create()
250    {
251        return new int[8];
252    }
253
254    public static long[] create64()
255    {
256        return new long[4];
257    }
258
259    public static int[] createExt()
260    {
261        return new int[16];
262    }
263
264    public static long[] createExt64()
265    {
266        return new long[8];
267    }
268
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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