001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Vladimir N. Molotkov
020: * @version $Revision$
021: */package java.security.spec;
022:
023: import java.math.BigInteger;
024: import java.util.Arrays;
025:
026: import org.apache.harmony.security.internal.nls.Messages;
027:
028: /**
029: * @com.intel.drl.spec_ref
030: *
031: */
032: public class EllipticCurve {
033:
034: // Underlying finite field
035: private final ECField field;
036:
037: // The first coefficient of the equation defining this elliptic curve
038: private final BigInteger a;
039:
040: // The second coefficient of the equation defining this elliptic curve
041: private final BigInteger b;
042:
043: // Bytes used during this elliptic curve generation,
044: // if it was generated randomly
045: private final byte[] seed;
046:
047: // Hash code
048: private volatile int hash;
049:
050: /**
051: * @com.intel.drl.spec_ref
052: */
053: public EllipticCurve(ECField field, BigInteger a, BigInteger b,
054: byte[] seed) {
055: this .field = field;
056: if (this .field == null) {
057: throw new NullPointerException(Messages
058: .getString("security.7A")); //$NON-NLS-1$
059: }
060: this .a = a;
061: if (this .a == null) {
062: throw new NullPointerException(Messages
063: .getString("security.7B")); //$NON-NLS-1$
064: }
065: this .b = b;
066: if (this .b == null) {
067: throw new NullPointerException(Messages
068: .getString("security.7C")); //$NON-NLS-1$
069: }
070: // make defensive copy
071: if (seed == null) {
072: this .seed = null;
073: } else {
074: this .seed = new byte[seed.length];
075: System.arraycopy(seed, 0, this .seed, 0, this .seed.length);
076: }
077: // check parameters for ECFieldFp and ECFieldF2m.
078: // Check invariant: a and b must be in the field.
079: // Check conditions for custom ECField are not specified.
080: if (this .field instanceof ECFieldFp) {
081: BigInteger p = ((ECFieldFp) this .field).getP();
082: if (this .a.signum() < 0 || this .a.compareTo(p) >= 0) {
083: throw new IllegalArgumentException(Messages
084: .getString("security.7D")); //$NON-NLS-1$
085: }
086: if (this .b.signum() < 0 || this .b.compareTo(p) >= 0) {
087: throw new IllegalArgumentException(Messages
088: .getString("security.7E")); //$NON-NLS-1$
089: }
090: } else if (this .field instanceof ECFieldF2m) {
091: int fieldSizeInBits = this .field.getFieldSize();
092: if (!(this .a.bitLength() <= fieldSizeInBits)) {
093: throw new IllegalArgumentException(Messages
094: .getString("security.7D")); //$NON-NLS-1$
095: }
096: if (!(this .b.bitLength() <= fieldSizeInBits)) {
097: throw new IllegalArgumentException(Messages
098: .getString("security.7E")); //$NON-NLS-1$
099: }
100: }
101: }
102:
103: /**
104: * @com.intel.drl.spec_ref
105: */
106: public EllipticCurve(ECField field, BigInteger a, BigInteger b) {
107: this (field, a, b, null);
108: }
109:
110: /**
111: * @com.intel.drl.spec_ref
112: */
113: public BigInteger getA() {
114: return a;
115: }
116:
117: /**
118: * @com.intel.drl.spec_ref
119: */
120: public BigInteger getB() {
121: return b;
122: }
123:
124: /**
125: * @com.intel.drl.spec_ref
126: */
127: public ECField getField() {
128: return field;
129: }
130:
131: /**
132: * @com.intel.drl.spec_ref
133: */
134: public byte[] getSeed() {
135: if (seed == null) {
136: return null;
137: } else {
138: // return copy
139: byte[] ret = new byte[seed.length];
140: System.arraycopy(seed, 0, ret, 0, ret.length);
141: return ret;
142: }
143: }
144:
145: /**
146: * @com.intel.drl.spec_ref
147: */
148: public boolean equals(Object other) {
149: if (this == other) {
150: return true;
151: }
152: if (!(other instanceof EllipticCurve)) {
153: return false;
154: }
155: EllipticCurve otherEc = (EllipticCurve) other;
156: return this .field.equals(otherEc.field)
157: && this .a.equals(otherEc.a) && this .b.equals(otherEc.b)
158: && Arrays.equals(this .seed, otherEc.seed);
159: }
160:
161: /**
162: * @com.intel.drl.spec_ref
163: */
164: public int hashCode() {
165: // hash init is delayed
166: if (hash == 0) {
167: int hash0 = 11;
168: hash0 = hash0 * 31 + field.hashCode();
169: hash0 = hash0 * 31 + a.hashCode();
170: hash0 = hash0 * 31 + b.hashCode();
171: if (seed != null) {
172: for (int i = 0; i < seed.length; i++) {
173: hash0 = hash0 * 31 + seed[i];
174: }
175: } else {
176: hash0 = hash0 * 31;
177: }
178: hash = hash0;
179: }
180: return hash;
181: }
182: }
|