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

SphincsPlusSigner

public sealed class SphincsPlusSigner : IMessageSigner
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; using System; namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus { [Obsolete("Use SLH-DSA instead")] public sealed class SphincsPlusSigner : IMessageSigner { private SphincsPlusPrivateKeyParameters m_privKey; private SphincsPlusPublicKeyParameters m_pubKey; private SecureRandom m_random; public void Init(bool forSigning, ICipherParameters param) { if (forSigning) { m_pubKey = null; ParametersWithRandom parametersWithRandom = param as ParametersWithRandom; if (parametersWithRandom != null) { m_privKey = (SphincsPlusPrivateKeyParameters)parametersWithRandom.Parameters; m_random = parametersWithRandom.Random; } else { m_privKey = (SphincsPlusPrivateKeyParameters)param; m_random = null; } } else { m_pubKey = (SphincsPlusPublicKeyParameters)param; m_privKey = null; m_random = null; } } public byte[] GenerateSignature(byte[] message) { SphincsPlusEngine engine = m_privKey.Parameters.GetEngine(); engine.Init(m_privKey.GetPublicSeed()); byte[] array = new byte[engine.N]; if (m_random != null) m_random.NextBytes(array); else Array.Copy(m_privKey.m_pk.seed, 0, array, 0, array.Length); Fors fors = new Fors(engine); byte[] array2 = engine.PRF_msg(m_privKey.m_sk.prf, array, message, 0, message.Length); IndexedDigest indexedDigest = engine.H_msg(array2, m_privKey.m_pk.seed, m_privKey.m_pk.root, message, 0, message.Length); byte[] digest = indexedDigest.digest; ulong idx_tree = indexedDigest.idx_tree; uint idx_leaf = indexedDigest.idx_leaf; Adrs adrs = new Adrs(); adrs.SetTypeAndClear(3); adrs.SetTreeAddress(idx_tree); adrs.SetKeyPairAddress(idx_leaf); SIG_FORS[] array3 = fors.Sign(digest, m_privKey.m_sk.seed, m_privKey.m_pk.seed, adrs, true); adrs = new Adrs(); adrs.SetTypeAndClear(3); adrs.SetTreeAddress(idx_tree); adrs.SetKeyPairAddress(idx_leaf); byte[] m = fors.PKFromSig(array3, digest, m_privKey.m_pk.seed, adrs, true); new Adrs().SetTypeAndClear(2); HT hT = new HT(engine, m_privKey.GetSeed(), m_privKey.GetPublicSeed()); byte[] array4 = new byte[engine.SignatureLength]; int pos = 0; Array.Copy(array2, 0, array4, 0, array2.Length); pos += array2.Length; for (int i = 0; i < array3.Length; i++) { array3[i].CopyToSignature(array4, ref pos); } hT.Sign(m, idx_tree, idx_leaf, array4, ref pos); return array4; } public bool VerifySignature(byte[] message, byte[] signature) { SphincsPlusEngine engine = m_pubKey.Parameters.GetEngine(); if (engine.SignatureLength != signature.Length) return false; engine.Init(m_pubKey.GetSeed()); 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, m_pubKey.GetSeed(), m_pubKey.GetRoot(), message, 0, message.Length); 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, m_pubKey.GetSeed(), adrs, true); adrs.SetTypeAndClear(2); adrs.SetLayerAddress(0); adrs.SetTreeAddress(idx_tree); adrs.SetKeyPairAddress(idx_leaf); return new HT(engine, null, m_pubKey.GetSeed()).Verify(m, sIG_HT, m_pubKey.GetSeed(), idx_tree, idx_leaf, m_pubKey.GetRoot()); } } }