LmsPublicKeyParameters
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.IO;
using System;
using System.IO;
namespace Org.BouncyCastle.Pqc.Crypto.Lms
{
public sealed class LmsPublicKeyParameters : LmsKeyParameters, ILmsContextBasedVerifier
{
private LMSigParameters parameterSet;
private LMOtsParameters lmOtsType;
private byte[] I;
private byte[] T1;
public LmsPublicKeyParameters(LMSigParameters parameterSet, LMOtsParameters lmOtsType, byte[] T1, byte[] I)
: base(false)
{
this.parameterSet = parameterSet;
this.lmOtsType = lmOtsType;
this.I = Arrays.Clone(I);
this.T1 = Arrays.Clone(T1);
}
public static LmsPublicKeyParameters GetInstance(object src)
{
LmsPublicKeyParameters lmsPublicKeyParameters = src as LmsPublicKeyParameters;
if (lmsPublicKeyParameters != null)
return lmsPublicKeyParameters;
BinaryReader binaryReader = src as BinaryReader;
if (binaryReader != null)
return Parse(binaryReader);
Stream stream = src as Stream;
if (stream != null)
return Parse(stream);
byte[] array = src as byte[];
if (array != null)
return Parse(array);
throw new ArgumentException($"""{src}");
}
internal static LmsPublicKeyParameters Parse(BinaryReader binaryReader)
{
LMSigParameters lMSigParameters = LMSigParameters.ParseByID(binaryReader);
LMOtsParameters lMOtsParameters = LMOtsParameters.ParseByID(binaryReader);
byte[] i = BinaryReaders.ReadBytesFully(binaryReader, 16);
byte[] t = BinaryReaders.ReadBytesFully(binaryReader, lMSigParameters.M);
return new LmsPublicKeyParameters(lMSigParameters, lMOtsParameters, t, i);
}
internal static LmsPublicKeyParameters Parse(Stream stream)
{
return BinaryReaders.Parse(Parse, stream, true);
}
internal static LmsPublicKeyParameters Parse(byte[] buf)
{
return BinaryReaders.Parse(Parse, new MemoryStream(buf, false), false);
}
internal static LmsPublicKeyParameters Parse(byte[] buf, int off, int len)
{
return BinaryReaders.Parse(Parse, new MemoryStream(buf, off, len, false), false);
}
public override byte[] GetEncoded()
{
return ToByteArray();
}
public LMSigParameters GetSigParameters()
{
return parameterSet;
}
public LMOtsParameters GetOtsParameters()
{
return lmOtsType;
}
public LmsParameters GetLmsParameters()
{
return new LmsParameters(GetSigParameters(), GetOtsParameters());
}
public byte[] GetT1()
{
return Arrays.Clone(T1);
}
internal bool MatchesT1(byte[] sig)
{
return Arrays.FixedTimeEquals(T1, sig);
}
public byte[] GetI()
{
return Arrays.Clone(I);
}
internal byte[] RefI()
{
return I;
}
public override bool Equals(object o)
{
if (this == o)
return true;
LmsPublicKeyParameters lmsPublicKeyParameters = o as LmsPublicKeyParameters;
if (lmsPublicKeyParameters != null && parameterSet.Equals(lmsPublicKeyParameters.parameterSet) && lmOtsType.Equals(lmsPublicKeyParameters.lmOtsType) && Arrays.AreEqual(I, lmsPublicKeyParameters.I))
return Arrays.AreEqual(T1, lmsPublicKeyParameters.T1);
return false;
}
public override int GetHashCode()
{
int hashCode = parameterSet.GetHashCode();
hashCode = 31 * hashCode + lmOtsType.GetHashCode();
hashCode = 31 * hashCode + Arrays.GetHashCode(I);
return 31 * hashCode + Arrays.GetHashCode(T1);
}
internal byte[] ToByteArray()
{
return Composer.Compose().U32Str(parameterSet.ID).U32Str(lmOtsType.ID)
.Bytes(I)
.Bytes(T1)
.Build();
}
public LmsContext GenerateLmsContext(byte[] signature)
{
try {
return GenerateOtsContext(LmsSignature.GetInstance(signature));
} catch (IOException ex) {
throw new IOException("cannot parse signature: " + ex.Message);
}
}
internal LmsContext GenerateOtsContext(LmsSignature S)
{
int iD = GetOtsParameters().ID;
if (S.OtsSignature.ParamType.ID != iD)
throw new ArgumentException("ots type from lsm signature does not match ots signature type from embedded ots signature");
return new LMOtsPublicKey(LMOtsParameters.GetParametersByID(iD), I, S.Q, null).CreateOtsContext(S);
}
public bool Verify(LmsContext context)
{
return Lms.VerifySignature(this, context);
}
}
}