18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpackage org.bouncycastle.asn1.x9; 20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport java.math.BigInteger; 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1EncodableVector; 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1Integer; 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1Object; 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1ObjectIdentifier; 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1OctetString; 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1Primitive; 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1Sequence; 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.DERBitString; 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.DERSequence; 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.math.ec.ECCurve; 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/** 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ASN.1 def for Elliptic-Curve Curve structure. See 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * X9.62, for further details. 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic class X9Curve 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project extends ASN1Object 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project implements X9ObjectIdentifiers 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project private ECCurve curve; 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project private byte[] seed; 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project private ASN1ObjectIdentifier fieldIdentifier = null; 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project public X9Curve( 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ECCurve curve) 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project this.curve = curve; 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project this.seed = null; 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setFieldIdentifier(); 34635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project public X9Curve( 37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ECCurve curve, 38635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project byte[] seed) 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project this.curve = curve; 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project this.seed = seed; 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setFieldIdentifier(); 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 44563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project public X9Curve( 46cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block X9FieldID fieldID, 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASN1Sequence seq) 48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project fieldIdentifier = fieldID.getIdentifier(); 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fieldIdentifier.equals(prime_field)) 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 5281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch BigInteger p = ((ASN1Integer)fieldID.getParameters()).getValue(); 53635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project X9FieldElement x9A = new X9FieldElement(p, (ASN1OctetString)seq.getObjectAt(0)); 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project X9FieldElement x9B = new X9FieldElement(p, (ASN1OctetString)seq.getObjectAt(1)); 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project curve = new ECCurve.Fp(p, x9A.getValue().toBigInteger(), x9B.getValue().toBigInteger()); 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 58563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark { 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fieldIdentifier.equals(characteristic_two_field)) 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Characteristic two field 62a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASN1Sequence parameters = ASN1Sequence.getInstance(fieldID.getParameters()); 63563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark int m = ((ASN1Integer)parameters.getObjectAt(0)).getValue(). 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project intValue(); 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASN1ObjectIdentifier representation 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project = (ASN1ObjectIdentifier)parameters.getObjectAt(1); 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int k1 = 0; 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int k2 = 0; 7081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch int k3 = 0; 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (representation.equals(tpBasis)) 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Trinomial basis representation 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project k1 = ((ASN1Integer)parameters.getObjectAt(2)).getValue(). 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project intValue(); 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Pentanomial basis representation 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project DERSequence pentanomial 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project = (DERSequence)parameters.getObjectAt(2); 82635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project k1 = ((ASN1Integer)pentanomial.getObjectAt(0)).getValue(). 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project intValue(); 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project k2 = ((ASN1Integer)pentanomial.getObjectAt(1)).getValue(). 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project intValue(); 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project k3 = ((ASN1Integer)pentanomial.getObjectAt(2)).getValue(). 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project intValue(); 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project X9FieldElement x9A = new X9FieldElement(m, k1, k2, k3, (ASN1OctetString)seq.getObjectAt(0)); 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project X9FieldElement x9B = new X9FieldElement(m, k1, k2, k3, (ASN1OctetString)seq.getObjectAt(1)); 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // TODO Is it possible to get the order (n) and cofactor(h) too? 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project curve = new ECCurve.F2m(m, k1, k2, k3, x9A.getValue().toBigInteger(), x9B.getValue().toBigInteger()); 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (seq.size() == 3) 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project seed = ((DERBitString)seq.getObjectAt(2)).getBytes(); 990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch private void setFieldIdentifier() 1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (curve instanceof ECCurve.Fp) 1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch fieldIdentifier = prime_field; 1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch else if (curve instanceof ECCurve.F2m) 1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch fieldIdentifier = characteristic_two_field; 1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project throw new IllegalArgumentException("This type of ECCurve is not " 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project + "implemented"); 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project public ECCurve getCurve() 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return curve; 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project public byte[] getSeed() 125635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project { 126635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return seed; 127635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /** 130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Produce an object suitable for an ASN1OutputStream. 131635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * <pre> 1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Curve ::= SEQUENCE { 1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * a FieldElement, 134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * b FieldElement, 135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * seed BIT STRING OPTIONAL 136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * } 137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * </pre> 138635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */ 139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project public ASN1Primitive toASN1Primitive() 140635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project { 141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASN1EncodableVector v = new ASN1EncodableVector(); 142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fieldIdentifier.equals(prime_field)) 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project v.add(new X9FieldElement(curve.getA()).toASN1Primitive()); 146643ca7872b450ea4efacab6188849e5aac2ba161Steve Block v.add(new X9FieldElement(curve.getB()).toASN1Primitive()); 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (fieldIdentifier.equals(characteristic_two_field)) 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project v.add(new X9FieldElement(curve.getA()).toASN1Primitive()); 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project v.add(new X9FieldElement(curve.getB()).toASN1Primitive()); 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (seed != null) 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project v.add(new DERBitString(seed)); 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 158643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 159635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return new DERSequence(v); 160635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 161635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project