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

SlhDsaPrivateKeyParameters

using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Crypto.Parameters { public sealed class SlhDsaPrivateKeyParameters : SlhDsaKeyParameters { private readonly SK m_sk; private readonly PK m_pk; internal PK PK => m_pk; internal SK SK => m_sk; public static SlhDsaPrivateKeyParameters FromEncoding(SlhDsaParameters parameters, byte[] encoding) { if (parameters == null) throw new ArgumentNullException("parameters"); if (encoding == null) throw new ArgumentNullException("encoding"); if (encoding.Length != parameters.ParameterSet.PrivateKeyLength) throw new ArgumentException("invalid encoding", "encoding"); int n = parameters.ParameterSet.N; SK sk = new SK(Arrays.CopyOfRange(encoding, 0, n), Arrays.CopyOfRange(encoding, n, 2 * n)); PK pk = new PK(Arrays.CopyOfRange(encoding, 2 * n, 3 * n), Arrays.CopyOfRange(encoding, 3 * n, 4 * n)); return new SlhDsaPrivateKeyParameters(parameters, sk, pk); } internal SlhDsaPrivateKeyParameters(SlhDsaParameters parameters, SK sk, PK pk) : base(true, parameters) { m_sk = sk; m_pk = pk; } public byte[] GetEncoded() { return Arrays.ConcatenateAll(m_sk.seed, m_sk.prf, m_pk.seed, m_pk.root); } public SlhDsaPublicKeyParameters GetPublicKey() { return new SlhDsaPublicKeyParameters(base.Parameters, m_pk); } public byte[] GetPublicKeyEncoded() { return Arrays.Concatenate(m_pk.seed, m_pk.root); } internal byte[] SignInternal(byte[] optRand, byte[] msg, int msgOff, int msgLen) { SphincsPlusEngine engine = base.Parameters.ParameterSet.GetEngine(); if (optRand == null) optRand = Arrays.CopyOfRange(PK.seed, 0, engine.N); else if (optRand.Length != engine.N) { throw new ArgumentOutOfRangeException("optRand"); } engine.Init(PK.seed); Fors fors = new Fors(engine); byte[] array = engine.PRF_msg(SK.prf, optRand, msg, msgOff, msgLen); IndexedDigest indexedDigest = engine.H_msg(array, PK.seed, PK.root, msg, msgOff, msgLen); 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[] array2 = fors.Sign(digest, SK.seed, PK.seed, adrs, false); adrs = new Adrs(); adrs.SetTypeAndClear(3); adrs.SetTreeAddress(idx_tree); adrs.SetKeyPairAddress(idx_leaf); byte[] m = fors.PKFromSig(array2, digest, PK.seed, adrs, false); new Adrs().SetTypeAndClear(2); HT hT = new HT(engine, SK.seed, PK.seed); byte[] array3 = new byte[engine.SignatureLength]; int pos = 0; Array.Copy(array, 0, array3, 0, array.Length); pos += array.Length; for (int i = 0; i < array2.Length; i++) { array2[i].CopyToSignature(array3, ref pos); } hT.Sign(m, idx_tree, idx_leaf, array3, ref pos); return array3; } } }