- Initial commit
This commit is contained in:
169
Runtime/3rdParty/BouncyCastle/crypto/signers/HMacDsaKCalculator.cs
vendored
Normal file
169
Runtime/3rdParty/BouncyCastle/crypto/signers/HMacDsaKCalculator.cs
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
/**
|
||||
* A deterministic K calculator based on the algorithm in section 3.2 of RFC 6979.
|
||||
*/
|
||||
public class HMacDsaKCalculator
|
||||
: IDsaKCalculator
|
||||
{
|
||||
private readonly HMac hMac;
|
||||
private readonly byte[] K;
|
||||
private readonly byte[] V;
|
||||
|
||||
private BigInteger n;
|
||||
|
||||
/**
|
||||
* Base constructor.
|
||||
*
|
||||
* @param digest digest to build the HMAC on.
|
||||
*/
|
||||
public HMacDsaKCalculator(IDigest digest)
|
||||
{
|
||||
this.hMac = new HMac(digest);
|
||||
this.V = new byte[hMac.GetMacSize()];
|
||||
this.K = new byte[hMac.GetMacSize()];
|
||||
}
|
||||
|
||||
public virtual bool IsDeterministic
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public virtual void Init(BigInteger n, SecureRandom random)
|
||||
{
|
||||
throw new InvalidOperationException("Operation not supported");
|
||||
}
|
||||
|
||||
public void Init(BigInteger n, BigInteger d, byte[] message)
|
||||
{
|
||||
this.n = n;
|
||||
|
||||
Arrays.Fill(V, 0x01);
|
||||
Arrays.Fill(K, 0);
|
||||
|
||||
BigInteger mInt = BitsToInt(message);
|
||||
if (mInt.CompareTo(n) >= 0)
|
||||
{
|
||||
mInt = mInt.Subtract(n);
|
||||
}
|
||||
|
||||
int size = BigIntegers.GetUnsignedByteLength(n);
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
int xmSize = size * 2;
|
||||
Span<byte> xm = xmSize <= 512
|
||||
? stackalloc byte[xmSize]
|
||||
: new byte[xmSize];
|
||||
BigIntegers.AsUnsignedByteArray(d, xm[..size]);
|
||||
BigIntegers.AsUnsignedByteArray(mInt, xm[size..]);
|
||||
#else
|
||||
byte[] x = BigIntegers.AsUnsignedByteArray(size, d);
|
||||
byte[] m = BigIntegers.AsUnsignedByteArray(size, mInt);
|
||||
#endif
|
||||
|
||||
hMac.Init(new KeyParameter(K));
|
||||
|
||||
hMac.BlockUpdate(V, 0, V.Length);
|
||||
hMac.Update(0x00);
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
hMac.BlockUpdate(xm);
|
||||
#else
|
||||
hMac.BlockUpdate(x, 0, x.Length);
|
||||
hMac.BlockUpdate(m, 0, m.Length);
|
||||
#endif
|
||||
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(0x01);
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
hMac.BlockUpdate(xm);
|
||||
#else
|
||||
hMac.BlockUpdate(x, 0, x.Length);
|
||||
hMac.BlockUpdate(m, 0, m.Length);
|
||||
#endif
|
||||
hMac.DoFinal(K, 0);
|
||||
|
||||
hMac.Init(new KeyParameter(K));
|
||||
hMac.BlockUpdate(V, 0, V.Length);
|
||||
hMac.DoFinal(V, 0);
|
||||
}
|
||||
|
||||
public virtual BigInteger NextK()
|
||||
{
|
||||
byte[] t = new byte[BigIntegers.GetUnsignedByteLength(n)];
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int tOff = 0;
|
||||
|
||||
while (tOff < t.Length)
|
||||
{
|
||||
hMac.BlockUpdate(V, 0, V.Length);
|
||||
hMac.DoFinal(V, 0);
|
||||
|
||||
int len = System.Math.Min(t.Length - tOff, V.Length);
|
||||
Array.Copy(V, 0, t, tOff, len);
|
||||
tOff += len;
|
||||
}
|
||||
|
||||
BigInteger k = BitsToInt(t);
|
||||
|
||||
if (k.SignValue > 0 && k.CompareTo(n) < 0)
|
||||
return k;
|
||||
|
||||
hMac.BlockUpdate(V, 0, V.Length);
|
||||
hMac.Update(0x00);
|
||||
hMac.DoFinal(K, 0);
|
||||
|
||||
hMac.Init(new KeyParameter(K));
|
||||
hMac.BlockUpdate(V, 0, V.Length);
|
||||
hMac.DoFinal(V, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Supports use of additional input.</summary>
|
||||
/// <remarks>
|
||||
/// RFC 6979 3.6. Additional data may be added to the input of HMAC [..]. A use case may be a protocol that
|
||||
/// requires a non-deterministic signature algorithm on a system that does not have access to a high-quality
|
||||
/// random source. It suffices that the additional data[..] is non-repeating(e.g., a signature counter or a
|
||||
/// monotonic clock) to ensure "random-looking" signatures are indistinguishable, in a cryptographic way, from
|
||||
/// plain (EC)DSA signatures.
|
||||
/// <para/>
|
||||
/// By default there is no additional input. Override this method to supply additional input, bearing in mind
|
||||
/// that this calculator may be used for many signatures.
|
||||
/// </remarks>
|
||||
/// <param name="hmac0">The <see cref="HMac"/> to which the additional input should be added.</param>
|
||||
protected virtual void InitAdditionalInput0(HMac hmac0)
|
||||
{
|
||||
}
|
||||
|
||||
private BigInteger BitsToInt(byte[] t)
|
||||
{
|
||||
BigInteger v = new BigInteger(1, t);
|
||||
|
||||
if (t.Length * 8 > n.BitLength)
|
||||
{
|
||||
v = v.ShiftRight(t.Length * 8 - n.BitLength);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
Reference in New Issue
Block a user