1d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootpackage org.bouncycastle.math.ec.custom.sec; 2d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 3d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootimport java.math.BigInteger; 4d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 5d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootimport org.bouncycastle.math.ec.ECFieldElement; 6d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootimport org.bouncycastle.math.raw.Mod; 7d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootimport org.bouncycastle.math.raw.Nat; 8d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootimport org.bouncycastle.math.raw.Nat224; 9d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootimport org.bouncycastle.util.Arrays; 10d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 11d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootpublic class SecP224R1FieldElement extends ECFieldElement 12d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root{ 13d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public static final BigInteger Q = SecP224R1Curve.q; 14d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 15d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root protected int[] x; 16d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 17d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public SecP224R1FieldElement(BigInteger x) 18d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 19d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (x == null || x.signum() < 0 || x.compareTo(Q) >= 0) 20d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 21d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root throw new IllegalArgumentException("x value invalid for SecP224R1FieldElement"); 22d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 23d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 24d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root this.x = SecP224R1Field.fromBigInteger(x); 25d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 26d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 27d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public SecP224R1FieldElement() 28d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 29d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root this.x = Nat224.create(); 30d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 31d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 32d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root protected SecP224R1FieldElement(int[] x) 33d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 34d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root this.x = x; 35d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 36d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 37d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public boolean isZero() 38d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 39d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Nat224.isZero(x); 40d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 41d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 42d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public boolean isOne() 43d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 44d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Nat224.isOne(x); 45d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 46d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 47d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public boolean testBitZero() 48d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 49d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Nat224.getBit(x, 0) == 1; 50d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 51d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 52d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public BigInteger toBigInteger() 53d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 54d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Nat224.toBigInteger(x); 55d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 56d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 57d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public String getFieldName() 58d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 59d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return "SecP224R1Field"; 60d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 61d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 62d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public int getFieldSize() 63d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 64d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Q.bitLength(); 65d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 66d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 67d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement add(ECFieldElement b) 68d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 69d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat224.create(); 70d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.add(x, ((SecP224R1FieldElement)b).x, z); 71d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP224R1FieldElement(z); 72d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 73d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 74d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement addOne() 75d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 76d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat224.create(); 77d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.addOne(x, z); 78d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP224R1FieldElement(z); 79d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 80d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 81d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement subtract(ECFieldElement b) 82d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 83d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat224.create(); 84d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.subtract(x, ((SecP224R1FieldElement)b).x, z); 85d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP224R1FieldElement(z); 86d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 87d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 88d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement multiply(ECFieldElement b) 89d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 90d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat224.create(); 91d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.multiply(x, ((SecP224R1FieldElement)b).x, z); 92d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP224R1FieldElement(z); 93d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 94d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 95d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement divide(ECFieldElement b) 96d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 97d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root// return multiply(b.invert()); 98d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat224.create(); 99d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Mod.invert(SecP224R1Field.P, ((SecP224R1FieldElement)b).x, z); 100d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.multiply(z, x, z); 101d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP224R1FieldElement(z); 102d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 103d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 104d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement negate() 105d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 106d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat224.create(); 107d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.negate(x, z); 108d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP224R1FieldElement(z); 109d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 110d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 111d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement square() 112d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 113d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat224.create(); 114d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.square(x, z); 115d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP224R1FieldElement(z); 116d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 117d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 118d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement invert() 119d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 120d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root// return new SecP224R1FieldElement(toBigInteger().modInverse(Q)); 121d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat224.create(); 122d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Mod.invert(SecP224R1Field.P, x, z); 123d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP224R1FieldElement(z); 124d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 125d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 126d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root /** 127d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root * return a sqrt root - the routine verifies that the calculation returns the right value - if 128d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root * none exists it returns null. 129d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root */ 130d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement sqrt() 131d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 132d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] c = this.x; 133d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (Nat224.isZero(c) || Nat224.isOne(c)) 134d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 135d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return this; 136d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 137d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 138d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] nc = Nat224.create(); 139d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.negate(c, nc); 140d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 141d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] r = Mod.random(SecP224R1Field.P); 142d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] t = Nat224.create(); 143d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 144d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (!isSquare(c)) 145d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 146d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return null; 147d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 148d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 149d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root while (!trySqrt(nc, r, t)) 150d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 151d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.addOne(r, r); 152d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 153d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 154d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.square(t, r); 155d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 156d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Nat224.eq(c, r) ? new SecP224R1FieldElement(t) : null; 157d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 158d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 159d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public boolean equals(Object other) 160d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 161d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (other == this) 162d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 163d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return true; 164d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 165d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 166d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (!(other instanceof SecP224R1FieldElement)) 167d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 168d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return false; 169d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 170d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 171d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1FieldElement o = (SecP224R1FieldElement)other; 172d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Nat224.eq(x, o.x); 173d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 174d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 175d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public int hashCode() 176d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 177d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Q.hashCode() ^ Arrays.hashCode(x, 0, 7); 178d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 179d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 180d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root private static boolean isSquare(int[] x) 181d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 182d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] t1 = Nat224.create(); 183d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] t2 = Nat224.create(); 184d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Nat224.copy(x, t1); 185d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 186d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root for (int i = 0; i < 7; ++i) 187d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 188d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Nat224.copy(t1, t2); 189d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.squareN(t1, 1 << i, t1); 190d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.multiply(t1, t2, t1); 191d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 192d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 193d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.squareN(t1, 95, t1); 194d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Nat224.isOne(t1); 195d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 196d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 197d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root private static void RM(int[] nc, int[] d0, int[] e0, int[] d1, int[] e1, int[] f1, int[] t) 198d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 199d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.multiply(e1, e0, t); 200d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.multiply(t, nc, t); 201d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.multiply(d1, d0, f1); 202d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.add(f1, t, f1); 203d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.multiply(d1, e0, t); 204d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Nat224.copy(f1, d1); 205d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.multiply(e1, d0, e1); 206d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.add(e1, t, e1); 207d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.square(e1, f1); 208d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.multiply(f1, nc, f1); 209d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 210d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 211d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root private static void RP(int[] nc, int[] d1, int[] e1, int[] f1, int[] t) 212d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 213d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Nat224.copy(nc, f1); 214d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 215d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] d0 = Nat224.create(); 216d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] e0 = Nat224.create(); 217d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 218d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root for (int i = 0; i < 7; ++i) 219d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 220d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Nat224.copy(d1, d0); 221d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Nat224.copy(e1, e0); 222d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 223d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int j = 1 << i; 224d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root while (--j >= 0) 225d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 226d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root RS(d1, e1, f1, t); 227d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 228d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 229d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root RM(nc, d0, e0, d1, e1, f1, t); 230d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 231d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 232d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 233d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root private static void RS(int[] d, int[] e, int[] f, int[] t) 234d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 235d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.multiply(e, d, e); 236d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.twice(e, e); 237d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.square(d, t); 238d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.add(f, t, d); 239d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.multiply(f, t, f); 240d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int c = Nat.shiftUpBits(7, f, 2, 0); 241d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.reduce32(c, f); 242d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 243d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 244d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root private static boolean trySqrt(int[] nc, int[] r, int[] t) 245d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 246d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] d1 = Nat224.create(); 247d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Nat224.copy(r, d1); 248d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] e1 = Nat224.create(); 249d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root e1[0] = 1; 250d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] f1 = Nat224.create(); 251d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root RP(nc, d1, e1, f1, t); 252d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 253d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] d0 = Nat224.create(); 254d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] e0 = Nat224.create(); 255d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 256d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root for (int k = 1; k < 96; ++k) 257d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 258d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Nat224.copy(d1, d0); 259d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Nat224.copy(e1, e0); 260d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 261d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root RS(d1, e1, f1, t); 262d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 263d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (Nat224.isZero(d1)) 264d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 265d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Mod.invert(SecP224R1Field.P, e0, t); 266d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP224R1Field.multiply(t, d0, t); 267d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return true; 268d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 269d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 270d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 271d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return false; 272d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 273d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root} 274