MLDsaPrivateKeyParameters
using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium;
using Org.BouncyCastle.Utilities;
using System;
namespace Org.BouncyCastle.Crypto.Parameters
{
public sealed class MLDsaPrivateKeyParameters : MLDsaKeyParameters
{
public enum Format
{
SeedOnly,
EncodingOnly,
SeedAndEncoding
}
internal readonly byte[] m_rho;
internal readonly byte[] m_k;
internal readonly byte[] m_tr;
internal readonly byte[] m_s1;
internal readonly byte[] m_s2;
internal readonly byte[] m_t0;
internal readonly byte[] m_t1;
internal readonly byte[] m_seed;
private readonly Format m_preferredFormat;
public Format PreferredFormat => m_preferredFormat;
internal byte[] Seed => m_seed;
public static MLDsaPrivateKeyParameters FromEncoding(MLDsaParameters 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");
DilithiumEngine engine = parameters.ParameterSet.GetEngine(null);
int num = 0;
byte[] rho = Arrays.CopyOfRange(encoding, 0, 32);
num += 32;
byte[] k = Arrays.CopyOfRange(encoding, num, num + 32);
num += 32;
byte[] tr = Arrays.CopyOfRange(encoding, num, num + 64);
num += 64;
int num2 = engine.L * engine.PolyEtaPackedBytes;
byte[] array = Arrays.CopyOfRange(encoding, num, num + num2);
num += num2;
num2 = engine.K * engine.PolyEtaPackedBytes;
byte[] array2 = Arrays.CopyOfRange(encoding, num, num + num2);
num += num2;
num2 = engine.K * 416;
byte[] array3 = Arrays.CopyOfRange(encoding, num, num + num2);
byte[] t = engine.DeriveT1(rho, array, array2, array3);
byte[] seed = null;
return new MLDsaPrivateKeyParameters(parameters, rho, k, tr, array, array2, array3, t, seed, Format.EncodingOnly);
}
public static MLDsaPrivateKeyParameters FromSeed(MLDsaParameters parameters, byte[] seed)
{
return FromSeed(parameters, seed, Format.SeedOnly);
}
public static MLDsaPrivateKeyParameters FromSeed(MLDsaParameters 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);
parameters.ParameterSet.GetEngine(null).GenerateKeyPairInternal(seed, false, out byte[] rho, out byte[] k, out byte[] tr, out byte[] s1_, out byte[] s2_, out byte[] t0_, out byte[] encT);
return new MLDsaPrivateKeyParameters(parameters, rho, k, tr, s1_, s2_, t0_, encT, seed, preferredFormat2);
}
internal MLDsaPrivateKeyParameters(MLDsaParameters parameters, byte[] rho, byte[] k, byte[] tr, byte[] s1, byte[] s2, byte[] t0, byte[] t1, byte[] seed, Format preferredFormat)
: base(true, parameters)
{
m_rho = rho;
m_k = k;
m_tr = tr;
m_s1 = s1;
m_s2 = s2;
m_t0 = t0;
m_t1 = t1;
m_seed = seed;
m_preferredFormat = preferredFormat;
}
public byte[] GetEncoded()
{
return Arrays.ConcatenateAll(m_rho, m_k, m_tr, m_s1, m_s2, m_t0);
}
public MLDsaPublicKeyParameters GetPublicKey()
{
return new MLDsaPublicKeyParameters(base.Parameters, m_rho, m_t1);
}
public byte[] GetPublicKeyEncoded()
{
return Arrays.Concatenate(m_rho, m_t1);
}
public byte[] GetSeed()
{
return Arrays.Clone(m_seed);
}
internal byte[] SignInternal(byte[] rnd, byte[] msg, int msgOff, int msgLen)
{
DilithiumEngine engine = base.Parameters.ParameterSet.GetEngine(null);
byte[] array = new byte[engine.CryptoBytes];
engine.SignInternal(array, array.Length, msg, msgOff, msgLen, m_rho, m_k, m_tr, m_t0, m_s1, m_s2, rnd, false);
return array;
}
public MLDsaPrivateKeyParameters WithPreferredFormat(Format preferredFormat)
{
if (m_preferredFormat == preferredFormat)
return this;
return new MLDsaPrivateKeyParameters(base.Parameters, m_rho, m_k, m_tr, m_s1, m_s2, m_t0, m_t1, 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;
}
}
}