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