1d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootpackage org.bouncycastle.math.ec.custom.sec;
2d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
3d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootimport java.math.BigInteger;
4d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
5d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootimport org.bouncycastle.math.raw.Nat;
6d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootimport org.bouncycastle.math.raw.Nat192;
7d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
8d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootpublic class SecP192R1Field
9d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root{
10d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    private static final long M = 0xFFFFFFFFL;
11d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
12d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    // 2^192 - 2^64 - 1
13d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    static final int[] P = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
14d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001,
15d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
16d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFE,
17d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000002 };
18d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    private static final int P5 = 0xFFFFFFFF;
19d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    private static final int PExt11 = 0xFFFFFFFF;
20d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
21d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void add(int[] x, int[] y, int[] z)
22d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
23d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        int c = Nat192.add(x, y, z);
24d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
25d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
26d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            addPInvTo(z);
27d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
28d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
29d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
30d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void addExt(int[] xx, int[] yy, int[] zz)
31d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
32d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        int c = Nat.add(12, xx, yy, zz);
33d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (c != 0 || (zz[11] == PExt11 && Nat.gte(12, zz, PExt)))
34d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
35d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
36d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            {
37d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root                Nat.incAt(12, zz, PExtInv.length);
38d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            }
39d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
40d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
41d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
42d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void addOne(int[] x, int[] z)
43d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
44d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        int c = Nat.inc(6, x, z);
45d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
46d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
47d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            addPInvTo(z);
48d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
49d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
50d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
51d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static int[] fromBigInteger(BigInteger x)
52d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
53d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        int[] z = Nat192.fromBigInteger(x);
54d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (z[5] == P5 && Nat192.gte(z, P))
55d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
56d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            Nat192.subFrom(P, z);
57d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
58d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        return z;
59d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
60d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
61d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void half(int[] x, int[] z)
62d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
63d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if ((x[0] & 1) == 0)
64d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
65d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            Nat.shiftDownBit(6, x, 0, z);
66d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
67d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        else
68d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
69d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            int c = Nat192.add(x, P, z);
70d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            Nat.shiftDownBit(6, z, c);
71d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
72d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
73d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
74d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void multiply(int[] x, int[] y, int[] z)
75d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
76d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        int[] tt = Nat192.createExt();
77d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        Nat192.mul(x, y, tt);
78d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        reduce(tt, z);
79d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
80d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
81d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
82d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
83d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        int c = Nat192.mulAddTo(x, y, zz);
84d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (c != 0 || (zz[11] == PExt11 && Nat.gte(12, zz, PExt)))
85d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
86d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
87d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            {
88d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root                Nat.incAt(12, zz, PExtInv.length);
89d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            }
90d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
91d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
92d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
93d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void negate(int[] x, int[] z)
94d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
95d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (Nat192.isZero(x))
96d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
97d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            Nat192.zero(z);
98d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
99d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        else
100d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
101d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            Nat192.sub(P, x, z);
102d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
103d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
104d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
105d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void reduce(int[] xx, int[] z)
106d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
107d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        long xx06 = xx[6] & M, xx07 = xx[7] & M, xx08 = xx[8] & M;
108d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        long xx09 = xx[9] & M, xx10 = xx[10] & M, xx11 = xx[11] & M;
109d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
110d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        long t0 = xx06 + xx10;
111d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        long t1 = xx07 + xx11;
112d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
113d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        long cc = 0;
114d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc += (xx[0] & M) + t0;
115d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        int z0 = (int)cc;
116d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc >>= 32;
117d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc += (xx[1] & M) + t1;
118d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        z[1] = (int)cc;
119d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc >>= 32;
120d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
121d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        t0 += xx08;
122d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        t1 += xx09;
123d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
124d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc += (xx[2] & M) + t0;
125d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        long z2 = cc & M;
126d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc >>= 32;
127d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc += (xx[3] & M) + t1;
128d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        z[3] = (int)cc;
129d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc >>= 32;
130d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
131d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        t0 -= xx06;
132d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        t1 -= xx07;
133d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
134d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc += (xx[4] & M) + t0;
135d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        z[4] = (int)cc;
136d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc >>= 32;
137d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc += (xx[5] & M) + t1;
138d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        z[5] = (int)cc;
139d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc >>= 32;
140d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
141d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        z2 += cc;
142d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
143d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc += (z0 & M);
144d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        z[0] = (int)cc;
145d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc >>= 32;
146d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (cc != 0)
147d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
148d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            cc += (z[1] & M);
149d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            z[1] = (int)cc;
150d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            z2 += cc >> 32;
151d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
152d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        z[2] = (int)z2;
153d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        cc = z2 >> 32;
154d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
155d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root//      assert cc == 0 || cc == 1;
156d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
157d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if ((cc != 0 && Nat.incAt(6, z, 3) != 0)
158d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            || (z[5] == P5 && Nat192.gte(z, P)))
159d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
160d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            addPInvTo(z);
161d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
162d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
163d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
164d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void reduce32(int x, int[] z)
165d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
166d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        long cc = 0;
167d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
168d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (x != 0)
169d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
170d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            long xx06 = x & M;
171d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
172d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            cc += (z[0] & M) + xx06;
173d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            z[0] = (int)cc;
174d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            cc >>= 32;
175d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            if (cc != 0)
176d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            {
177d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root                cc += (z[1] & M);
178d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root                z[1] = (int)cc;
179d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root                cc >>= 32;
180d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            }
181d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            cc += (z[2] & M) + xx06;
182d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            z[2] = (int)cc;
183d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            cc >>= 32;
184d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
185d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root//            assert cc == 0 || cc == 1;
186d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
187d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
188d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if ((cc != 0 && Nat.incAt(6, z, 3) != 0)
189d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            || (z[5] == P5 && Nat192.gte(z, P)))
190d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
191d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            addPInvTo(z);
192d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
193d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
194d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
195d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void square(int[] x, int[] z)
196d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
197d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        int[] tt = Nat192.createExt();
198d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        Nat192.square(x, tt);
199d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        reduce(tt, z);
200d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
201d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
202d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void squareN(int[] x, int n, int[] z)
203d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
204d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root//        assert n > 0;
205d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
206d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        int[] tt = Nat192.createExt();
207d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        Nat192.square(x, tt);
208d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        reduce(tt, z);
209d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
210d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        while (--n > 0)
211d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
212d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            Nat192.square(z, tt);
213d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            reduce(tt, z);
214d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
215d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
216d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
217d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void subtract(int[] x, int[] y, int[] z)
218d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
219d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        int c = Nat192.sub(x, y, z);
220d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (c != 0)
221d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
222d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            subPInvFrom(z);
223d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
224d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
225d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
226d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void subtractExt(int[] xx, int[] yy, int[] zz)
227d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
228d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        int c = Nat.sub(12, xx, yy, zz);
229d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (c != 0)
230d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
231d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            if (Nat.subFrom(PExtInv.length, PExtInv, zz) != 0)
232d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            {
233d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root                Nat.decAt(12, zz, PExtInv.length);
234d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            }
235d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
236d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
237d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
238d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    public static void twice(int[] x, int[] z)
239d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
240d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        int c = Nat.shiftUpBit(6, x, 0, z);
241d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
242d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
243d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            addPInvTo(z);
244d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
245d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
246d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
247d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    private static void addPInvTo(int[] z)
248d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
249d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        long c = (z[0] & M) + 1;
250d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        z[0] = (int)c;
251d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        c >>= 32;
252d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (c != 0)
253d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
254d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            c += (z[1] & M);
255d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            z[1] = (int)c;
256d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            c >>= 32;
257d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
258d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        c += (z[2] & M) + 1;
259d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        z[2] = (int)c;
260d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        c >>= 32;
261d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (c != 0)
262d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
263d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            Nat.incAt(6, z, 3);
264d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
265d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
266d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root
267d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    private static void subPInvFrom(int[] z)
268d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    {
269d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        long c = (z[0] & M) - 1;
270d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        z[0] = (int)c;
271d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        c >>= 32;
272d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (c != 0)
273d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
274d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            c += (z[1] & M);
275d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            z[1] = (int)c;
276d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            c >>= 32;
277d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
278d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        c += (z[2] & M) - 1;
279d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        z[2] = (int)c;
280d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        c >>= 32;
281d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        if (c != 0)
282d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        {
283d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            Nat.decAt(6, z, 3);
284d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        }
285d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root    }
286d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root}
287