<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.0" />

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); } } }