HMacDsaKCalculator
using Org.BouncyCastle.Crypto.Macs;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using System;
namespace Org.BouncyCastle.Crypto.Signers
{
public class HMacDsaKCalculator : IDsaKCalculator
{
private readonly HMac hMac;
private readonly byte[] K;
private readonly byte[] V;
private BigInteger n;
public virtual bool IsDeterministic => true;
public HMacDsaKCalculator(IDigest digest)
{
hMac = new HMac(digest);
int macSize = hMac.GetMacSize();
V = new byte[macSize];
K = new byte[macSize];
}
public virtual void Init(BigInteger n, SecureRandom random)
{
throw new InvalidOperationException("Operation not supported");
}
public unsafe void Init(BigInteger n, BigInteger d, byte[] message)
{
this.n = n;
BigInteger bigInteger = BitsToInt(message);
if (bigInteger.CompareTo(n) >= 0)
bigInteger = bigInteger.Subtract(n);
int unsignedByteLength = BigIntegers.GetUnsignedByteLength(n);
int num = unsignedByteLength * 2;
Span<byte> span;
int num2;
if (num <= 512) {
num2 = num;
span = new Span<byte>(stackalloc byte[(int)(uint)num2], num2);
} else
span = new byte[num];
Span<byte> span2 = span;
BigIntegers.AsUnsignedByteArray(d, span2.Slice(0, unsignedByteLength));
BigInteger bigInteger2 = bigInteger;
num2 = unsignedByteLength;
BigIntegers.AsUnsignedByteArray(bigInteger2, span2.Slice(num2, span2.Length - num2));
Arrays.Fill(K, 0);
Arrays.Fill(V, 1);
hMac.Init(new KeyParameter(K));
hMac.BlockUpdate(V, 0, V.Length);
hMac.Update(0);
hMac.BlockUpdate(span2);
InitAdditionalInput0(hMac);
hMac.DoFinal(K, 0);
hMac.Init(new KeyParameter(K));
hMac.BlockUpdate(V, 0, V.Length);
hMac.DoFinal(V, 0);
hMac.BlockUpdate(V, 0, V.Length);
hMac.Update(1);
hMac.BlockUpdate(span2);
InitAdditionalInput1(hMac);
hMac.DoFinal(K, 0);
hMac.Init(new KeyParameter(K));
hMac.BlockUpdate(V, 0, V.Length);
hMac.DoFinal(V, 0);
}
public virtual BigInteger NextK()
{
byte[] array = new byte[BigIntegers.GetUnsignedByteLength(n)];
BigInteger bigInteger;
while (true) {
int num;
for (int i = 0; i < array.Length; i += num) {
hMac.BlockUpdate(V, 0, V.Length);
hMac.DoFinal(V, 0);
num = System.Math.Min(array.Length - i, V.Length);
Array.Copy(V, 0, array, i, num);
}
bigInteger = BitsToInt(array);
if (bigInteger.SignValue > 0 && bigInteger.CompareTo(n) < 0)
break;
hMac.BlockUpdate(V, 0, V.Length);
hMac.Update(0);
hMac.DoFinal(K, 0);
hMac.Init(new KeyParameter(K));
hMac.BlockUpdate(V, 0, V.Length);
hMac.DoFinal(V, 0);
}
return bigInteger;
}
protected virtual void InitAdditionalInput0(HMac hmac0)
{
}
protected virtual void InitAdditionalInput1(HMac hmac1)
{
}
private BigInteger BitsToInt(byte[] t)
{
int num = t.Length * 8;
int bitLength = n.BitLength;
BigInteger bigInteger = BigIntegers.FromUnsignedByteArray(t);
if (num > bitLength)
bigInteger = bigInteger.ShiftRight(num - bitLength);
return bigInteger;
}
}
}