DHKekGenerator
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto.Utilities;
using System;
namespace Org.BouncyCastle.Crypto.Agreement.Kdf
{
public sealed class DHKekGenerator : IDerivationFunction
{
private readonly IDigest m_digest;
private DerObjectIdentifier algorithm;
private int keySize;
private byte[] z;
private byte[] partyAInfo;
public IDigest Digest => m_digest;
public DHKekGenerator(IDigest digest)
{
m_digest = digest;
}
public void Init(IDerivationParameters param)
{
DHKdfParameters dHKdfParameters = (DHKdfParameters)param;
algorithm = dHKdfParameters.Algorithm;
keySize = dHKdfParameters.KeySize;
z = dHKdfParameters.GetZ();
partyAInfo = dHKdfParameters.GetExtraInfo();
}
public int GenerateBytes(byte[] outBytes, int outOff, int length)
{
Check.OutputLength(outBytes, outOff, length, "output buffer too short");
return GenerateBytes(outBytes.AsSpan(outOff, length));
}
public unsafe int GenerateBytes(Span<byte> output)
{
long num = output.Length;
int digestSize = m_digest.GetDigestSize();
if (num > 8589934591)
throw new ArgumentException("Output length too large");
int num2 = (int)((num + digestSize - 1) / digestSize);
Span<byte> span;
if (digestSize <= 128) {
int num3 = digestSize;
span = new Span<byte>(stackalloc byte[(int)(uint)num3], num3);
} else
span = new byte[digestSize];
Span<byte> output2 = span;
uint num4 = 1;
for (int i = 0; i < num2; i++) {
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(new DerSequence(algorithm, new DerOctetString(Pack.UInt32_To_BE(num4))));
if (partyAInfo != null)
asn1EncodableVector.Add(new DerTaggedObject(true, 0, new DerOctetString(partyAInfo)));
asn1EncodableVector.Add(new DerTaggedObject(true, 2, new DerOctetString(Pack.UInt32_To_BE((uint)keySize))));
byte[] derEncoded = new DerSequence(asn1EncodableVector).GetDerEncoded();
m_digest.BlockUpdate(z);
m_digest.BlockUpdate(derEncoded);
m_digest.DoFinal(output2);
int length = output.Length;
if (length > digestSize) {
output2.CopyTo(output);
int num3 = digestSize;
output = output.Slice(num3, output.Length - num3);
} else {
span = output2.Slice(0, length);
span.CopyTo(output);
}
num4++;
}
m_digest.Reset();
return (int)num;
}
}
}