HssPublicKeyParameters
using Org.BouncyCastle.Utilities.IO;
using System;
using System.IO;
namespace Org.BouncyCastle.Pqc.Crypto.Lms
{
    public sealed class HssPublicKeyParameters : LmsKeyParameters, ILmsContextBasedVerifier
    {
        private readonly int m_level;
        private readonly LmsPublicKeyParameters m_lmsPublicKey;
        [Obsolete("Use 'Level' instead")]
        public int L {
            get {
                return m_level;
            }
        }
        public int Level => m_level;
        public LmsPublicKeyParameters LmsPublicKey => m_lmsPublicKey;
        public HssPublicKeyParameters(int l, LmsPublicKeyParameters lmsPublicKey)
            : base(false)
        {
            m_level = l;
            if (lmsPublicKey == null)
                throw new ArgumentNullException("lmsPublicKey");
            m_lmsPublicKey = lmsPublicKey;
        }
        public static HssPublicKeyParameters GetInstance(object src)
        {
            HssPublicKeyParameters hssPublicKeyParameters = src as HssPublicKeyParameters;
            if (hssPublicKeyParameters != null)
                return hssPublicKeyParameters;
            BinaryReader binaryReader = src as BinaryReader;
            if (binaryReader != null)
                return Parse(binaryReader);
            Stream stream = src as Stream;
            if (stream != null)
                return BinaryReaders.Parse(Parse, stream, true);
            byte[] array = src as byte[];
            if (array != null)
                return BinaryReaders.Parse(Parse, new MemoryStream(array, false), false);
            throw new ArgumentException($"""{src}");
        }
        internal static HssPublicKeyParameters Parse(BinaryReader binaryReader)
        {
            int l = BinaryReaders.ReadInt32BigEndian(binaryReader);
            LmsPublicKeyParameters lmsPublicKey = LmsPublicKeyParameters.Parse(binaryReader);
            return new HssPublicKeyParameters(l, lmsPublicKey);
        }
        public override bool Equals(object o)
        {
            if (this == o)
                return true;
            HssPublicKeyParameters hssPublicKeyParameters = o as HssPublicKeyParameters;
            if (hssPublicKeyParameters != null && m_level == hssPublicKeyParameters.m_level)
                return m_lmsPublicKey.Equals(hssPublicKeyParameters.m_lmsPublicKey);
            return false;
        }
        public override int GetHashCode()
        {
            int level = m_level;
            return 31 * level + m_lmsPublicKey.GetHashCode();
        }
        public override byte[] GetEncoded()
        {
            return Composer.Compose().U32Str(m_level).Bytes(m_lmsPublicKey.GetEncoded())
                .Build();
        }
        public LmsContext GenerateLmsContext(byte[] sigEnc)
        {
            HssSignature instance;
            try {
                instance = HssSignature.GetInstance(sigEnc, Level);
            } catch (IOException ex) {
                throw new Exception("cannot parse signature: " + ex.Message);
            }
            LmsSignedPubKey[] signedPubKeys = instance.SignedPubKeys;
            LmsPublicKeyParameters lmsPublicKeyParameters = LmsPublicKey;
            if (signedPubKeys.Length != 0)
                lmsPublicKeyParameters = signedPubKeys[signedPubKeys.Length - 1].PublicKey;
            return lmsPublicKeyParameters.GenerateOtsContext(instance.Signature).WithSignedPublicKeys(signedPubKeys);
        }
        public bool Verify(LmsContext context)
        {
            LmsSignedPubKey[] signedPubKeys = context.SignedPubKeys;
            if (signedPubKeys.Length != Level - 1)
                return false;
            LmsPublicKeyParameters lmsPublicKeyParameters = LmsPublicKey;
            bool flag = false;
            for (int i = 0; i < signedPubKeys.Length; i++) {
                LmsSignature signature = signedPubKeys[i].Signature;
                LmsPublicKeyParameters publicKey = signedPubKeys[i].PublicKey;
                if (!Lms.VerifySignature(lmsPublicKeyParameters, signature, publicKey.ToByteArray()))
                    flag = true;
                lmsPublicKeyParameters = publicKey;
            }
            return !flag & lmsPublicKeyParameters.Verify(context);
        }
    }
}