- Initial commit
This commit is contained in:
222
Runtime/3rdParty/BouncyCastle/crypto/agreement/srp/SRP6Utilities.cs
vendored
Normal file
222
Runtime/3rdParty/BouncyCastle/crypto/agreement/srp/SRP6Utilities.cs
vendored
Normal file
@ -0,0 +1,222 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
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.Agreement.Srp
|
||||
{
|
||||
public class Srp6Utilities
|
||||
{
|
||||
public static BigInteger CalculateK(IDigest digest, BigInteger N, BigInteger g)
|
||||
{
|
||||
return HashPaddedPair(digest, N, N, g);
|
||||
}
|
||||
|
||||
public static BigInteger CalculateU(IDigest digest, BigInteger N, BigInteger A, BigInteger B)
|
||||
{
|
||||
return HashPaddedPair(digest, N, A, B);
|
||||
}
|
||||
|
||||
public static BigInteger CalculateX(IDigest digest, BigInteger N, byte[] salt, byte[] identity, byte[] password)
|
||||
{
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
return CalculateX(digest, N, salt.AsSpan(), identity.AsSpan(), password.AsSpan());
|
||||
#else
|
||||
byte[] output = new byte[digest.GetDigestSize()];
|
||||
|
||||
digest.BlockUpdate(identity, 0, identity.Length);
|
||||
digest.Update((byte)':');
|
||||
digest.BlockUpdate(password, 0, password.Length);
|
||||
digest.DoFinal(output, 0);
|
||||
|
||||
digest.BlockUpdate(salt, 0, salt.Length);
|
||||
digest.BlockUpdate(output, 0, output.Length);
|
||||
digest.DoFinal(output, 0);
|
||||
|
||||
return new BigInteger(1, output);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public static BigInteger CalculateX(IDigest digest, BigInteger N, ReadOnlySpan<byte> salt,
|
||||
ReadOnlySpan<byte> identity, ReadOnlySpan<byte> password)
|
||||
{
|
||||
int digestSize = digest.GetDigestSize();
|
||||
Span<byte> output = digestSize <= 128
|
||||
? stackalloc byte[digestSize]
|
||||
: new byte[digestSize];
|
||||
|
||||
digest.BlockUpdate(identity);
|
||||
digest.Update((byte)':');
|
||||
digest.BlockUpdate(password);
|
||||
digest.DoFinal(output);
|
||||
|
||||
digest.BlockUpdate(salt);
|
||||
digest.BlockUpdate(output);
|
||||
digest.DoFinal(output);
|
||||
|
||||
return new BigInteger(1, output);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static BigInteger GeneratePrivateValue(IDigest digest, BigInteger N, BigInteger g, SecureRandom random)
|
||||
{
|
||||
int minBits = System.Math.Min(256, N.BitLength / 2);
|
||||
BigInteger min = BigInteger.One.ShiftLeft(minBits - 1);
|
||||
BigInteger max = N.Subtract(BigInteger.One);
|
||||
|
||||
return BigIntegers.CreateRandomInRange(min, max, random);
|
||||
}
|
||||
|
||||
public static BigInteger ValidatePublicValue(BigInteger N, BigInteger val)
|
||||
{
|
||||
val = val.Mod(N);
|
||||
|
||||
// Check that val % N != 0
|
||||
if (val.Equals(BigInteger.Zero))
|
||||
throw new CryptoException("Invalid public value: 0");
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the client evidence message (M1) according to the standard routine:
|
||||
* M1 = H( A | B | S )
|
||||
* @param digest The Digest used as the hashing function H
|
||||
* @param N Modulus used to get the pad length
|
||||
* @param A The public client value
|
||||
* @param B The public server value
|
||||
* @param S The secret calculated by both sides
|
||||
* @return M1 The calculated client evidence message
|
||||
*/
|
||||
public static BigInteger CalculateM1(IDigest digest, BigInteger N, BigInteger A, BigInteger B, BigInteger S)
|
||||
{
|
||||
BigInteger M1 = HashPaddedTriplet(digest, N, A, B, S);
|
||||
return M1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the server evidence message (M2) according to the standard routine:
|
||||
* M2 = H( A | M1 | S )
|
||||
* @param digest The Digest used as the hashing function H
|
||||
* @param N Modulus used to get the pad length
|
||||
* @param A The public client value
|
||||
* @param M1 The client evidence message
|
||||
* @param S The secret calculated by both sides
|
||||
* @return M2 The calculated server evidence message
|
||||
*/
|
||||
public static BigInteger CalculateM2(IDigest digest, BigInteger N, BigInteger A, BigInteger M1, BigInteger S)
|
||||
{
|
||||
BigInteger M2 = HashPaddedTriplet(digest, N, A, M1, S);
|
||||
return M2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the final Key according to the standard routine: Key = H(S)
|
||||
* @param digest The Digest used as the hashing function H
|
||||
* @param N Modulus used to get the pad length
|
||||
* @param S The secret calculated by both sides
|
||||
* @return
|
||||
*/
|
||||
public static BigInteger CalculateKey(IDigest digest, BigInteger N, BigInteger S)
|
||||
{
|
||||
int paddedLength = (N.BitLength + 7) / 8;
|
||||
int digestSize = digest.GetDigestSize();
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
Span<byte> bytes = paddedLength <= 512
|
||||
? stackalloc byte[paddedLength]
|
||||
: new byte[paddedLength];
|
||||
BigIntegers.AsUnsignedByteArray(S, bytes);
|
||||
digest.BlockUpdate(bytes);
|
||||
|
||||
Span<byte> output = digestSize <= 128
|
||||
? stackalloc byte[digestSize]
|
||||
: new byte[digestSize];
|
||||
digest.DoFinal(output);
|
||||
#else
|
||||
byte[] bytes = new byte[paddedLength];
|
||||
BigIntegers.AsUnsignedByteArray(S, bytes, 0, bytes.Length);
|
||||
digest.BlockUpdate(bytes, 0, bytes.Length);
|
||||
|
||||
byte[] output = new byte[digestSize];
|
||||
digest.DoFinal(output, 0);
|
||||
#endif
|
||||
|
||||
return new BigInteger(1, output);
|
||||
}
|
||||
|
||||
private static BigInteger HashPaddedTriplet(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2, BigInteger n3)
|
||||
{
|
||||
int paddedLength = (N.BitLength + 7) / 8;
|
||||
int digestSize = digest.GetDigestSize();
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
Span<byte> bytes = paddedLength <= 512
|
||||
? stackalloc byte[paddedLength]
|
||||
: new byte[paddedLength];
|
||||
BigIntegers.AsUnsignedByteArray(n1, bytes);
|
||||
digest.BlockUpdate(bytes);
|
||||
BigIntegers.AsUnsignedByteArray(n2, bytes);
|
||||
digest.BlockUpdate(bytes);
|
||||
BigIntegers.AsUnsignedByteArray(n3, bytes);
|
||||
digest.BlockUpdate(bytes);
|
||||
|
||||
Span<byte> output = digestSize <= 128
|
||||
? stackalloc byte[digestSize]
|
||||
: new byte[digestSize];
|
||||
digest.DoFinal(output);
|
||||
#else
|
||||
byte[] bytes = new byte[paddedLength];
|
||||
BigIntegers.AsUnsignedByteArray(n1, bytes, 0, bytes.Length);
|
||||
digest.BlockUpdate(bytes, 0, bytes.Length);
|
||||
BigIntegers.AsUnsignedByteArray(n2, bytes, 0, bytes.Length);
|
||||
digest.BlockUpdate(bytes, 0, bytes.Length);
|
||||
BigIntegers.AsUnsignedByteArray(n3, bytes, 0, bytes.Length);
|
||||
digest.BlockUpdate(bytes, 0, bytes.Length);
|
||||
|
||||
byte[] output = new byte[digestSize];
|
||||
digest.DoFinal(output, 0);
|
||||
#endif
|
||||
|
||||
return new BigInteger(1, output);
|
||||
}
|
||||
|
||||
private static BigInteger HashPaddedPair(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2)
|
||||
{
|
||||
int paddedLength = (N.BitLength + 7) / 8;
|
||||
int digestSize = digest.GetDigestSize();
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
Span<byte> bytes = paddedLength <= 512
|
||||
? stackalloc byte[paddedLength]
|
||||
: new byte[paddedLength];
|
||||
BigIntegers.AsUnsignedByteArray(n1, bytes);
|
||||
digest.BlockUpdate(bytes);
|
||||
BigIntegers.AsUnsignedByteArray(n2, bytes);
|
||||
digest.BlockUpdate(bytes);
|
||||
|
||||
Span<byte> output = digestSize <= 128
|
||||
? stackalloc byte[digestSize]
|
||||
: new byte[digestSize];
|
||||
digest.DoFinal(output);
|
||||
#else
|
||||
byte[] bytes = new byte[paddedLength];
|
||||
BigIntegers.AsUnsignedByteArray(n1, bytes, 0, bytes.Length);
|
||||
digest.BlockUpdate(bytes, 0, bytes.Length);
|
||||
BigIntegers.AsUnsignedByteArray(n2, bytes, 0, bytes.Length);
|
||||
digest.BlockUpdate(bytes, 0, bytes.Length);
|
||||
|
||||
byte[] output = new byte[digestSize];
|
||||
digest.DoFinal(output, 0);
|
||||
#endif
|
||||
|
||||
return new BigInteger(1, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
Reference in New Issue
Block a user