using GostCryptography.Properties; using System; namespace GostCryptography.Asn1.Ber { [Serializable] public class Asn1BigInteger : Asn1Type { private const int MaxBigIntLen = 0x186a0; public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BigIntegerTypeCode); public static readonly BigInteger Zero = new BigInteger(); private BigInteger _value; public Asn1BigInteger() { _value = new BigInteger(); } public Asn1BigInteger(BigInteger value) { _value = value; } public Asn1BigInteger(string value) { _value = new BigInteger(value); } public Asn1BigInteger(string value, int radix) { _value = new BigInteger(value, radix); } public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) { var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength; _value = DecodeValue(buffer, length); buffer.TypeCode = 2; } public BigInteger DecodeValue(Asn1DecodeBuffer buffer, int length) { var ivalue = new byte[length]; if (length > MaxBigIntLen) { throw ExceptionUtility.CryptographicException(Resources.Asn1TooBigIntegerValue, length); } for (var i = 0; i < length; ++i) { ivalue[i] = (byte)buffer.ReadByte(); } var integer = new BigInteger(); if (length > 0) { integer.SetData(ivalue); } return integer; } public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) { var len = EncodeValue(buffer, _value, true); if (explicitTagging) { len += buffer.EncodeTagAndLength(Tag, len); } return len; } public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) { if (explicitTagging) { outs.EncodeTag(Tag); } var buffer = new Asn1BerEncodeBuffer(); var len = EncodeValue(buffer, _value, true); outs.EncodeLength(len); outs.Write(buffer.MsgCopy); } private static int EncodeValue(Asn1EncodeBuffer buffer, BigInteger ivalue, bool doCopy) { var data = ivalue.GetData(); var length = data.Length; for (var i = length - 1; i >= 0; --i) { if (doCopy) { buffer.Copy(data[i]); } } return length; } public virtual bool Equals(long value) { return _value.Equals(value); } public override bool Equals(object value) { var integer = value as Asn1BigInteger; if (integer == null) { return false; } return _value.Equals(integer._value); } public override int GetHashCode() { return _value.GetHashCode(); } public override string ToString() { return _value.ToString(10); } } }