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

SeedDerive

public sealed class SeedDerive
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Pqc.Crypto.Lms { public sealed class SeedDerive { private readonly byte[] m_I; private readonly byte[] m_masterSeed; private readonly IDigest m_digest; public int J { get; set; } public int Q { get; set; } [Obsolete("Use 'GetI' instead")] public byte[] I { get { return m_I; } } [Obsolete("Use 'GetMasterSeed' instead")] public byte[] MasterSeed { get { return m_masterSeed; } } public SeedDerive(byte[] I, byte[] masterSeed, IDigest digest) { m_I = I; m_masterSeed = masterSeed; m_digest = digest; } public byte[] GetI() { return Arrays.Clone(m_I); } public byte[] GetMasterSeed() { return Arrays.Clone(m_masterSeed); } public unsafe byte[] DeriveSeed(bool incJ, byte[] target, int offset) { if (target.Length - offset < m_digest.GetDigestSize()) throw new ArgumentException("target length is less than digest size.", "target"); int q = Q; int j = J; m_digest.BlockUpdate(I, 0, I.Length); Span<byte> span = new Span<byte>(stackalloc byte[7], 7); Pack.UInt32_To_BE((uint)q, span); Pack.UInt16_To_BE((ushort)j, span.Slice(4, span.Length - 4)); span[6] = byte.MaxValue; m_digest.BlockUpdate(span); m_digest.BlockUpdate(m_masterSeed, 0, m_masterSeed.Length); m_digest.DoFinal(target, offset); if (incJ) { int num = ++J; } return target; } } }