121 lines
3.3 KiB
C#
121 lines
3.3 KiB
C#
using System;
|
|
using Org.BouncyCastle.Math;
|
|
using Org.BouncyCastle.Math.EC;
|
|
using Org.BouncyCastle.Utilities;
|
|
|
|
namespace Org.BouncyCastle.Asn1.X9;
|
|
|
|
public class X9Curve : Asn1Encodable
|
|
{
|
|
private readonly ECCurve curve;
|
|
|
|
private readonly byte[] seed;
|
|
|
|
private readonly DerObjectIdentifier fieldIdentifier;
|
|
|
|
public ECCurve Curve => curve;
|
|
|
|
public X9Curve(ECCurve curve)
|
|
: this(curve, null)
|
|
{
|
|
}
|
|
|
|
public X9Curve(ECCurve curve, byte[] seed)
|
|
{
|
|
if (curve == null)
|
|
{
|
|
throw new ArgumentNullException("curve");
|
|
}
|
|
this.curve = curve;
|
|
this.seed = Arrays.Clone(seed);
|
|
if (ECAlgorithms.IsFpCurve(curve))
|
|
{
|
|
fieldIdentifier = X9ObjectIdentifiers.PrimeField;
|
|
return;
|
|
}
|
|
if (ECAlgorithms.IsF2mCurve(curve))
|
|
{
|
|
fieldIdentifier = X9ObjectIdentifiers.CharacteristicTwoField;
|
|
return;
|
|
}
|
|
throw new ArgumentException("This type of ECCurve is not implemented");
|
|
}
|
|
|
|
[Obsolete("Use constructor including order/cofactor")]
|
|
public X9Curve(X9FieldID fieldID, Asn1Sequence seq)
|
|
: this(fieldID, null, null, seq)
|
|
{
|
|
}
|
|
|
|
public X9Curve(X9FieldID fieldID, BigInteger order, BigInteger cofactor, Asn1Sequence seq)
|
|
{
|
|
if (fieldID == null)
|
|
{
|
|
throw new ArgumentNullException("fieldID");
|
|
}
|
|
if (seq == null)
|
|
{
|
|
throw new ArgumentNullException("seq");
|
|
}
|
|
fieldIdentifier = fieldID.Identifier;
|
|
if (fieldIdentifier.Equals(X9ObjectIdentifiers.PrimeField))
|
|
{
|
|
BigInteger value = ((DerInteger)fieldID.Parameters).Value;
|
|
BigInteger a = new BigInteger(1, Asn1OctetString.GetInstance(seq[0]).GetOctets());
|
|
BigInteger b = new BigInteger(1, Asn1OctetString.GetInstance(seq[1]).GetOctets());
|
|
curve = new FpCurve(value, a, b, order, cofactor);
|
|
}
|
|
else
|
|
{
|
|
if (!fieldIdentifier.Equals(X9ObjectIdentifiers.CharacteristicTwoField))
|
|
{
|
|
throw new ArgumentException("This type of ECCurve is not implemented");
|
|
}
|
|
DerSequence derSequence = (DerSequence)fieldID.Parameters;
|
|
int intValue = ((DerInteger)derSequence[0]).Value.IntValue;
|
|
DerObjectIdentifier derObjectIdentifier = (DerObjectIdentifier)derSequence[1];
|
|
int num = 0;
|
|
int k = 0;
|
|
int k2 = 0;
|
|
if (derObjectIdentifier.Equals(X9ObjectIdentifiers.TPBasis))
|
|
{
|
|
num = ((DerInteger)derSequence[2]).Value.IntValue;
|
|
}
|
|
else
|
|
{
|
|
DerSequence derSequence2 = (DerSequence)derSequence[2];
|
|
num = ((DerInteger)derSequence2[0]).Value.IntValue;
|
|
k = ((DerInteger)derSequence2[1]).Value.IntValue;
|
|
k2 = ((DerInteger)derSequence2[2]).Value.IntValue;
|
|
}
|
|
BigInteger a2 = new BigInteger(1, Asn1OctetString.GetInstance(seq[0]).GetOctets());
|
|
BigInteger b2 = new BigInteger(1, Asn1OctetString.GetInstance(seq[1]).GetOctets());
|
|
curve = new F2mCurve(intValue, num, k, k2, a2, b2, order, cofactor);
|
|
}
|
|
if (seq.Count == 3)
|
|
{
|
|
seed = ((DerBitString)seq[2]).GetBytes();
|
|
}
|
|
}
|
|
|
|
public byte[] GetSeed()
|
|
{
|
|
return Arrays.Clone(seed);
|
|
}
|
|
|
|
public override Asn1Object ToAsn1Object()
|
|
{
|
|
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
|
if (fieldIdentifier.Equals(X9ObjectIdentifiers.PrimeField) || fieldIdentifier.Equals(X9ObjectIdentifiers.CharacteristicTwoField))
|
|
{
|
|
asn1EncodableVector.Add(new X9FieldElement(curve.A).ToAsn1Object());
|
|
asn1EncodableVector.Add(new X9FieldElement(curve.B).ToAsn1Object());
|
|
}
|
|
if (seed != null)
|
|
{
|
|
asn1EncodableVector.Add(new DerBitString(seed));
|
|
}
|
|
return new DerSequence(asn1EncodableVector);
|
|
}
|
|
}
|