18212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrompackage org.bouncycastle.math.ec; 28212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 38212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstromimport java.math.BigInteger; 48212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstromimport java.util.Random; 58212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 68212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom/** 78212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * base class for an elliptic curve 88212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 98212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrompublic abstract class ECCurve 108212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom{ 118212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement a, b; 128212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 138212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public abstract int getFieldSize(); 148212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 158212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public abstract ECFieldElement fromBigInteger(BigInteger x); 168212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 178212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public abstract ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression); 188212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 198212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public abstract ECPoint decodePoint(byte[] encoded); 208212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 218212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public abstract ECPoint getInfinity(); 228212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 238212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public ECFieldElement getA() 248212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 258212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return a; 268212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 278212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 288212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public ECFieldElement getB() 298212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 308212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return b; 318212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 328212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 338212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 348212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Elliptic curve over Fp 358212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 368212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public static class Fp extends ECCurve 378212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 388212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom BigInteger q; 398212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECPoint.Fp infinity; 408212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 418212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public Fp(BigInteger q, BigInteger a, BigInteger b) 428212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 438212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.q = q; 448212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.a = fromBigInteger(a); 458212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.b = fromBigInteger(b); 468212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.infinity = new ECPoint.Fp(this, null, null); 478212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 488212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 498212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public BigInteger getQ() 508212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 518212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return q; 528212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 538212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 548212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public int getFieldSize() 558212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 568212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return q.bitLength(); 578212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 588212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 598212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public ECFieldElement fromBigInteger(BigInteger x) 608212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 618212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return new ECFieldElement.Fp(this.q, x); 628212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 638212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 648212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression) 658212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 668212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return new ECPoint.Fp(this, fromBigInteger(x), fromBigInteger(y), withCompression); 678212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 688212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 698212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 708212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Decode a point on this curve from its ASN.1 encoding. The different 718212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * encodings are taken account of, including point compression for 728212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>F<sub>p</sub></code> (X9.62 s 4.2.1 pg 17). 738212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @return The decoded point. 748212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 758212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public ECPoint decodePoint(byte[] encoded) 768212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 778212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECPoint p = null; 788212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 798212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom switch (encoded[0]) 808212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 818212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom // infinity 828212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom case 0x00: 836e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (encoded.length > 1) 846e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 856e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom throw new RuntimeException("Invalid point encoding"); 866e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 878212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom p = getInfinity(); 888212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom break; 898212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom // compressed 908212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom case 0x02: 918212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom case 0x03: 928212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int ytilde = encoded[0] & 1; 938212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom byte[] i = new byte[encoded.length - 1]; 948212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 958212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom System.arraycopy(encoded, 1, i, 0, i.length); 968212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 978212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement x = new ECFieldElement.Fp(this.q, new BigInteger(1, i)); 988212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement alpha = x.multiply(x.square().add(a)).add(b); 998212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement beta = alpha.sqrt(); 1008212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1018212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom // 1028212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom // if we can't find a sqrt we haven't got a point on the 1038212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom // curve - run! 1048212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom // 1058212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (beta == null) 1068212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 1078212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom throw new RuntimeException("Invalid point compression"); 1088212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 1098212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1108212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int bit0 = (beta.toBigInteger().testBit(0) ? 1 : 0); 1118212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1128212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (bit0 == ytilde) 1138212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 1148212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom p = new ECPoint.Fp(this, x, beta, true); 1158212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 1168212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom else 1178212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 1188212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom p = new ECPoint.Fp(this, x, 1198212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom new ECFieldElement.Fp(this.q, q.subtract(beta.toBigInteger())), true); 1208212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 1218212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom break; 1228212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom // uncompressed 1238212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom case 0x04: 1248212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom // hybrid 1258212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom case 0x06: 1268212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom case 0x07: 1278212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom byte[] xEnc = new byte[(encoded.length - 1) / 2]; 1288212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom byte[] yEnc = new byte[(encoded.length - 1) / 2]; 1298212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1308212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom System.arraycopy(encoded, 1, xEnc, 0, xEnc.length); 1318212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom System.arraycopy(encoded, xEnc.length + 1, yEnc, 0, yEnc.length); 1328212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1338212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom p = new ECPoint.Fp(this, 1348212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom new ECFieldElement.Fp(this.q, new BigInteger(1, xEnc)), 1358212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom new ECFieldElement.Fp(this.q, new BigInteger(1, yEnc))); 1368212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom break; 1378212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom default: 1388212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom throw new RuntimeException("Invalid point encoding 0x" + Integer.toString(encoded[0], 16)); 1398212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 1408212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1418212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return p; 1428212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 1438212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1448212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public ECPoint getInfinity() 1458212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 1468212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return infinity; 1478212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 1488212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1498212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public boolean equals( 1508212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom Object anObject) 1518212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 1528212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (anObject == this) 1538212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 1548212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return true; 1558212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 1568212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1578212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (!(anObject instanceof ECCurve.Fp)) 1588212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 1598212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return false; 1608212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 1618212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1628212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECCurve.Fp other = (ECCurve.Fp) anObject; 1638212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1648212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return this.q.equals(other.q) 1658212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom && a.equals(other.a) && b.equals(other.b); 1668212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 1678212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1688212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public int hashCode() 1698212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 1708212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return a.hashCode() ^ b.hashCode() ^ q.hashCode(); 1718212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 1728212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 1738212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1748212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 1758212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Elliptic curves over F2m. The Weierstrass equation is given by 1768212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>y<sup>2</sup> + xy = x<sup>3</sup> + ax<sup>2</sup> + b</code>. 1778212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 1788212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public static class F2m extends ECCurve 1798212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 1808212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 1818212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * The exponent <code>m</code> of <code>F<sub>2<sup>m</sup></sub></code>. 1828212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 1838212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom private int m; // can't be final - JDK 1.1 1848212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1858212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 1868212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * TPB: The integer <code>k</code> where <code>x<sup>m</sup> + 1878212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * x<sup>k</sup> + 1</code> represents the reduction polynomial 1888212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>f(z)</code>.<br> 1898212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * PPB: The integer <code>k1</code> where <code>x<sup>m</sup> + 1908212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> 1918212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * represents the reduction polynomial <code>f(z)</code>.<br> 1928212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 1938212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom private int k1; // can't be final - JDK 1.1 1948212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 1958212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 1968212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * TPB: Always set to <code>0</code><br> 1978212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * PPB: The integer <code>k2</code> where <code>x<sup>m</sup> + 1988212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> 1998212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * represents the reduction polynomial <code>f(z)</code>.<br> 2008212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 2018212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom private int k2; // can't be final - JDK 1.1 2028212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 2038212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 2048212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * TPB: Always set to <code>0</code><br> 2058212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * PPB: The integer <code>k3</code> where <code>x<sup>m</sup> + 2068212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> 2078212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * represents the reduction polynomial <code>f(z)</code>.<br> 2088212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 2098212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom private int k3; // can't be final - JDK 1.1 2108212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 2118212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 2128212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * The order of the base point of the curve. 2138212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 2148212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom private BigInteger n; // can't be final - JDK 1.1 2158212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 2168212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 2178212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * The cofactor of the curve. 2188212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 2198212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom private BigInteger h; // can't be final - JDK 1.1 2208212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 2218212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 2228212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * The point at infinity on this curve. 2238212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 2248212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom private ECPoint.F2m infinity; // can't be final - JDK 1.1 2258212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 2268212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 2278212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * The parameter <code>μ</code> of the elliptic curve if this is 2288212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * a Koblitz curve. 2298212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 2308212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom private byte mu = 0; 2318212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 2328212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 2338212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * The auxiliary values <code>s<sub>0</sub></code> and 2348212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>s<sub>1</sub></code> used for partial modular reduction for 2358212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Koblitz curves. 2368212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 2378212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom private BigInteger[] si = null; 2388212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 2398212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 2408212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Constructor for Trinomial Polynomial Basis (TPB). 2418212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param m The exponent <code>m</code> of 2428212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>F<sub>2<sup>m</sup></sub></code>. 2438212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param k The integer <code>k</code> where <code>x<sup>m</sup> + 2448212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * x<sup>k</sup> + 1</code> represents the reduction 2458212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * polynomial <code>f(z)</code>. 2468212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param a The coefficient <code>a</code> in the Weierstrass equation 2478212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * for non-supersingular elliptic curves over 2488212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>F<sub>2<sup>m</sup></sub></code>. 2498212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param b The coefficient <code>b</code> in the Weierstrass equation 2508212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * for non-supersingular elliptic curves over 2518212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>F<sub>2<sup>m</sup></sub></code>. 2528212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 2538212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public F2m( 2548212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int m, 2558212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int k, 2568212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom BigInteger a, 2578212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom BigInteger b) 2588212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 2598212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this(m, k, 0, 0, a, b, null, null); 2608212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 2618212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 2628212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 2638212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Constructor for Trinomial Polynomial Basis (TPB). 2648212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param m The exponent <code>m</code> of 2658212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>F<sub>2<sup>m</sup></sub></code>. 2668212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param k The integer <code>k</code> where <code>x<sup>m</sup> + 2678212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * x<sup>k</sup> + 1</code> represents the reduction 2688212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * polynomial <code>f(z)</code>. 2698212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param a The coefficient <code>a</code> in the Weierstrass equation 2708212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * for non-supersingular elliptic curves over 2718212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>F<sub>2<sup>m</sup></sub></code>. 2728212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param b The coefficient <code>b</code> in the Weierstrass equation 2738212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * for non-supersingular elliptic curves over 2748212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>F<sub>2<sup>m</sup></sub></code>. 2758212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param n The order of the main subgroup of the elliptic curve. 2768212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param h The cofactor of the elliptic curve, i.e. 2778212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>#E<sub>a</sub>(F<sub>2<sup>m</sup></sub>) = h * n</code>. 2788212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 2798212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public F2m( 2808212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int m, 2818212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int k, 2828212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom BigInteger a, 2838212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom BigInteger b, 2848212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom BigInteger n, 2858212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom BigInteger h) 2868212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 2878212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this(m, k, 0, 0, a, b, n, h); 2888212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 2898212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 2908212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 2918212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Constructor for Pentanomial Polynomial Basis (PPB). 2928212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param m The exponent <code>m</code> of 2938212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>F<sub>2<sup>m</sup></sub></code>. 2948212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> + 2958212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> 2968212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * represents the reduction polynomial <code>f(z)</code>. 2978212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param k2 The integer <code>k2</code> where <code>x<sup>m</sup> + 2988212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> 2998212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * represents the reduction polynomial <code>f(z)</code>. 3008212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param k3 The integer <code>k3</code> where <code>x<sup>m</sup> + 3018212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> 3028212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * represents the reduction polynomial <code>f(z)</code>. 3038212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param a The coefficient <code>a</code> in the Weierstrass equation 3048212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * for non-supersingular elliptic curves over 3058212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>F<sub>2<sup>m</sup></sub></code>. 3068212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param b The coefficient <code>b</code> in the Weierstrass equation 3078212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * for non-supersingular elliptic curves over 3088212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>F<sub>2<sup>m</sup></sub></code>. 3098212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 3108212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public F2m( 3118212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int m, 3128212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int k1, 3138212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int k2, 3148212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int k3, 3158212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom BigInteger a, 3168212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom BigInteger b) 3178212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 3188212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this(m, k1, k2, k3, a, b, null, null); 3198212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 3208212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 3218212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 3228212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Constructor for Pentanomial Polynomial Basis (PPB). 3238212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param m The exponent <code>m</code> of 3248212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>F<sub>2<sup>m</sup></sub></code>. 3258212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> + 3268212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> 3278212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * represents the reduction polynomial <code>f(z)</code>. 3288212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param k2 The integer <code>k2</code> where <code>x<sup>m</sup> + 3298212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> 3308212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * represents the reduction polynomial <code>f(z)</code>. 3318212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param k3 The integer <code>k3</code> where <code>x<sup>m</sup> + 3328212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> 3338212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * represents the reduction polynomial <code>f(z)</code>. 3348212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param a The coefficient <code>a</code> in the Weierstrass equation 3358212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * for non-supersingular elliptic curves over 3368212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>F<sub>2<sup>m</sup></sub></code>. 3378212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param b The coefficient <code>b</code> in the Weierstrass equation 3388212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * for non-supersingular elliptic curves over 3398212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>F<sub>2<sup>m</sup></sub></code>. 3408212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param n The order of the main subgroup of the elliptic curve. 3418212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param h The cofactor of the elliptic curve, i.e. 3428212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>#E<sub>a</sub>(F<sub>2<sup>m</sup></sub>) = h * n</code>. 3438212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 3448212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public F2m( 3458212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int m, 3468212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int k1, 3478212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int k2, 3488212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int k3, 3498212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom BigInteger a, 3508212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom BigInteger b, 3518212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom BigInteger n, 3528212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom BigInteger h) 3538212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 3548212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.m = m; 3558212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.k1 = k1; 3568212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.k2 = k2; 3578212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.k3 = k3; 3588212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.n = n; 3598212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.h = h; 3608212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 3618212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (k1 == 0) 3628212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 3638212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom throw new IllegalArgumentException("k1 must be > 0"); 3648212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 3658212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 3668212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (k2 == 0) 3678212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 3688212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (k3 != 0) 3698212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 3708212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom throw new IllegalArgumentException("k3 must be 0 if k2 == 0"); 3718212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 3728212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 3738212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom else 3748212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 3758212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (k2 <= k1) 3768212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 3778212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom throw new IllegalArgumentException("k2 must be > k1"); 3788212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 3798212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 3808212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (k3 <= k2) 3818212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 3828212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom throw new IllegalArgumentException("k3 must be > k2"); 3838212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 3848212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 3858212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 3868212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.a = fromBigInteger(a); 3878212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.b = fromBigInteger(b); 3888212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.infinity = new ECPoint.F2m(this, null, null); 3898212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 3908212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 3918212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public int getFieldSize() 3928212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 3938212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return m; 3948212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 3958212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 3968212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public ECFieldElement fromBigInteger(BigInteger x) 3978212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 3988212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, x); 3998212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 4008212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 4018212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression) 4028212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 4038212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return new ECPoint.F2m(this, fromBigInteger(x), fromBigInteger(y), withCompression); 4048212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 4058212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 4068212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /* (non-Javadoc) 4078212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @see org.bouncycastle.math.ec.ECCurve#decodePoint(byte[]) 4088212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 4098212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public ECPoint decodePoint(byte[] encoded) 4108212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 4118212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECPoint p = null; 4128212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 4138212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom switch (encoded[0]) 4148212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 4158212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom // infinity 4168212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom case 0x00: 4176e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (encoded.length > 1) 4186e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 4196e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom throw new RuntimeException("Invalid point encoding"); 4206e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 4218212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom p = getInfinity(); 4228212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom break; 4238212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom // compressed 4248212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom case 0x02: 4258212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom case 0x03: 4268212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom byte[] enc = new byte[encoded.length - 1]; 4278212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom System.arraycopy(encoded, 1, enc, 0, enc.length); 4288212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (encoded[0] == 0x02) 4298212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 4308212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom p = decompressPoint(enc, 0); 4318212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 4328212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom else 4338212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 4348212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom p = decompressPoint(enc, 1); 4358212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 4368212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom break; 4378212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom // uncompressed 4388212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom case 0x04: 4398212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom // hybrid 4408212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom case 0x06: 4418212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom case 0x07: 4428212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom byte[] xEnc = new byte[(encoded.length - 1) / 2]; 4438212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom byte[] yEnc = new byte[(encoded.length - 1) / 2]; 4448212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 4458212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom System.arraycopy(encoded, 1, xEnc, 0, xEnc.length); 4468212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom System.arraycopy(encoded, xEnc.length + 1, yEnc, 0, yEnc.length); 4478212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 4488212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom p = new ECPoint.F2m(this, 4498212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, 4508212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom new BigInteger(1, xEnc)), 4518212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, 4528212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom new BigInteger(1, yEnc)), false); 4538212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom break; 4548212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 4558212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom default: 4568212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom throw new RuntimeException("Invalid point encoding 0x" + Integer.toString(encoded[0], 16)); 4578212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 4588212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 4598212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return p; 4608212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 4618212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 4628212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public ECPoint getInfinity() 4638212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 4648212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return infinity; 4658212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 4668212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 4678212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 4688212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Returns true if this is a Koblitz curve (ABC curve). 4698212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @return true if this is a Koblitz curve (ABC curve), false otherwise 4708212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 4718212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public boolean isKoblitz() 4728212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 4738212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return ((n != null) && (h != null) && 4748212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ((a.toBigInteger().equals(ECConstants.ZERO)) || 4758212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom (a.toBigInteger().equals(ECConstants.ONE))) && 4768212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom (b.toBigInteger().equals(ECConstants.ONE))); 4778212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 4788212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 4798212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 4808212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Returns the parameter <code>μ</code> of the elliptic curve. 4818212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @return <code>μ</code> of the elliptic curve. 4828212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @throws IllegalArgumentException if the given ECCurve is not a 4838212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Koblitz curve. 4848212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 4858212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom synchronized byte getMu() 4868212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 4878212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (mu == 0) 4888212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 4898212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom mu = Tnaf.getMu(this); 4908212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 4918212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return mu; 4928212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 4938212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 4948212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 4958212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @return the auxiliary values <code>s<sub>0</sub></code> and 4968212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>s<sub>1</sub></code> used for partial modular reduction for 4978212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Koblitz curves. 4988212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 4998212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom synchronized BigInteger[] getSi() 5008212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5018212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (si == null) 5028212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5038212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom si = Tnaf.getSi(this); 5048212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 5058212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return si; 5068212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 5078212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 5088212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 5098212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2). 5108212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * 5118212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param xEnc 5128212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * The encoding of field element xp. 5138212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param ypBit 5148212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * ~yp, an indication bit for the decompression of yp. 5158212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @return the decompressed point. 5168212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 5178212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom private ECPoint decompressPoint( 5188212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom byte[] xEnc, 5198212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int ypBit) 5208212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5218212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement xp = new ECFieldElement.F2m( 5228212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.m, this.k1, this.k2, this.k3, new BigInteger(1, xEnc)); 5238212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement yp = null; 5248212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (xp.toBigInteger().equals(ECConstants.ZERO)) 5258212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5268212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom yp = (ECFieldElement.F2m)b; 5278212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom for (int i = 0; i < m - 1; i++) 5288212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5298212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom yp = yp.square(); 5308212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 5318212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 5328212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom else 5338212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5348212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement beta = xp.add(a).add( 5358212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom b.multiply(xp.square().invert())); 5368212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement z = solveQuadradicEquation(beta); 5378212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (z == null) 5388212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5398212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom throw new RuntimeException("Invalid point compression"); 5408212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 5418212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom int zBit = 0; 5428212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (z.toBigInteger().testBit(0)) 5438212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5448212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom zBit = 1; 5458212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 5468212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (zBit != ypBit) 5478212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5488212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom z = z.add(new ECFieldElement.F2m(this.m, this.k1, this.k2, 5498212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.k3, ECConstants.ONE)); 5508212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 5518212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom yp = xp.multiply(z); 5528212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 5538212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 5548212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return new ECPoint.F2m(this, xp, yp); 5558212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 5568212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 5578212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 5588212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Solves a quadratic equation <code>z<sup>2</sup> + z = beta</code>(X9.62 5598212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * D.1.6) The other solution is <code>z + 1</code>. 5608212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * 5618212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @param beta 5628212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * The value to solve the qradratic equation for. 5638212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @return the solution for <code>z<sup>2</sup> + z = beta</code> or 5648212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * <code>null</code> if no solution exists. 5658212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 5668212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom private ECFieldElement solveQuadradicEquation(ECFieldElement beta) 5678212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5688212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement zeroElement = new ECFieldElement.F2m( 5698212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.m, this.k1, this.k2, this.k3, ECConstants.ZERO); 5708212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 5718212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (beta.toBigInteger().equals(ECConstants.ZERO)) 5728212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5738212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return zeroElement; 5748212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 5758212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 5768212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement z = null; 5778212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement gamma = zeroElement; 5788212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 5798212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom Random rand = new Random(); 5808212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom do 5818212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5828212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement t = new ECFieldElement.F2m(this.m, this.k1, 5838212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom this.k2, this.k3, new BigInteger(m, rand)); 5848212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom z = zeroElement; 5858212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement w = beta; 5868212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom for (int i = 1; i <= m - 1; i++) 5878212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5888212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECFieldElement w2 = w.square(); 5898212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom z = z.square().add(w2.multiply(t)); 5908212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom w = w2.add(beta); 5918212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 5928212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (!w.toBigInteger().equals(ECConstants.ZERO)) 5938212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 5948212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return null; 5958212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 5968212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom gamma = z.square().add(z); 5978212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 5988212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom while (gamma.toBigInteger().equals(ECConstants.ZERO)); 5998212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 6008212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return z; 6018212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 6028212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 6038212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public boolean equals( 6048212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom Object anObject) 6058212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 6068212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (anObject == this) 6078212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 6088212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return true; 6098212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 6108212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 6118212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom if (!(anObject instanceof ECCurve.F2m)) 6128212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 6138212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return false; 6148212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 6158212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 6168212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom ECCurve.F2m other = (ECCurve.F2m)anObject; 6178212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 6188212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return (this.m == other.m) && (this.k1 == other.k1) 6198212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom && (this.k2 == other.k2) && (this.k3 == other.k3) 6208212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom && a.equals(other.a) && b.equals(other.b); 6218212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 6228212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 6238212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public int hashCode() 6248212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 6258212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return this.a.hashCode() ^ this.b.hashCode() ^ m ^ k1 ^ k2 ^ k3; 6268212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 6278212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 6288212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public int getM() 6298212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 6308212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return m; 6318212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 6328212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 6338212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom /** 6348212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * Return true if curve uses a Trinomial basis. 6358212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * 6368212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * @return true if curve Trinomial, false otherwise. 6378212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */ 6388212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public boolean isTrinomial() 6398212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 6408212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return k2 == 0 && k3 == 0; 6418212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 6428212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 6438212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public int getK1() 6448212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 6458212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return k1; 6468212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 6478212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 6488212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public int getK2() 6498212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 6508212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return k2; 6518212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 6528212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 6538212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public int getK3() 6548212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 6558212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return k3; 6568212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 6578212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 6588212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public BigInteger getN() 6598212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 6608212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return n; 6618212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 6628212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom 6638212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom public BigInteger getH() 6648212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom { 6658212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom return h; 6668212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 6678212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom } 6688212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom} 669