51 private static void checkValidity(ECField field, BigInteger c, 52 String cName) { 53 // can only perform check if field is ECFieldFp or ECFieldF2m. 54 if (field instanceof ECFieldFp) { 55 BigInteger p = ((ECFieldFp)field).getP(); 56 if (p.compareTo(c) != 1) { 57 throw new IllegalArgumentException(cName + " is too large"); 58 } else if (c.signum() < 0) { 59 throw new IllegalArgumentException(cName + " is negative"); 60 } 61 } else if (field instanceof ECFieldF2m) { 62 int m = ((ECFieldF2m)field).getM(); 63 if (c.bitLength() > m) { 64 throw new IllegalArgumentException(cName + " is too large"); 65 } 66 } 67 } 68 69 /** 70 * Creates an elliptic curve with the specified elliptic field 71 * <code>field</code> and the coefficients <code>a</code> and 72 * <code>b</code>. 73 * @param field the finite field that this elliptic curve is over. 74 * @param a the first coefficient of this elliptic curve. 75 * @param b the second coefficient of this elliptic curve. 76 * @exception NullPointerException if <code>field</code>, 77 * <code>a</code>, or <code>b</code> is null. 78 * @exception IllegalArgumentException if <code>a</code> 79 * or <code>b</code> is not null and not in <code>field</code>. 80 */ 81 public EllipticCurve(ECField field, BigInteger a, 82 BigInteger b) { 83 this(field, a, b, null); 84 } 85 86 /** 87 * Creates an elliptic curve with the specified elliptic field 88 * <code>field</code>, the coefficients <code>a</code> and 89 * <code>b</code>, and the <code>seed</code> used for curve generation. 90 * @param field the finite field that this elliptic curve is over. 91 * @param a the first coefficient of this elliptic curve. 92 * @param b the second coefficient of this elliptic curve. 93 * @param seed the bytes used during curve generation for later 94 * validation. Contents of this array are copied to protect against 95 * subsequent modification. 96 * @exception NullPointerException if <code>field</code>, 97 * <code>a</code>, or <code>b</code> is null. 98 * @exception IllegalArgumentException if <code>a</code> 99 * or <code>b</code> is not null and not in <code>field</code>. 100 */ 101 public EllipticCurve(ECField field, BigInteger a, 102 BigInteger b, byte[] seed) { 103 if (field == null) { 104 throw new NullPointerException("field is null"); 105 } 106 if (a == null) { 107 throw new NullPointerException("first coefficient is null"); 108 } 109 if (b == null) { 110 throw new NullPointerException("second coefficient is null"); 111 } 112 checkValidity(field, a, "first coefficient"); 113 checkValidity(field, b, "second coefficient"); 114 this.field = field; 115 this.a = a; 116 this.b = b; 117 if (seed != null) { 118 this.seed = seed.clone(); 119 } else { 120 this.seed = null; 121 } 122 } 123 124 /** 125 * Returns the finite field <code>field</code> that this 126 * elliptic curve is over. 127 * @return the field <code>field</code> that this curve 128 * is over. 129 */ 130 public ECField getField() { 131 return field; 132 } 133 134 /** 135 * Returns the first coefficient <code>a</code> of the 136 * elliptic curve. 137 * @return the first coefficient <code>a</code>. 138 */ 139 public BigInteger getA() { 140 return a; 141 } 142 143 /** 144 * Returns the second coefficient <code>b</code> of the 145 * elliptic curve. 146 * @return the second coefficient <code>b</code>. 147 */ 148 public BigInteger getB() { 149 return b; 150 } 151 152 /** 153 * Returns the seeding bytes <code>seed</code> used 154 * during curve generation. May be null if not specified. 155 * @return the seeding bytes <code>seed</code>. A new 156 * array is returned each time this method is called. 157 */ 158 public byte[] getSeed() { 159 if (seed == null) return null; 160 else return seed.clone(); 161 } 162 163 /** 164 * Compares this elliptic curve for equality with the 165 * specified object. 166 * @param obj the object to be compared. 167 * @return true if <code>obj</code> is an instance of 168 * EllipticCurve and the field, A, and B match, false otherwise. 169 */ 170 public boolean equals(Object obj) { 171 if (this == obj) return true; 172 if (obj instanceof EllipticCurve) { 173 EllipticCurve curve = (EllipticCurve) obj; 174 if ((field.equals(curve.field)) && 175 (a.equals(curve.a)) && 176 (b.equals(curve.b))) { 177 return true; 178 } 179 } 180 return false; 181 } 182 183 /** 184 * Returns a hash code value for this elliptic curve. 185 * @return a hash code value computed from the hash codes of the field, A, 186 * and B, as follows: 187 * <pre>{@code | 51 private static void checkValidity(ECField field, BigInteger c, 52 String cName) { 53 // can only perform check if field is ECFieldFp or ECFieldF2m. 54 if (field instanceof ECFieldFp) { 55 BigInteger p = ((ECFieldFp)field).getP(); 56 if (p.compareTo(c) != 1) { 57 throw new IllegalArgumentException(cName + " is too large"); 58 } else if (c.signum() < 0) { 59 throw new IllegalArgumentException(cName + " is negative"); 60 } 61 } else if (field instanceof ECFieldF2m) { 62 int m = ((ECFieldF2m)field).getM(); 63 if (c.bitLength() > m) { 64 throw new IllegalArgumentException(cName + " is too large"); 65 } 66 } 67 } 68 69 /** 70 * Creates an elliptic curve with the specified elliptic field 71 * {@code field} and the coefficients {@code a} and 72 * {@code b}. 73 * @param field the finite field that this elliptic curve is over. 74 * @param a the first coefficient of this elliptic curve. 75 * @param b the second coefficient of this elliptic curve. 76 * @exception NullPointerException if {@code field}, 77 * {@code a}, or {@code b} is null. 78 * @exception IllegalArgumentException if {@code a} 79 * or {@code b} is not null and not in {@code field}. 80 */ 81 public EllipticCurve(ECField field, BigInteger a, 82 BigInteger b) { 83 this(field, a, b, null); 84 } 85 86 /** 87 * Creates an elliptic curve with the specified elliptic field 88 * {@code field}, the coefficients {@code a} and 89 * {@code b}, and the {@code seed} used for curve generation. 90 * @param field the finite field that this elliptic curve is over. 91 * @param a the first coefficient of this elliptic curve. 92 * @param b the second coefficient of this elliptic curve. 93 * @param seed the bytes used during curve generation for later 94 * validation. Contents of this array are copied to protect against 95 * subsequent modification. 96 * @exception NullPointerException if {@code field}, 97 * {@code a}, or {@code b} is null. 98 * @exception IllegalArgumentException if {@code a} 99 * or {@code b} is not null and not in {@code field}. 100 */ 101 public EllipticCurve(ECField field, BigInteger a, 102 BigInteger b, byte[] seed) { 103 if (field == null) { 104 throw new NullPointerException("field is null"); 105 } 106 if (a == null) { 107 throw new NullPointerException("first coefficient is null"); 108 } 109 if (b == null) { 110 throw new NullPointerException("second coefficient is null"); 111 } 112 checkValidity(field, a, "first coefficient"); 113 checkValidity(field, b, "second coefficient"); 114 this.field = field; 115 this.a = a; 116 this.b = b; 117 if (seed != null) { 118 this.seed = seed.clone(); 119 } else { 120 this.seed = null; 121 } 122 } 123 124 /** 125 * Returns the finite field {@code field} that this 126 * elliptic curve is over. 127 * @return the field {@code field} that this curve 128 * is over. 129 */ 130 public ECField getField() { 131 return field; 132 } 133 134 /** 135 * Returns the first coefficient {@code a} of the 136 * elliptic curve. 137 * @return the first coefficient {@code a}. 138 */ 139 public BigInteger getA() { 140 return a; 141 } 142 143 /** 144 * Returns the second coefficient {@code b} of the 145 * elliptic curve. 146 * @return the second coefficient {@code b}. 147 */ 148 public BigInteger getB() { 149 return b; 150 } 151 152 /** 153 * Returns the seeding bytes {@code seed} used 154 * during curve generation. May be null if not specified. 155 * @return the seeding bytes {@code seed}. A new 156 * array is returned each time this method is called. 157 */ 158 public byte[] getSeed() { 159 if (seed == null) return null; 160 else return seed.clone(); 161 } 162 163 /** 164 * Compares this elliptic curve for equality with the 165 * specified object. 166 * @param obj the object to be compared. 167 * @return true if {@code obj} is an instance of 168 * EllipticCurve and the field, A, and B match, false otherwise. 169 */ 170 public boolean equals(Object obj) { 171 if (this == obj) return true; 172 if (obj instanceof EllipticCurve) { 173 EllipticCurve curve = (EllipticCurve) obj; 174 if ((field.equals(curve.field)) && 175 (a.equals(curve.a)) && 176 (b.equals(curve.b))) { 177 return true; 178 } 179 } 180 return false; 181 } 182 183 /** 184 * Returns a hash code value for this elliptic curve. 185 * @return a hash code value computed from the hash codes of the field, A, 186 * and B, as follows: 187 * <pre>{@code |