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