X9Curve.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
1package org.bouncycastle.asn1.x9; 2 3import java.math.BigInteger; 4 5import org.bouncycastle.asn1.ASN1EncodableVector; 6import org.bouncycastle.asn1.ASN1Integer; 7import org.bouncycastle.asn1.ASN1Object; 8import org.bouncycastle.asn1.ASN1ObjectIdentifier; 9import org.bouncycastle.asn1.ASN1OctetString; 10import org.bouncycastle.asn1.ASN1Primitive; 11import org.bouncycastle.asn1.ASN1Sequence; 12import org.bouncycastle.asn1.DERBitString; 13import org.bouncycastle.asn1.DERSequence; 14import org.bouncycastle.math.ec.ECCurve; 15 16/** 17 * ASN.1 def for Elliptic-Curve Curve structure. See 18 * X9.62, for further details. 19 */ 20public class X9Curve 21 extends ASN1Object 22 implements X9ObjectIdentifiers 23{ 24 private ECCurve curve; 25 private byte[] seed; 26 private ASN1ObjectIdentifier fieldIdentifier = null; 27 28 public X9Curve( 29 ECCurve curve) 30 { 31 this.curve = curve; 32 this.seed = null; 33 setFieldIdentifier(); 34 } 35 36 public X9Curve( 37 ECCurve curve, 38 byte[] seed) 39 { 40 this.curve = curve; 41 this.seed = seed; 42 setFieldIdentifier(); 43 } 44 45 public X9Curve( 46 X9FieldID fieldID, 47 ASN1Sequence seq) 48 { 49 fieldIdentifier = fieldID.getIdentifier(); 50 if (fieldIdentifier.equals(prime_field)) 51 { 52 BigInteger p = ((ASN1Integer)fieldID.getParameters()).getValue(); 53 X9FieldElement x9A = new X9FieldElement(p, (ASN1OctetString)seq.getObjectAt(0)); 54 X9FieldElement x9B = new X9FieldElement(p, (ASN1OctetString)seq.getObjectAt(1)); 55 curve = new ECCurve.Fp(p, x9A.getValue().toBigInteger(), x9B.getValue().toBigInteger()); 56 } 57 else 58 { 59 if (fieldIdentifier.equals(characteristic_two_field)) 60 { 61 // Characteristic two field 62 ASN1Sequence parameters = ASN1Sequence.getInstance(fieldID.getParameters()); 63 int m = ((ASN1Integer)parameters.getObjectAt(0)).getValue(). 64 intValue(); 65 ASN1ObjectIdentifier representation 66 = (ASN1ObjectIdentifier)parameters.getObjectAt(1); 67 68 int k1 = 0; 69 int k2 = 0; 70 int k3 = 0; 71 if (representation.equals(tpBasis)) 72 { 73 // Trinomial basis representation 74 k1 = ((ASN1Integer)parameters.getObjectAt(2)).getValue(). 75 intValue(); 76 } 77 else 78 { 79 // Pentanomial basis representation 80 DERSequence pentanomial 81 = (DERSequence)parameters.getObjectAt(2); 82 k1 = ((ASN1Integer)pentanomial.getObjectAt(0)).getValue(). 83 intValue(); 84 k2 = ((ASN1Integer)pentanomial.getObjectAt(1)).getValue(). 85 intValue(); 86 k3 = ((ASN1Integer)pentanomial.getObjectAt(2)).getValue(). 87 intValue(); 88 } 89 X9FieldElement x9A = new X9FieldElement(m, k1, k2, k3, (ASN1OctetString)seq.getObjectAt(0)); 90 X9FieldElement x9B = new X9FieldElement(m, k1, k2, k3, (ASN1OctetString)seq.getObjectAt(1)); 91 // TODO Is it possible to get the order (n) and cofactor(h) too? 92 curve = new ECCurve.F2m(m, k1, k2, k3, x9A.getValue().toBigInteger(), x9B.getValue().toBigInteger()); 93 } 94 } 95 96 if (seq.size() == 3) 97 { 98 seed = ((DERBitString)seq.getObjectAt(2)).getBytes(); 99 } 100 } 101 102 private void setFieldIdentifier() 103 { 104 if (curve instanceof ECCurve.Fp) 105 { 106 fieldIdentifier = prime_field; 107 } 108 else if (curve instanceof ECCurve.F2m) 109 { 110 fieldIdentifier = characteristic_two_field; 111 } 112 else 113 { 114 throw new IllegalArgumentException("This type of ECCurve is not " 115 + "implemented"); 116 } 117 } 118 119 public ECCurve getCurve() 120 { 121 return curve; 122 } 123 124 public byte[] getSeed() 125 { 126 return seed; 127 } 128 129 /** 130 * Produce an object suitable for an ASN1OutputStream. 131 * <pre> 132 * Curve ::= SEQUENCE { 133 * a FieldElement, 134 * b FieldElement, 135 * seed BIT STRING OPTIONAL 136 * } 137 * </pre> 138 */ 139 public ASN1Primitive toASN1Primitive() 140 { 141 ASN1EncodableVector v = new ASN1EncodableVector(); 142 143 if (fieldIdentifier.equals(prime_field)) 144 { 145 v.add(new X9FieldElement(curve.getA()).toASN1Primitive()); 146 v.add(new X9FieldElement(curve.getB()).toASN1Primitive()); 147 } 148 else if (fieldIdentifier.equals(characteristic_two_field)) 149 { 150 v.add(new X9FieldElement(curve.getA()).toASN1Primitive()); 151 v.add(new X9FieldElement(curve.getB()).toASN1Primitive()); 152 } 153 154 if (seed != null) 155 { 156 v.add(new DERBitString(seed)); 157 } 158 159 return new DERSequence(v); 160 } 161} 162