153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giropackage org.bouncycastle.math.ec.custom.sec; 253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giroimport java.math.BigInteger; 453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giroimport org.bouncycastle.math.raw.Nat; 653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giroimport org.bouncycastle.math.raw.Nat224; 753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giropublic class SecP224R1Field 953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro{ 1053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro private static final long M = 0xFFFFFFFFL; 1153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 1253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro // 2^224 - 2^96 + 1 1353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro static final int[] P = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; 1453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 1553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 0xFFFFFFFF, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; 1653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000000, 1753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 0x00000000, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001 }; 1853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro private static final int P6 = 0xFFFFFFFF; 1953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro private static final int PExt13 = 0xFFFFFFFF; 2053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 2153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void add(int[] x, int[] y, int[] z) 2253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 2353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro int c = Nat224.add(x, y, z); 2453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (c != 0 || (z[6] == P6 && Nat224.gte(z, P))) 2553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 2653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro addPInvTo(z); 2753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 2853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 2953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 3053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void addExt(int[] xx, int[] yy, int[] zz) 3153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 3253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro int c = Nat.add(14, xx, yy, zz); 3353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (c != 0 || (zz[13] == PExt13 && Nat.gte(14, zz, PExt))) 3453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 3553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0) 3653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 3753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat.incAt(14, zz, PExtInv.length); 3853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 3953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 4053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 4153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 4253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void addOne(int[] x, int[] z) 4353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 4453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro int c = Nat.inc(7, x, z); 4553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (c != 0 || (z[6] == P6 && Nat224.gte(z, P))) 4653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 4753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro addPInvTo(z); 4853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 4953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 5053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 5153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static int[] fromBigInteger(BigInteger x) 5253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 5353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro int[] z = Nat224.fromBigInteger(x); 5453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (z[6] == P6 && Nat224.gte(z, P)) 5553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 5653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat224.subFrom(P, z); 5753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 5853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro return z; 5953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 6053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 6153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void half(int[] x, int[] z) 6253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 6353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if ((x[0] & 1) == 0) 6453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 6553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat.shiftDownBit(7, x, 0, z); 6653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 6753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro else 6853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 6953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro int c = Nat224.add(x, P, z); 7053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat.shiftDownBit(7, z, c); 7153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 7253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 7353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 7453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void multiply(int[] x, int[] y, int[] z) 7553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 7653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro int[] tt = Nat224.createExt(); 7753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat224.mul(x, y, tt); 7853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro reduce(tt, z); 7953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 8053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 8153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void multiplyAddToExt(int[] x, int[] y, int[] zz) 8253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 8353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro int c = Nat224.mulAddTo(x, y, zz); 8453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (c != 0 || (zz[13] == PExt13 && Nat.gte(14, zz, PExt))) 8553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 8653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0) 8753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 8853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat.incAt(14, zz, PExtInv.length); 8953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 9053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 9153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 9253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 9353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void negate(int[] x, int[] z) 9453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 9553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (Nat224.isZero(x)) 9653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 9753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat224.zero(z); 9853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 9953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro else 10053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 10153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat224.sub(P, x, z); 10253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 10353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 10453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 10553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void reduce(int[] xx, int[] z) 10653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 10753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro long xx10 = xx[10] & M, xx11 = xx[11] & M, xx12 = xx[12] & M, xx13 = xx[13] & M; 10853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 10953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro final long n = 1; 11053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 11153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro long t0 = (xx[7] & M) + xx11 - n; 11253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro long t1 = (xx[8] & M) + xx12; 11353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro long t2 = (xx[9] & M) + xx13; 11453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 11553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro long cc = 0; 11653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += (xx[0] & M) - t0; 11753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro long z0 = cc & M; 11853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc >>= 32; 11953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += (xx[1] & M) - t1; 12053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[1] = (int)cc; 12153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc >>= 32; 12253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += (xx[2] & M) - t2; 12353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[2] = (int)cc; 12453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc >>= 32; 12553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += (xx[3] & M) + t0 - xx10; 12653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro long z3 = cc & M; 12753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc >>= 32; 12853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += (xx[4] & M) + t1 - xx11; 12953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[4] = (int)cc; 13053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc >>= 32; 13153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += (xx[5] & M) + t2 - xx12; 13253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[5] = (int)cc; 13353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc >>= 32; 13453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += (xx[6] & M) + xx10 - xx13; 13553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[6] = (int)cc; 13653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc >>= 32; 13753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += n; 13853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 13953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro// assert cc >= 0; 14053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 14153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z3 += cc; 14253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 14353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z0 -= cc; 14453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[0] = (int)z0; 14553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc = z0 >> 32; 14653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (cc != 0) 14753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 14853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += (z[1] & M); 14953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[1] = (int)cc; 15053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc >>= 32; 15153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += (z[2] & M); 15253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[2] = (int)cc; 15353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z3 += cc >> 32; 15453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 15553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[3] = (int)z3; 15653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc = z3 >> 32; 15753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 15853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro// assert cc == 0 || cc == 1; 15953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 16053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if ((cc != 0 && Nat.incAt(7, z, 4) != 0) 16153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro || (z[6] == P6 && Nat224.gte(z, P))) 16253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 16353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro addPInvTo(z); 16453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 16553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 16653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 16753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void reduce32(int x, int[] z) 16853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 16953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro long cc = 0; 17053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 17153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (x != 0) 17253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 17353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro long xx07 = x & M; 174bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 17553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += (z[0] & M) - xx07; 17653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[0] = (int)cc; 17753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc >>= 32; 17853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (cc != 0) 17953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 18053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += (z[1] & M); 18153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[1] = (int)cc; 18253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc >>= 32; 18353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += (z[2] & M); 18453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[2] = (int)cc; 18553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc >>= 32; 18653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 18753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc += (z[3] & M) + xx07; 18853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[3] = (int)cc; 18953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro cc >>= 32; 19053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 19153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro// assert cc == 0 || cc == 1; 19253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 19353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 19453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if ((cc != 0 && Nat.incAt(7, z, 4) != 0) 19553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro || (z[6] == P6 && Nat224.gte(z, P))) 19653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 19753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro addPInvTo(z); 19853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 19953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 20053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 20153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void square(int[] x, int[] z) 20253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 20353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro int[] tt = Nat224.createExt(); 20453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat224.square(x, tt); 20553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro reduce(tt, z); 20653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 20753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 20853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void squareN(int[] x, int n, int[] z) 20953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 21053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro// assert n > 0; 21153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 21253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro int[] tt = Nat224.createExt(); 21353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat224.square(x, tt); 21453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro reduce(tt, z); 21553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 21653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro while (--n > 0) 21753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 21853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat224.square(z, tt); 21953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro reduce(tt, z); 22053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 22153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 22253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 22353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void subtract(int[] x, int[] y, int[] z) 22453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 22553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro int c = Nat224.sub(x, y, z); 22653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (c != 0) 22753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 22853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro subPInvFrom(z); 22953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 23053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 23153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 23253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void subtractExt(int[] xx, int[] yy, int[] zz) 23353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 23453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro int c = Nat.sub(14, xx, yy, zz); 23553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (c != 0) 23653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 23753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (Nat.subFrom(PExtInv.length, PExtInv, zz) != 0) 23853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 23953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat.decAt(14, zz, PExtInv.length); 24053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 24153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 24253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 24353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 24453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public static void twice(int[] x, int[] z) 24553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 24653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro int c = Nat.shiftUpBit(7, x, 0, z); 24753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (c != 0 || (z[6] == P6 && Nat224.gte(z, P))) 24853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 24953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro addPInvTo(z); 25053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 25153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 25253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 25353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro private static void addPInvTo(int[] z) 25453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 25553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro long c = (z[0] & M) - 1; 25653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[0] = (int)c; 25753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c >>= 32; 25853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (c != 0) 25953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 26053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c += (z[1] & M); 26153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[1] = (int)c; 26253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c >>= 32; 26353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c += (z[2] & M); 26453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[2] = (int)c; 26553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c >>= 32; 26653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 26753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c += (z[3] & M) + 1; 26853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[3] = (int)c; 26953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c >>= 32; 27053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (c != 0) 27153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 27253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat.incAt(7, z, 4); 27353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 27453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 27553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 27653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro private static void subPInvFrom(int[] z) 27753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 27853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro long c = (z[0] & M) + 1; 27953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[0] = (int)c; 28053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c >>= 32; 28153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (c != 0) 28253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 28353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c += (z[1] & M); 28453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[1] = (int)c; 28553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c >>= 32; 28653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c += (z[2] & M); 28753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[2] = (int)c; 28853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c >>= 32; 28953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 29053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c += (z[3] & M) - 1; 29153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro z[3] = (int)c; 29253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro c >>= 32; 29353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (c != 0) 29453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 29553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Nat.decAt(7, z, 4); 29653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 29753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 29853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro} 299