001package org.apache.commons.ssl.org.bouncycastle.asn1.ua; 002 003import java.math.BigInteger; 004 005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector; 006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer; 007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object; 008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1OctetString; 009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive; 010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence; 011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject; 012import org.apache.commons.ssl.org.bouncycastle.asn1.DEROctetString; 013import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence; 014import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject; 015import org.bouncycastle.crypto.params.ECDomainParameters; 016import org.bouncycastle.math.ec.ECAlgorithms; 017import org.bouncycastle.math.ec.ECCurve; 018import org.bouncycastle.math.field.PolynomialExtensionField; 019import org.bouncycastle.util.Arrays; 020 021public class DSTU4145ECBinary 022 extends ASN1Object 023{ 024 BigInteger version = BigInteger.valueOf(0); 025 026 DSTU4145BinaryField f; 027 ASN1Integer a; 028 ASN1OctetString b; 029 ASN1Integer n; 030 ASN1OctetString bp; 031 032 public DSTU4145ECBinary(ECDomainParameters params) 033 { 034 ECCurve curve = params.getCurve(); 035 if (!ECAlgorithms.isF2mCurve(curve)) 036 { 037 throw new IllegalArgumentException("only binary domain is possible"); 038 } 039 040 // We always use big-endian in parameter encoding 041 042 PolynomialExtensionField field = (PolynomialExtensionField)curve.getField(); 043 int[] exponents = field.getMinimalPolynomial().getExponentsPresent(); 044 if (exponents.length == 3) 045 { 046 f = new DSTU4145BinaryField(exponents[2], exponents[1]); 047 } 048 else if (exponents.length == 5) 049 { 050 f = new DSTU4145BinaryField(exponents[4], exponents[1], exponents[2], exponents[3]); 051 } 052 053 a = new ASN1Integer(curve.getA().toBigInteger()); 054 b = new DEROctetString(curve.getB().getEncoded()); 055 n = new ASN1Integer(params.getN()); 056 bp = new DEROctetString(DSTU4145PointEncoder.encodePoint(params.getG())); 057 } 058 059 private DSTU4145ECBinary(ASN1Sequence seq) 060 { 061 int index = 0; 062 063 if (seq.getObjectAt(index) instanceof ASN1TaggedObject) 064 { 065 ASN1TaggedObject taggedVersion = (ASN1TaggedObject)seq.getObjectAt(index); 066 if (taggedVersion.isExplicit() && 0 == taggedVersion.getTagNo()) 067 { 068 version = ASN1Integer.getInstance(taggedVersion.getLoadedObject()).getValue(); 069 index++; 070 } 071 else 072 { 073 throw new IllegalArgumentException("object parse error"); 074 } 075 } 076 f = DSTU4145BinaryField.getInstance(seq.getObjectAt(index)); 077 index++; 078 a = ASN1Integer.getInstance(seq.getObjectAt(index)); 079 index++; 080 b = ASN1OctetString.getInstance(seq.getObjectAt(index)); 081 index++; 082 n = ASN1Integer.getInstance(seq.getObjectAt(index)); 083 index++; 084 bp = ASN1OctetString.getInstance(seq.getObjectAt(index)); 085 } 086 087 public static DSTU4145ECBinary getInstance(Object obj) 088 { 089 if (obj instanceof DSTU4145ECBinary) 090 { 091 return (DSTU4145ECBinary)obj; 092 } 093 094 if (obj != null) 095 { 096 return new DSTU4145ECBinary(ASN1Sequence.getInstance(obj)); 097 } 098 099 return null; 100 } 101 102 public DSTU4145BinaryField getField() 103 { 104 return f; 105 } 106 107 public BigInteger getA() 108 { 109 return a.getValue(); 110 } 111 112 public byte[] getB() 113 { 114 return Arrays.clone(b.getOctets()); 115 } 116 117 public BigInteger getN() 118 { 119 return n.getValue(); 120 } 121 122 public byte[] getG() 123 { 124 return Arrays.clone(bp.getOctets()); 125 } 126 127 /** 128 * ECBinary ::= SEQUENCE { 129 * version [0] EXPLICIT INTEGER DEFAULT 0, 130 * f BinaryField, 131 * a INTEGER (0..1), 132 * b OCTET STRING, 133 * n INTEGER, 134 * bp OCTET STRING} 135 */ 136 public ASN1Primitive toASN1Primitive() 137 { 138 139 ASN1EncodableVector v = new ASN1EncodableVector(); 140 141 if (0 != version.compareTo(BigInteger.valueOf(0))) 142 { 143 v.add(new DERTaggedObject(true, 0, new ASN1Integer(version))); 144 } 145 v.add(f); 146 v.add(a); 147 v.add(b); 148 v.add(n); 149 v.add(bp); 150 151 return new DERSequence(v); 152 } 153 154}