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.Nat192; 8d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootimport org.bouncycastle.util.Arrays; 9d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 10d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootpublic class SecP192R1FieldElement extends ECFieldElement 11d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root{ 12d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public static final BigInteger Q = SecP192R1Curve.q; 13d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 14d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root protected int[] x; 15d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 16d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public SecP192R1FieldElement(BigInteger x) 17d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 18d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (x == null || x.signum() < 0 || x.compareTo(Q) >= 0) 19d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 20d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root throw new IllegalArgumentException("x value invalid for SecP192R1FieldElement"); 21d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 22d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 23d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root this.x = SecP192R1Field.fromBigInteger(x); 24d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 25d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 26d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public SecP192R1FieldElement() 27d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 28d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root this.x = Nat192.create(); 29d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 30d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 31d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root protected SecP192R1FieldElement(int[] x) 32d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 33d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root this.x = x; 34d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 35d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 36d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public boolean isZero() 37d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 38d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Nat192.isZero(x); 39d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 40d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 41d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public boolean isOne() 42d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 43d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Nat192.isOne(x); 44d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 45d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 46d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public boolean testBitZero() 47d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 48d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Nat192.getBit(x, 0) == 1; 49d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 50d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 51d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public BigInteger toBigInteger() 52d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 53d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Nat192.toBigInteger(x); 54d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 55d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 56d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public String getFieldName() 57d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 58d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return "SecP192R1Field"; 59d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 60d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 61d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public int getFieldSize() 62d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 63d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Q.bitLength(); 64d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 65d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 66d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement add(ECFieldElement b) 67d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 68d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat192.create(); 69d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.add(x, ((SecP192R1FieldElement)b).x, z); 70d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP192R1FieldElement(z); 71d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 72d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 73d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement addOne() 74d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 75d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat192.create(); 76d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.addOne(x, z); 77d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP192R1FieldElement(z); 78d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 79d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 80d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement subtract(ECFieldElement b) 81d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 82d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat192.create(); 83d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.subtract(x, ((SecP192R1FieldElement)b).x, z); 84d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP192R1FieldElement(z); 85d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 86d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 87d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement multiply(ECFieldElement b) 88d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 89d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat192.create(); 90d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.multiply(x, ((SecP192R1FieldElement)b).x, z); 91d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP192R1FieldElement(z); 92d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 93d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 94d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement divide(ECFieldElement b) 95d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 96d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root// return multiply(b.invert()); 97d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat192.create(); 98d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Mod.invert(SecP192R1Field.P, ((SecP192R1FieldElement)b).x, z); 99d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.multiply(z, x, z); 100d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP192R1FieldElement(z); 101d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 102d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 103d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement negate() 104d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 105d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat192.create(); 106d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.negate(x, z); 107d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP192R1FieldElement(z); 108d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 109d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 110d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement square() 111d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 112d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat192.create(); 113d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.square(x, z); 114d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP192R1FieldElement(z); 115d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 116d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 117d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public ECFieldElement invert() 118d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 119d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root// return new SecP192R1FieldElement(toBigInteger().modInverse(Q)); 120d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] z = Nat192.create(); 121d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root Mod.invert(SecP192R1Field.P, x, z); 122d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return new SecP192R1FieldElement(z); 123d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 124d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 125d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root // D.1.4 91 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 // Raise this element to the exponent 2^190 - 2^62 133d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 134d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] x1 = this.x; 135d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (Nat192.isZero(x1) || Nat192.isOne(x1)) 136d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 137d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return this; 138d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 139d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 140d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] t1 = Nat192.create(); 141d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int[] t2 = Nat192.create(); 142d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 143d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.square(x1, t1); 144d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.multiply(t1, x1, t1); 145d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 146d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.squareN(t1, 2, t2); 147d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.multiply(t2, t1, t2); 148d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 149d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.squareN(t2, 4, t1); 150d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.multiply(t1, t2, t1); 151d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 152d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.squareN(t1, 8, t2); 153d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.multiply(t2, t1, t2); 154d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 155d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.squareN(t2, 16, t1); 156d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.multiply(t1, t2, t1); 157d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 158d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.squareN(t1, 32, t2); 159d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.multiply(t2, t1, t2); 160d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 161d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.squareN(t2, 64, t1); 162d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.multiply(t1, t2, t1); 163d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 164d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.squareN(t1, 62, t1); 165d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1Field.square(t1, t2); 166d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 167d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Nat192.eq(x1, t2) ? new SecP192R1FieldElement(t1) : null; 168d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 169d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 170d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public boolean equals(Object other) 171d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 172d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (other == this) 173d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 174d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return true; 175d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 176d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 177d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (!(other instanceof SecP192R1FieldElement)) 178d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 179d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return false; 180d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 181d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 182d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root SecP192R1FieldElement o = (SecP192R1FieldElement)other; 183d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Nat192.eq(x, o.x); 184d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 185d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root 186d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root public int hashCode() 187d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 188d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return Q.hashCode() ^ Arrays.hashCode(x, 0, 6); 189d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 190d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root} 191