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