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

MLKemPrivateKeyParameters

using Org.BouncyCastle.Crypto.Kems.MLKem; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Crypto.Parameters { public sealed class MLKemPrivateKeyParameters : MLKemKeyParameters { public enum Format { SeedOnly, EncodingOnly, SeedAndEncoding } internal readonly byte[] m_s; internal readonly byte[] m_hpk; internal readonly byte[] m_nonce; internal readonly byte[] m_t; internal readonly byte[] m_rho; internal readonly byte[] m_seed; private readonly Format m_preferredFormat; public Format PreferredFormat => m_preferredFormat; internal byte[] Seed => m_seed; public static MLKemPrivateKeyParameters FromEncoding(MLKemParameters 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"); MLKemEngine engine = parameters.ParameterSet.GetEngine(null); int num = 0; byte[] s = Arrays.CopyOfRange(encoding, 0, engine.IndCpaSecretKeyBytes); num += engine.IndCpaSecretKeyBytes; byte[] t = Arrays.CopyOfRange(encoding, num, num + engine.IndCpaPublicKeyBytes - 32); num += engine.IndCpaPublicKeyBytes - 32; byte[] rho = Arrays.CopyOfRange(encoding, num, num + 32); num += 32; byte[] hpk = Arrays.CopyOfRange(encoding, num, num + 32); num += 32; byte[] nonce = Arrays.CopyOfRange(encoding, num, num + 32); byte[] seed = null; return new MLKemPrivateKeyParameters(parameters, s, hpk, nonce, t, rho, seed, Format.EncodingOnly); } public static MLKemPrivateKeyParameters FromSeed(MLKemParameters parameters, byte[] seed) { return FromSeed(parameters, seed, Format.SeedOnly); } public static MLKemPrivateKeyParameters FromSeed(MLKemParameters parameters, byte[] seed, Format preferredFormat) { if (parameters == null) throw new ArgumentNullException("parameters"); if (seed == null) throw new ArgumentNullException("seed"); if (seed.Length != parameters.ParameterSet.SeedLength) throw new ArgumentException("invalid seed", "seed"); Format preferredFormat2 = CheckFormat(preferredFormat, seed); MLKemEngine engine = parameters.ParameterSet.GetEngine(null); byte[] d = Arrays.CopyOfRange(seed, 0, 32); byte[] z = Arrays.CopyOfRange(seed, 32, seed.Length); engine.GenerateKemKeyPairInternal(d, z, out byte[] t, out byte[] rho, out byte[] s, out byte[] hpk, out byte[] nonce, out byte[] seed2); return new MLKemPrivateKeyParameters(parameters, s, hpk, nonce, t, rho, seed2, preferredFormat2); } internal MLKemPrivateKeyParameters(MLKemParameters parameters, byte[] s, byte[] hpk, byte[] nonce, byte[] t, byte[] rho, byte[] seed, Format preferredFormat) : base(true, parameters) { m_s = s; m_hpk = hpk; m_nonce = nonce; m_t = t; m_rho = rho; m_seed = seed; m_preferredFormat = preferredFormat; } public byte[] GetEncoded() { return Arrays.ConcatenateAll(m_s, m_t, m_rho, m_hpk, m_nonce); } public MLKemPublicKeyParameters GetPublicKey() { return new MLKemPublicKeyParameters(base.Parameters, m_t, m_rho); } public byte[] GetPublicKeyEncoded() { return Arrays.Concatenate(m_t, m_rho); } public byte[] GetSeed() { return Arrays.Clone(m_seed); } public MLKemPrivateKeyParameters WithPreferredFormat(Format preferredFormat) { if (m_preferredFormat == preferredFormat) return this; return new MLKemPrivateKeyParameters(base.Parameters, m_seed, m_hpk, m_nonce, m_t, m_rho, m_seed, CheckFormat(preferredFormat, m_seed)); } private static Format CheckFormat(Format preferredFormat, byte[] seed) { switch (preferredFormat) { case Format.SeedOnly: case Format.SeedAndEncoding: if (seed == null) throw new InvalidOperationException("no seed available"); break; default: throw new ArgumentException("invalid format", "preferredFormat"); case Format.EncodingOnly: break; } return preferredFormat; } } }