SlhDsaPublicKeyParameters
using Org.BouncyCastle.Pqc.Crypto.SphincsPlus;
using Org.BouncyCastle.Utilities;
using System;
namespace Org.BouncyCastle.Crypto.Parameters
{
public sealed class SlhDsaPublicKeyParameters : SlhDsaKeyParameters
{
private readonly PK m_pk;
internal PK PK => m_pk;
public static SlhDsaPublicKeyParameters FromEncoding(SlhDsaParameters parameters, byte[] encoding)
{
if (parameters == null)
throw new ArgumentNullException("parameters");
if (encoding == null)
throw new ArgumentNullException("encoding");
if (encoding.Length != parameters.ParameterSet.PublicKeyLength)
throw new ArgumentException("invalid encoding", "encoding");
int n = parameters.ParameterSet.N;
PK pk = new PK(Arrays.CopyOfRange(encoding, 0, n), Arrays.CopyOfRange(encoding, n, 2 * n));
return new SlhDsaPublicKeyParameters(parameters, pk);
}
internal SlhDsaPublicKeyParameters(SlhDsaParameters parameters, PK pk)
: base(false, parameters)
{
m_pk = pk;
}
public byte[] GetEncoded()
{
return Arrays.Concatenate(m_pk.seed, m_pk.root);
}
internal bool VerifyInternal(byte[] msg, int msgOff, int msgLen, byte[] signature)
{
SphincsPlusEngine engine = base.Parameters.ParameterSet.GetEngine();
if (engine.SignatureLength != signature.Length)
return false;
engine.Init(PK.seed);
Adrs adrs = new Adrs();
SIG sIG = new SIG(engine.N, engine.K, engine.A, engine.D, engine.H_PRIME, engine.WOTS_LEN, signature);
byte[] r = sIG.R;
SIG_FORS[] sIG_FORS = sIG.SIG_FORS;
SIG_XMSS[] sIG_HT = sIG.SIG_HT;
IndexedDigest indexedDigest = engine.H_msg(r, PK.seed, PK.root, msg, msgOff, msgLen);
byte[] digest = indexedDigest.digest;
ulong idx_tree = indexedDigest.idx_tree;
uint idx_leaf = indexedDigest.idx_leaf;
adrs.SetTypeAndClear(3);
adrs.SetLayerAddress(0);
adrs.SetTreeAddress(idx_tree);
adrs.SetKeyPairAddress(idx_leaf);
byte[] m = new Fors(engine).PKFromSig(sIG_FORS, digest, PK.seed, adrs, false);
adrs.SetTypeAndClear(2);
adrs.SetLayerAddress(0);
adrs.SetTreeAddress(idx_tree);
adrs.SetKeyPairAddress(idx_leaf);
return new HT(engine, null, PK.seed).Verify(m, sIG_HT, PK.seed, idx_tree, idx_leaf, PK.root);
}
}
}