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 ECFieldF2m implements ECField {
033: // Mid terms array length for trinomial basis
034: private static final int TPB_MID_LEN = 1;
035: // Mid terms array length for pentanomial basis
036: private static final int PPB_MID_LEN = 3;
037: // All terms number for trinomial basis
038: private static final int TPB_LEN = TPB_MID_LEN + 2;
039: // All terms number for pentanomial basis
040: private static final int PPB_LEN = PPB_MID_LEN + 2;
041: // m value
042: private final int m;
043: // Reduction polynomial
044: private final BigInteger rp;
045: // Mid term(s) of reduction polynomial
046: private final int[] ks;
047:
048: /**
049: * @com.intel.drl.spec_ref
050: */
051: public ECFieldF2m(int m) {
052: this .m = m;
053: if (this .m <= 0) {
054: throw new IllegalArgumentException(Messages
055: .getString("security.75")); //$NON-NLS-1$
056: }
057: this .rp = null;
058: this .ks = null;
059: }
060:
061: /**
062: * @com.intel.drl.spec_ref
063: */
064: public ECFieldF2m(int m, BigInteger rp) {
065: this .m = m;
066: if (this .m <= 0) {
067: throw new IllegalArgumentException(Messages
068: .getString("security.75")); //$NON-NLS-1$
069: }
070: this .rp = rp;
071: if (this .rp == null) {
072: throw new NullPointerException(Messages
073: .getString("security.76")); //$NON-NLS-1$
074: }
075: // the leftmost bit must be (m+1)-th one,
076: // set bits count must be 3 or 5,
077: // bits 0 and m must be set
078: int rp_bc = this .rp.bitCount();
079: if ((this .rp.bitLength() != (m + 1))
080: || (rp_bc != TPB_LEN && rp_bc != PPB_LEN)
081: || (!this .rp.testBit(0) || !this .rp.testBit(m))) {
082: throw new IllegalArgumentException(Messages
083: .getString("security.77")); //$NON-NLS-1$
084: }
085:
086: // setup ks using rp:
087: // allocate for mid terms only
088: ks = new int[rp_bc - 2];
089: // find midterm orders and set ks accordingly
090: BigInteger rpTmp = rp.clearBit(0);
091: for (int i = ks.length - 1; i >= 0; i--) {
092: ks[i] = rpTmp.getLowestSetBit();
093: rpTmp = rpTmp.clearBit(ks[i]);
094: }
095: }
096:
097: /**
098: * @com.intel.drl.spec_ref
099: */
100: public ECFieldF2m(int m, int[] ks) {
101: this .m = m;
102: if (this .m <= 0) {
103: throw new IllegalArgumentException(Messages
104: .getString("security.75")); //$NON-NLS-1$
105: }
106: // Defensively copies array parameter
107: // to prevent subsequent modification.
108: // NPE as specified if ks is null
109: this .ks = new int[ks.length];
110: System.arraycopy(ks, 0, this .ks, 0, this .ks.length);
111:
112: // no need to check for null already
113: if (this .ks.length != TPB_MID_LEN
114: && this .ks.length != PPB_MID_LEN) {
115: // must be either trinomial or pentanomial basis
116: throw new IllegalArgumentException(Messages
117: .getString("security.78")); //$NON-NLS-1$
118: }
119: // trinomial basis:
120: // check that m > k >= 1, where k is ks[0]
121: // pentanomial basis:
122: // check that m > k3 > k2 > k1 >= 1
123: // and kx in descending order, where
124: // k3 is ks[0], k2 is ks[1], k1 is ks[2]
125: boolean checkFailed = false;
126: int prev = this .m;
127: for (int i = 0; i < this .ks.length; i++) {
128: if (this .ks[i] < prev) {
129: prev = this .ks[i];
130: continue;
131: }
132: checkFailed = true;
133: break;
134: }
135: if (checkFailed || prev < 1) {
136: throw new IllegalArgumentException(Messages
137: .getString("security.79")); //$NON-NLS-1$
138: }
139:
140: // Setup rp using ks:
141: // bits 0 and m always set
142: BigInteger rpTmp = BigInteger.ONE.setBit(this .m);
143: // set remaining bits according to ks
144: for (int i = 0; i < this .ks.length; i++) {
145: rpTmp = rpTmp.setBit(this .ks[i]);
146: }
147: rp = rpTmp;
148: }
149:
150: /**
151: * @com.intel.drl.spec_ref
152: */
153: public boolean equals(Object obj) {
154: // object equals to itself
155: if (this == obj) {
156: return true;
157: }
158: if (obj instanceof ECFieldF2m) {
159: ECFieldF2m o = (ECFieldF2m) obj;
160: // check m
161: if (this .m == o.m) {
162: // check rp
163: if (this .rp == null) {
164: if (o.rp == null) {
165: // fields both with normal basis
166: return true;
167: }
168: } else {
169: // at least this field with polynomial basis
170: // check that rp match
171: // return this.rp.equals(o.rp);
172: return Arrays.equals(this .ks, o.ks);
173: }
174: }
175: }
176: return false;
177: }
178:
179: /**
180: * @com.intel.drl.spec_ref
181: */
182: public int getFieldSize() {
183: return m;
184: }
185:
186: /**
187: * @com.intel.drl.spec_ref
188: */
189: public int getM() {
190: return m;
191: }
192:
193: /**
194: * @com.intel.drl.spec_ref
195: */
196: public int[] getMidTermsOfReductionPolynomial() {
197: // Defensively copies private array
198: // to prevent subsequent modification
199: // was: return ks == null ? null : (int[])ks.clone();
200: if (ks == null) {
201: return null;
202: } else {
203: int[] ret = new int[ks.length];
204: System.arraycopy(ks, 0, ret, 0, ret.length);
205: return ret;
206: }
207: }
208:
209: /**
210: * @com.intel.drl.spec_ref
211: */
212: public BigInteger getReductionPolynomial() {
213: return rp;
214: }
215:
216: /**
217: * @com.intel.drl.spec_ref
218: */
219: public int hashCode() {
220: return rp == null ? m : m + rp.hashCode();
221: }
222: }
|