1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
/* * @(#)ECFieldF2m.java 1.4 05/11/17 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package java.security.spec; import java.math.BigInteger; import java.util.Arrays; /** * This immutable class defines an elliptic curve (EC) * characteristic 2 finite field. * * @see ECField * * @author Valerie Peng * @version 1.4, 11/17/05 * * @since 1.5 */ public class ECFieldF2m implements ECField { private int m; private int[] ks; private BigInteger rp; /** * Creates an elliptic curve characteristic 2 finite * field which has 2^<code>m</code> elements with normal basis. * @param m with 2^<code>m</code> being the number of elements. * @exception IllegalArgumentException if <code>m</code> * is not positive. */ public ECFieldF2m(int m) { if (m <= 0) { throw new IllegalArgumentException("m is not positive"); } this.m = m; this.ks = null; this.rp = null; } /** * Creates an elliptic curve characteristic 2 finite * field which has 2^<code>m</code> elements with * polynomial basis. * The reduction polynomial for this field is based * on <code>rp</code> whose i-th bit correspondes to * the i-th coefficient of the reduction polynomial.<p> * Note: A valid reduction polynomial is either a * trinomial (X^<code>m</code> + X^<code>k</code> + 1 * with <code>m</code> > <code>k</code> >= 1) or a * pentanomial (X^<code>m</code> + X^<code>k3</code> * + X^<code>k2</code> + X^<code>k1</code> + 1 with * <code>m</code> > <code>k3</code> > <code>k2</code> * > <code>k1</code> >= 1). * @param m with 2^<code>m</code> being the number of elements. * @param rp the BigInteger whose i-th bit corresponds to * the i-th coefficient of the reduction polynomial. * @exception NullPointerException if <code>rp</code> is null. * @exception IllegalArgumentException if <code>m</code> * is not positive, or <code>rp</code> does not represent * a valid reduction polynomial. */ public ECFieldF2m(int m, BigInteger rp) { // check m and rp this.m = m; this.rp = rp; if (m <= 0) { throw new IllegalArgumentException("m is not positive"); } int bitCount = this.rp.bitCount(); if (!this.rp.testBit(0) || !this.rp.testBit(m) || ((bitCount != 3) && (bitCount != 5))) { throw new IllegalArgumentException ("rp does not represent a valid reduction polynomial"); } // convert rp into ks BigInteger temp = this.rp.clearBit(0).clearBit(m); this.ks = new int[bitCount-2]; for (int i = this.ks.length-1; i >= 0; i--) { int index = temp.getLowestSetBit(); this.ks[i] = index; temp = temp.clearBit(index); } } /** * Creates an elliptic curve characteristic 2 finite * field which has 2^<code>m</code> elements with * polynomial basis. The reduction polynomial for this * field is based on <code>ks</code> whose content * contains the order of the middle term(s) of the * reduction polynomial. * Note: A valid reduction polynomial is either a * trinomial (X^<code>m</code> + X^<code>k</code> + 1 * with <code>m</code> > <code>k</code> >= 1) or a * pentanomial (X^<code>m</code> + X^<code>k3</code> * + X^<code>k2</code> + X^<code>k1</code> + 1 with * <code>m</code> > <code>k3</code> > <code>k2</code> * > <code>k1</code> >= 1), so <code>ks</code> should * have length 1 or 3. * @param m with 2^<code>m</code> being the number of elements. * @param ks the order of the middle term(s) of the * reduction polynomial. Contents of this array are copied * to protect against subsequent modification. * @exception NullPointerException if <code>ks</code> is null. * @exception IllegalArgumentException if<code>m</code> * is not positive, or the length of <code>ks</code> * is neither 1 nor 3, or values in <code>ks</code> * are not between <code>m</code>-1 and 1 (inclusive) * and in descending order. */ public ECFieldF2m(int m, int[] ks) { // check m and ks this.m = m; this.ks = (int[]) ks.clone(); if (m <= 0) { throw new IllegalArgumentException("m is not positive"); } if ((this.ks.length != 1) && (this.ks.length != 3)) { throw new IllegalArgumentException ("length of ks is neither 1 nor 3"); } for (int i = 0; i < this.ks.length; i++) { if ((this.ks[i] < 1) || (this.ks[i] > m-1)) { throw new IllegalArgumentException ("ks["+ i + "] is out of range"); } if ((i != 0) && (this.ks[i] >= this.ks[i-1])) { throw new IllegalArgumentException ("values in ks are not in descending order"); } } // convert ks into rp this.rp = BigInteger.ONE; this.rp = rp.setBit(m); for (int j = 0; j < this.ks.length; j++) { rp = rp.setBit(this.ks[j]); } } /** * Returns the field size in bits which is <code>m</code> * for this characteristic 2 finite field. * @return the field size in bits. */ public int getFieldSize() { return m; } /** * Returns the value <code>m</code> of this characteristic * 2 finite field. * @return <code>m</code> with 2^<code>m</code> being the * number of elements. */ public int getM() { return m; } /** * Returns a BigInteger whose i-th bit corresponds to the * i-th coefficient of the reduction polynomial for polynomial * basis or null for normal basis. * @return a BigInteger whose i-th bit corresponds to the * i-th coefficient of the reduction polynomial for polynomial * basis or null for normal basis. */ public BigInteger getReductionPolynomial() { return rp; } /** * Returns an integer array which contains the order of the * middle term(s) of the reduction polynomial for polynomial * basis or null for normal basis. * @return an integer array which contains the order of the * middle term(s) of the reduction polynomial for polynomial * basis or null for normal basis. A new array is returned * each time this method is called. */ public int[] getMidTermsOfReductionPolynomial() { if (ks == null) { return null; } else { return (int[]) ks.clone(); } } /** * Compares this finite field for equality with the * specified object. * @param obj the object to be compared. * @return true if <code>obj</code> is an instance * of ECFieldF2m and both <code>m</code> and the reduction * polynomial match, false otherwise. */ public boolean equals(Object obj) { if (this == obj) return true; if (obj instanceof ECFieldF2m) { // no need to compare rp here since ks and rp // should be equivalent return ((m == ((ECFieldF2m)obj).m) && (Arrays.equals(ks, ((ECFieldF2m) obj).ks))); } return false; } /** * Returns a hash code value for this characteristic 2 * finite field. * @return a hash code value. */ public int hashCode() { int value = m << 5; value += (rp==null? 0:rp.hashCode()); // no need to involve ks here since ks and rp // should be equivalent. return value; } }