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