You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
4.1 KiB
155 lines
4.1 KiB
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) |
|
#pragma warning disable |
|
using System; |
|
|
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities; |
|
|
|
namespace BestHTTP.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, (byte)0x01); |
|
Arrays.Fill(K, (byte)0); |
|
|
|
int size = BigIntegers.GetUnsignedByteLength(n); |
|
byte[] x = new byte[size]; |
|
byte[] dVal = BigIntegers.AsUnsignedByteArray(d); |
|
|
|
Array.Copy(dVal, 0, x, x.Length - dVal.Length, dVal.Length); |
|
|
|
byte[] m = new byte[size]; |
|
|
|
BigInteger mInt = BitsToInt(message); |
|
|
|
if (mInt.CompareTo(n) >= 0) |
|
{ |
|
mInt = mInt.Subtract(n); |
|
} |
|
|
|
byte[] mVal = BigIntegers.AsUnsignedByteArray(mInt); |
|
|
|
Array.Copy(mVal, 0, m, m.Length - mVal.Length, mVal.Length); |
|
|
|
hMac.Init(new KeyParameter(K)); |
|
|
|
hMac.BlockUpdate(V, 0, V.Length); |
|
hMac.Update((byte)0x00); |
|
hMac.BlockUpdate(x, 0, x.Length); |
|
hMac.BlockUpdate(m, 0, m.Length); |
|
|
|
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((byte)0x01); |
|
hMac.BlockUpdate(x, 0, x.Length); |
|
hMac.BlockUpdate(m, 0, m.Length); |
|
|
|
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((byte)0x00); |
|
|
|
hMac.DoFinal(K, 0); |
|
|
|
hMac.Init(new KeyParameter(K)); |
|
|
|
hMac.BlockUpdate(V, 0, V.Length); |
|
|
|
hMac.DoFinal(V, 0); |
|
} |
|
} |
|
|
|
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
|
|
|