mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-09-27 02:36:14 +00:00
提交Unity 联机Pro
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 192ce040c8f883047926a9f104e89219
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,548 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math
|
||||
{
|
||||
/// <summary>Utility methods for generating primes and testing for primality.</summary>
|
||||
public static class Primes
|
||||
{
|
||||
public static readonly int SmallFactorLimit = 211;
|
||||
|
||||
private static readonly BigInteger One = BigInteger.One;
|
||||
private static readonly BigInteger Two = BigInteger.Two;
|
||||
private static readonly BigInteger Three = BigInteger.Three;
|
||||
|
||||
/// <summary>Used to return the output from the
|
||||
/// <see cref="EnhancedMRProbablePrimeTest(BigInteger, SecureRandom, int)">
|
||||
/// Enhanced Miller-Rabin Probabilistic Primality Test</see></summary>
|
||||
public sealed class MROutput
|
||||
{
|
||||
internal static MROutput ProbablyPrime()
|
||||
{
|
||||
return new MROutput(false, null);
|
||||
}
|
||||
|
||||
internal static MROutput ProvablyCompositeWithFactor(BigInteger factor)
|
||||
{
|
||||
return new MROutput(true, factor);
|
||||
}
|
||||
|
||||
internal static MROutput ProvablyCompositeNotPrimePower()
|
||||
{
|
||||
return new MROutput(true, null);
|
||||
}
|
||||
|
||||
private readonly bool m_provablyComposite;
|
||||
private readonly BigInteger m_factor;
|
||||
|
||||
private MROutput(bool provablyComposite, BigInteger factor)
|
||||
{
|
||||
m_provablyComposite = provablyComposite;
|
||||
m_factor = factor;
|
||||
}
|
||||
|
||||
public BigInteger Factor => m_factor;
|
||||
|
||||
public bool IsProvablyComposite => m_provablyComposite;
|
||||
|
||||
public bool IsNotPrimePower => m_provablyComposite && m_factor == null;
|
||||
}
|
||||
|
||||
/// <summary>Used to return the output from the <see cref="GenerateSTRandomPrime(IDigest, int, byte[])">
|
||||
/// Shawe-Taylor Random_Prime Routine</see></summary>
|
||||
public sealed class STOutput
|
||||
{
|
||||
private readonly BigInteger m_prime;
|
||||
private readonly byte[] m_primeSeed;
|
||||
private readonly int m_primeGenCounter;
|
||||
|
||||
internal STOutput(BigInteger prime, byte[] primeSeed, int primeGenCounter)
|
||||
{
|
||||
m_prime = prime;
|
||||
m_primeSeed = primeSeed;
|
||||
m_primeGenCounter = primeGenCounter;
|
||||
}
|
||||
|
||||
public BigInteger Prime => m_prime;
|
||||
|
||||
public byte[] PrimeSeed => m_primeSeed;
|
||||
|
||||
public int PrimeGenCounter => m_primeGenCounter;
|
||||
}
|
||||
|
||||
/// <summary>FIPS 186-4 C.6 Shawe-Taylor Random_Prime Routine.</summary>
|
||||
/// <remarks>Construct a provable prime number using a hash function.</remarks>
|
||||
/// <param name="hash">The <see cref="IDigest"/> instance to use (as "Hash()"). Cannot be null.</param>
|
||||
/// <param name="length">The length (in bits) of the prime to be generated. Must be at least 2.</param>
|
||||
/// <param name="inputSeed">The seed to be used for the generation of the requested prime. Cannot be null or
|
||||
/// empty.</param>
|
||||
/// <returns>An <see cref="STOutput"/> instance containing the requested prime.</returns>
|
||||
public static STOutput GenerateSTRandomPrime(IDigest hash, int length, byte[] inputSeed)
|
||||
{
|
||||
if (hash == null)
|
||||
throw new ArgumentNullException(nameof(hash));
|
||||
if (length < 2)
|
||||
throw new ArgumentException("must be >= 2", nameof(length));
|
||||
if (inputSeed == null)
|
||||
throw new ArgumentNullException(nameof(inputSeed));
|
||||
if (inputSeed.Length == 0)
|
||||
throw new ArgumentException("cannot be empty", nameof(inputSeed));
|
||||
|
||||
return ImplSTRandomPrime(hash, length, Arrays.Clone(inputSeed));
|
||||
}
|
||||
|
||||
/// <summary>FIPS 186-4 C.3.2 Enhanced Miller-Rabin Probabilistic Primality Test.</summary>
|
||||
/// <remarks>
|
||||
/// Run several iterations of the Miller-Rabin algorithm with randomly-chosen bases. This is an alternative to
|
||||
/// <see cref="IsMRProbablePrime(BigInteger, SecureRandom, int)"/> that provides more information about a
|
||||
/// composite candidate, which may be useful when generating or validating RSA moduli.
|
||||
/// </remarks>
|
||||
/// <param name="candidate">The <see cref="BigInteger"/> instance to test for primality.</param>
|
||||
/// <param name="random">The source of randomness to use to choose bases.</param>
|
||||
/// <param name="iterations">The number of randomly-chosen bases to perform the test for.</param>
|
||||
/// <returns>An <see cref="MROutput"/> instance that can be further queried for details.</returns>
|
||||
public static MROutput EnhancedMRProbablePrimeTest(BigInteger candidate, SecureRandom random, int iterations)
|
||||
{
|
||||
CheckCandidate(candidate, nameof(candidate));
|
||||
|
||||
if (random == null)
|
||||
throw new ArgumentNullException(nameof(random));
|
||||
if (iterations < 1)
|
||||
throw new ArgumentException("must be > 0", nameof(iterations));
|
||||
|
||||
if (candidate.BitLength == 2)
|
||||
return MROutput.ProbablyPrime();
|
||||
|
||||
if (!candidate.TestBit(0))
|
||||
return MROutput.ProvablyCompositeWithFactor(Two);
|
||||
|
||||
BigInteger w = candidate;
|
||||
BigInteger wSubOne = candidate.Subtract(One);
|
||||
BigInteger wSubTwo = candidate.Subtract(Two);
|
||||
|
||||
int a = wSubOne.GetLowestSetBit();
|
||||
BigInteger m = wSubOne.ShiftRight(a);
|
||||
|
||||
for (int i = 0; i < iterations; ++i)
|
||||
{
|
||||
BigInteger b = BigIntegers.CreateRandomInRange(Two, wSubTwo, random);
|
||||
BigInteger g = b.Gcd(w);
|
||||
|
||||
if (g.CompareTo(One) > 0)
|
||||
return MROutput.ProvablyCompositeWithFactor(g);
|
||||
|
||||
BigInteger z = b.ModPow(m, w);
|
||||
|
||||
if (z.Equals(One) || z.Equals(wSubOne))
|
||||
continue;
|
||||
|
||||
bool primeToBase = false;
|
||||
|
||||
BigInteger x = z;
|
||||
for (int j = 1; j < a; ++j)
|
||||
{
|
||||
z = z.Square().Mod(w);
|
||||
|
||||
if (z.Equals(wSubOne))
|
||||
{
|
||||
primeToBase = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (z.Equals(One))
|
||||
break;
|
||||
|
||||
x = z;
|
||||
}
|
||||
|
||||
if (!primeToBase)
|
||||
{
|
||||
if (!z.Equals(One))
|
||||
{
|
||||
x = z;
|
||||
z = z.Square().Mod(w);
|
||||
|
||||
if (!z.Equals(One))
|
||||
{
|
||||
x = z;
|
||||
}
|
||||
}
|
||||
|
||||
g = x.Subtract(One).Gcd(w);
|
||||
|
||||
if (g.CompareTo(One) > 0)
|
||||
return MROutput.ProvablyCompositeWithFactor(g);
|
||||
|
||||
return MROutput.ProvablyCompositeNotPrimePower();
|
||||
}
|
||||
}
|
||||
|
||||
return MROutput.ProbablyPrime();
|
||||
}
|
||||
|
||||
/// <summary>A fast check for small divisors, up to some implementation-specific limit.</summary>
|
||||
/// <param name="candidate">The <see cref="BigInteger"/> instance to test for division by small factors.</param>
|
||||
/// <returns><c>true</c> if the candidate is found to have any small factors, <c>false</c> otherwise.</returns>
|
||||
public static bool HasAnySmallFactors(BigInteger candidate)
|
||||
{
|
||||
CheckCandidate(candidate, nameof(candidate));
|
||||
|
||||
return ImplHasAnySmallFactors(candidate);
|
||||
}
|
||||
|
||||
/// <summary>FIPS 186-4 C.3.1 Miller-Rabin Probabilistic Primality Test.</summary>
|
||||
/// <remarks>Run several iterations of the Miller-Rabin algorithm with randomly-chosen bases.</remarks>
|
||||
/// <param name="candidate">The <see cref="BigInteger"/> instance to test for primality.</param>
|
||||
/// <param name="random">The source of randomness to use to choose bases.</param>
|
||||
/// <param name="iterations">The number of randomly-chosen bases to perform the test for.</param>
|
||||
/// <returns>
|
||||
/// <c>false</c> if any witness to compositeness is found amongst the chosen bases (so
|
||||
/// <paramref name="candidate"/> is definitely NOT prime), or else <c>true</c> (indicating primality with some
|
||||
/// probability dependent on the number of iterations that were performed).
|
||||
/// </returns>
|
||||
public static bool IsMRProbablePrime(BigInteger candidate, SecureRandom random, int iterations)
|
||||
{
|
||||
CheckCandidate(candidate, nameof(candidate));
|
||||
|
||||
if (random == null)
|
||||
throw new ArgumentException("cannot be null", nameof(random));
|
||||
if (iterations < 1)
|
||||
throw new ArgumentException("must be > 0", nameof(iterations));
|
||||
|
||||
if (candidate.BitLength == 2)
|
||||
return true;
|
||||
if (!candidate.TestBit(0))
|
||||
return false;
|
||||
|
||||
BigInteger w = candidate;
|
||||
BigInteger wSubOne = candidate.Subtract(One);
|
||||
BigInteger wSubTwo = candidate.Subtract(Two);
|
||||
|
||||
int a = wSubOne.GetLowestSetBit();
|
||||
BigInteger m = wSubOne.ShiftRight(a);
|
||||
|
||||
for (int i = 0; i < iterations; ++i)
|
||||
{
|
||||
BigInteger b = BigIntegers.CreateRandomInRange(Two, wSubTwo, random);
|
||||
|
||||
if (!ImplMRProbablePrimeToBase(w, wSubOne, m, a, b))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>FIPS 186-4 C.3.1 Miller-Rabin Probabilistic Primality Test (to a fixed base).</summary>
|
||||
/// <remarks>Run a single iteration of the Miller-Rabin algorithm against the specified base.</remarks>
|
||||
/// <param name="candidate">The <see cref="BigInteger"/> instance to test for primality.</param>
|
||||
/// <param name="baseValue">The base value to use for this iteration.</param>
|
||||
/// <returns><c>false</c> if <paramref name="baseValue"/> is a witness to compositeness (so
|
||||
/// <paramref name="candidate"/> is definitely NOT prime), or else <c>true</c>.</returns>
|
||||
public static bool IsMRProbablePrimeToBase(BigInteger candidate, BigInteger baseValue)
|
||||
{
|
||||
CheckCandidate(candidate, nameof(candidate));
|
||||
CheckCandidate(baseValue, nameof(baseValue));
|
||||
|
||||
if (baseValue.CompareTo(candidate.Subtract(One)) >= 0)
|
||||
throw new ArgumentException("must be < ('candidate' - 1)", nameof(baseValue));
|
||||
|
||||
if (candidate.BitLength == 2)
|
||||
return true;
|
||||
|
||||
BigInteger w = candidate;
|
||||
BigInteger wSubOne = candidate.Subtract(One);
|
||||
|
||||
int a = wSubOne.GetLowestSetBit();
|
||||
BigInteger m = wSubOne.ShiftRight(a);
|
||||
|
||||
return ImplMRProbablePrimeToBase(w, wSubOne, m, a, baseValue);
|
||||
}
|
||||
|
||||
private static void CheckCandidate(BigInteger n, string name)
|
||||
{
|
||||
if (n == null || n.SignValue < 1 || n.BitLength < 2)
|
||||
throw new ArgumentException("must be non-null and >= 2", name);
|
||||
}
|
||||
|
||||
private static bool ImplHasAnySmallFactors(BigInteger x)
|
||||
{
|
||||
/*
|
||||
* Bundle trial divisors into ~32-bit moduli then use fast tests on the ~32-bit remainders.
|
||||
*/
|
||||
int m = 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23;
|
||||
int r = x.Mod(BigInteger.ValueOf(m)).IntValue;
|
||||
if ((r % 2) == 0 || (r % 3) == 0 || (r % 5) == 0 || (r % 7) == 0 || (r % 11) == 0 || (r % 13) == 0
|
||||
|| (r % 17) == 0 || (r % 19) == 0 || (r % 23) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
m = 29 * 31 * 37 * 41 * 43;
|
||||
r = x.Mod(BigInteger.ValueOf(m)).IntValue;
|
||||
if ((r % 29) == 0 || (r % 31) == 0 || (r % 37) == 0 || (r % 41) == 0 || (r % 43) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
m = 47 * 53 * 59 * 61 * 67;
|
||||
r = x.Mod(BigInteger.ValueOf(m)).IntValue;
|
||||
if ((r % 47) == 0 || (r % 53) == 0 || (r % 59) == 0 || (r % 61) == 0 || (r % 67) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
m = 71 * 73 * 79 * 83;
|
||||
r = x.Mod(BigInteger.ValueOf(m)).IntValue;
|
||||
if ((r % 71) == 0 || (r % 73) == 0 || (r % 79) == 0 || (r % 83) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
m = 89 * 97 * 101 * 103;
|
||||
r = x.Mod(BigInteger.ValueOf(m)).IntValue;
|
||||
if ((r % 89) == 0 || (r % 97) == 0 || (r % 101) == 0 || (r % 103) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
m = 107 * 109 * 113 * 127;
|
||||
r = x.Mod(BigInteger.ValueOf(m)).IntValue;
|
||||
if ((r % 107) == 0 || (r % 109) == 0 || (r % 113) == 0 || (r % 127) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
m = 131 * 137 * 139 * 149;
|
||||
r = x.Mod(BigInteger.ValueOf(m)).IntValue;
|
||||
if ((r % 131) == 0 || (r % 137) == 0 || (r % 139) == 0 || (r % 149) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
m = 151 * 157 * 163 * 167;
|
||||
r = x.Mod(BigInteger.ValueOf(m)).IntValue;
|
||||
if ((r % 151) == 0 || (r % 157) == 0 || (r % 163) == 0 || (r % 167) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
m = 173 * 179 * 181 * 191;
|
||||
r = x.Mod(BigInteger.ValueOf(m)).IntValue;
|
||||
if ((r % 173) == 0 || (r % 179) == 0 || (r % 181) == 0 || (r % 191) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
m = 193 * 197 * 199 * 211;
|
||||
r = x.Mod(BigInteger.ValueOf(m)).IntValue;
|
||||
if ((r % 193) == 0 || (r % 197) == 0 || (r % 199) == 0 || (r % 211) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: Unit tests depend on SMALL_FACTOR_LIMIT matching the
|
||||
* highest small factor tested here.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool ImplMRProbablePrimeToBase(BigInteger w, BigInteger wSubOne, BigInteger m, int a, BigInteger b)
|
||||
{
|
||||
BigInteger z = b.ModPow(m, w);
|
||||
|
||||
if (z.Equals(One) || z.Equals(wSubOne))
|
||||
return true;
|
||||
|
||||
for (int j = 1; j < a; ++j)
|
||||
{
|
||||
z = z.Square().Mod(w);
|
||||
|
||||
if (z.Equals(wSubOne))
|
||||
return true;
|
||||
|
||||
if (z.Equals(One))
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static STOutput ImplSTRandomPrime(IDigest d, int length, byte[] primeSeed)
|
||||
{
|
||||
int dLen = d.GetDigestSize();
|
||||
int cLen = System.Math.Max(4, dLen);
|
||||
|
||||
if (length < 33)
|
||||
{
|
||||
int primeGenCounter = 0;
|
||||
|
||||
byte[] c0 = new byte[cLen];
|
||||
byte[] c1 = new byte[cLen];
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Hash(d, primeSeed, c0, cLen - dLen);
|
||||
Inc(primeSeed, 1);
|
||||
|
||||
Hash(d, primeSeed, c1, cLen - dLen);
|
||||
Inc(primeSeed, 1);
|
||||
|
||||
uint c = Pack.BE_To_UInt32(c0, cLen - 4)
|
||||
^ Pack.BE_To_UInt32(c1, cLen - 4);
|
||||
c &= uint.MaxValue >> (32 - length);
|
||||
c |= (1U << (length - 1)) | 1U;
|
||||
|
||||
++primeGenCounter;
|
||||
|
||||
if (IsPrime32(c))
|
||||
return new STOutput(BigInteger.ValueOf(c), primeSeed, primeGenCounter);
|
||||
|
||||
if (primeGenCounter > (4 * length))
|
||||
throw new InvalidOperationException("Too many iterations in Shawe-Taylor Random_Prime Routine");
|
||||
}
|
||||
}
|
||||
|
||||
STOutput rec = ImplSTRandomPrime(d, (length + 3)/2, primeSeed);
|
||||
|
||||
{
|
||||
BigInteger c0 = rec.Prime;
|
||||
primeSeed = rec.PrimeSeed;
|
||||
int primeGenCounter = rec.PrimeGenCounter;
|
||||
|
||||
int outlen = 8 * dLen;
|
||||
int iterations = (length - 1)/outlen;
|
||||
|
||||
int oldCounter = primeGenCounter;
|
||||
|
||||
BigInteger x = HashGen(d, primeSeed, iterations + 1);
|
||||
x = x.Mod(One.ShiftLeft(length - 1)).SetBit(length - 1);
|
||||
|
||||
BigInteger c0x2 = c0.ShiftLeft(1);
|
||||
BigInteger tx2 = x.Subtract(One).Divide(c0x2).Add(One).ShiftLeft(1);
|
||||
int dt = 0;
|
||||
|
||||
BigInteger c = tx2.Multiply(c0).Add(One);
|
||||
|
||||
/*
|
||||
* TODO Since the candidate primes are generated by constant steps ('c0x2'),
|
||||
* sieving could be used here in place of the 'HasAnySmallFactors' approach.
|
||||
*/
|
||||
for (;;)
|
||||
{
|
||||
if (c.BitLength > length)
|
||||
{
|
||||
tx2 = One.ShiftLeft(length - 1).Subtract(One).Divide(c0x2).Add(One).ShiftLeft(1);
|
||||
c = tx2.Multiply(c0).Add(One);
|
||||
}
|
||||
|
||||
++primeGenCounter;
|
||||
|
||||
/*
|
||||
* This is an optimization of the original algorithm, using trial division to screen out
|
||||
* many non-primes quickly.
|
||||
*
|
||||
* NOTE: 'primeSeed' is still incremented as if we performed the full check!
|
||||
*/
|
||||
if (ImplHasAnySmallFactors(c))
|
||||
{
|
||||
Inc(primeSeed, iterations + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
BigInteger a = HashGen(d, primeSeed, iterations + 1);
|
||||
a = a.Mod(c.Subtract(Three)).Add(Two);
|
||||
|
||||
tx2 = tx2.Add(BigInteger.ValueOf(dt));
|
||||
dt = 0;
|
||||
|
||||
BigInteger z = a.ModPow(tx2, c);
|
||||
|
||||
if (c.Gcd(z.Subtract(One)).Equals(One) && z.ModPow(c0, c).Equals(One))
|
||||
return new STOutput(c, primeSeed, primeGenCounter);
|
||||
}
|
||||
|
||||
if (primeGenCounter >= ((4 * length) + oldCounter))
|
||||
throw new InvalidOperationException("Too many iterations in Shawe-Taylor Random_Prime Routine");
|
||||
|
||||
dt += 2;
|
||||
c = c.Add(c0x2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Hash(IDigest d, byte[] input, byte[] output, int outPos)
|
||||
{
|
||||
d.BlockUpdate(input, 0, input.Length);
|
||||
d.DoFinal(output, outPos);
|
||||
}
|
||||
|
||||
private static BigInteger HashGen(IDigest d, byte[] seed, int count)
|
||||
{
|
||||
int dLen = d.GetDigestSize();
|
||||
int pos = count * dLen;
|
||||
byte[] buf = new byte[pos];
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
pos -= dLen;
|
||||
Hash(d, seed, buf, pos);
|
||||
Inc(seed, 1);
|
||||
}
|
||||
return new BigInteger(1, buf);
|
||||
}
|
||||
|
||||
private static void Inc(byte[] seed, int c)
|
||||
{
|
||||
int pos = seed.Length;
|
||||
while (c > 0 && --pos >= 0)
|
||||
{
|
||||
c += seed[pos];
|
||||
seed[pos] = (byte)c;
|
||||
c >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsPrime32(uint x)
|
||||
{
|
||||
/*
|
||||
* Use wheel factorization with 2, 3, 5 to select trial divisors.
|
||||
*/
|
||||
|
||||
if (x < 32)
|
||||
return ((1 << (int)x) & 0b0010_0000_1000_1010_0010_1000_1010_1100) != 0;
|
||||
|
||||
if (((1 << (int)(x % 30U)) & 0b1010_0000_1000_1010_0010_1000_1000_0010U) == 0)
|
||||
return false;
|
||||
|
||||
uint[] ds = new uint[]{ 1, 7, 11, 13, 17, 19, 23, 29 };
|
||||
uint b = 0;
|
||||
for (int pos = 1;; pos = 0)
|
||||
{
|
||||
/*
|
||||
* Trial division by wheel-selected divisors
|
||||
*/
|
||||
while (pos < ds.Length)
|
||||
{
|
||||
uint d = b + ds[pos];
|
||||
if (x % d == 0)
|
||||
return false;
|
||||
|
||||
++pos;
|
||||
}
|
||||
|
||||
b += 30;
|
||||
|
||||
if ((b >> 16 != 0) || (b * b >= x))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7607b79d7fda4b4fb7452bd465e4f1a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d60220356cda474badfff94d625ad9d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,20 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC
|
||||
{
|
||||
public abstract class AbstractECLookupTable
|
||||
: ECLookupTable
|
||||
{
|
||||
public abstract ECPoint Lookup(int index);
|
||||
public abstract int Size { get; }
|
||||
|
||||
public virtual ECPoint LookupVar(int index)
|
||||
{
|
||||
return Lookup(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50418ef6492b4ea4eaa2c772913ae160
|
||||
timeCreated: 1572510030
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,614 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Endo;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Field;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC
|
||||
{
|
||||
public class ECAlgorithms
|
||||
{
|
||||
public static bool IsF2mCurve(ECCurve c)
|
||||
{
|
||||
return IsF2mField(c.Field);
|
||||
}
|
||||
|
||||
public static bool IsF2mField(IFiniteField field)
|
||||
{
|
||||
return field.Dimension > 1 && field.Characteristic.Equals(BigInteger.Two)
|
||||
&& field is IPolynomialExtensionField;
|
||||
}
|
||||
|
||||
public static bool IsFpCurve(ECCurve c)
|
||||
{
|
||||
return IsFpField(c.Field);
|
||||
}
|
||||
|
||||
public static bool IsFpField(IFiniteField field)
|
||||
{
|
||||
return field.Dimension == 1;
|
||||
}
|
||||
|
||||
public static ECPoint SumOfMultiplies(ECPoint[] ps, BigInteger[] ks)
|
||||
{
|
||||
if (ps == null || ks == null || ps.Length != ks.Length || ps.Length < 1)
|
||||
throw new ArgumentException("point and scalar arrays should be non-null, and of equal, non-zero, length");
|
||||
|
||||
int count = ps.Length;
|
||||
switch (count)
|
||||
{
|
||||
case 1:
|
||||
return ps[0].Multiply(ks[0]);
|
||||
case 2:
|
||||
return SumOfTwoMultiplies(ps[0], ks[0], ps[1], ks[1]);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ECPoint p = ps[0];
|
||||
ECCurve c = p.Curve;
|
||||
|
||||
ECPoint[] imported = new ECPoint[count];
|
||||
imported[0] = p;
|
||||
for (int i = 1; i < count; ++i)
|
||||
{
|
||||
imported[i] = ImportPoint(c, ps[i]);
|
||||
}
|
||||
|
||||
GlvEndomorphism glvEndomorphism = c.GetEndomorphism() as GlvEndomorphism;
|
||||
if (glvEndomorphism != null)
|
||||
{
|
||||
return ImplCheckResult(ImplSumOfMultipliesGlv(imported, ks, glvEndomorphism));
|
||||
}
|
||||
|
||||
return ImplCheckResult(ImplSumOfMultiplies(imported, ks));
|
||||
}
|
||||
|
||||
public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b)
|
||||
{
|
||||
ECCurve cp = P.Curve;
|
||||
Q = ImportPoint(cp, Q);
|
||||
|
||||
// Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick
|
||||
{
|
||||
AbstractF2mCurve f2mCurve = cp as AbstractF2mCurve;
|
||||
if (f2mCurve != null && f2mCurve.IsKoblitz)
|
||||
{
|
||||
return ImplCheckResult(P.Multiply(a).Add(Q.Multiply(b)));
|
||||
}
|
||||
}
|
||||
|
||||
GlvEndomorphism glvEndomorphism = cp.GetEndomorphism() as GlvEndomorphism;
|
||||
if (glvEndomorphism != null)
|
||||
{
|
||||
return ImplCheckResult(
|
||||
ImplSumOfMultipliesGlv(new ECPoint[] { P, Q }, new BigInteger[] { a, b }, glvEndomorphism));
|
||||
}
|
||||
|
||||
return ImplCheckResult(ImplShamirsTrickWNaf(P, a, Q, b));
|
||||
}
|
||||
|
||||
/*
|
||||
* "Shamir's Trick", originally due to E. G. Straus
|
||||
* (Addition chains of vectors. American Mathematical Monthly,
|
||||
* 71(7):806-808, Aug./Sept. 1964)
|
||||
*
|
||||
* Input: The points P, Q, scalar k = (km?, ... , k1, k0)
|
||||
* and scalar l = (lm?, ... , l1, l0).
|
||||
* Output: R = k * P + l * Q.
|
||||
* 1: Z <- P + Q
|
||||
* 2: R <- O
|
||||
* 3: for i from m-1 down to 0 do
|
||||
* 4: R <- R + R {point doubling}
|
||||
* 5: if (ki = 1) and (li = 0) then R <- R + P end if
|
||||
* 6: if (ki = 0) and (li = 1) then R <- R + Q end if
|
||||
* 7: if (ki = 1) and (li = 1) then R <- R + Z end if
|
||||
* 8: end for
|
||||
* 9: return R
|
||||
*/
|
||||
public static ECPoint ShamirsTrick(ECPoint P, BigInteger k, ECPoint Q, BigInteger l)
|
||||
{
|
||||
ECCurve cp = P.Curve;
|
||||
Q = ImportPoint(cp, Q);
|
||||
|
||||
return ImplCheckResult(ImplShamirsTrickJsf(P, k, Q, l));
|
||||
}
|
||||
|
||||
public static ECPoint ImportPoint(ECCurve c, ECPoint p)
|
||||
{
|
||||
ECCurve cp = p.Curve;
|
||||
if (!c.Equals(cp))
|
||||
throw new ArgumentException("Point must be on the same curve");
|
||||
|
||||
return c.ImportPoint(p);
|
||||
}
|
||||
|
||||
public static void MontgomeryTrick(ECFieldElement[] zs, int off, int len)
|
||||
{
|
||||
MontgomeryTrick(zs, off, len, null);
|
||||
}
|
||||
|
||||
public static void MontgomeryTrick(ECFieldElement[] zs, int off, int len, ECFieldElement scale)
|
||||
{
|
||||
/*
|
||||
* Uses the "Montgomery Trick" to invert many field elements, with only a single actual
|
||||
* field inversion. See e.g. the paper:
|
||||
* "Fast Multi-scalar Multiplication Methods on Elliptic Curves with Precomputation Strategy Using Montgomery Trick"
|
||||
* by Katsuyuki Okeya, Kouichi Sakurai.
|
||||
*/
|
||||
|
||||
ECFieldElement[] c = new ECFieldElement[len];
|
||||
c[0] = zs[off];
|
||||
|
||||
int i = 0;
|
||||
while (++i < len)
|
||||
{
|
||||
c[i] = c[i - 1].Multiply(zs[off + i]);
|
||||
}
|
||||
|
||||
--i;
|
||||
|
||||
if (scale != null)
|
||||
{
|
||||
c[i] = c[i].Multiply(scale);
|
||||
}
|
||||
|
||||
ECFieldElement u = c[i].Invert();
|
||||
|
||||
while (i > 0)
|
||||
{
|
||||
int j = off + i--;
|
||||
ECFieldElement tmp = zs[j];
|
||||
zs[j] = c[i].Multiply(u);
|
||||
u = u.Multiply(tmp);
|
||||
}
|
||||
|
||||
zs[off] = u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple shift-and-add multiplication. Serves as reference implementation to verify (possibly
|
||||
* faster) implementations, and for very small scalars. CAUTION: This implementation is NOT
|
||||
* constant-time in any way. It is only intended to be used for diagnostics.
|
||||
*
|
||||
* @param p
|
||||
* The point to multiply.
|
||||
* @param k
|
||||
* The multiplier.
|
||||
* @return The result of the point multiplication <code>kP</code>.
|
||||
*/
|
||||
public static ECPoint ReferenceMultiply(ECPoint p, BigInteger k)
|
||||
{
|
||||
BigInteger x = k.Abs();
|
||||
ECPoint q = p.Curve.Infinity;
|
||||
int t = x.BitLength;
|
||||
if (t > 0)
|
||||
{
|
||||
if (x.TestBit(0))
|
||||
{
|
||||
q = p;
|
||||
}
|
||||
for (int i = 1; i < t; i++)
|
||||
{
|
||||
p = p.Twice();
|
||||
if (x.TestBit(i))
|
||||
{
|
||||
q = q.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return k.SignValue < 0 ? q.Negate() : q;
|
||||
}
|
||||
|
||||
public static ECPoint ValidatePoint(ECPoint p)
|
||||
{
|
||||
if (!p.IsValid())
|
||||
throw new InvalidOperationException("Invalid point");
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
public static ECPoint CleanPoint(ECCurve c, ECPoint p)
|
||||
{
|
||||
ECCurve cp = p.Curve;
|
||||
if (!c.Equals(cp))
|
||||
throw new ArgumentException("Point must be on the same curve", nameof(p));
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
int encodedLength = p.GetEncodedLength(false);
|
||||
Span<byte> encoding = encodedLength <= 512
|
||||
? stackalloc byte[encodedLength]
|
||||
: new byte[encodedLength];
|
||||
p.EncodeTo(false, encoding);
|
||||
return c.DecodePoint(encoding);
|
||||
#else
|
||||
return c.DecodePoint(p.GetEncoded(false));
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static ECPoint ImplCheckResult(ECPoint p)
|
||||
{
|
||||
if (!p.IsValidPartial())
|
||||
throw new InvalidOperationException("Invalid result");
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
internal static ECPoint ImplShamirsTrickJsf(ECPoint P, BigInteger k, ECPoint Q, BigInteger l)
|
||||
{
|
||||
ECCurve curve = P.Curve;
|
||||
ECPoint infinity = curve.Infinity;
|
||||
|
||||
// TODO conjugate co-Z addition (ZADDC) can return both of these
|
||||
ECPoint PaddQ = P.Add(Q);
|
||||
ECPoint PsubQ = P.Subtract(Q);
|
||||
|
||||
ECPoint[] points = new ECPoint[] { Q, PsubQ, P, PaddQ };
|
||||
curve.NormalizeAll(points);
|
||||
|
||||
ECPoint[] table = new ECPoint[] {
|
||||
points[3].Negate(), points[2].Negate(), points[1].Negate(),
|
||||
points[0].Negate(), infinity, points[0],
|
||||
points[1], points[2], points[3] };
|
||||
|
||||
byte[] jsf = WNafUtilities.GenerateJsf(k, l);
|
||||
|
||||
ECPoint R = infinity;
|
||||
|
||||
int i = jsf.Length;
|
||||
while (--i >= 0)
|
||||
{
|
||||
int jsfi = jsf[i];
|
||||
|
||||
// NOTE: The shifting ensures the sign is extended correctly
|
||||
int kDigit = ((jsfi << 24) >> 28), lDigit = ((jsfi << 28) >> 28);
|
||||
|
||||
int index = 4 + (kDigit * 3) + lDigit;
|
||||
R = R.TwicePlus(table[index]);
|
||||
}
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k,
|
||||
ECPoint Q, BigInteger l)
|
||||
{
|
||||
bool negK = k.SignValue < 0, negL = l.SignValue < 0;
|
||||
|
||||
BigInteger kAbs = k.Abs(), lAbs = l.Abs();
|
||||
|
||||
int minWidthP = WNafUtilities.GetWindowSize(kAbs.BitLength, 8);
|
||||
int minWidthQ = WNafUtilities.GetWindowSize(lAbs.BitLength, 8);
|
||||
|
||||
WNafPreCompInfo infoP = WNafUtilities.Precompute(P, minWidthP, true);
|
||||
WNafPreCompInfo infoQ = WNafUtilities.Precompute(Q, minWidthQ, true);
|
||||
|
||||
// When P, Q are 'promoted' (i.e. reused several times), switch to fixed-point algorithm
|
||||
{
|
||||
ECCurve c = P.Curve;
|
||||
int combSize = FixedPointUtilities.GetCombSize(c);
|
||||
if (!negK && !negL
|
||||
&& k.BitLength <= combSize && l.BitLength <= combSize
|
||||
&& infoP.IsPromoted && infoQ.IsPromoted)
|
||||
{
|
||||
return ImplShamirsTrickFixedPoint(P, k, Q, l);
|
||||
}
|
||||
}
|
||||
|
||||
int widthP = System.Math.Min(8, infoP.Width);
|
||||
int widthQ = System.Math.Min(8, infoQ.Width);
|
||||
|
||||
ECPoint[] preCompP = negK ? infoP.PreCompNeg : infoP.PreComp;
|
||||
ECPoint[] preCompQ = negL ? infoQ.PreCompNeg : infoQ.PreComp;
|
||||
ECPoint[] preCompNegP = negK ? infoP.PreComp : infoP.PreCompNeg;
|
||||
ECPoint[] preCompNegQ = negL ? infoQ.PreComp : infoQ.PreCompNeg;
|
||||
|
||||
byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, kAbs);
|
||||
byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, lAbs);
|
||||
|
||||
return ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ);
|
||||
}
|
||||
|
||||
internal static ECPoint ImplShamirsTrickWNaf(ECEndomorphism endomorphism, ECPoint P, BigInteger k, BigInteger l)
|
||||
{
|
||||
bool negK = k.SignValue < 0, negL = l.SignValue < 0;
|
||||
|
||||
k = k.Abs();
|
||||
l = l.Abs();
|
||||
|
||||
int minWidth = WNafUtilities.GetWindowSize(System.Math.Max(k.BitLength, l.BitLength), 8);
|
||||
|
||||
WNafPreCompInfo infoP = WNafUtilities.Precompute(P, minWidth, true);
|
||||
ECPoint Q = EndoUtilities.MapPoint(endomorphism, P);
|
||||
WNafPreCompInfo infoQ = WNafUtilities.PrecomputeWithPointMap(Q, endomorphism.PointMap, infoP, true);
|
||||
|
||||
int widthP = System.Math.Min(8, infoP.Width);
|
||||
int widthQ = System.Math.Min(8, infoQ.Width);
|
||||
|
||||
ECPoint[] preCompP = negK ? infoP.PreCompNeg : infoP.PreComp;
|
||||
ECPoint[] preCompQ = negL ? infoQ.PreCompNeg : infoQ.PreComp;
|
||||
ECPoint[] preCompNegP = negK ? infoP.PreComp : infoP.PreCompNeg;
|
||||
ECPoint[] preCompNegQ = negL ? infoQ.PreComp : infoQ.PreCompNeg;
|
||||
|
||||
byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, k);
|
||||
byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, l);
|
||||
|
||||
return ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ);
|
||||
}
|
||||
|
||||
private static ECPoint ImplShamirsTrickWNaf(ECPoint[] preCompP, ECPoint[] preCompNegP, byte[] wnafP,
|
||||
ECPoint[] preCompQ, ECPoint[] preCompNegQ, byte[] wnafQ)
|
||||
{
|
||||
int len = System.Math.Max(wnafP.Length, wnafQ.Length);
|
||||
|
||||
ECCurve curve = preCompP[0].Curve;
|
||||
ECPoint infinity = curve.Infinity;
|
||||
|
||||
ECPoint R = infinity;
|
||||
int zeroes = 0;
|
||||
|
||||
for (int i = len - 1; i >= 0; --i)
|
||||
{
|
||||
int wiP = i < wnafP.Length ? (int)(sbyte)wnafP[i] : 0;
|
||||
int wiQ = i < wnafQ.Length ? (int)(sbyte)wnafQ[i] : 0;
|
||||
|
||||
if ((wiP | wiQ) == 0)
|
||||
{
|
||||
++zeroes;
|
||||
continue;
|
||||
}
|
||||
|
||||
ECPoint r = infinity;
|
||||
if (wiP != 0)
|
||||
{
|
||||
int nP = System.Math.Abs(wiP);
|
||||
ECPoint[] tableP = wiP < 0 ? preCompNegP : preCompP;
|
||||
r = r.Add(tableP[nP >> 1]);
|
||||
}
|
||||
if (wiQ != 0)
|
||||
{
|
||||
int nQ = System.Math.Abs(wiQ);
|
||||
ECPoint[] tableQ = wiQ < 0 ? preCompNegQ : preCompQ;
|
||||
r = r.Add(tableQ[nQ >> 1]);
|
||||
}
|
||||
|
||||
if (zeroes > 0)
|
||||
{
|
||||
R = R.TimesPow2(zeroes);
|
||||
zeroes = 0;
|
||||
}
|
||||
|
||||
R = R.TwicePlus(r);
|
||||
}
|
||||
|
||||
if (zeroes > 0)
|
||||
{
|
||||
R = R.TimesPow2(zeroes);
|
||||
}
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
internal static ECPoint ImplSumOfMultiplies(ECPoint[] ps, BigInteger[] ks)
|
||||
{
|
||||
int count = ps.Length;
|
||||
bool[] negs = new bool[count];
|
||||
WNafPreCompInfo[] infos = new WNafPreCompInfo[count];
|
||||
byte[][] wnafs = new byte[count][];
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
BigInteger ki = ks[i]; negs[i] = ki.SignValue < 0; ki = ki.Abs();
|
||||
|
||||
int minWidth = WNafUtilities.GetWindowSize(ki.BitLength, 8);
|
||||
WNafPreCompInfo info = WNafUtilities.Precompute(ps[i], minWidth, true);
|
||||
|
||||
int width = System.Math.Min(8, info.Width);
|
||||
|
||||
infos[i] = info;
|
||||
wnafs[i] = WNafUtilities.GenerateWindowNaf(width, ki);
|
||||
}
|
||||
|
||||
return ImplSumOfMultiplies(negs, infos, wnafs);
|
||||
}
|
||||
|
||||
internal static ECPoint ImplSumOfMultipliesGlv(ECPoint[] ps, BigInteger[] ks, GlvEndomorphism glvEndomorphism)
|
||||
{
|
||||
BigInteger n = ps[0].Curve.Order;
|
||||
|
||||
int len = ps.Length;
|
||||
|
||||
BigInteger[] abs = new BigInteger[len << 1];
|
||||
for (int i = 0, j = 0; i < len; ++i)
|
||||
{
|
||||
BigInteger[] ab = glvEndomorphism.DecomposeScalar(ks[i].Mod(n));
|
||||
abs[j++] = ab[0];
|
||||
abs[j++] = ab[1];
|
||||
}
|
||||
|
||||
if (glvEndomorphism.HasEfficientPointMap)
|
||||
{
|
||||
return ImplSumOfMultiplies(glvEndomorphism, ps, abs);
|
||||
}
|
||||
|
||||
ECPoint[] pqs = new ECPoint[len << 1];
|
||||
for (int i = 0, j = 0; i < len; ++i)
|
||||
{
|
||||
ECPoint p = ps[i];
|
||||
ECPoint q = EndoUtilities.MapPoint(glvEndomorphism, p);
|
||||
pqs[j++] = p;
|
||||
pqs[j++] = q;
|
||||
}
|
||||
|
||||
return ImplSumOfMultiplies(pqs, abs);
|
||||
}
|
||||
|
||||
internal static ECPoint ImplSumOfMultiplies(ECEndomorphism endomorphism, ECPoint[] ps, BigInteger[] ks)
|
||||
{
|
||||
int halfCount = ps.Length, fullCount = halfCount << 1;
|
||||
|
||||
bool[] negs = new bool[fullCount];
|
||||
WNafPreCompInfo[] infos = new WNafPreCompInfo[fullCount];
|
||||
byte[][] wnafs = new byte[fullCount][];
|
||||
|
||||
ECPointMap pointMap = endomorphism.PointMap;
|
||||
|
||||
for (int i = 0; i < halfCount; ++i)
|
||||
{
|
||||
int j0 = i << 1, j1 = j0 + 1;
|
||||
|
||||
BigInteger kj0 = ks[j0]; negs[j0] = kj0.SignValue < 0; kj0 = kj0.Abs();
|
||||
BigInteger kj1 = ks[j1]; negs[j1] = kj1.SignValue < 0; kj1 = kj1.Abs();
|
||||
|
||||
int minWidth = WNafUtilities.GetWindowSize(System.Math.Max(kj0.BitLength, kj1.BitLength), 8);
|
||||
|
||||
ECPoint P = ps[i];
|
||||
WNafPreCompInfo infoP = WNafUtilities.Precompute(P, minWidth, true);
|
||||
ECPoint Q = EndoUtilities.MapPoint(endomorphism, P);
|
||||
WNafPreCompInfo infoQ = WNafUtilities.PrecomputeWithPointMap(Q, pointMap, infoP, true);
|
||||
|
||||
int widthP = System.Math.Min(8, infoP.Width);
|
||||
int widthQ = System.Math.Min(8, infoQ.Width);
|
||||
|
||||
infos[j0] = infoP;
|
||||
infos[j1] = infoQ;
|
||||
wnafs[j0] = WNafUtilities.GenerateWindowNaf(widthP, kj0);
|
||||
wnafs[j1] = WNafUtilities.GenerateWindowNaf(widthQ, kj1);
|
||||
}
|
||||
|
||||
return ImplSumOfMultiplies(negs, infos, wnafs);
|
||||
}
|
||||
|
||||
private static ECPoint ImplSumOfMultiplies(bool[] negs, WNafPreCompInfo[] infos, byte[][] wnafs)
|
||||
{
|
||||
int len = 0, count = wnafs.Length;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
len = System.Math.Max(len, wnafs[i].Length);
|
||||
}
|
||||
|
||||
ECCurve curve = infos[0].PreComp[0].Curve;
|
||||
ECPoint infinity = curve.Infinity;
|
||||
|
||||
ECPoint R = infinity;
|
||||
int zeroes = 0;
|
||||
|
||||
for (int i = len - 1; i >= 0; --i)
|
||||
{
|
||||
ECPoint r = infinity;
|
||||
|
||||
for (int j = 0; j < count; ++j)
|
||||
{
|
||||
byte[] wnaf = wnafs[j];
|
||||
int wi = i < wnaf.Length ? (int)(sbyte)wnaf[i] : 0;
|
||||
if (wi != 0)
|
||||
{
|
||||
int n = System.Math.Abs(wi);
|
||||
WNafPreCompInfo info = infos[j];
|
||||
ECPoint[] table = (wi < 0 == negs[j]) ? info.PreComp : info.PreCompNeg;
|
||||
r = r.Add(table[n >> 1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (r == infinity)
|
||||
{
|
||||
++zeroes;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (zeroes > 0)
|
||||
{
|
||||
R = R.TimesPow2(zeroes);
|
||||
zeroes = 0;
|
||||
}
|
||||
|
||||
R = R.TwicePlus(r);
|
||||
}
|
||||
|
||||
if (zeroes > 0)
|
||||
{
|
||||
R = R.TimesPow2(zeroes);
|
||||
}
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
private static ECPoint ImplShamirsTrickFixedPoint(ECPoint p, BigInteger k, ECPoint q, BigInteger l)
|
||||
{
|
||||
ECCurve c = p.Curve;
|
||||
int combSize = FixedPointUtilities.GetCombSize(c);
|
||||
|
||||
if (k.BitLength > combSize || l.BitLength > combSize)
|
||||
{
|
||||
/*
|
||||
* TODO The comb works best when the scalars are less than the (possibly unknown) order.
|
||||
* Still, if we want to handle larger scalars, we could allow customization of the comb
|
||||
* size, or alternatively we could deal with the 'extra' bits either by running the comb
|
||||
* multiple times as necessary, or by using an alternative multiplier as prelude.
|
||||
*/
|
||||
throw new InvalidOperationException("fixed-point comb doesn't support scalars larger than the curve order");
|
||||
}
|
||||
|
||||
FixedPointPreCompInfo infoP = FixedPointUtilities.Precompute(p);
|
||||
FixedPointPreCompInfo infoQ = FixedPointUtilities.Precompute(q);
|
||||
|
||||
ECLookupTable lookupTableP = infoP.LookupTable;
|
||||
ECLookupTable lookupTableQ = infoQ.LookupTable;
|
||||
|
||||
int widthP = infoP.Width;
|
||||
int widthQ = infoQ.Width;
|
||||
|
||||
// TODO This shouldn't normally happen, but a better "solution" is desirable anyway
|
||||
if (widthP != widthQ)
|
||||
{
|
||||
FixedPointCombMultiplier m = new FixedPointCombMultiplier();
|
||||
ECPoint r1 = m.Multiply(p, k);
|
||||
ECPoint r2 = m.Multiply(q, l);
|
||||
return r1.Add(r2);
|
||||
}
|
||||
|
||||
int width = widthP;
|
||||
|
||||
int d = (combSize + width - 1) / width;
|
||||
|
||||
ECPoint R = c.Infinity;
|
||||
|
||||
int fullComb = d * width;
|
||||
uint[] K = Nat.FromBigInteger(fullComb, k);
|
||||
uint[] L = Nat.FromBigInteger(fullComb, l);
|
||||
|
||||
int top = fullComb - 1;
|
||||
for (int i = 0; i < d; ++i)
|
||||
{
|
||||
uint secretIndexK = 0, secretIndexL = 0;
|
||||
|
||||
for (int j = top - i; j >= 0; j -= d)
|
||||
{
|
||||
uint secretBitK = K[j >> 5] >> (j & 0x1F);
|
||||
secretIndexK ^= secretBitK >> 1;
|
||||
secretIndexK <<= 1;
|
||||
secretIndexK ^= secretBitK;
|
||||
|
||||
uint secretBitL = L[j >> 5] >> (j & 0x1F);
|
||||
secretIndexL ^= secretBitL >> 1;
|
||||
secretIndexL <<= 1;
|
||||
secretIndexL ^= secretBitL;
|
||||
}
|
||||
|
||||
ECPoint addP = lookupTableP.LookupVar((int)secretIndexK);
|
||||
ECPoint addQ = lookupTableQ.LookupVar((int)secretIndexL);
|
||||
|
||||
ECPoint T = addP.Add(addQ);
|
||||
|
||||
R = R.TwicePlus(T);
|
||||
}
|
||||
|
||||
return R.Add(infoP.Offset).Add(infoQ.Offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5f3620d97ee7c342a95b5b57c924d90
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ba3b2a3c2430914fbced44c7df90596
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,945 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC
|
||||
{
|
||||
public abstract class ECFieldElement
|
||||
{
|
||||
public abstract BigInteger ToBigInteger();
|
||||
public abstract string FieldName { get; }
|
||||
public abstract int FieldSize { get; }
|
||||
public abstract ECFieldElement Add(ECFieldElement b);
|
||||
public abstract ECFieldElement AddOne();
|
||||
public abstract ECFieldElement Subtract(ECFieldElement b);
|
||||
public abstract ECFieldElement Multiply(ECFieldElement b);
|
||||
public abstract ECFieldElement Divide(ECFieldElement b);
|
||||
public abstract ECFieldElement Negate();
|
||||
public abstract ECFieldElement Square();
|
||||
public abstract ECFieldElement Invert();
|
||||
public abstract ECFieldElement Sqrt();
|
||||
|
||||
public virtual int BitLength
|
||||
{
|
||||
get { return ToBigInteger().BitLength; }
|
||||
}
|
||||
|
||||
public virtual bool IsOne
|
||||
{
|
||||
get { return BitLength == 1; }
|
||||
}
|
||||
|
||||
public virtual bool IsZero
|
||||
{
|
||||
get { return 0 == ToBigInteger().SignValue; }
|
||||
}
|
||||
|
||||
public virtual ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return Multiply(b).Subtract(x.Multiply(y));
|
||||
}
|
||||
|
||||
public virtual ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return Multiply(b).Add(x.Multiply(y));
|
||||
}
|
||||
|
||||
public virtual ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return Square().Subtract(x.Multiply(y));
|
||||
}
|
||||
|
||||
public virtual ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return Square().Add(x.Multiply(y));
|
||||
}
|
||||
|
||||
public virtual ECFieldElement SquarePow(int pow)
|
||||
{
|
||||
ECFieldElement r = this;
|
||||
for (int i = 0; i < pow; ++i)
|
||||
{
|
||||
r = r.Square();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public virtual bool TestBitZero()
|
||||
{
|
||||
return ToBigInteger().TestBit(0);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as ECFieldElement);
|
||||
}
|
||||
|
||||
public virtual bool Equals(ECFieldElement other)
|
||||
{
|
||||
if (this == other)
|
||||
return true;
|
||||
if (null == other)
|
||||
return false;
|
||||
return ToBigInteger().Equals(other.ToBigInteger());
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ToBigInteger().GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return this.ToBigInteger().ToString(16);
|
||||
}
|
||||
|
||||
public virtual byte[] GetEncoded()
|
||||
{
|
||||
return BigIntegers.AsUnsignedByteArray(GetEncodedLength(), ToBigInteger());
|
||||
}
|
||||
|
||||
public virtual int GetEncodedLength()
|
||||
{
|
||||
return (FieldSize + 7) / 8;
|
||||
}
|
||||
|
||||
public virtual void EncodeTo(byte[] buf, int off)
|
||||
{
|
||||
BigIntegers.AsUnsignedByteArray(ToBigInteger(), buf, off, GetEncodedLength());
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
|
||||
public virtual void EncodeTo(Span<byte> buf)
|
||||
{
|
||||
BigIntegers.AsUnsignedByteArray(ToBigInteger(), buf[..GetEncodedLength()]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public abstract class AbstractFpFieldElement
|
||||
: ECFieldElement
|
||||
{
|
||||
}
|
||||
|
||||
public class FpFieldElement
|
||||
: AbstractFpFieldElement
|
||||
{
|
||||
private readonly BigInteger q, r, x;
|
||||
|
||||
internal static BigInteger CalculateResidue(BigInteger p)
|
||||
{
|
||||
int bitLength = p.BitLength;
|
||||
if (bitLength >= 96)
|
||||
{
|
||||
BigInteger firstWord = p.ShiftRight(bitLength - 64);
|
||||
if (firstWord.LongValue == -1L)
|
||||
{
|
||||
return BigInteger.One.ShiftLeft(bitLength).Subtract(p);
|
||||
}
|
||||
if ((bitLength & 7) == 0)
|
||||
{
|
||||
return BigInteger.One.ShiftLeft(bitLength << 1).Divide(p).Negate();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal FpFieldElement(BigInteger q, BigInteger r, BigInteger x)
|
||||
{
|
||||
this.q = q;
|
||||
this.r = r;
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public override BigInteger ToBigInteger()
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the field name for this field.
|
||||
*
|
||||
* @return the string "Fp".
|
||||
*/
|
||||
public override string FieldName
|
||||
{
|
||||
get { return "Fp"; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return q.BitLength; }
|
||||
}
|
||||
|
||||
public BigInteger Q
|
||||
{
|
||||
get { return q; }
|
||||
}
|
||||
|
||||
public override ECFieldElement Add(
|
||||
ECFieldElement b)
|
||||
{
|
||||
return new FpFieldElement(q, r, ModAdd(x, b.ToBigInteger()));
|
||||
}
|
||||
|
||||
public override ECFieldElement AddOne()
|
||||
{
|
||||
BigInteger x2 = x.Add(BigInteger.One);
|
||||
if (x2.CompareTo(q) == 0)
|
||||
{
|
||||
x2 = BigInteger.Zero;
|
||||
}
|
||||
return new FpFieldElement(q, r, x2);
|
||||
}
|
||||
|
||||
public override ECFieldElement Subtract(
|
||||
ECFieldElement b)
|
||||
{
|
||||
return new FpFieldElement(q, r, ModSubtract(x, b.ToBigInteger()));
|
||||
}
|
||||
|
||||
public override ECFieldElement Multiply(
|
||||
ECFieldElement b)
|
||||
{
|
||||
return new FpFieldElement(q, r, ModMult(x, b.ToBigInteger()));
|
||||
}
|
||||
|
||||
public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
BigInteger ax = this.x, bx = b.ToBigInteger(), xx = x.ToBigInteger(), yx = y.ToBigInteger();
|
||||
BigInteger ab = ax.Multiply(bx);
|
||||
BigInteger xy = xx.Multiply(yx);
|
||||
return new FpFieldElement(q, r, ModReduce(ab.Subtract(xy)));
|
||||
}
|
||||
|
||||
public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
BigInteger ax = this.x, bx = b.ToBigInteger(), xx = x.ToBigInteger(), yx = y.ToBigInteger();
|
||||
BigInteger ab = ax.Multiply(bx);
|
||||
BigInteger xy = xx.Multiply(yx);
|
||||
BigInteger sum = ab.Add(xy);
|
||||
if (r != null && r.SignValue < 0 && sum.BitLength > (q.BitLength << 1))
|
||||
{
|
||||
sum = sum.Subtract(q.ShiftLeft(q.BitLength));
|
||||
}
|
||||
return new FpFieldElement(q, r, ModReduce(sum));
|
||||
}
|
||||
|
||||
public override ECFieldElement Divide(
|
||||
ECFieldElement b)
|
||||
{
|
||||
return new FpFieldElement(q, r, ModMult(x, ModInverse(b.ToBigInteger())));
|
||||
}
|
||||
|
||||
public override ECFieldElement Negate()
|
||||
{
|
||||
return x.SignValue == 0 ? this : new FpFieldElement(q, r, q.Subtract(x));
|
||||
}
|
||||
|
||||
public override ECFieldElement Square()
|
||||
{
|
||||
return new FpFieldElement(q, r, ModMult(x, x));
|
||||
}
|
||||
|
||||
public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
BigInteger ax = this.x, xx = x.ToBigInteger(), yx = y.ToBigInteger();
|
||||
BigInteger aa = ax.Multiply(ax);
|
||||
BigInteger xy = xx.Multiply(yx);
|
||||
return new FpFieldElement(q, r, ModReduce(aa.Subtract(xy)));
|
||||
}
|
||||
|
||||
public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
BigInteger ax = this.x, xx = x.ToBigInteger(), yx = y.ToBigInteger();
|
||||
BigInteger aa = ax.Multiply(ax);
|
||||
BigInteger xy = xx.Multiply(yx);
|
||||
BigInteger sum = aa.Add(xy);
|
||||
if (r != null && r.SignValue < 0 && sum.BitLength > (q.BitLength << 1))
|
||||
{
|
||||
sum = sum.Subtract(q.ShiftLeft(q.BitLength));
|
||||
}
|
||||
return new FpFieldElement(q, r, ModReduce(sum));
|
||||
}
|
||||
|
||||
public override ECFieldElement Invert()
|
||||
{
|
||||
// TODO Modular inversion can be faster for a (Generalized) Mersenne Prime.
|
||||
return new FpFieldElement(q, r, ModInverse(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* return a sqrt root - the routine verifies that the calculation
|
||||
* returns the right value - if none exists it returns null.
|
||||
*/
|
||||
public override ECFieldElement Sqrt()
|
||||
{
|
||||
if (IsZero || IsOne)
|
||||
return this;
|
||||
|
||||
if (!q.TestBit(0))
|
||||
throw new NotImplementedException("even value of q");
|
||||
|
||||
if (q.TestBit(1)) // q == 4m + 3
|
||||
{
|
||||
BigInteger e = q.ShiftRight(2).Add(BigInteger.One);
|
||||
return CheckSqrt(new FpFieldElement(q, r, x.ModPow(e, q)));
|
||||
}
|
||||
|
||||
if (q.TestBit(2)) // q == 8m + 5
|
||||
{
|
||||
BigInteger t1 = x.ModPow(q.ShiftRight(3), q);
|
||||
BigInteger t2 = ModMult(t1, x);
|
||||
BigInteger t3 = ModMult(t2, t1);
|
||||
|
||||
if (t3.Equals(BigInteger.One))
|
||||
{
|
||||
return CheckSqrt(new FpFieldElement(q, r, t2));
|
||||
}
|
||||
|
||||
// TODO This is constant and could be precomputed
|
||||
BigInteger t4 = BigInteger.Two.ModPow(q.ShiftRight(2), q);
|
||||
|
||||
BigInteger y = ModMult(t2, t4);
|
||||
|
||||
return CheckSqrt(new FpFieldElement(q, r, y));
|
||||
}
|
||||
|
||||
// q == 8m + 1
|
||||
|
||||
BigInteger legendreExponent = q.ShiftRight(1);
|
||||
if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
|
||||
return null;
|
||||
|
||||
BigInteger X = this.x;
|
||||
BigInteger fourX = ModDouble(ModDouble(X)); ;
|
||||
|
||||
BigInteger k = legendreExponent.Add(BigInteger.One), qMinusOne = q.Subtract(BigInteger.One);
|
||||
|
||||
BigInteger U, V;
|
||||
do
|
||||
{
|
||||
BigInteger P;
|
||||
do
|
||||
{
|
||||
P = BigInteger.Arbitrary(q.BitLength);
|
||||
}
|
||||
while (P.CompareTo(q) >= 0
|
||||
|| !ModReduce(P.Multiply(P).Subtract(fourX)).ModPow(legendreExponent, q).Equals(qMinusOne));
|
||||
|
||||
BigInteger[] result = LucasSequence(P, X, k);
|
||||
U = result[0];
|
||||
V = result[1];
|
||||
|
||||
if (ModMult(V, V).Equals(fourX))
|
||||
{
|
||||
return new FpFieldElement(q, r, ModHalfAbs(V));
|
||||
}
|
||||
}
|
||||
while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private ECFieldElement CheckSqrt(ECFieldElement z)
|
||||
{
|
||||
return z.Square().Equals(this) ? z : null;
|
||||
}
|
||||
|
||||
private BigInteger[] LucasSequence(
|
||||
BigInteger P,
|
||||
BigInteger Q,
|
||||
BigInteger k)
|
||||
{
|
||||
// TODO Research and apply "common-multiplicand multiplication here"
|
||||
|
||||
int n = k.BitLength;
|
||||
int s = k.GetLowestSetBit();
|
||||
|
||||
Debug.Assert(k.TestBit(s));
|
||||
|
||||
BigInteger Uh = BigInteger.One;
|
||||
BigInteger Vl = BigInteger.Two;
|
||||
BigInteger Vh = P;
|
||||
BigInteger Ql = BigInteger.One;
|
||||
BigInteger Qh = BigInteger.One;
|
||||
|
||||
for (int j = n - 1; j >= s + 1; --j)
|
||||
{
|
||||
Ql = ModMult(Ql, Qh);
|
||||
|
||||
if (k.TestBit(j))
|
||||
{
|
||||
Qh = ModMult(Ql, Q);
|
||||
Uh = ModMult(Uh, Vh);
|
||||
Vl = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql)));
|
||||
Vh = ModReduce(Vh.Multiply(Vh).Subtract(Qh.ShiftLeft(1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
Qh = Ql;
|
||||
Uh = ModReduce(Uh.Multiply(Vl).Subtract(Ql));
|
||||
Vh = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql)));
|
||||
Vl = ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)));
|
||||
}
|
||||
}
|
||||
|
||||
Ql = ModMult(Ql, Qh);
|
||||
Qh = ModMult(Ql, Q);
|
||||
Uh = ModReduce(Uh.Multiply(Vl).Subtract(Ql));
|
||||
Vl = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql)));
|
||||
Ql = ModMult(Ql, Qh);
|
||||
|
||||
for (int j = 1; j <= s; ++j)
|
||||
{
|
||||
Uh = ModMult(Uh, Vl);
|
||||
Vl = ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)));
|
||||
Ql = ModMult(Ql, Ql);
|
||||
}
|
||||
|
||||
return new BigInteger[] { Uh, Vl };
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModAdd(BigInteger x1, BigInteger x2)
|
||||
{
|
||||
BigInteger x3 = x1.Add(x2);
|
||||
if (x3.CompareTo(q) >= 0)
|
||||
{
|
||||
x3 = x3.Subtract(q);
|
||||
}
|
||||
return x3;
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModDouble(BigInteger x)
|
||||
{
|
||||
BigInteger _2x = x.ShiftLeft(1);
|
||||
if (_2x.CompareTo(q) >= 0)
|
||||
{
|
||||
_2x = _2x.Subtract(q);
|
||||
}
|
||||
return _2x;
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModHalf(BigInteger x)
|
||||
{
|
||||
if (x.TestBit(0))
|
||||
{
|
||||
x = q.Add(x);
|
||||
}
|
||||
return x.ShiftRight(1);
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModHalfAbs(BigInteger x)
|
||||
{
|
||||
if (x.TestBit(0))
|
||||
{
|
||||
x = q.Subtract(x);
|
||||
}
|
||||
return x.ShiftRight(1);
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModInverse(BigInteger x)
|
||||
{
|
||||
return BigIntegers.ModOddInverse(q, x);
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModMult(BigInteger x1, BigInteger x2)
|
||||
{
|
||||
return ModReduce(x1.Multiply(x2));
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModReduce(BigInteger x)
|
||||
{
|
||||
if (r == null)
|
||||
{
|
||||
x = x.Mod(q);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool negative = x.SignValue < 0;
|
||||
if (negative)
|
||||
{
|
||||
x = x.Abs();
|
||||
}
|
||||
int qLen = q.BitLength;
|
||||
if (r.SignValue > 0)
|
||||
{
|
||||
BigInteger qMod = BigInteger.One.ShiftLeft(qLen);
|
||||
bool rIsOne = r.Equals(BigInteger.One);
|
||||
while (x.BitLength > (qLen + 1))
|
||||
{
|
||||
BigInteger u = x.ShiftRight(qLen);
|
||||
BigInteger v = x.Remainder(qMod);
|
||||
if (!rIsOne)
|
||||
{
|
||||
u = u.Multiply(r);
|
||||
}
|
||||
x = u.Add(v);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int d = ((qLen - 1) & 31) + 1;
|
||||
BigInteger mu = r.Negate();
|
||||
BigInteger u = mu.Multiply(x.ShiftRight(qLen - d));
|
||||
BigInteger quot = u.ShiftRight(qLen + d);
|
||||
BigInteger v = quot.Multiply(q);
|
||||
BigInteger bk1 = BigInteger.One.ShiftLeft(qLen + d);
|
||||
v = v.Remainder(bk1);
|
||||
x = x.Remainder(bk1);
|
||||
x = x.Subtract(v);
|
||||
if (x.SignValue < 0)
|
||||
{
|
||||
x = x.Add(bk1);
|
||||
}
|
||||
}
|
||||
while (x.CompareTo(q) >= 0)
|
||||
{
|
||||
x = x.Subtract(q);
|
||||
}
|
||||
if (negative && x.SignValue != 0)
|
||||
{
|
||||
x = q.Subtract(x);
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModSubtract(BigInteger x1, BigInteger x2)
|
||||
{
|
||||
BigInteger x3 = x1.Subtract(x2);
|
||||
if (x3.SignValue < 0)
|
||||
{
|
||||
x3 = x3.Add(q);
|
||||
}
|
||||
return x3;
|
||||
}
|
||||
|
||||
public override bool Equals(
|
||||
object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
FpFieldElement other = obj as FpFieldElement;
|
||||
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
return Equals(other);
|
||||
}
|
||||
|
||||
public virtual bool Equals(
|
||||
FpFieldElement other)
|
||||
{
|
||||
return q.Equals(other.q) && base.Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return q.GetHashCode() ^ base.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class AbstractF2mFieldElement
|
||||
: ECFieldElement
|
||||
{
|
||||
public virtual ECFieldElement HalfTrace()
|
||||
{
|
||||
int m = FieldSize;
|
||||
if ((m & 1) == 0)
|
||||
throw new InvalidOperationException("Half-trace only defined for odd m");
|
||||
|
||||
//ECFieldElement ht = this;
|
||||
//for (int i = 1; i < m; i += 2)
|
||||
//{
|
||||
// ht = ht.SquarePow(2).Add(this);
|
||||
//}
|
||||
|
||||
int n = (m + 1) >> 1;
|
||||
int k = 31 - Integers.NumberOfLeadingZeros(n);
|
||||
int nk = 1;
|
||||
|
||||
ECFieldElement ht = this;
|
||||
while (k > 0)
|
||||
{
|
||||
ht = ht.SquarePow(nk << 1).Add(ht);
|
||||
nk = n >> --k;
|
||||
if (0 != (nk & 1))
|
||||
{
|
||||
ht = ht.SquarePow(2).Add(this);
|
||||
}
|
||||
}
|
||||
|
||||
return ht;
|
||||
}
|
||||
|
||||
public virtual bool HasFastTrace
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public virtual int Trace()
|
||||
{
|
||||
int m = FieldSize;
|
||||
|
||||
//ECFieldElement tr = this;
|
||||
//for (int i = 1; i < m; ++i)
|
||||
//{
|
||||
// tr = tr.Square().Add(this);
|
||||
//}
|
||||
|
||||
int k = 31 - Integers.NumberOfLeadingZeros(m);
|
||||
int mk = 1;
|
||||
|
||||
ECFieldElement tr = this;
|
||||
while (k > 0)
|
||||
{
|
||||
tr = tr.SquarePow(mk).Add(tr);
|
||||
mk = m >> --k;
|
||||
if (0 != (mk & 1))
|
||||
{
|
||||
tr = tr.Square().Add(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (tr.IsZero)
|
||||
return 0;
|
||||
if (tr.IsOne)
|
||||
return 1;
|
||||
throw new InvalidOperationException("Internal error in trace calculation");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing the Elements of the finite field
|
||||
* <code>F<sub>2<sup>m</sup></sub></code> in polynomial basis (PB)
|
||||
* representation. Both trinomial (Tpb) and pentanomial (Ppb) polynomial
|
||||
* basis representations are supported. Gaussian normal basis (GNB)
|
||||
* representation is not supported.
|
||||
*/
|
||||
public class F2mFieldElement
|
||||
: AbstractF2mFieldElement
|
||||
{
|
||||
/**
|
||||
* Indicates gaussian normal basis representation (GNB). Number chosen
|
||||
* according to X9.62. GNB is not implemented at present.
|
||||
*/
|
||||
public const int Gnb = 1;
|
||||
|
||||
/**
|
||||
* Indicates trinomial basis representation (Tpb). Number chosen
|
||||
* according to X9.62.
|
||||
*/
|
||||
public const int Tpb = 2;
|
||||
|
||||
/**
|
||||
* Indicates pentanomial basis representation (Ppb). Number chosen
|
||||
* according to X9.62.
|
||||
*/
|
||||
public const int Ppb = 3;
|
||||
|
||||
/**
|
||||
* Tpb or Ppb.
|
||||
*/
|
||||
private int representation;
|
||||
|
||||
/**
|
||||
* The exponent <code>m</code> of <code>F<sub>2<sup>m</sup></sub></code>.
|
||||
*/
|
||||
private int m;
|
||||
|
||||
private int[] ks;
|
||||
|
||||
/**
|
||||
* The <code>LongArray</code> holding the bits.
|
||||
*/
|
||||
internal LongArray x;
|
||||
|
||||
internal F2mFieldElement(int m, int[] ks, LongArray x)
|
||||
{
|
||||
this.m = m;
|
||||
this.representation = (ks.Length == 1) ? Tpb : Ppb;
|
||||
this.ks = ks;
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public override int BitLength
|
||||
{
|
||||
get { return x.Degree(); }
|
||||
}
|
||||
|
||||
public override bool IsOne
|
||||
{
|
||||
get { return x.IsOne(); }
|
||||
}
|
||||
|
||||
public override bool IsZero
|
||||
{
|
||||
get { return x.IsZero(); }
|
||||
}
|
||||
|
||||
public override bool TestBitZero()
|
||||
{
|
||||
return x.TestBitZero();
|
||||
}
|
||||
|
||||
public override BigInteger ToBigInteger()
|
||||
{
|
||||
return x.ToBigInteger();
|
||||
}
|
||||
|
||||
public override string FieldName
|
||||
{
|
||||
get { return "F2m"; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return m; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, if the ECFieldElements <code>a</code> and <code>b</code>
|
||||
* are elements of the same field <code>F<sub>2<sup>m</sup></sub></code>
|
||||
* (having the same representation).
|
||||
* @param a field element.
|
||||
* @param b field element to be compared.
|
||||
* @throws ArgumentException if <code>a</code> and <code>b</code>
|
||||
* are not elements of the same field
|
||||
* <code>F<sub>2<sup>m</sup></sub></code> (having the same
|
||||
* representation).
|
||||
*/
|
||||
public static void CheckFieldElements(
|
||||
ECFieldElement a,
|
||||
ECFieldElement b)
|
||||
{
|
||||
if (!(a is F2mFieldElement) || !(b is F2mFieldElement))
|
||||
{
|
||||
throw new ArgumentException("Field elements are not "
|
||||
+ "both instances of F2mFieldElement");
|
||||
}
|
||||
|
||||
F2mFieldElement aF2m = (F2mFieldElement)a;
|
||||
F2mFieldElement bF2m = (F2mFieldElement)b;
|
||||
|
||||
if (aF2m.representation != bF2m.representation)
|
||||
{
|
||||
// Should never occur
|
||||
throw new ArgumentException("One of the F2m field elements has incorrect representation");
|
||||
}
|
||||
|
||||
if ((aF2m.m != bF2m.m) || !Arrays.AreEqual(aF2m.ks, bF2m.ks))
|
||||
{
|
||||
throw new ArgumentException("Field elements are not elements of the same field F2m");
|
||||
}
|
||||
}
|
||||
|
||||
public override ECFieldElement Add(
|
||||
ECFieldElement b)
|
||||
{
|
||||
// No check performed here for performance reasons. Instead the
|
||||
// elements involved are checked in ECPoint.F2m
|
||||
// checkFieldElements(this, b);
|
||||
LongArray iarrClone = this.x.Copy();
|
||||
F2mFieldElement bF2m = (F2mFieldElement)b;
|
||||
iarrClone.AddShiftedByWords(bF2m.x, 0);
|
||||
return new F2mFieldElement(m, ks, iarrClone);
|
||||
}
|
||||
|
||||
public override ECFieldElement AddOne()
|
||||
{
|
||||
return new F2mFieldElement(m, ks, x.AddOne());
|
||||
}
|
||||
|
||||
public override ECFieldElement Subtract(
|
||||
ECFieldElement b)
|
||||
{
|
||||
// Addition and subtraction are the same in F2m
|
||||
return Add(b);
|
||||
}
|
||||
|
||||
public override ECFieldElement Multiply(
|
||||
ECFieldElement b)
|
||||
{
|
||||
// Right-to-left comb multiplication in the LongArray
|
||||
// Input: Binary polynomials a(z) and b(z) of degree at most m-1
|
||||
// Output: c(z) = a(z) * b(z) mod f(z)
|
||||
|
||||
// No check performed here for performance reasons. Instead the
|
||||
// elements involved are checked in ECPoint.F2m
|
||||
// checkFieldElements(this, b);
|
||||
return new F2mFieldElement(m, ks, x.ModMultiply(((F2mFieldElement)b).x, m, ks));
|
||||
}
|
||||
|
||||
public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return MultiplyPlusProduct(b, x, y);
|
||||
}
|
||||
|
||||
public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
LongArray ax = this.x, bx = ((F2mFieldElement)b).x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x;
|
||||
|
||||
LongArray ab = ax.Multiply(bx, m, ks);
|
||||
LongArray xy = xx.Multiply(yx, m, ks);
|
||||
|
||||
if (LongArray.AreAliased(ref ab, ref ax) || LongArray.AreAliased(ref ab, ref bx))
|
||||
{
|
||||
ab = ab.Copy();
|
||||
}
|
||||
|
||||
ab.AddShiftedByWords(xy, 0);
|
||||
ab.Reduce(m, ks);
|
||||
|
||||
return new F2mFieldElement(m, ks, ab);
|
||||
}
|
||||
|
||||
public override ECFieldElement Divide(
|
||||
ECFieldElement b)
|
||||
{
|
||||
// There may be more efficient implementations
|
||||
ECFieldElement bInv = b.Invert();
|
||||
return Multiply(bInv);
|
||||
}
|
||||
|
||||
public override ECFieldElement Negate()
|
||||
{
|
||||
// -x == x holds for all x in F2m
|
||||
return this;
|
||||
}
|
||||
|
||||
public override ECFieldElement Square()
|
||||
{
|
||||
return new F2mFieldElement(m, ks, x.ModSquare(m, ks));
|
||||
}
|
||||
|
||||
public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return SquarePlusProduct(x, y);
|
||||
}
|
||||
|
||||
public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
LongArray ax = this.x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x;
|
||||
|
||||
LongArray aa = ax.Square(m, ks);
|
||||
LongArray xy = xx.Multiply(yx, m, ks);
|
||||
|
||||
if (LongArray.AreAliased(ref aa, ref ax))
|
||||
{
|
||||
aa = aa.Copy();
|
||||
}
|
||||
|
||||
aa.AddShiftedByWords(xy, 0);
|
||||
aa.Reduce(m, ks);
|
||||
|
||||
return new F2mFieldElement(m, ks, aa);
|
||||
}
|
||||
|
||||
public override ECFieldElement SquarePow(int pow)
|
||||
{
|
||||
return pow < 1 ? this : new F2mFieldElement(m, ks, x.ModSquareN(pow, m, ks));
|
||||
}
|
||||
|
||||
public override ECFieldElement Invert()
|
||||
{
|
||||
return new F2mFieldElement(this.m, this.ks, this.x.ModInverse(m, ks));
|
||||
}
|
||||
|
||||
public override ECFieldElement Sqrt()
|
||||
{
|
||||
return (x.IsZero() || x.IsOne()) ? this : SquarePow(m - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the representation of the field
|
||||
* <code>F<sub>2<sup>m</sup></sub></code>, either of
|
||||
* {@link F2mFieldElement.Tpb} (trinomial
|
||||
* basis representation) or
|
||||
* {@link F2mFieldElement.Ppb} (pentanomial
|
||||
* basis representation).
|
||||
*/
|
||||
public int Representation
|
||||
{
|
||||
get { return this.representation; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the degree <code>m</code> of the reduction polynomial
|
||||
* <code>f(z)</code>.
|
||||
*/
|
||||
public int M
|
||||
{
|
||||
get { return this.m; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Tpb: The integer <code>k</code> where <code>x<sup>m</sup> +
|
||||
* x<sup>k</sup> + 1</code> represents the reduction polynomial
|
||||
* <code>f(z)</code>.<br/>
|
||||
* Ppb: The integer <code>k1</code> where <code>x<sup>m</sup> +
|
||||
* x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
|
||||
* represents the reduction polynomial <code>f(z)</code>.<br/>
|
||||
*/
|
||||
public int K1
|
||||
{
|
||||
get { return this.ks[0]; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Tpb: Always returns <code>0</code><br/>
|
||||
* Ppb: The integer <code>k2</code> where <code>x<sup>m</sup> +
|
||||
* x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
|
||||
* represents the reduction polynomial <code>f(z)</code>.<br/>
|
||||
*/
|
||||
public int K2
|
||||
{
|
||||
get { return this.ks.Length >= 2 ? this.ks[1] : 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Tpb: Always set to <code>0</code><br/>
|
||||
* Ppb: The integer <code>k3</code> where <code>x<sup>m</sup> +
|
||||
* x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
|
||||
* represents the reduction polynomial <code>f(z)</code>.<br/>
|
||||
*/
|
||||
public int K3
|
||||
{
|
||||
get { return this.ks.Length >= 3 ? this.ks[2] : 0; }
|
||||
}
|
||||
|
||||
public override bool Equals(
|
||||
object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
F2mFieldElement other = obj as F2mFieldElement;
|
||||
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
return Equals(other);
|
||||
}
|
||||
|
||||
public virtual bool Equals(
|
||||
F2mFieldElement other)
|
||||
{
|
||||
return ((this.m == other.m)
|
||||
&& (this.representation == other.representation)
|
||||
&& Arrays.AreEqual(this.ks, other.ks)
|
||||
&& (this.x.Equals(other.x)));
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return x.GetHashCode() ^ m ^ Arrays.GetHashCode(ks);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c83e7d57be27b5d428630a56b05d18a1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,15 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC
|
||||
{
|
||||
public interface ECLookupTable
|
||||
{
|
||||
int Size { get; }
|
||||
ECPoint Lookup(int index);
|
||||
ECPoint LookupVar(int index);
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6bf6a19f32e54374cbf2f2354aedc71e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0708bb98a46600e47b0eee7ea6b0d44d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,13 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC
|
||||
{
|
||||
public interface ECPointMap
|
||||
{
|
||||
ECPoint Map(ECPoint p);
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b16b78238477b4749b0ad4ff2a2bcf28
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c64005ee201237e4fb747b16625d3307
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,24 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC
|
||||
{
|
||||
public class ScaleXNegateYPointMap
|
||||
: ECPointMap
|
||||
{
|
||||
protected readonly ECFieldElement scale;
|
||||
|
||||
public ScaleXNegateYPointMap(ECFieldElement scale)
|
||||
{
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public virtual ECPoint Map(ECPoint p)
|
||||
{
|
||||
return p.ScaleXNegateY(scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7aaf91c41b94fe94abe7ac7eb28506c3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,24 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC
|
||||
{
|
||||
public class ScaleXPointMap
|
||||
: ECPointMap
|
||||
{
|
||||
protected readonly ECFieldElement scale;
|
||||
|
||||
public ScaleXPointMap(ECFieldElement scale)
|
||||
{
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public virtual ECPoint Map(ECPoint p)
|
||||
{
|
||||
return p.ScaleX(scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9dfd9f72fc2d48e42b878a2169f7e4d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,24 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC
|
||||
{
|
||||
public class ScaleYNegateXPointMap
|
||||
: ECPointMap
|
||||
{
|
||||
protected readonly ECFieldElement scale;
|
||||
|
||||
public ScaleYNegateXPointMap(ECFieldElement scale)
|
||||
{
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public virtual ECPoint Map(ECPoint p)
|
||||
{
|
||||
return p.ScaleYNegateX(scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6dba7a7d14e9d61449311c3d6c5af9a0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,24 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC
|
||||
{
|
||||
public class ScaleYPointMap
|
||||
: ECPointMap
|
||||
{
|
||||
protected readonly ECFieldElement scale;
|
||||
|
||||
public ScaleYPointMap(ECFieldElement scale)
|
||||
{
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public virtual ECPoint Map(ECPoint p)
|
||||
{
|
||||
return p.ScaleY(scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0012fa428aef224e95dfcbacde294a1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,44 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC
|
||||
{
|
||||
public class SimpleLookupTable
|
||||
: AbstractECLookupTable
|
||||
{
|
||||
private static ECPoint[] Copy(ECPoint[] points, int off, int len)
|
||||
{
|
||||
ECPoint[] result = new ECPoint[len];
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
result[i] = points[off + i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private readonly ECPoint[] points;
|
||||
|
||||
public SimpleLookupTable(ECPoint[] points, int off, int len)
|
||||
{
|
||||
this.points = Copy(points, off, len);
|
||||
}
|
||||
|
||||
public override int Size
|
||||
{
|
||||
get { return points.Length; }
|
||||
}
|
||||
|
||||
public override ECPoint Lookup(int index)
|
||||
{
|
||||
throw new NotSupportedException("Constant-time lookup not supported");
|
||||
}
|
||||
|
||||
public override ECPoint LookupVar(int index)
|
||||
{
|
||||
return points[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31b37f390092cbf49912e6eec081a533
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40e69c1e558a62e4cb5a52d30eb8fdfd
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,245 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Abc
|
||||
{
|
||||
/**
|
||||
* Class representing a simple version of a big decimal. A
|
||||
* <code>SimpleBigDecimal</code> is basically a
|
||||
* {@link java.math.BigInteger BigInteger} with a few digits on the right of
|
||||
* the decimal point. The number of (binary) digits on the right of the decimal
|
||||
* point is called the <code>scale</code> of the <code>SimpleBigDecimal</code>.
|
||||
* Unlike in {@link java.math.BigDecimal BigDecimal}, the scale is not adjusted
|
||||
* automatically, but must be set manually. All <code>SimpleBigDecimal</code>s
|
||||
* taking part in the same arithmetic operation must have equal scale. The
|
||||
* result of a multiplication of two <code>SimpleBigDecimal</code>s returns a
|
||||
* <code>SimpleBigDecimal</code> with double scale.
|
||||
*/
|
||||
internal class SimpleBigDecimal
|
||||
// : Number
|
||||
{
|
||||
// private static final long serialVersionUID = 1L;
|
||||
|
||||
private readonly BigInteger bigInt;
|
||||
private readonly int scale;
|
||||
|
||||
/**
|
||||
* Returns a <code>SimpleBigDecimal</code> representing the same numerical
|
||||
* value as <code>value</code>.
|
||||
* @param value The value of the <code>SimpleBigDecimal</code> to be
|
||||
* created.
|
||||
* @param scale The scale of the <code>SimpleBigDecimal</code> to be
|
||||
* created.
|
||||
* @return The such created <code>SimpleBigDecimal</code>.
|
||||
*/
|
||||
public static SimpleBigDecimal GetInstance(BigInteger val, int scale)
|
||||
{
|
||||
return new SimpleBigDecimal(val.ShiftLeft(scale), scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for <code>SimpleBigDecimal</code>. The value of the
|
||||
* constructed <code>SimpleBigDecimal</code> Equals <code>bigInt /
|
||||
* 2<sup>scale</sup></code>.
|
||||
* @param bigInt The <code>bigInt</code> value parameter.
|
||||
* @param scale The scale of the constructed <code>SimpleBigDecimal</code>.
|
||||
*/
|
||||
public SimpleBigDecimal(BigInteger bigInt, int scale)
|
||||
{
|
||||
if (scale < 0)
|
||||
throw new ArgumentException("scale may not be negative");
|
||||
|
||||
this.bigInt = bigInt;
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
private SimpleBigDecimal(SimpleBigDecimal limBigDec)
|
||||
{
|
||||
bigInt = limBigDec.bigInt;
|
||||
scale = limBigDec.scale;
|
||||
}
|
||||
|
||||
private void CheckScale(SimpleBigDecimal b)
|
||||
{
|
||||
if (scale != b.scale)
|
||||
throw new ArgumentException("Only SimpleBigDecimal of same scale allowed in arithmetic operations");
|
||||
}
|
||||
|
||||
public SimpleBigDecimal AdjustScale(int newScale)
|
||||
{
|
||||
if (newScale < 0)
|
||||
throw new ArgumentException("scale may not be negative");
|
||||
|
||||
if (newScale == scale)
|
||||
return this;
|
||||
|
||||
return new SimpleBigDecimal(bigInt.ShiftLeft(newScale - scale), newScale);
|
||||
}
|
||||
|
||||
public SimpleBigDecimal Add(SimpleBigDecimal b)
|
||||
{
|
||||
CheckScale(b);
|
||||
return new SimpleBigDecimal(bigInt.Add(b.bigInt), scale);
|
||||
}
|
||||
|
||||
public SimpleBigDecimal Add(BigInteger b)
|
||||
{
|
||||
return new SimpleBigDecimal(bigInt.Add(b.ShiftLeft(scale)), scale);
|
||||
}
|
||||
|
||||
public SimpleBigDecimal Negate()
|
||||
{
|
||||
return new SimpleBigDecimal(bigInt.Negate(), scale);
|
||||
}
|
||||
|
||||
public SimpleBigDecimal Subtract(SimpleBigDecimal b)
|
||||
{
|
||||
return Add(b.Negate());
|
||||
}
|
||||
|
||||
public SimpleBigDecimal Subtract(BigInteger b)
|
||||
{
|
||||
return new SimpleBigDecimal(bigInt.Subtract(b.ShiftLeft(scale)), scale);
|
||||
}
|
||||
|
||||
public SimpleBigDecimal Multiply(SimpleBigDecimal b)
|
||||
{
|
||||
CheckScale(b);
|
||||
return new SimpleBigDecimal(bigInt.Multiply(b.bigInt), scale + scale);
|
||||
}
|
||||
|
||||
public SimpleBigDecimal Multiply(BigInteger b)
|
||||
{
|
||||
return new SimpleBigDecimal(bigInt.Multiply(b), scale);
|
||||
}
|
||||
|
||||
public SimpleBigDecimal Divide(SimpleBigDecimal b)
|
||||
{
|
||||
CheckScale(b);
|
||||
BigInteger dividend = bigInt.ShiftLeft(scale);
|
||||
return new SimpleBigDecimal(dividend.Divide(b.bigInt), scale);
|
||||
}
|
||||
|
||||
public SimpleBigDecimal Divide(BigInteger b)
|
||||
{
|
||||
return new SimpleBigDecimal(bigInt.Divide(b), scale);
|
||||
}
|
||||
|
||||
public SimpleBigDecimal ShiftLeft(int n)
|
||||
{
|
||||
return new SimpleBigDecimal(bigInt.ShiftLeft(n), scale);
|
||||
}
|
||||
|
||||
public int CompareTo(SimpleBigDecimal val)
|
||||
{
|
||||
CheckScale(val);
|
||||
return bigInt.CompareTo(val.bigInt);
|
||||
}
|
||||
|
||||
public int CompareTo(BigInteger val)
|
||||
{
|
||||
return bigInt.CompareTo(val.ShiftLeft(scale));
|
||||
}
|
||||
|
||||
public BigInteger Floor()
|
||||
{
|
||||
return bigInt.ShiftRight(scale);
|
||||
}
|
||||
|
||||
public BigInteger Round()
|
||||
{
|
||||
SimpleBigDecimal oneHalf = new SimpleBigDecimal(BigInteger.One, 1);
|
||||
return Add(oneHalf.AdjustScale(scale)).Floor();
|
||||
}
|
||||
|
||||
public int IntValue
|
||||
{
|
||||
get { return Floor().IntValue; }
|
||||
}
|
||||
|
||||
public long LongValue
|
||||
{
|
||||
get { return Floor().LongValue; }
|
||||
}
|
||||
|
||||
// public double doubleValue()
|
||||
// {
|
||||
// return new Double(ToString()).doubleValue();
|
||||
// }
|
||||
//
|
||||
// public float floatValue()
|
||||
// {
|
||||
// return new Float(ToString()).floatValue();
|
||||
// }
|
||||
|
||||
public int Scale
|
||||
{
|
||||
get { return scale; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (scale == 0)
|
||||
return bigInt.ToString();
|
||||
|
||||
BigInteger floorBigInt = Floor();
|
||||
|
||||
BigInteger fract = bigInt.Subtract(floorBigInt.ShiftLeft(scale));
|
||||
if (bigInt.SignValue < 0)
|
||||
{
|
||||
fract = BigInteger.One.ShiftLeft(scale).Subtract(fract);
|
||||
}
|
||||
|
||||
if ((floorBigInt.SignValue == -1) && (!(fract.Equals(BigInteger.Zero))))
|
||||
{
|
||||
floorBigInt = floorBigInt.Add(BigInteger.One);
|
||||
}
|
||||
string leftOfPoint = floorBigInt.ToString();
|
||||
|
||||
char[] fractCharArr = new char[scale];
|
||||
string fractStr = fract.ToString(2);
|
||||
int fractLen = fractStr.Length;
|
||||
int zeroes = scale - fractLen;
|
||||
for (int i = 0; i < zeroes; i++)
|
||||
{
|
||||
fractCharArr[i] = '0';
|
||||
}
|
||||
for (int j = 0; j < fractLen; j++)
|
||||
{
|
||||
fractCharArr[zeroes + j] = fractStr[j];
|
||||
}
|
||||
string rightOfPoint = new string(fractCharArr);
|
||||
|
||||
StringBuilder sb = new StringBuilder(leftOfPoint);
|
||||
sb.Append(".");
|
||||
sb.Append(rightOfPoint);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override bool Equals(
|
||||
object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
SimpleBigDecimal other = obj as SimpleBigDecimal;
|
||||
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
return bigInt.Equals(other.bigInt)
|
||||
&& scale == other.scale;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return bigInt.GetHashCode() ^ scale;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90b2a6bdef50756439d9f47423252e4b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,849 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Abc
|
||||
{
|
||||
/**
|
||||
* Class holding methods for point multiplication based on the window
|
||||
* τ-adic nonadjacent form (WTNAF). The algorithms are based on the
|
||||
* paper "Improved Algorithms for Arithmetic on Anomalous Binary Curves"
|
||||
* by Jerome A. Solinas. The paper first appeared in the Proceedings of
|
||||
* Crypto 1997.
|
||||
*/
|
||||
internal class Tnaf
|
||||
{
|
||||
private static readonly BigInteger MinusOne = BigInteger.One.Negate();
|
||||
private static readonly BigInteger MinusTwo = BigInteger.Two.Negate();
|
||||
private static readonly BigInteger MinusThree = BigInteger.Three.Negate();
|
||||
private static readonly BigInteger Four = BigInteger.ValueOf(4);
|
||||
|
||||
/**
|
||||
* The window width of WTNAF. The standard value of 4 is slightly less
|
||||
* than optimal for running time, but keeps space requirements for
|
||||
* precomputation low. For typical curves, a value of 5 or 6 results in
|
||||
* a better running time. When changing this value, the
|
||||
* <code>α<sub>u</sub></code>'s must be computed differently, see
|
||||
* e.g. "Guide to Elliptic Curve Cryptography", Darrel Hankerson,
|
||||
* Alfred Menezes, Scott Vanstone, Springer-Verlag New York Inc., 2004,
|
||||
* p. 121-122
|
||||
*/
|
||||
public const sbyte Width = 4;
|
||||
|
||||
/**
|
||||
* 2<sup>4</sup>
|
||||
*/
|
||||
public const sbyte Pow2Width = 16;
|
||||
|
||||
/**
|
||||
* The <code>α<sub>u</sub></code>'s for <code>a=0</code> as an array
|
||||
* of <code>ZTauElement</code>s.
|
||||
*/
|
||||
public static readonly ZTauElement[] Alpha0 =
|
||||
{
|
||||
null,
|
||||
new ZTauElement(BigInteger.One, BigInteger.Zero), null,
|
||||
new ZTauElement(MinusThree, MinusOne), null,
|
||||
new ZTauElement(MinusOne, MinusOne), null,
|
||||
new ZTauElement(BigInteger.One, MinusOne), null
|
||||
};
|
||||
|
||||
/**
|
||||
* The <code>α<sub>u</sub></code>'s for <code>a=0</code> as an array
|
||||
* of TNAFs.
|
||||
*/
|
||||
public static readonly sbyte[][] Alpha0Tnaf =
|
||||
{
|
||||
null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, 1}
|
||||
};
|
||||
|
||||
/**
|
||||
* The <code>α<sub>u</sub></code>'s for <code>a=1</code> as an array
|
||||
* of <code>ZTauElement</code>s.
|
||||
*/
|
||||
public static readonly ZTauElement[] Alpha1 =
|
||||
{
|
||||
null,
|
||||
new ZTauElement(BigInteger.One, BigInteger.Zero), null,
|
||||
new ZTauElement(MinusThree, BigInteger.One), null,
|
||||
new ZTauElement(MinusOne, BigInteger.One), null,
|
||||
new ZTauElement(BigInteger.One, BigInteger.One), null
|
||||
};
|
||||
|
||||
/**
|
||||
* The <code>α<sub>u</sub></code>'s for <code>a=1</code> as an array
|
||||
* of TNAFs.
|
||||
*/
|
||||
public static readonly sbyte[][] Alpha1Tnaf =
|
||||
{
|
||||
null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, -1}
|
||||
};
|
||||
|
||||
/**
|
||||
* Computes the norm of an element <code>λ</code> of
|
||||
* <code><b>Z</b>[τ]</code>.
|
||||
* @param mu The parameter <code>μ</code> of the elliptic curve.
|
||||
* @param lambda The element <code>λ</code> of
|
||||
* <code><b>Z</b>[τ]</code>.
|
||||
* @return The norm of <code>λ</code>.
|
||||
*/
|
||||
public static BigInteger Norm(sbyte mu, ZTauElement lambda)
|
||||
{
|
||||
BigInteger norm;
|
||||
|
||||
// s1 = u^2
|
||||
BigInteger s1 = lambda.u.Multiply(lambda.u);
|
||||
|
||||
// s2 = u * v
|
||||
BigInteger s2 = lambda.u.Multiply(lambda.v);
|
||||
|
||||
// s3 = 2 * v^2
|
||||
BigInteger s3 = lambda.v.Multiply(lambda.v).ShiftLeft(1);
|
||||
|
||||
if (mu == 1)
|
||||
{
|
||||
norm = s1.Add(s2).Add(s3);
|
||||
}
|
||||
else if (mu == -1)
|
||||
{
|
||||
norm = s1.Subtract(s2).Add(s3);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("mu must be 1 or -1");
|
||||
}
|
||||
|
||||
return norm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the norm of an element <code>λ</code> of
|
||||
* <code><b>R</b>[τ]</code>, where <code>λ = u + vτ</code>
|
||||
* and <code>u</code> and <code>u</code> are real numbers (elements of
|
||||
* <code><b>R</b></code>).
|
||||
* @param mu The parameter <code>μ</code> of the elliptic curve.
|
||||
* @param u The real part of the element <code>λ</code> of
|
||||
* <code><b>R</b>[τ]</code>.
|
||||
* @param v The <code>τ</code>-adic part of the element
|
||||
* <code>λ</code> of <code><b>R</b>[τ]</code>.
|
||||
* @return The norm of <code>λ</code>.
|
||||
*/
|
||||
public static SimpleBigDecimal Norm(sbyte mu, SimpleBigDecimal u, SimpleBigDecimal v)
|
||||
{
|
||||
SimpleBigDecimal norm;
|
||||
|
||||
// s1 = u^2
|
||||
SimpleBigDecimal s1 = u.Multiply(u);
|
||||
|
||||
// s2 = u * v
|
||||
SimpleBigDecimal s2 = u.Multiply(v);
|
||||
|
||||
// s3 = 2 * v^2
|
||||
SimpleBigDecimal s3 = v.Multiply(v).ShiftLeft(1);
|
||||
|
||||
if (mu == 1)
|
||||
{
|
||||
norm = s1.Add(s2).Add(s3);
|
||||
}
|
||||
else if (mu == -1)
|
||||
{
|
||||
norm = s1.Subtract(s2).Add(s3);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("mu must be 1 or -1");
|
||||
}
|
||||
|
||||
return norm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rounds an element <code>λ</code> of <code><b>R</b>[τ]</code>
|
||||
* to an element of <code><b>Z</b>[τ]</code>, such that their difference
|
||||
* has minimal norm. <code>λ</code> is given as
|
||||
* <code>λ = λ<sub>0</sub> + λ<sub>1</sub>τ</code>.
|
||||
* @param lambda0 The component <code>λ<sub>0</sub></code>.
|
||||
* @param lambda1 The component <code>λ<sub>1</sub></code>.
|
||||
* @param mu The parameter <code>μ</code> of the elliptic curve. Must
|
||||
* equal 1 or -1.
|
||||
* @return The rounded element of <code><b>Z</b>[τ]</code>.
|
||||
* @throws ArgumentException if <code>lambda0</code> and
|
||||
* <code>lambda1</code> do not have same scale.
|
||||
*/
|
||||
public static ZTauElement Round(SimpleBigDecimal lambda0,
|
||||
SimpleBigDecimal lambda1, sbyte mu)
|
||||
{
|
||||
int scale = lambda0.Scale;
|
||||
if (lambda1.Scale != scale)
|
||||
throw new ArgumentException("lambda0 and lambda1 do not have same scale");
|
||||
|
||||
if (!((mu == 1) || (mu == -1)))
|
||||
throw new ArgumentException("mu must be 1 or -1");
|
||||
|
||||
BigInteger f0 = lambda0.Round();
|
||||
BigInteger f1 = lambda1.Round();
|
||||
|
||||
SimpleBigDecimal eta0 = lambda0.Subtract(f0);
|
||||
SimpleBigDecimal eta1 = lambda1.Subtract(f1);
|
||||
|
||||
// eta = 2*eta0 + mu*eta1
|
||||
SimpleBigDecimal eta = eta0.Add(eta0);
|
||||
if (mu == 1)
|
||||
{
|
||||
eta = eta.Add(eta1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// mu == -1
|
||||
eta = eta.Subtract(eta1);
|
||||
}
|
||||
|
||||
// check1 = eta0 - 3*mu*eta1
|
||||
// check2 = eta0 + 4*mu*eta1
|
||||
SimpleBigDecimal threeEta1 = eta1.Add(eta1).Add(eta1);
|
||||
SimpleBigDecimal fourEta1 = threeEta1.Add(eta1);
|
||||
SimpleBigDecimal check1;
|
||||
SimpleBigDecimal check2;
|
||||
if (mu == 1)
|
||||
{
|
||||
check1 = eta0.Subtract(threeEta1);
|
||||
check2 = eta0.Add(fourEta1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// mu == -1
|
||||
check1 = eta0.Add(threeEta1);
|
||||
check2 = eta0.Subtract(fourEta1);
|
||||
}
|
||||
|
||||
sbyte h0 = 0;
|
||||
sbyte h1 = 0;
|
||||
|
||||
// if eta >= 1
|
||||
if (eta.CompareTo(BigInteger.One) >= 0)
|
||||
{
|
||||
if (check1.CompareTo(MinusOne) < 0)
|
||||
{
|
||||
h1 = mu;
|
||||
}
|
||||
else
|
||||
{
|
||||
h0 = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// eta < 1
|
||||
if (check2.CompareTo(BigInteger.Two) >= 0)
|
||||
{
|
||||
h1 = mu;
|
||||
}
|
||||
}
|
||||
|
||||
// if eta < -1
|
||||
if (eta.CompareTo(MinusOne) < 0)
|
||||
{
|
||||
if (check1.CompareTo(BigInteger.One) >= 0)
|
||||
{
|
||||
h1 = (sbyte)-mu;
|
||||
}
|
||||
else
|
||||
{
|
||||
h0 = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// eta >= -1
|
||||
if (check2.CompareTo(MinusTwo) < 0)
|
||||
{
|
||||
h1 = (sbyte)-mu;
|
||||
}
|
||||
}
|
||||
|
||||
BigInteger q0 = f0.Add(BigInteger.ValueOf(h0));
|
||||
BigInteger q1 = f1.Add(BigInteger.ValueOf(h1));
|
||||
return new ZTauElement(q0, q1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Approximate division by <code>n</code>. For an integer
|
||||
* <code>k</code>, the value <code>λ = s k / n</code> is
|
||||
* computed to <code>c</code> bits of accuracy.
|
||||
* @param k The parameter <code>k</code>.
|
||||
* @param s The curve parameter <code>s<sub>0</sub></code> or
|
||||
* <code>s<sub>1</sub></code>.
|
||||
* @param vm The Lucas Sequence element <code>V<sub>m</sub></code>.
|
||||
* @param a The parameter <code>a</code> of the elliptic curve.
|
||||
* @param m The bit length of the finite field
|
||||
* <code><b>F</b><sub>m</sub></code>.
|
||||
* @param c The number of bits of accuracy, i.e. the scale of the returned
|
||||
* <code>SimpleBigDecimal</code>.
|
||||
* @return The value <code>λ = s k / n</code> computed to
|
||||
* <code>c</code> bits of accuracy.
|
||||
*/
|
||||
public static SimpleBigDecimal ApproximateDivisionByN(BigInteger k,
|
||||
BigInteger s, BigInteger vm, sbyte a, int m, int c)
|
||||
{
|
||||
int _k = (m + 5)/2 + c;
|
||||
BigInteger ns = k.ShiftRight(m - _k - 2 + a);
|
||||
|
||||
BigInteger gs = s.Multiply(ns);
|
||||
|
||||
BigInteger hs = gs.ShiftRight(m);
|
||||
|
||||
BigInteger js = vm.Multiply(hs);
|
||||
|
||||
BigInteger gsPlusJs = gs.Add(js);
|
||||
BigInteger ls = gsPlusJs.ShiftRight(_k-c);
|
||||
if (gsPlusJs.TestBit(_k-c-1))
|
||||
{
|
||||
// round up
|
||||
ls = ls.Add(BigInteger.One);
|
||||
}
|
||||
|
||||
return new SimpleBigDecimal(ls, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the <code>τ</code>-adic NAF (non-adjacent form) of an
|
||||
* element <code>λ</code> of <code><b>Z</b>[τ]</code>.
|
||||
* @param mu The parameter <code>μ</code> of the elliptic curve.
|
||||
* @param lambda The element <code>λ</code> of
|
||||
* <code><b>Z</b>[τ]</code>.
|
||||
* @return The <code>τ</code>-adic NAF of <code>λ</code>.
|
||||
*/
|
||||
public static sbyte[] TauAdicNaf(sbyte mu, ZTauElement lambda)
|
||||
{
|
||||
if (!((mu == 1) || (mu == -1)))
|
||||
throw new ArgumentException("mu must be 1 or -1");
|
||||
|
||||
BigInteger norm = Norm(mu, lambda);
|
||||
|
||||
// Ceiling of log2 of the norm
|
||||
int log2Norm = norm.BitLength;
|
||||
|
||||
// If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52
|
||||
int maxLength = log2Norm > 30 ? log2Norm + 4 : 34;
|
||||
|
||||
// The array holding the TNAF
|
||||
sbyte[] u = new sbyte[maxLength];
|
||||
int i = 0;
|
||||
|
||||
// The actual length of the TNAF
|
||||
int length = 0;
|
||||
|
||||
BigInteger r0 = lambda.u;
|
||||
BigInteger r1 = lambda.v;
|
||||
|
||||
while(!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero))))
|
||||
{
|
||||
// If r0 is odd
|
||||
if (r0.TestBit(0))
|
||||
{
|
||||
u[i] = (sbyte) BigInteger.Two.Subtract((r0.Subtract(r1.ShiftLeft(1))).Mod(Four)).IntValue;
|
||||
|
||||
// r0 = r0 - u[i]
|
||||
if (u[i] == 1)
|
||||
{
|
||||
r0 = r0.ClearBit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// u[i] == -1
|
||||
r0 = r0.Add(BigInteger.One);
|
||||
}
|
||||
length = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
u[i] = 0;
|
||||
}
|
||||
|
||||
BigInteger t = r0;
|
||||
BigInteger s = r0.ShiftRight(1);
|
||||
if (mu == 1)
|
||||
{
|
||||
r0 = r1.Add(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
// mu == -1
|
||||
r0 = r1.Subtract(s);
|
||||
}
|
||||
|
||||
r1 = t.ShiftRight(1).Negate();
|
||||
i++;
|
||||
}
|
||||
|
||||
length++;
|
||||
|
||||
// Reduce the TNAF array to its actual length
|
||||
sbyte[] tnaf = new sbyte[length];
|
||||
Array.Copy(u, 0, tnaf, 0, length);
|
||||
return tnaf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the operation <code>τ()</code> to an
|
||||
* <code>AbstractF2mPoint</code>.
|
||||
* @param p The AbstractF2mPoint to which <code>τ()</code> is applied.
|
||||
* @return <code>τ(p)</code>
|
||||
*/
|
||||
public static AbstractF2mPoint Tau(AbstractF2mPoint p)
|
||||
{
|
||||
return p.Tau();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parameter <code>μ</code> of the elliptic curve.
|
||||
* @param curve The elliptic curve from which to obtain <code>μ</code>.
|
||||
* The curve must be a Koblitz curve, i.e. <code>a</code> Equals
|
||||
* <code>0</code> or <code>1</code> and <code>b</code> Equals
|
||||
* <code>1</code>.
|
||||
* @return <code>μ</code> of the elliptic curve.
|
||||
* @throws ArgumentException if the given ECCurve is not a Koblitz
|
||||
* curve.
|
||||
*/
|
||||
public static sbyte GetMu(AbstractF2mCurve curve)
|
||||
{
|
||||
BigInteger a = curve.A.ToBigInteger();
|
||||
|
||||
sbyte mu;
|
||||
if (a.SignValue == 0)
|
||||
{
|
||||
mu = -1;
|
||||
}
|
||||
else if (a.Equals(BigInteger.One))
|
||||
{
|
||||
mu = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("No Koblitz curve (ABC), TNAF multiplication not possible");
|
||||
}
|
||||
return mu;
|
||||
}
|
||||
|
||||
public static sbyte GetMu(ECFieldElement curveA)
|
||||
{
|
||||
return (sbyte)(curveA.IsZero ? -1 : 1);
|
||||
}
|
||||
|
||||
public static sbyte GetMu(int curveA)
|
||||
{
|
||||
return (sbyte)(curveA == 0 ? -1 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the Lucas Sequence elements <code>U<sub>k-1</sub></code> and
|
||||
* <code>U<sub>k</sub></code> or <code>V<sub>k-1</sub></code> and
|
||||
* <code>V<sub>k</sub></code>.
|
||||
* @param mu The parameter <code>μ</code> of the elliptic curve.
|
||||
* @param k The index of the second element of the Lucas Sequence to be
|
||||
* returned.
|
||||
* @param doV If set to true, computes <code>V<sub>k-1</sub></code> and
|
||||
* <code>V<sub>k</sub></code>, otherwise <code>U<sub>k-1</sub></code> and
|
||||
* <code>U<sub>k</sub></code>.
|
||||
* @return An array with 2 elements, containing <code>U<sub>k-1</sub></code>
|
||||
* and <code>U<sub>k</sub></code> or <code>V<sub>k-1</sub></code>
|
||||
* and <code>V<sub>k</sub></code>.
|
||||
*/
|
||||
public static BigInteger[] GetLucas(sbyte mu, int k, bool doV)
|
||||
{
|
||||
if (!(mu == 1 || mu == -1))
|
||||
throw new ArgumentException("mu must be 1 or -1");
|
||||
|
||||
BigInteger u0;
|
||||
BigInteger u1;
|
||||
BigInteger u2;
|
||||
|
||||
if (doV)
|
||||
{
|
||||
u0 = BigInteger.Two;
|
||||
u1 = BigInteger.ValueOf(mu);
|
||||
}
|
||||
else
|
||||
{
|
||||
u0 = BigInteger.Zero;
|
||||
u1 = BigInteger.One;
|
||||
}
|
||||
|
||||
for (int i = 1; i < k; i++)
|
||||
{
|
||||
// u2 = mu*u1 - 2*u0;
|
||||
BigInteger s = null;
|
||||
if (mu == 1)
|
||||
{
|
||||
s = u1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// mu == -1
|
||||
s = u1.Negate();
|
||||
}
|
||||
|
||||
u2 = s.Subtract(u0.ShiftLeft(1));
|
||||
u0 = u1;
|
||||
u1 = u2;
|
||||
// System.out.println(i + ": " + u2);
|
||||
// System.out.println();
|
||||
}
|
||||
|
||||
BigInteger[] retVal = {u0, u1};
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the auxiliary value <code>t<sub>w</sub></code>. If the width is
|
||||
* 4, then for <code>mu = 1</code>, <code>t<sub>w</sub> = 6</code> and for
|
||||
* <code>mu = -1</code>, <code>t<sub>w</sub> = 10</code>
|
||||
* @param mu The parameter <code>μ</code> of the elliptic curve.
|
||||
* @param w The window width of the WTNAF.
|
||||
* @return the auxiliary value <code>t<sub>w</sub></code>
|
||||
*/
|
||||
public static BigInteger GetTw(sbyte mu, int w)
|
||||
{
|
||||
if (w == 4)
|
||||
{
|
||||
if (mu == 1)
|
||||
{
|
||||
return BigInteger.ValueOf(6);
|
||||
}
|
||||
else
|
||||
{
|
||||
// mu == -1
|
||||
return BigInteger.ValueOf(10);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For w <> 4, the values must be computed
|
||||
BigInteger[] us = GetLucas(mu, w, false);
|
||||
BigInteger twoToW = BigInteger.Zero.SetBit(w);
|
||||
BigInteger u1invert = us[1].ModInverse(twoToW);
|
||||
BigInteger tw;
|
||||
tw = BigInteger.Two.Multiply(us[0]).Multiply(u1invert).Mod(twoToW);
|
||||
//System.out.println("mu = " + mu);
|
||||
//System.out.println("tw = " + tw);
|
||||
return tw;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the auxiliary values <code>s<sub>0</sub></code> and
|
||||
* <code>s<sub>1</sub></code> used for partial modular reduction.
|
||||
* @param curve The elliptic curve for which to compute
|
||||
* <code>s<sub>0</sub></code> and <code>s<sub>1</sub></code>.
|
||||
* @throws ArgumentException if <code>curve</code> is not a
|
||||
* Koblitz curve (Anomalous Binary Curve, ABC).
|
||||
*/
|
||||
public static BigInteger[] GetSi(AbstractF2mCurve curve)
|
||||
{
|
||||
if (!curve.IsKoblitz)
|
||||
throw new ArgumentException("si is defined for Koblitz curves only");
|
||||
|
||||
int m = curve.FieldSize;
|
||||
int a = curve.A.ToBigInteger().IntValue;
|
||||
sbyte mu = GetMu(a);
|
||||
int shifts = GetShiftsForCofactor(curve.Cofactor);
|
||||
int index = m + 3 - a;
|
||||
BigInteger[] ui = GetLucas(mu, index, false);
|
||||
|
||||
if (mu == 1)
|
||||
{
|
||||
ui[0] = ui[0].Negate();
|
||||
ui[1] = ui[1].Negate();
|
||||
}
|
||||
|
||||
BigInteger dividend0 = BigInteger.One.Add(ui[1]).ShiftRight(shifts);
|
||||
BigInteger dividend1 = BigInteger.One.Add(ui[0]).ShiftRight(shifts).Negate();
|
||||
|
||||
return new BigInteger[] { dividend0, dividend1 };
|
||||
}
|
||||
|
||||
public static BigInteger[] GetSi(int fieldSize, int curveA, BigInteger cofactor)
|
||||
{
|
||||
sbyte mu = GetMu(curveA);
|
||||
int shifts = GetShiftsForCofactor(cofactor);
|
||||
int index = fieldSize + 3 - curveA;
|
||||
BigInteger[] ui = GetLucas(mu, index, false);
|
||||
if (mu == 1)
|
||||
{
|
||||
ui[0] = ui[0].Negate();
|
||||
ui[1] = ui[1].Negate();
|
||||
}
|
||||
|
||||
BigInteger dividend0 = BigInteger.One.Add(ui[1]).ShiftRight(shifts);
|
||||
BigInteger dividend1 = BigInteger.One.Add(ui[0]).ShiftRight(shifts).Negate();
|
||||
|
||||
return new BigInteger[] { dividend0, dividend1 };
|
||||
}
|
||||
|
||||
protected static int GetShiftsForCofactor(BigInteger h)
|
||||
{
|
||||
if (h != null && h.BitLength < 4)
|
||||
{
|
||||
int hi = h.IntValue;
|
||||
if (hi == 2)
|
||||
return 1;
|
||||
if (hi == 4)
|
||||
return 2;
|
||||
}
|
||||
|
||||
throw new ArgumentException("h (Cofactor) must be 2 or 4");
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial modular reduction modulo
|
||||
* <code>(τ<sup>m</sup> - 1)/(τ - 1)</code>.
|
||||
* @param k The integer to be reduced.
|
||||
* @param m The bitlength of the underlying finite field.
|
||||
* @param a The parameter <code>a</code> of the elliptic curve.
|
||||
* @param s The auxiliary values <code>s<sub>0</sub></code> and
|
||||
* <code>s<sub>1</sub></code>.
|
||||
* @param mu The parameter μ of the elliptic curve.
|
||||
* @param c The precision (number of bits of accuracy) of the partial
|
||||
* modular reduction.
|
||||
* @return <code>ρ := k partmod (τ<sup>m</sup> - 1)/(τ - 1)</code>
|
||||
*/
|
||||
public static ZTauElement PartModReduction(BigInteger k, int m, sbyte a,
|
||||
BigInteger[] s, sbyte mu, sbyte c)
|
||||
{
|
||||
// d0 = s[0] + mu*s[1]; mu is either 1 or -1
|
||||
BigInteger d0;
|
||||
if (mu == 1)
|
||||
{
|
||||
d0 = s[0].Add(s[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
d0 = s[0].Subtract(s[1]);
|
||||
}
|
||||
|
||||
BigInteger[] v = GetLucas(mu, m, true);
|
||||
BigInteger vm = v[1];
|
||||
|
||||
SimpleBigDecimal lambda0 = ApproximateDivisionByN(
|
||||
k, s[0], vm, a, m, c);
|
||||
|
||||
SimpleBigDecimal lambda1 = ApproximateDivisionByN(
|
||||
k, s[1], vm, a, m, c);
|
||||
|
||||
ZTauElement q = Round(lambda0, lambda1, mu);
|
||||
|
||||
// r0 = n - d0*q0 - 2*s1*q1
|
||||
BigInteger r0 = k.Subtract(d0.Multiply(q.u)).Subtract(
|
||||
BigInteger.ValueOf(2).Multiply(s[1]).Multiply(q.v));
|
||||
|
||||
// r1 = s1*q0 - s0*q1
|
||||
BigInteger r1 = s[1].Multiply(q.u).Subtract(s[0].Multiply(q.v));
|
||||
|
||||
return new ZTauElement(r0, r1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint}
|
||||
* by a <code>BigInteger</code> using the reduced <code>τ</code>-adic
|
||||
* NAF (RTNAF) method.
|
||||
* @param p The AbstractF2mPoint to Multiply.
|
||||
* @param k The <code>BigInteger</code> by which to Multiply <code>p</code>.
|
||||
* @return <code>k * p</code>
|
||||
*/
|
||||
public static AbstractF2mPoint MultiplyRTnaf(AbstractF2mPoint p, BigInteger k)
|
||||
{
|
||||
AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve;
|
||||
int m = curve.FieldSize;
|
||||
int a = curve.A.ToBigInteger().IntValue;
|
||||
sbyte mu = GetMu(a);
|
||||
BigInteger[] s = curve.GetSi();
|
||||
ZTauElement rho = PartModReduction(k, m, (sbyte)a, s, mu, (sbyte)10);
|
||||
|
||||
return MultiplyTnaf(p, rho);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint}
|
||||
* by an element <code>λ</code> of <code><b>Z</b>[τ]</code>
|
||||
* using the <code>τ</code>-adic NAF (TNAF) method.
|
||||
* @param p The AbstractF2mPoint to Multiply.
|
||||
* @param lambda The element <code>λ</code> of
|
||||
* <code><b>Z</b>[τ]</code>.
|
||||
* @return <code>λ * p</code>
|
||||
*/
|
||||
public static AbstractF2mPoint MultiplyTnaf(AbstractF2mPoint p, ZTauElement lambda)
|
||||
{
|
||||
AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve;
|
||||
sbyte mu = GetMu(curve.A);
|
||||
sbyte[] u = TauAdicNaf(mu, lambda);
|
||||
|
||||
AbstractF2mPoint q = MultiplyFromTnaf(p, u);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint}
|
||||
* by an element <code>λ</code> of <code><b>Z</b>[τ]</code>
|
||||
* using the <code>τ</code>-adic NAF (TNAF) method, given the TNAF
|
||||
* of <code>λ</code>.
|
||||
* @param p The AbstractF2mPoint to Multiply.
|
||||
* @param u The the TNAF of <code>λ</code>..
|
||||
* @return <code>λ * p</code>
|
||||
*/
|
||||
public static AbstractF2mPoint MultiplyFromTnaf(AbstractF2mPoint p, sbyte[] u)
|
||||
{
|
||||
ECCurve curve = p.Curve;
|
||||
AbstractF2mPoint q = (AbstractF2mPoint)curve.Infinity;
|
||||
AbstractF2mPoint pNeg = (AbstractF2mPoint)p.Negate();
|
||||
int tauCount = 0;
|
||||
for (int i = u.Length - 1; i >= 0; i--)
|
||||
{
|
||||
++tauCount;
|
||||
sbyte ui = u[i];
|
||||
if (ui != 0)
|
||||
{
|
||||
q = q.TauPow(tauCount);
|
||||
tauCount = 0;
|
||||
|
||||
ECPoint x = ui > 0 ? p : pNeg;
|
||||
q = (AbstractF2mPoint)q.Add(x);
|
||||
}
|
||||
}
|
||||
if (tauCount > 0)
|
||||
{
|
||||
q = q.TauPow(tauCount);
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the <code>[τ]</code>-adic window NAF of an element
|
||||
* <code>λ</code> of <code><b>Z</b>[τ]</code>.
|
||||
* @param mu The parameter μ of the elliptic curve.
|
||||
* @param lambda The element <code>λ</code> of
|
||||
* <code><b>Z</b>[τ]</code> of which to compute the
|
||||
* <code>[τ]</code>-adic NAF.
|
||||
* @param width The window width of the resulting WNAF.
|
||||
* @param pow2w 2<sup>width</sup>.
|
||||
* @param tw The auxiliary value <code>t<sub>w</sub></code>.
|
||||
* @param alpha The <code>α<sub>u</sub></code>'s for the window width.
|
||||
* @return The <code>[τ]</code>-adic window NAF of
|
||||
* <code>λ</code>.
|
||||
*/
|
||||
public static sbyte[] TauAdicWNaf(sbyte mu, ZTauElement lambda,
|
||||
sbyte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha)
|
||||
{
|
||||
if (!((mu == 1) || (mu == -1)))
|
||||
throw new ArgumentException("mu must be 1 or -1");
|
||||
|
||||
BigInteger norm = Norm(mu, lambda);
|
||||
|
||||
// Ceiling of log2 of the norm
|
||||
int log2Norm = norm.BitLength;
|
||||
|
||||
// If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52
|
||||
int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width;
|
||||
|
||||
// The array holding the TNAF
|
||||
sbyte[] u = new sbyte[maxLength];
|
||||
|
||||
// 2^(width - 1)
|
||||
BigInteger pow2wMin1 = pow2w.ShiftRight(1);
|
||||
|
||||
// Split lambda into two BigIntegers to simplify calculations
|
||||
BigInteger r0 = lambda.u;
|
||||
BigInteger r1 = lambda.v;
|
||||
int i = 0;
|
||||
|
||||
// while lambda <> (0, 0)
|
||||
while (!((r0.Equals(BigInteger.Zero))&&(r1.Equals(BigInteger.Zero))))
|
||||
{
|
||||
// if r0 is odd
|
||||
if (r0.TestBit(0))
|
||||
{
|
||||
// uUnMod = r0 + r1*tw Mod 2^width
|
||||
BigInteger uUnMod
|
||||
= r0.Add(r1.Multiply(tw)).Mod(pow2w);
|
||||
|
||||
sbyte uLocal;
|
||||
// if uUnMod >= 2^(width - 1)
|
||||
if (uUnMod.CompareTo(pow2wMin1) >= 0)
|
||||
{
|
||||
uLocal = (sbyte) uUnMod.Subtract(pow2w).IntValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
uLocal = (sbyte) uUnMod.IntValue;
|
||||
}
|
||||
// uLocal is now in [-2^(width-1), 2^(width-1)-1]
|
||||
|
||||
u[i] = uLocal;
|
||||
bool s = true;
|
||||
if (uLocal < 0)
|
||||
{
|
||||
s = false;
|
||||
uLocal = (sbyte)-uLocal;
|
||||
}
|
||||
// uLocal is now >= 0
|
||||
|
||||
if (s)
|
||||
{
|
||||
r0 = r0.Subtract(alpha[uLocal].u);
|
||||
r1 = r1.Subtract(alpha[uLocal].v);
|
||||
}
|
||||
else
|
||||
{
|
||||
r0 = r0.Add(alpha[uLocal].u);
|
||||
r1 = r1.Add(alpha[uLocal].v);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
u[i] = 0;
|
||||
}
|
||||
|
||||
BigInteger t = r0;
|
||||
|
||||
if (mu == 1)
|
||||
{
|
||||
r0 = r1.Add(r0.ShiftRight(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
// mu == -1
|
||||
r0 = r1.Subtract(r0.ShiftRight(1));
|
||||
}
|
||||
r1 = t.ShiftRight(1).Negate();
|
||||
i++;
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the precomputation for WTNAF multiplication.
|
||||
* @param p The <code>ECPoint</code> for which to do the precomputation.
|
||||
* @param a The parameter <code>a</code> of the elliptic curve.
|
||||
* @return The precomputation array for <code>p</code>.
|
||||
*/
|
||||
public static AbstractF2mPoint[] GetPreComp(AbstractF2mPoint p, sbyte a)
|
||||
{
|
||||
sbyte[][] alphaTnaf = (a == 0) ? Tnaf.Alpha0Tnaf : Tnaf.Alpha1Tnaf;
|
||||
|
||||
AbstractF2mPoint[] pu = new AbstractF2mPoint[(uint)(alphaTnaf.Length + 1) >> 1];
|
||||
pu[0] = p;
|
||||
|
||||
uint precompLen = (uint)alphaTnaf.Length;
|
||||
for (uint i = 3; i < precompLen; i += 2)
|
||||
{
|
||||
pu[i >> 1] = Tnaf.MultiplyFromTnaf(p, alphaTnaf[i]);
|
||||
}
|
||||
|
||||
p.Curve.NormalizeAll(pu);
|
||||
|
||||
return pu;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c350a1fcb33886749ad8b6d264d92746
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,40 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Abc
|
||||
{
|
||||
/**
|
||||
* Class representing an element of <code><b>Z</b>[τ]</code>. Let
|
||||
* <code>λ</code> be an element of <code><b>Z</b>[τ]</code>. Then
|
||||
* <code>λ</code> is given as <code>λ = u + vτ</code>. The
|
||||
* components <code>u</code> and <code>v</code> may be used directly, there
|
||||
* are no accessor methods.
|
||||
* Immutable class.
|
||||
*/
|
||||
internal class ZTauElement
|
||||
{
|
||||
/**
|
||||
* The "real" part of <code>λ</code>.
|
||||
*/
|
||||
public readonly BigInteger u;
|
||||
|
||||
/**
|
||||
* The "<code>τ</code>-adic" part of <code>λ</code>.
|
||||
*/
|
||||
public readonly BigInteger v;
|
||||
|
||||
/**
|
||||
* Constructor for an element <code>λ</code> of
|
||||
* <code><b>Z</b>[τ]</code>.
|
||||
* @param u The "real" part of <code>λ</code>.
|
||||
* @param v The "<code>τ</code>-adic" part of
|
||||
* <code>λ</code>.
|
||||
*/
|
||||
public ZTauElement(BigInteger u, BigInteger v)
|
||||
{
|
||||
this.u = u;
|
||||
this.v = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 06f1426762adf7a4a814250bf4084ce7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f13f8a0df1a5e424796c38a3c077a81c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a38ef3f332029e945bb971d37bccd8a4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,3 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd030ecdc7871c74ca192e7bf4c31075
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,3 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bc45dc149a92fe4d934ea8137fa7174
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 055f8fc08106e0646a52547e1a32b372
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,174 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.GM
|
||||
{
|
||||
internal class SM2P256V1Curve
|
||||
: AbstractFpCurve
|
||||
{
|
||||
public static readonly BigInteger q = SM2P256V1FieldElement.Q;
|
||||
|
||||
private const int SM2P256V1_DEFAULT_COORDS = COORD_JACOBIAN;
|
||||
private const int SM2P256V1_FE_INTS = 8;
|
||||
private static readonly ECFieldElement[] SM2P256V1_AFFINE_ZS = new ECFieldElement[] { new SM2P256V1FieldElement(BigInteger.One) };
|
||||
|
||||
protected readonly SM2P256V1Point m_infinity;
|
||||
|
||||
public SM2P256V1Curve()
|
||||
: base(q)
|
||||
{
|
||||
this.m_infinity = new SM2P256V1Point(this, null, null);
|
||||
|
||||
this.m_a = FromBigInteger(new BigInteger(1,
|
||||
Hex.DecodeStrict("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC")));
|
||||
this.m_b = FromBigInteger(new BigInteger(1,
|
||||
Hex.DecodeStrict("28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93")));
|
||||
this.m_order = new BigInteger(1, Hex.DecodeStrict("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"));
|
||||
this.m_cofactor = BigInteger.One;
|
||||
this.m_coord = SM2P256V1_DEFAULT_COORDS;
|
||||
}
|
||||
|
||||
protected override ECCurve CloneCurve()
|
||||
{
|
||||
return new SM2P256V1Curve();
|
||||
}
|
||||
|
||||
public override bool SupportsCoordinateSystem(int coord)
|
||||
{
|
||||
switch (coord)
|
||||
{
|
||||
case COORD_JACOBIAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BigInteger Q
|
||||
{
|
||||
get { return q; }
|
||||
}
|
||||
|
||||
public override ECPoint Infinity
|
||||
{
|
||||
get { return m_infinity; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement FromBigInteger(BigInteger x)
|
||||
{
|
||||
return new SM2P256V1FieldElement(x);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return new SM2P256V1Point(this, x, y);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
{
|
||||
return new SM2P256V1Point(this, x, y, zs);
|
||||
}
|
||||
|
||||
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
|
||||
{
|
||||
uint[] table = new uint[len * SM2P256V1_FE_INTS * 2];
|
||||
{
|
||||
int pos = 0;
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
ECPoint p = points[off + i];
|
||||
Nat256.Copy(((SM2P256V1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SM2P256V1_FE_INTS;
|
||||
Nat256.Copy(((SM2P256V1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SM2P256V1_FE_INTS;
|
||||
}
|
||||
}
|
||||
|
||||
return new SM2P256V1LookupTable(this, table, len);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElement(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat256.Create();
|
||||
SM2P256V1Field.Random(r, x);
|
||||
return new SM2P256V1FieldElement(x);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElementMult(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat256.Create();
|
||||
SM2P256V1Field.RandomMult(r, x);
|
||||
return new SM2P256V1FieldElement(x);
|
||||
}
|
||||
|
||||
private class SM2P256V1LookupTable
|
||||
: AbstractECLookupTable
|
||||
{
|
||||
private readonly SM2P256V1Curve m_outer;
|
||||
private readonly uint[] m_table;
|
||||
private readonly int m_size;
|
||||
|
||||
internal SM2P256V1LookupTable(SM2P256V1Curve outer, uint[] table, int size)
|
||||
{
|
||||
this.m_outer = outer;
|
||||
this.m_table = table;
|
||||
this.m_size = size;
|
||||
}
|
||||
|
||||
public override int Size
|
||||
{
|
||||
get { return m_size; }
|
||||
}
|
||||
|
||||
public override ECPoint Lookup(int index)
|
||||
{
|
||||
uint[] x = Nat256.Create(), y = Nat256.Create();
|
||||
int pos = 0;
|
||||
|
||||
for (int i = 0; i < m_size; ++i)
|
||||
{
|
||||
uint MASK = (uint)(((i ^ index) - 1) >> 31);
|
||||
|
||||
for (int j = 0; j < SM2P256V1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] ^= m_table[pos + j] & MASK;
|
||||
y[j] ^= m_table[pos + SM2P256V1_FE_INTS + j] & MASK;
|
||||
}
|
||||
|
||||
pos += (SM2P256V1_FE_INTS * 2);
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
public override ECPoint LookupVar(int index)
|
||||
{
|
||||
uint[] x = Nat256.Create(), y = Nat256.Create();
|
||||
int pos = index * SM2P256V1_FE_INTS * 2;
|
||||
|
||||
for (int j = 0; j < SM2P256V1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] = m_table[pos + j];
|
||||
y[j] = m_table[pos + SM2P256V1_FE_INTS + j];
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
private ECPoint CreatePoint(uint[] x, uint[] y)
|
||||
{
|
||||
return m_outer.CreateRawPoint(new SM2P256V1FieldElement(x), new SM2P256V1FieldElement(y), SM2P256V1_AFFINE_ZS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: acbfba639c7e65d4093f380a4ba84523
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,349 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.GM
|
||||
{
|
||||
internal class SM2P256V1Field
|
||||
{
|
||||
// 2^256 - 2^224 - 2^96 + 2^64 - 1
|
||||
internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE };
|
||||
private static readonly uint[] PExt = new uint[]{ 00000001, 0x00000000, 0xFFFFFFFE, 0x00000001, 0x00000001,
|
||||
0xFFFFFFFE, 0x00000000, 0x00000002, 0xFFFFFFFE, 0xFFFFFFFD, 0x00000003, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0x00000000, 0xFFFFFFFE };
|
||||
private const uint P7 = 0xFFFFFFFE;
|
||||
private const uint PExt15 = 0xFFFFFFFE;
|
||||
|
||||
public static void Add(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
uint c = Nat256.Add(x, y, z);
|
||||
if (c != 0 || (z[7] >= P7 && Nat256.Gte(z, P)))
|
||||
{
|
||||
AddPInvTo(z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
|
||||
{
|
||||
uint c = Nat.Add(16, xx, yy, zz);
|
||||
if (c != 0 || (zz[15] >= PExt15 && Nat.Gte(16, zz, PExt)))
|
||||
{
|
||||
Nat.SubFrom(16, PExt, zz);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddOne(uint[] x, uint[] z)
|
||||
{
|
||||
uint c = Nat.Inc(8, x, z);
|
||||
if (c != 0 || (z[7] >= P7 && Nat256.Gte(z, P)))
|
||||
{
|
||||
AddPInvTo(z);
|
||||
}
|
||||
}
|
||||
|
||||
public static uint[] FromBigInteger(BigInteger x)
|
||||
{
|
||||
uint[] z = Nat.FromBigInteger(256, x);
|
||||
if (z[7] >= P7 && Nat256.Gte(z, P))
|
||||
{
|
||||
Nat256.SubFrom(P, z);
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
public static void Inv(uint[] x, uint[] z)
|
||||
{
|
||||
Mod.CheckedModOddInverse(P, x, z);
|
||||
}
|
||||
|
||||
public static void Half(uint[] x, uint[] z)
|
||||
{
|
||||
if ((x[0] & 1) == 0)
|
||||
{
|
||||
Nat.ShiftDownBit(8, x, 0, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint c = Nat256.Add(x, P, z);
|
||||
Nat.ShiftDownBit(8, z, c);
|
||||
}
|
||||
}
|
||||
|
||||
public static int IsZero(uint[] x)
|
||||
{
|
||||
uint d = 0;
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
d |= x[i];
|
||||
}
|
||||
d = (d >> 1) | (d & 1);
|
||||
return ((int)d - 1) >> 31;
|
||||
}
|
||||
|
||||
public static void Multiply(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
uint[] tt = Nat256.CreateExt();
|
||||
Nat256.Mul(x, y, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
|
||||
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
|
||||
{
|
||||
uint c = Nat256.MulAddTo(x, y, zz);
|
||||
if (c != 0 || (zz[15] >= PExt15 && Nat.Gte(16, zz, PExt)))
|
||||
{
|
||||
Nat.SubFrom(16, PExt, zz);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Negate(uint[] x, uint[] z)
|
||||
{
|
||||
if (0 != IsZero(x))
|
||||
{
|
||||
Nat256.Sub(P, P, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
Nat256.Sub(P, x, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Random(SecureRandom r, uint[] z)
|
||||
{
|
||||
byte[] bb = new byte[8 * 4];
|
||||
do
|
||||
{
|
||||
r.NextBytes(bb);
|
||||
Pack.LE_To_UInt32(bb, 0, z, 0, 8);
|
||||
}
|
||||
while (0 == Nat.LessThan(8, z, P));
|
||||
}
|
||||
|
||||
public static void RandomMult(SecureRandom r, uint[] z)
|
||||
{
|
||||
do
|
||||
{
|
||||
Random(r, z);
|
||||
}
|
||||
while (0 != IsZero(z));
|
||||
}
|
||||
|
||||
public static void Reduce(uint[] xx, uint[] z)
|
||||
{
|
||||
long xx08 = xx[8], xx09 = xx[9], xx10 = xx[10], xx11 = xx[11];
|
||||
long xx12 = xx[12], xx13 = xx[13], xx14 = xx[14], xx15 = xx[15];
|
||||
|
||||
long t0 = xx08 + xx09;
|
||||
long t1 = xx10 + xx11;
|
||||
long t2 = xx12 + xx15;
|
||||
long t3 = xx13 + xx14;
|
||||
long t4 = t3 + (xx15 << 1);
|
||||
|
||||
long ts = t0 + t3;
|
||||
long tt = t1 + t2 + ts;
|
||||
|
||||
long cc = 0;
|
||||
cc += (long)xx[0] + tt + xx13 + xx14 + xx15;
|
||||
z[0] = (uint)cc;
|
||||
cc >>= 32;
|
||||
cc += (long)xx[1] + tt - xx08 + xx14 + xx15;
|
||||
z[1] = (uint)cc;
|
||||
cc >>= 32;
|
||||
cc += (long)xx[2] - ts;
|
||||
z[2] = (uint)cc;
|
||||
cc >>= 32;
|
||||
cc += (long)xx[3] + tt - xx09 - xx10 + xx13;
|
||||
z[3] = (uint)cc;
|
||||
cc >>= 32;
|
||||
cc += (long)xx[4] + tt - t1 - xx08 + xx14;
|
||||
z[4] = (uint)cc;
|
||||
cc >>= 32;
|
||||
cc += (long)xx[5] + t4 + xx10;
|
||||
z[5] = (uint)cc;
|
||||
cc >>= 32;
|
||||
cc += (long)xx[6] + xx11 + xx14 + xx15;
|
||||
z[6] = (uint)cc;
|
||||
cc >>= 32;
|
||||
cc += (long)xx[7] + tt + t4 + xx12;
|
||||
z[7] = (uint)cc;
|
||||
cc >>= 32;
|
||||
|
||||
Debug.Assert(cc >= 0);
|
||||
|
||||
Reduce32((uint)cc, z);
|
||||
}
|
||||
|
||||
public static void Reduce32(uint x, uint[] z)
|
||||
{
|
||||
long cc = 0;
|
||||
|
||||
if (x != 0)
|
||||
{
|
||||
long xx08 = x;
|
||||
|
||||
cc += (long)z[0] + xx08;
|
||||
z[0] = (uint)cc;
|
||||
cc >>= 32;
|
||||
if (cc != 0)
|
||||
{
|
||||
cc += (long)z[1];
|
||||
z[1] = (uint)cc;
|
||||
cc >>= 32;
|
||||
}
|
||||
cc += (long)z[2] - xx08;
|
||||
z[2] = (uint)cc;
|
||||
cc >>= 32;
|
||||
cc += (long)z[3] + xx08;
|
||||
z[3] = (uint)cc;
|
||||
cc >>= 32;
|
||||
if (cc != 0)
|
||||
{
|
||||
cc += (long)z[4];
|
||||
z[4] = (uint)cc;
|
||||
cc >>= 32;
|
||||
cc += (long)z[5];
|
||||
z[5] = (uint)cc;
|
||||
cc >>= 32;
|
||||
cc += (long)z[6];
|
||||
z[6] = (uint)cc;
|
||||
cc >>= 32;
|
||||
}
|
||||
cc += (long)z[7] + xx08;
|
||||
z[7] = (uint)cc;
|
||||
cc >>= 32;
|
||||
|
||||
Debug.Assert(cc == 0 || cc == 1);
|
||||
}
|
||||
|
||||
if (cc != 0 || (z[7] >= P7 && Nat256.Gte(z, P)))
|
||||
{
|
||||
AddPInvTo(z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Square(uint[] x, uint[] z)
|
||||
{
|
||||
uint[] tt = Nat256.CreateExt();
|
||||
Nat256.Square(x, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
|
||||
public static void SquareN(uint[] x, int n, uint[] z)
|
||||
{
|
||||
Debug.Assert(n > 0);
|
||||
|
||||
uint[] tt = Nat256.CreateExt();
|
||||
Nat256.Square(x, tt);
|
||||
Reduce(tt, z);
|
||||
|
||||
while (--n > 0)
|
||||
{
|
||||
Nat256.Square(z, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Subtract(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
int c = Nat256.Sub(x, y, z);
|
||||
if (c != 0)
|
||||
{
|
||||
SubPInvFrom(z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
|
||||
{
|
||||
int c = Nat.Sub(16, xx, yy, zz);
|
||||
if (c != 0)
|
||||
{
|
||||
Nat.AddTo(16, PExt, zz);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Twice(uint[] x, uint[] z)
|
||||
{
|
||||
uint c = Nat.ShiftUpBit(8, x, 0, z);
|
||||
if (c != 0 || (z[7] >= P7 && Nat256.Gte(z, P)))
|
||||
{
|
||||
AddPInvTo(z);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddPInvTo(uint[] z)
|
||||
{
|
||||
long c = (long)z[0] + 1;
|
||||
z[0] = (uint)c;
|
||||
c >>= 32;
|
||||
if (c != 0)
|
||||
{
|
||||
c += (long)z[1];
|
||||
z[1] = (uint)c;
|
||||
c >>= 32;
|
||||
}
|
||||
c += (long)z[2] - 1;
|
||||
z[2] = (uint)c;
|
||||
c >>= 32;
|
||||
c += (long)z[3] + 1;
|
||||
z[3] = (uint)c;
|
||||
c >>= 32;
|
||||
if (c != 0)
|
||||
{
|
||||
c += (long)z[4];
|
||||
z[4] = (uint)c;
|
||||
c >>= 32;
|
||||
c += (long)z[5];
|
||||
z[5] = (uint)c;
|
||||
c >>= 32;
|
||||
c += (long)z[6];
|
||||
z[6] = (uint)c;
|
||||
c >>= 32;
|
||||
}
|
||||
c += (long)z[7] + 1;
|
||||
z[7] = (uint)c;
|
||||
//c >>= 32;
|
||||
}
|
||||
|
||||
private static void SubPInvFrom(uint[] z)
|
||||
{
|
||||
long c = (long)z[0] - 1;
|
||||
z[0] = (uint)c;
|
||||
c >>= 32;
|
||||
if (c != 0)
|
||||
{
|
||||
c += (long)z[1];
|
||||
z[1] = (uint)c;
|
||||
c >>= 32;
|
||||
}
|
||||
c += (long)z[2] + 1;
|
||||
z[2] = (uint)c;
|
||||
c >>= 32;
|
||||
c += (long)z[3] - 1;
|
||||
z[3] = (uint)c;
|
||||
c >>= 32;
|
||||
if (c != 0)
|
||||
{
|
||||
c += (long)z[4];
|
||||
z[4] = (uint)c;
|
||||
c >>= 32;
|
||||
c += (long)z[5];
|
||||
z[5] = (uint)c;
|
||||
c >>= 32;
|
||||
c += (long)z[6];
|
||||
z[6] = (uint)c;
|
||||
c >>= 32;
|
||||
}
|
||||
c += (long)z[7] - 1;
|
||||
z[7] = (uint)c;
|
||||
//c >>= 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b192a254f279cb545b0e25c31042094e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,216 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.GM
|
||||
{
|
||||
internal class SM2P256V1FieldElement
|
||||
: AbstractFpFieldElement
|
||||
{
|
||||
public static readonly BigInteger Q = new BigInteger(1,
|
||||
Hex.DecodeStrict("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF"));
|
||||
|
||||
protected internal readonly uint[] x;
|
||||
|
||||
public SM2P256V1FieldElement(BigInteger x)
|
||||
{
|
||||
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
|
||||
throw new ArgumentException("value invalid for SM2P256V1FieldElement", "x");
|
||||
|
||||
this.x = SM2P256V1Field.FromBigInteger(x);
|
||||
}
|
||||
|
||||
public SM2P256V1FieldElement()
|
||||
{
|
||||
this.x = Nat256.Create();
|
||||
}
|
||||
|
||||
protected internal SM2P256V1FieldElement(uint[] x)
|
||||
{
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public override bool IsZero
|
||||
{
|
||||
get { return Nat256.IsZero(x); }
|
||||
}
|
||||
|
||||
public override bool IsOne
|
||||
{
|
||||
get { return Nat256.IsOne(x); }
|
||||
}
|
||||
|
||||
public override bool TestBitZero()
|
||||
{
|
||||
return Nat256.GetBit(x, 0) == 1;
|
||||
}
|
||||
|
||||
public override BigInteger ToBigInteger()
|
||||
{
|
||||
return Nat256.ToBigInteger(x);
|
||||
}
|
||||
|
||||
public override string FieldName
|
||||
{
|
||||
get { return "SM2P256V1Field"; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return Q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement Add(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat256.Create();
|
||||
SM2P256V1Field.Add(x, ((SM2P256V1FieldElement)b).x, z);
|
||||
return new SM2P256V1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement AddOne()
|
||||
{
|
||||
uint[] z = Nat256.Create();
|
||||
SM2P256V1Field.AddOne(x, z);
|
||||
return new SM2P256V1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Subtract(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat256.Create();
|
||||
SM2P256V1Field.Subtract(x, ((SM2P256V1FieldElement)b).x, z);
|
||||
return new SM2P256V1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Multiply(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat256.Create();
|
||||
SM2P256V1Field.Multiply(x, ((SM2P256V1FieldElement)b).x, z);
|
||||
return new SM2P256V1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Divide(ECFieldElement b)
|
||||
{
|
||||
//return Multiply(b.Invert());
|
||||
uint[] z = Nat256.Create();
|
||||
SM2P256V1Field.Inv(((SM2P256V1FieldElement)b).x, z);
|
||||
SM2P256V1Field.Multiply(z, x, z);
|
||||
return new SM2P256V1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Negate()
|
||||
{
|
||||
uint[] z = Nat256.Create();
|
||||
SM2P256V1Field.Negate(x, z);
|
||||
return new SM2P256V1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Square()
|
||||
{
|
||||
uint[] z = Nat256.Create();
|
||||
SM2P256V1Field.Square(x, z);
|
||||
return new SM2P256V1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Invert()
|
||||
{
|
||||
uint[] z = Nat256.Create();
|
||||
SM2P256V1Field.Inv(x, z);
|
||||
return new SM2P256V1FieldElement(z);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a sqrt root - the routine verifies that the calculation returns the right value - if
|
||||
* none exists it returns null.
|
||||
*/
|
||||
public override ECFieldElement Sqrt()
|
||||
{
|
||||
/*
|
||||
* Raise this element to the exponent 2^254 - 2^222 - 2^94 + 2^62
|
||||
*
|
||||
* Breaking up the exponent's binary representation into "repunits", we get:
|
||||
* { 31 1s } { 1 0s } { 128 1s } { 31 0s } { 1 1s } { 62 0s }
|
||||
*
|
||||
* We use an addition chain for the beginning: [1], 2, 3, 6, 12, [24], 30, [31]
|
||||
*/
|
||||
|
||||
uint[] x1 = this.x;
|
||||
if (Nat256.IsZero(x1) || Nat256.IsOne(x1))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
uint[] x2 = Nat256.Create();
|
||||
SM2P256V1Field.Square(x1, x2);
|
||||
SM2P256V1Field.Multiply(x2, x1, x2);
|
||||
uint[] x4 = Nat256.Create();
|
||||
SM2P256V1Field.SquareN(x2, 2, x4);
|
||||
SM2P256V1Field.Multiply(x4, x2, x4);
|
||||
uint[] x6 = Nat256.Create();
|
||||
SM2P256V1Field.SquareN(x4, 2, x6);
|
||||
SM2P256V1Field.Multiply(x6, x2, x6);
|
||||
uint[] x12 = x2;
|
||||
SM2P256V1Field.SquareN(x6, 6, x12);
|
||||
SM2P256V1Field.Multiply(x12, x6, x12);
|
||||
uint[] x24 = Nat256.Create();
|
||||
SM2P256V1Field.SquareN(x12, 12, x24);
|
||||
SM2P256V1Field.Multiply(x24, x12, x24);
|
||||
uint[] x30 = x12;
|
||||
SM2P256V1Field.SquareN(x24, 6, x30);
|
||||
SM2P256V1Field.Multiply(x30, x6, x30);
|
||||
uint[] x31 = x6;
|
||||
SM2P256V1Field.Square(x30, x31);
|
||||
SM2P256V1Field.Multiply(x31, x1, x31);
|
||||
|
||||
uint[] t1 = x24;
|
||||
SM2P256V1Field.SquareN(x31, 31, t1);
|
||||
|
||||
uint[] x62 = x30;
|
||||
SM2P256V1Field.Multiply(t1, x31, x62);
|
||||
|
||||
SM2P256V1Field.SquareN(t1, 32, t1);
|
||||
SM2P256V1Field.Multiply(t1, x62, t1);
|
||||
SM2P256V1Field.SquareN(t1, 62, t1);
|
||||
SM2P256V1Field.Multiply(t1, x62, t1);
|
||||
SM2P256V1Field.SquareN(t1, 4, t1);
|
||||
SM2P256V1Field.Multiply(t1, x4, t1);
|
||||
SM2P256V1Field.SquareN(t1, 32, t1);
|
||||
SM2P256V1Field.Multiply(t1, x1, t1);
|
||||
SM2P256V1Field.SquareN(t1, 62, t1);
|
||||
|
||||
uint[] t2 = x4;
|
||||
SM2P256V1Field.Square(t1, t2);
|
||||
|
||||
return Nat256.Eq(x1, t2) ? new SM2P256V1FieldElement(t1) : null;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as SM2P256V1FieldElement);
|
||||
}
|
||||
|
||||
public override bool Equals(ECFieldElement other)
|
||||
{
|
||||
return Equals(other as SM2P256V1FieldElement);
|
||||
}
|
||||
|
||||
public virtual bool Equals(SM2P256V1FieldElement other)
|
||||
{
|
||||
if (this == other)
|
||||
return true;
|
||||
if (null == other)
|
||||
return false;
|
||||
return Nat256.Eq(x, other.x);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73006e3eaec93cb44a4d004d03e84862
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,249 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.GM
|
||||
{
|
||||
internal class SM2P256V1Point
|
||||
: AbstractFpPoint
|
||||
{
|
||||
internal SM2P256V1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
|
||||
: base(curve, x, y)
|
||||
{
|
||||
}
|
||||
|
||||
internal SM2P256V1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
: base(curve, x, y, zs)
|
||||
{
|
||||
}
|
||||
|
||||
protected override ECPoint Detach()
|
||||
{
|
||||
return new SM2P256V1Point(null, AffineXCoord, AffineYCoord);
|
||||
}
|
||||
|
||||
public override ECPoint Add(ECPoint b)
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return this;
|
||||
if (this == b)
|
||||
return Twice();
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SM2P256V1FieldElement X1 = (SM2P256V1FieldElement)this.RawXCoord, Y1 = (SM2P256V1FieldElement)this.RawYCoord;
|
||||
SM2P256V1FieldElement X2 = (SM2P256V1FieldElement)b.RawXCoord, Y2 = (SM2P256V1FieldElement)b.RawYCoord;
|
||||
|
||||
SM2P256V1FieldElement Z1 = (SM2P256V1FieldElement)this.RawZCoords[0];
|
||||
SM2P256V1FieldElement Z2 = (SM2P256V1FieldElement)b.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
uint[] tt1 = Nat256.CreateExt();
|
||||
uint[] t2 = Nat256.Create();
|
||||
uint[] t3 = Nat256.Create();
|
||||
uint[] t4 = Nat256.Create();
|
||||
|
||||
bool Z1IsOne = Z1.IsOne;
|
||||
uint[] U2, S2;
|
||||
if (Z1IsOne)
|
||||
{
|
||||
U2 = X2.x;
|
||||
S2 = Y2.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S2 = t3;
|
||||
SM2P256V1Field.Square(Z1.x, S2);
|
||||
|
||||
U2 = t2;
|
||||
SM2P256V1Field.Multiply(S2, X2.x, U2);
|
||||
|
||||
SM2P256V1Field.Multiply(S2, Z1.x, S2);
|
||||
SM2P256V1Field.Multiply(S2, Y2.x, S2);
|
||||
}
|
||||
|
||||
bool Z2IsOne = Z2.IsOne;
|
||||
uint[] U1, S1;
|
||||
if (Z2IsOne)
|
||||
{
|
||||
U1 = X1.x;
|
||||
S1 = Y1.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S1 = t4;
|
||||
SM2P256V1Field.Square(Z2.x, S1);
|
||||
|
||||
U1 = tt1;
|
||||
SM2P256V1Field.Multiply(S1, X1.x, U1);
|
||||
|
||||
SM2P256V1Field.Multiply(S1, Z2.x, S1);
|
||||
SM2P256V1Field.Multiply(S1, Y1.x, S1);
|
||||
}
|
||||
|
||||
uint[] H = Nat256.Create();
|
||||
SM2P256V1Field.Subtract(U1, U2, H);
|
||||
|
||||
uint[] R = t2;
|
||||
SM2P256V1Field.Subtract(S1, S2, R);
|
||||
|
||||
// Check if b == this or b == -this
|
||||
if (Nat256.IsZero(H))
|
||||
{
|
||||
if (Nat256.IsZero(R))
|
||||
{
|
||||
// this == b, i.e. this must be doubled
|
||||
return this.Twice();
|
||||
}
|
||||
|
||||
// this == -b, i.e. the result is the point at infinity
|
||||
return curve.Infinity;
|
||||
}
|
||||
|
||||
uint[] HSquared = t3;
|
||||
SM2P256V1Field.Square(H, HSquared);
|
||||
|
||||
uint[] G = Nat256.Create();
|
||||
SM2P256V1Field.Multiply(HSquared, H, G);
|
||||
|
||||
uint[] V = t3;
|
||||
SM2P256V1Field.Multiply(HSquared, U1, V);
|
||||
|
||||
SM2P256V1Field.Negate(G, G);
|
||||
Nat256.Mul(S1, G, tt1);
|
||||
|
||||
c = Nat256.AddBothTo(V, V, G);
|
||||
SM2P256V1Field.Reduce32(c, G);
|
||||
|
||||
SM2P256V1FieldElement X3 = new SM2P256V1FieldElement(t4);
|
||||
SM2P256V1Field.Square(R, X3.x);
|
||||
SM2P256V1Field.Subtract(X3.x, G, X3.x);
|
||||
|
||||
SM2P256V1FieldElement Y3 = new SM2P256V1FieldElement(G);
|
||||
SM2P256V1Field.Subtract(V, X3.x, Y3.x);
|
||||
SM2P256V1Field.MultiplyAddToExt(Y3.x, R, tt1);
|
||||
SM2P256V1Field.Reduce(tt1, Y3.x);
|
||||
|
||||
SM2P256V1FieldElement Z3 = new SM2P256V1FieldElement(H);
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
SM2P256V1Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
if (!Z2IsOne)
|
||||
{
|
||||
SM2P256V1Field.Multiply(Z3.x, Z2.x, Z3.x);
|
||||
}
|
||||
|
||||
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
|
||||
|
||||
return new SM2P256V1Point(curve, X3, Y3, zs);
|
||||
}
|
||||
|
||||
public override ECPoint Twice()
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return this;
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SM2P256V1FieldElement Y1 = (SM2P256V1FieldElement)this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return curve.Infinity;
|
||||
|
||||
SM2P256V1FieldElement X1 = (SM2P256V1FieldElement)this.RawXCoord, Z1 = (SM2P256V1FieldElement)this.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
uint[] t1 = Nat256.Create();
|
||||
uint[] t2 = Nat256.Create();
|
||||
|
||||
uint[] Y1Squared = Nat256.Create();
|
||||
SM2P256V1Field.Square(Y1.x, Y1Squared);
|
||||
|
||||
uint[] T = Nat256.Create();
|
||||
SM2P256V1Field.Square(Y1Squared, T);
|
||||
|
||||
bool Z1IsOne = Z1.IsOne;
|
||||
|
||||
uint[] Z1Squared = Z1.x;
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
Z1Squared = t2;
|
||||
SM2P256V1Field.Square(Z1.x, Z1Squared);
|
||||
}
|
||||
|
||||
SM2P256V1Field.Subtract(X1.x, Z1Squared, t1);
|
||||
|
||||
uint[] M = t2;
|
||||
SM2P256V1Field.Add(X1.x, Z1Squared, M);
|
||||
SM2P256V1Field.Multiply(M, t1, M);
|
||||
c = Nat256.AddBothTo(M, M, M);
|
||||
SM2P256V1Field.Reduce32(c, M);
|
||||
|
||||
uint[] S = Y1Squared;
|
||||
SM2P256V1Field.Multiply(Y1Squared, X1.x, S);
|
||||
c = Nat.ShiftUpBits(8, S, 2, 0);
|
||||
SM2P256V1Field.Reduce32(c, S);
|
||||
|
||||
c = Nat.ShiftUpBits(8, T, 3, 0, t1);
|
||||
SM2P256V1Field.Reduce32(c, t1);
|
||||
|
||||
SM2P256V1FieldElement X3 = new SM2P256V1FieldElement(T);
|
||||
SM2P256V1Field.Square(M, X3.x);
|
||||
SM2P256V1Field.Subtract(X3.x, S, X3.x);
|
||||
SM2P256V1Field.Subtract(X3.x, S, X3.x);
|
||||
|
||||
SM2P256V1FieldElement Y3 = new SM2P256V1FieldElement(S);
|
||||
SM2P256V1Field.Subtract(S, X3.x, Y3.x);
|
||||
SM2P256V1Field.Multiply(Y3.x, M, Y3.x);
|
||||
SM2P256V1Field.Subtract(Y3.x, t1, Y3.x);
|
||||
|
||||
SM2P256V1FieldElement Z3 = new SM2P256V1FieldElement(M);
|
||||
SM2P256V1Field.Twice(Y1.x, Z3.x);
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
SM2P256V1Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
|
||||
return new SM2P256V1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
|
||||
}
|
||||
|
||||
public override ECPoint TwicePlus(ECPoint b)
|
||||
{
|
||||
if (this == b)
|
||||
return ThreeTimes();
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return Twice();
|
||||
|
||||
ECFieldElement Y1 = this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return b;
|
||||
|
||||
return Twice().Add(b);
|
||||
}
|
||||
|
||||
public override ECPoint ThreeTimes()
|
||||
{
|
||||
if (this.IsInfinity || this.RawYCoord.IsZero)
|
||||
return this;
|
||||
|
||||
// NOTE: Be careful about recursions between TwicePlus and ThreeTimes
|
||||
return Twice().Add(this);
|
||||
}
|
||||
|
||||
public override ECPoint Negate()
|
||||
{
|
||||
if (IsInfinity)
|
||||
return this;
|
||||
|
||||
return new SM2P256V1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c6a52fc113d5c74a839cb2861ce100d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: edf4874c4cb236144b35b46e9a8037ad
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,175 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP128R1Curve
|
||||
: AbstractFpCurve
|
||||
{
|
||||
public static readonly BigInteger q = SecP128R1FieldElement.Q;
|
||||
|
||||
private const int SECP128R1_DEFAULT_COORDS = COORD_JACOBIAN;
|
||||
private const int SECP128R1_FE_INTS = 4;
|
||||
private static readonly ECFieldElement[] SECP128R1_AFFINE_ZS = new ECFieldElement[] { new SecP128R1FieldElement(BigInteger.One) };
|
||||
|
||||
protected readonly SecP128R1Point m_infinity;
|
||||
|
||||
public SecP128R1Curve()
|
||||
: base(q)
|
||||
{
|
||||
this.m_infinity = new SecP128R1Point(this, null, null);
|
||||
|
||||
this.m_a = FromBigInteger(new BigInteger(1,
|
||||
Hex.DecodeStrict("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC")));
|
||||
this.m_b = FromBigInteger(new BigInteger(1,
|
||||
Hex.DecodeStrict("E87579C11079F43DD824993C2CEE5ED3")));
|
||||
this.m_order = new BigInteger(1, Hex.DecodeStrict("FFFFFFFE0000000075A30D1B9038A115"));
|
||||
this.m_cofactor = BigInteger.One;
|
||||
|
||||
this.m_coord = SECP128R1_DEFAULT_COORDS;
|
||||
}
|
||||
|
||||
protected override ECCurve CloneCurve()
|
||||
{
|
||||
return new SecP128R1Curve();
|
||||
}
|
||||
|
||||
public override bool SupportsCoordinateSystem(int coord)
|
||||
{
|
||||
switch (coord)
|
||||
{
|
||||
case COORD_JACOBIAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BigInteger Q
|
||||
{
|
||||
get { return q; }
|
||||
}
|
||||
|
||||
public override ECPoint Infinity
|
||||
{
|
||||
get { return m_infinity; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement FromBigInteger(BigInteger x)
|
||||
{
|
||||
return new SecP128R1FieldElement(x);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return new SecP128R1Point(this, x, y);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
{
|
||||
return new SecP128R1Point(this, x, y, zs);
|
||||
}
|
||||
|
||||
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
|
||||
{
|
||||
uint[] table = new uint[len * SECP128R1_FE_INTS * 2];
|
||||
{
|
||||
int pos = 0;
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
ECPoint p = points[off + i];
|
||||
Nat128.Copy(((SecP128R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP128R1_FE_INTS;
|
||||
Nat128.Copy(((SecP128R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP128R1_FE_INTS;
|
||||
}
|
||||
}
|
||||
|
||||
return new SecP128R1LookupTable(this, table, len);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElement(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat128.Create();
|
||||
SecP128R1Field.Random(r, x);
|
||||
return new SecP128R1FieldElement(x);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElementMult(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat128.Create();
|
||||
SecP128R1Field.RandomMult(r, x);
|
||||
return new SecP128R1FieldElement(x);
|
||||
}
|
||||
|
||||
private class SecP128R1LookupTable
|
||||
: AbstractECLookupTable
|
||||
{
|
||||
private readonly SecP128R1Curve m_outer;
|
||||
private readonly uint[] m_table;
|
||||
private readonly int m_size;
|
||||
|
||||
internal SecP128R1LookupTable(SecP128R1Curve outer, uint[] table, int size)
|
||||
{
|
||||
this.m_outer = outer;
|
||||
this.m_table = table;
|
||||
this.m_size = size;
|
||||
}
|
||||
|
||||
public override int Size
|
||||
{
|
||||
get { return m_size; }
|
||||
}
|
||||
|
||||
public override ECPoint Lookup(int index)
|
||||
{
|
||||
uint[] x = Nat128.Create(), y = Nat128.Create();
|
||||
int pos = 0;
|
||||
|
||||
for (int i = 0; i < m_size; ++i)
|
||||
{
|
||||
uint MASK = (uint)(((i ^ index) - 1) >> 31);
|
||||
|
||||
for (int j = 0; j < SECP128R1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] ^= m_table[pos + j] & MASK;
|
||||
y[j] ^= m_table[pos + SECP128R1_FE_INTS + j] & MASK;
|
||||
}
|
||||
|
||||
pos += (SECP128R1_FE_INTS * 2);
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
public override ECPoint LookupVar(int index)
|
||||
{
|
||||
uint[] x = Nat128.Create(), y = Nat128.Create();
|
||||
int pos = index * SECP128R1_FE_INTS * 2;
|
||||
|
||||
for (int j = 0; j < SECP128R1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] = m_table[pos + j];
|
||||
y[j] = m_table[pos + SECP128R1_FE_INTS + j];
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
private ECPoint CreatePoint(uint[] x, uint[] y)
|
||||
{
|
||||
return m_outer.CreateRawPoint(new SecP128R1FieldElement(x), new SecP128R1FieldElement(y), SECP128R1_AFFINE_ZS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07d11740bf1c5f949b70c6663eb822ad
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,265 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP128R1Field
|
||||
{
|
||||
// 2^128 - 2^97 - 1
|
||||
internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD };
|
||||
private static readonly uint[] PExt = new uint[]{ 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFE,
|
||||
0xFFFFFFFF, 0x00000003, 0xFFFFFFFC };
|
||||
private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFB,
|
||||
0x00000001, 0x00000000, 0xFFFFFFFC, 0x00000003 };
|
||||
private const uint P3 = 0xFFFFFFFD;
|
||||
private const uint PExt7 = 0xFFFFFFFC;
|
||||
|
||||
public static void Add(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
uint c = Nat128.Add(x, y, z);
|
||||
if (c != 0 || (z[3] >= P3 && Nat128.Gte(z, P)))
|
||||
{
|
||||
AddPInvTo(z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
|
||||
{
|
||||
uint c = Nat256.Add(xx, yy, zz);
|
||||
if (c != 0 || (zz[7] >= PExt7 && Nat256.Gte(zz, PExt)))
|
||||
{
|
||||
Nat.AddTo(PExtInv.Length, PExtInv, zz);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddOne(uint[] x, uint[] z)
|
||||
{
|
||||
uint c = Nat.Inc(4, x, z);
|
||||
if (c != 0 || (z[3] >= P3 && Nat128.Gte(z, P)))
|
||||
{
|
||||
AddPInvTo(z);
|
||||
}
|
||||
}
|
||||
|
||||
public static uint[] FromBigInteger(BigInteger x)
|
||||
{
|
||||
uint[] z = Nat.FromBigInteger(128, x);
|
||||
if (z[3] >= P3 && Nat128.Gte(z, P))
|
||||
{
|
||||
Nat128.SubFrom(P, z);
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
public static void Half(uint[] x, uint[] z)
|
||||
{
|
||||
if ((x[0] & 1) == 0)
|
||||
{
|
||||
Nat.ShiftDownBit(4, x, 0, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint c = Nat128.Add(x, P, z);
|
||||
Nat.ShiftDownBit(4, z, c);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Inv(uint[] x, uint[] z)
|
||||
{
|
||||
Mod.CheckedModOddInverse(P, x, z);
|
||||
}
|
||||
|
||||
public static int IsZero(uint[] x)
|
||||
{
|
||||
uint d = 0;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
d |= x[i];
|
||||
}
|
||||
d = (d >> 1) | (d & 1);
|
||||
return ((int)d - 1) >> 31;
|
||||
}
|
||||
|
||||
public static void Multiply(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
uint[] tt = Nat128.CreateExt();
|
||||
Nat128.Mul(x, y, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
|
||||
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
|
||||
{
|
||||
uint c = Nat128.MulAddTo(x, y, zz);
|
||||
if (c != 0 || (zz[7] >= PExt7 && Nat256.Gte(zz, PExt)))
|
||||
{
|
||||
Nat.AddTo(PExtInv.Length, PExtInv, zz);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Negate(uint[] x, uint[] z)
|
||||
{
|
||||
if (0 != IsZero(x))
|
||||
{
|
||||
Nat128.Sub(P, P, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
Nat128.Sub(P, x, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Random(SecureRandom r, uint[] z)
|
||||
{
|
||||
byte[] bb = new byte[4 * 4];
|
||||
do
|
||||
{
|
||||
r.NextBytes(bb);
|
||||
Pack.LE_To_UInt32(bb, 0, z, 0, 4);
|
||||
}
|
||||
while (0 == Nat.LessThan(4, z, P));
|
||||
}
|
||||
|
||||
public static void RandomMult(SecureRandom r, uint[] z)
|
||||
{
|
||||
do
|
||||
{
|
||||
Random(r, z);
|
||||
}
|
||||
while (0 != IsZero(z));
|
||||
}
|
||||
|
||||
public static void Reduce(uint[] xx, uint[] z)
|
||||
{
|
||||
ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3];
|
||||
ulong x4 = xx[4], x5 = xx[5], x6 = xx[6], x7 = xx[7];
|
||||
|
||||
x3 += x7; x6 += (x7 << 1);
|
||||
x2 += x6; x5 += (x6 << 1);
|
||||
x1 += x5; x4 += (x5 << 1);
|
||||
x0 += x4; x3 += (x4 << 1);
|
||||
|
||||
z[0] = (uint)x0; x1 += (x0 >> 32);
|
||||
z[1] = (uint)x1; x2 += (x1 >> 32);
|
||||
z[2] = (uint)x2; x3 += (x2 >> 32);
|
||||
z[3] = (uint)x3;
|
||||
|
||||
Reduce32((uint)(x3 >> 32), z);
|
||||
}
|
||||
|
||||
public static void Reduce32(uint x, uint[] z)
|
||||
{
|
||||
while (x != 0)
|
||||
{
|
||||
ulong c, x4 = x;
|
||||
|
||||
c = (ulong)z[0] + x4;
|
||||
z[0] = (uint)c; c >>= 32;
|
||||
if (c != 0)
|
||||
{
|
||||
c += (ulong)z[1];
|
||||
z[1] = (uint)c; c >>= 32;
|
||||
c += (ulong)z[2];
|
||||
z[2] = (uint)c; c >>= 32;
|
||||
}
|
||||
c += (ulong)z[3] + (x4 << 1);
|
||||
z[3] = (uint)c; c >>= 32;
|
||||
|
||||
Debug.Assert(c >= 0 && c <= 2);
|
||||
|
||||
x = (uint)c;
|
||||
}
|
||||
|
||||
if (z[3] >= P3 && Nat128.Gte(z, P))
|
||||
{
|
||||
AddPInvTo(z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Square(uint[] x, uint[] z)
|
||||
{
|
||||
uint[] tt = Nat128.CreateExt();
|
||||
Nat128.Square(x, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
|
||||
public static void SquareN(uint[] x, int n, uint[] z)
|
||||
{
|
||||
Debug.Assert(n > 0);
|
||||
|
||||
uint[] tt = Nat128.CreateExt();
|
||||
Nat128.Square(x, tt);
|
||||
Reduce(tt, z);
|
||||
|
||||
while (--n > 0)
|
||||
{
|
||||
Nat128.Square(z, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Subtract(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
int c = Nat128.Sub(x, y, z);
|
||||
if (c != 0)
|
||||
{
|
||||
SubPInvFrom(z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
|
||||
{
|
||||
int c = Nat.Sub(10, xx, yy, zz);
|
||||
if (c != 0)
|
||||
{
|
||||
Nat.SubFrom(PExtInv.Length, PExtInv, zz);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Twice(uint[] x, uint[] z)
|
||||
{
|
||||
uint c = Nat.ShiftUpBit(4, x, 0, z);
|
||||
if (c != 0 || (z[3] >= P3 && Nat128.Gte(z, P)))
|
||||
{
|
||||
AddPInvTo(z);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddPInvTo(uint[] z)
|
||||
{
|
||||
long c = (long)z[0] + 1;
|
||||
z[0] = (uint)c; c >>= 32;
|
||||
if (c != 0)
|
||||
{
|
||||
c += (long)z[1];
|
||||
z[1] = (uint)c; c >>= 32;
|
||||
c += (long)z[2];
|
||||
z[2] = (uint)c; c >>= 32;
|
||||
}
|
||||
c += (long)z[3] + 2;
|
||||
z[3] = (uint)c;
|
||||
}
|
||||
|
||||
private static void SubPInvFrom(uint[] z)
|
||||
{
|
||||
long c = (long)z[0] - 1;
|
||||
z[0] = (uint)c; c >>= 32;
|
||||
if (c != 0)
|
||||
{
|
||||
c += (long)z[1];
|
||||
z[1] = (uint)c; c >>= 32;
|
||||
c += (long)z[2];
|
||||
z[2] = (uint)c; c >>= 32;
|
||||
}
|
||||
c += (long)z[3] - 2;
|
||||
z[3] = (uint)c;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f9d092c55e0cd03418fa2b044ec88ff3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,203 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP128R1FieldElement
|
||||
: AbstractFpFieldElement
|
||||
{
|
||||
public static readonly BigInteger Q = new BigInteger(1,
|
||||
Hex.DecodeStrict("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"));
|
||||
|
||||
protected internal readonly uint[] x;
|
||||
|
||||
public SecP128R1FieldElement(BigInteger x)
|
||||
{
|
||||
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
|
||||
throw new ArgumentException("value invalid for SecP128R1FieldElement", "x");
|
||||
|
||||
this.x = SecP128R1Field.FromBigInteger(x);
|
||||
}
|
||||
|
||||
public SecP128R1FieldElement()
|
||||
{
|
||||
this.x = Nat128.Create();
|
||||
}
|
||||
|
||||
protected internal SecP128R1FieldElement(uint[] x)
|
||||
{
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public override bool IsZero
|
||||
{
|
||||
get { return Nat128.IsZero(x); }
|
||||
}
|
||||
|
||||
public override bool IsOne
|
||||
{
|
||||
get { return Nat128.IsOne(x); }
|
||||
}
|
||||
|
||||
public override bool TestBitZero()
|
||||
{
|
||||
return Nat128.GetBit(x, 0) == 1;
|
||||
}
|
||||
|
||||
public override BigInteger ToBigInteger()
|
||||
{
|
||||
return Nat128.ToBigInteger(x);
|
||||
}
|
||||
|
||||
public override string FieldName
|
||||
{
|
||||
get { return "SecP128R1Field"; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return Q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement Add(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat128.Create();
|
||||
SecP128R1Field.Add(x, ((SecP128R1FieldElement)b).x, z);
|
||||
return new SecP128R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement AddOne()
|
||||
{
|
||||
uint[] z = Nat128.Create();
|
||||
SecP128R1Field.AddOne(x, z);
|
||||
return new SecP128R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Subtract(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat128.Create();
|
||||
SecP128R1Field.Subtract(x, ((SecP128R1FieldElement)b).x, z);
|
||||
return new SecP128R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Multiply(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat128.Create();
|
||||
SecP128R1Field.Multiply(x, ((SecP128R1FieldElement)b).x, z);
|
||||
return new SecP128R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Divide(ECFieldElement b)
|
||||
{
|
||||
// return multiply(b.invert());
|
||||
uint[] z = Nat128.Create();
|
||||
SecP128R1Field.Inv(((SecP128R1FieldElement)b).x, z);
|
||||
SecP128R1Field.Multiply(z, x, z);
|
||||
return new SecP128R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Negate()
|
||||
{
|
||||
uint[] z = Nat128.Create();
|
||||
SecP128R1Field.Negate(x, z);
|
||||
return new SecP128R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Square()
|
||||
{
|
||||
uint[] z = Nat128.Create();
|
||||
SecP128R1Field.Square(x, z);
|
||||
return new SecP128R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Invert()
|
||||
{
|
||||
uint[] z = Nat128.Create();
|
||||
SecP128R1Field.Inv(x, z);
|
||||
return new SecP128R1FieldElement(z);
|
||||
}
|
||||
|
||||
// D.1.4 91
|
||||
/**
|
||||
* return a sqrt root - the routine verifies that the calculation returns the right value - if
|
||||
* none exists it returns null.
|
||||
*/
|
||||
public override ECFieldElement Sqrt()
|
||||
{
|
||||
/*
|
||||
* Raise this element to the exponent 2^126 - 2^95
|
||||
*
|
||||
* Breaking up the exponent's binary representation into "repunits", we get:
|
||||
* { 31 1s } { 95 0s }
|
||||
*
|
||||
* Therefore we need an addition chain containing 31 (the length of the repunit) We use:
|
||||
* 1, 2, 4, 8, 10, 20, 30, [31]
|
||||
*/
|
||||
|
||||
uint[] x1 = this.x;
|
||||
if (Nat128.IsZero(x1) || Nat128.IsOne(x1))
|
||||
return this;
|
||||
|
||||
uint[] x2 = Nat128.Create();
|
||||
SecP128R1Field.Square(x1, x2);
|
||||
SecP128R1Field.Multiply(x2, x1, x2);
|
||||
uint[] x4 = Nat128.Create();
|
||||
SecP128R1Field.SquareN(x2, 2, x4);
|
||||
SecP128R1Field.Multiply(x4, x2, x4);
|
||||
uint[] x8 = Nat128.Create();
|
||||
SecP128R1Field.SquareN(x4, 4, x8);
|
||||
SecP128R1Field.Multiply(x8, x4, x8);
|
||||
uint[] x10 = x4;
|
||||
SecP128R1Field.SquareN(x8, 2, x10);
|
||||
SecP128R1Field.Multiply(x10, x2, x10);
|
||||
uint[] x20 = x2;
|
||||
SecP128R1Field.SquareN(x10, 10, x20);
|
||||
SecP128R1Field.Multiply(x20, x10, x20);
|
||||
uint[] x30 = x8;
|
||||
SecP128R1Field.SquareN(x20, 10, x30);
|
||||
SecP128R1Field.Multiply(x30, x10, x30);
|
||||
uint[] x31 = x10;
|
||||
SecP128R1Field.Square(x30, x31);
|
||||
SecP128R1Field.Multiply(x31, x1, x31);
|
||||
|
||||
uint[] t1 = x31;
|
||||
SecP128R1Field.SquareN(t1, 95, t1);
|
||||
|
||||
uint[] t2 = x30;
|
||||
SecP128R1Field.Square(t1, t2);
|
||||
|
||||
return Nat128.Eq(x1, t2) ? new SecP128R1FieldElement(t1) : null;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as SecP128R1FieldElement);
|
||||
}
|
||||
|
||||
public override bool Equals(ECFieldElement other)
|
||||
{
|
||||
return Equals(other as SecP128R1FieldElement);
|
||||
}
|
||||
|
||||
public virtual bool Equals(SecP128R1FieldElement other)
|
||||
{
|
||||
if (this == other)
|
||||
return true;
|
||||
if (null == other)
|
||||
return false;
|
||||
return Nat128.Eq(x, other.x);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1b6f52fadd8950438dcf90df281b600
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,249 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP128R1Point
|
||||
: AbstractFpPoint
|
||||
{
|
||||
internal SecP128R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
|
||||
: base(curve, x, y)
|
||||
{
|
||||
}
|
||||
|
||||
internal SecP128R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
: base(curve, x, y, zs)
|
||||
{
|
||||
}
|
||||
|
||||
protected override ECPoint Detach()
|
||||
{
|
||||
return new SecP128R1Point(null, AffineXCoord, AffineYCoord);
|
||||
}
|
||||
|
||||
public override ECPoint Add(ECPoint b)
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return this;
|
||||
if (this == b)
|
||||
return Twice();
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SecP128R1FieldElement X1 = (SecP128R1FieldElement)this.RawXCoord, Y1 = (SecP128R1FieldElement)this.RawYCoord;
|
||||
SecP128R1FieldElement X2 = (SecP128R1FieldElement)b.RawXCoord, Y2 = (SecP128R1FieldElement)b.RawYCoord;
|
||||
|
||||
SecP128R1FieldElement Z1 = (SecP128R1FieldElement)this.RawZCoords[0];
|
||||
SecP128R1FieldElement Z2 = (SecP128R1FieldElement)b.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
uint[] tt1 = Nat128.CreateExt();
|
||||
uint[] t2 = Nat128.Create();
|
||||
uint[] t3 = Nat128.Create();
|
||||
uint[] t4 = Nat128.Create();
|
||||
|
||||
bool Z1IsOne = Z1.IsOne;
|
||||
uint[] U2, S2;
|
||||
if (Z1IsOne)
|
||||
{
|
||||
U2 = X2.x;
|
||||
S2 = Y2.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S2 = t3;
|
||||
SecP128R1Field.Square(Z1.x, S2);
|
||||
|
||||
U2 = t2;
|
||||
SecP128R1Field.Multiply(S2, X2.x, U2);
|
||||
|
||||
SecP128R1Field.Multiply(S2, Z1.x, S2);
|
||||
SecP128R1Field.Multiply(S2, Y2.x, S2);
|
||||
}
|
||||
|
||||
bool Z2IsOne = Z2.IsOne;
|
||||
uint[] U1, S1;
|
||||
if (Z2IsOne)
|
||||
{
|
||||
U1 = X1.x;
|
||||
S1 = Y1.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S1 = t4;
|
||||
SecP128R1Field.Square(Z2.x, S1);
|
||||
|
||||
U1 = tt1;
|
||||
SecP128R1Field.Multiply(S1, X1.x, U1);
|
||||
|
||||
SecP128R1Field.Multiply(S1, Z2.x, S1);
|
||||
SecP128R1Field.Multiply(S1, Y1.x, S1);
|
||||
}
|
||||
|
||||
uint[] H = Nat128.Create();
|
||||
SecP128R1Field.Subtract(U1, U2, H);
|
||||
|
||||
uint[] R = t2;
|
||||
SecP128R1Field.Subtract(S1, S2, R);
|
||||
|
||||
// Check if b == this or b == -this
|
||||
if (Nat128.IsZero(H))
|
||||
{
|
||||
if (Nat128.IsZero(R))
|
||||
{
|
||||
// this == b, i.e. this must be doubled
|
||||
return this.Twice();
|
||||
}
|
||||
|
||||
// this == -b, i.e. the result is the point at infinity
|
||||
return curve.Infinity;
|
||||
}
|
||||
|
||||
uint[] HSquared = t3;
|
||||
SecP128R1Field.Square(H, HSquared);
|
||||
|
||||
uint[] G = Nat128.Create();
|
||||
SecP128R1Field.Multiply(HSquared, H, G);
|
||||
|
||||
uint[] V = t3;
|
||||
SecP128R1Field.Multiply(HSquared, U1, V);
|
||||
|
||||
SecP128R1Field.Negate(G, G);
|
||||
Nat128.Mul(S1, G, tt1);
|
||||
|
||||
c = Nat128.AddBothTo(V, V, G);
|
||||
SecP128R1Field.Reduce32(c, G);
|
||||
|
||||
SecP128R1FieldElement X3 = new SecP128R1FieldElement(t4);
|
||||
SecP128R1Field.Square(R, X3.x);
|
||||
SecP128R1Field.Subtract(X3.x, G, X3.x);
|
||||
|
||||
SecP128R1FieldElement Y3 = new SecP128R1FieldElement(G);
|
||||
SecP128R1Field.Subtract(V, X3.x, Y3.x);
|
||||
SecP128R1Field.MultiplyAddToExt(Y3.x, R, tt1);
|
||||
SecP128R1Field.Reduce(tt1, Y3.x);
|
||||
|
||||
SecP128R1FieldElement Z3 = new SecP128R1FieldElement(H);
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
SecP128R1Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
if (!Z2IsOne)
|
||||
{
|
||||
SecP128R1Field.Multiply(Z3.x, Z2.x, Z3.x);
|
||||
}
|
||||
|
||||
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
|
||||
|
||||
return new SecP128R1Point(curve, X3, Y3, zs);
|
||||
}
|
||||
|
||||
public override ECPoint Twice()
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return this;
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SecP128R1FieldElement Y1 = (SecP128R1FieldElement)this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return curve.Infinity;
|
||||
|
||||
SecP128R1FieldElement X1 = (SecP128R1FieldElement)this.RawXCoord, Z1 = (SecP128R1FieldElement)this.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
uint[] t1 = Nat128.Create();
|
||||
uint[] t2 = Nat128.Create();
|
||||
|
||||
uint[] Y1Squared = Nat128.Create();
|
||||
SecP128R1Field.Square(Y1.x, Y1Squared);
|
||||
|
||||
uint[] T = Nat128.Create();
|
||||
SecP128R1Field.Square(Y1Squared, T);
|
||||
|
||||
bool Z1IsOne = Z1.IsOne;
|
||||
|
||||
uint[] Z1Squared = Z1.x;
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
Z1Squared = t2;
|
||||
SecP128R1Field.Square(Z1.x, Z1Squared);
|
||||
}
|
||||
|
||||
SecP128R1Field.Subtract(X1.x, Z1Squared, t1);
|
||||
|
||||
uint[] M = t2;
|
||||
SecP128R1Field.Add(X1.x, Z1Squared, M);
|
||||
SecP128R1Field.Multiply(M, t1, M);
|
||||
c = Nat128.AddBothTo(M, M, M);
|
||||
SecP128R1Field.Reduce32(c, M);
|
||||
|
||||
uint[] S = Y1Squared;
|
||||
SecP128R1Field.Multiply(Y1Squared, X1.x, S);
|
||||
c = Nat.ShiftUpBits(4, S, 2, 0);
|
||||
SecP128R1Field.Reduce32(c, S);
|
||||
|
||||
c = Nat.ShiftUpBits(4, T, 3, 0, t1);
|
||||
SecP128R1Field.Reduce32(c, t1);
|
||||
|
||||
SecP128R1FieldElement X3 = new SecP128R1FieldElement(T);
|
||||
SecP128R1Field.Square(M, X3.x);
|
||||
SecP128R1Field.Subtract(X3.x, S, X3.x);
|
||||
SecP128R1Field.Subtract(X3.x, S, X3.x);
|
||||
|
||||
SecP128R1FieldElement Y3 = new SecP128R1FieldElement(S);
|
||||
SecP128R1Field.Subtract(S, X3.x, Y3.x);
|
||||
SecP128R1Field.Multiply(Y3.x, M, Y3.x);
|
||||
SecP128R1Field.Subtract(Y3.x, t1, Y3.x);
|
||||
|
||||
SecP128R1FieldElement Z3 = new SecP128R1FieldElement(M);
|
||||
SecP128R1Field.Twice(Y1.x, Z3.x);
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
SecP128R1Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
|
||||
return new SecP128R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
|
||||
}
|
||||
|
||||
public override ECPoint TwicePlus(ECPoint b)
|
||||
{
|
||||
if (this == b)
|
||||
return ThreeTimes();
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return Twice();
|
||||
|
||||
ECFieldElement Y1 = this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return b;
|
||||
|
||||
return Twice().Add(b);
|
||||
}
|
||||
|
||||
public override ECPoint ThreeTimes()
|
||||
{
|
||||
if (this.IsInfinity || this.RawYCoord.IsZero)
|
||||
return this;
|
||||
|
||||
// NOTE: Be careful about recursions between twicePlus and threeTimes
|
||||
return Twice().Add(this);
|
||||
}
|
||||
|
||||
public override ECPoint Negate()
|
||||
{
|
||||
if (IsInfinity)
|
||||
return this;
|
||||
|
||||
return new SecP128R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b719fcfaca4697a499481a1ec81e4e74
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,172 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP160K1Curve
|
||||
: AbstractFpCurve
|
||||
{
|
||||
public static readonly BigInteger q = SecP160R2FieldElement.Q;
|
||||
|
||||
private const int SECP160K1_DEFAULT_COORDS = COORD_JACOBIAN;
|
||||
private const int SECP160K1_FE_INTS = 5;
|
||||
private static readonly ECFieldElement[] SECP160K1_AFFINE_ZS = new ECFieldElement[] { new SecP160R2FieldElement(BigInteger.One) };
|
||||
|
||||
protected readonly SecP160K1Point m_infinity;
|
||||
|
||||
public SecP160K1Curve()
|
||||
: base(q)
|
||||
{
|
||||
this.m_infinity = new SecP160K1Point(this, null, null);
|
||||
|
||||
this.m_a = FromBigInteger(BigInteger.Zero);
|
||||
this.m_b = FromBigInteger(BigInteger.ValueOf(7));
|
||||
this.m_order = new BigInteger(1, Hex.DecodeStrict("0100000000000000000001B8FA16DFAB9ACA16B6B3"));
|
||||
this.m_cofactor = BigInteger.One;
|
||||
this.m_coord = SECP160K1_DEFAULT_COORDS;
|
||||
}
|
||||
|
||||
protected override ECCurve CloneCurve()
|
||||
{
|
||||
return new SecP160K1Curve();
|
||||
}
|
||||
|
||||
public override bool SupportsCoordinateSystem(int coord)
|
||||
{
|
||||
switch (coord)
|
||||
{
|
||||
case COORD_JACOBIAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BigInteger Q
|
||||
{
|
||||
get { return q; }
|
||||
}
|
||||
|
||||
public override ECPoint Infinity
|
||||
{
|
||||
get { return m_infinity; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement FromBigInteger(BigInteger x)
|
||||
{
|
||||
return new SecP160R2FieldElement(x);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return new SecP160K1Point(this, x, y);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
{
|
||||
return new SecP160K1Point(this, x, y, zs);
|
||||
}
|
||||
|
||||
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
|
||||
{
|
||||
uint[] table = new uint[len * SECP160K1_FE_INTS * 2];
|
||||
{
|
||||
int pos = 0;
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
ECPoint p = points[off + i];
|
||||
Nat160.Copy(((SecP160R2FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP160K1_FE_INTS;
|
||||
Nat160.Copy(((SecP160R2FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP160K1_FE_INTS;
|
||||
}
|
||||
}
|
||||
|
||||
return new SecP160K1LookupTable(this, table, len);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElement(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat160.Create();
|
||||
SecP160R2Field.Random(r, x);
|
||||
return new SecP160R2FieldElement(x);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElementMult(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat160.Create();
|
||||
SecP160R2Field.RandomMult(r, x);
|
||||
return new SecP160R2FieldElement(x);
|
||||
}
|
||||
|
||||
private class SecP160K1LookupTable
|
||||
: AbstractECLookupTable
|
||||
{
|
||||
private readonly SecP160K1Curve m_outer;
|
||||
private readonly uint[] m_table;
|
||||
private readonly int m_size;
|
||||
|
||||
internal SecP160K1LookupTable(SecP160K1Curve outer, uint[] table, int size)
|
||||
{
|
||||
this.m_outer = outer;
|
||||
this.m_table = table;
|
||||
this.m_size = size;
|
||||
}
|
||||
|
||||
public override int Size
|
||||
{
|
||||
get { return m_size; }
|
||||
}
|
||||
|
||||
public override ECPoint Lookup(int index)
|
||||
{
|
||||
uint[] x = Nat256.Create(), y = Nat256.Create();
|
||||
int pos = 0;
|
||||
|
||||
for (int i = 0; i < m_size; ++i)
|
||||
{
|
||||
uint MASK = (uint)(((i ^ index) - 1) >> 31);
|
||||
|
||||
for (int j = 0; j < SECP160K1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] ^= m_table[pos + j] & MASK;
|
||||
y[j] ^= m_table[pos + SECP160K1_FE_INTS + j] & MASK;
|
||||
}
|
||||
|
||||
pos += (SECP160K1_FE_INTS * 2);
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
public override ECPoint LookupVar(int index)
|
||||
{
|
||||
uint[] x = Nat256.Create(), y = Nat256.Create();
|
||||
int pos = index * SECP160K1_FE_INTS * 2;
|
||||
|
||||
for (int j = 0; j < SECP160K1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] = m_table[pos + j];
|
||||
y[j] = m_table[pos + SECP160K1_FE_INTS + j];
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
private ECPoint CreatePoint(uint[] x, uint[] y)
|
||||
{
|
||||
return m_outer.CreateRawPoint(new SecP160R2FieldElement(x), new SecP160R2FieldElement(y), SECP160K1_AFFINE_ZS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1150199688daf104cb227e8776202137
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,238 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP160K1Point
|
||||
: AbstractFpPoint
|
||||
{
|
||||
internal SecP160K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
|
||||
: base(curve, x, y)
|
||||
{
|
||||
}
|
||||
|
||||
internal SecP160K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
: base(curve, x, y, zs)
|
||||
{
|
||||
}
|
||||
|
||||
protected override ECPoint Detach()
|
||||
{
|
||||
return new SecP160K1Point(null, AffineXCoord, AffineYCoord);
|
||||
}
|
||||
|
||||
// B.3 pg 62
|
||||
public override ECPoint Add(ECPoint b)
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return this;
|
||||
if (this == b)
|
||||
return Twice();
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SecP160R2FieldElement X1 = (SecP160R2FieldElement)this.RawXCoord, Y1 = (SecP160R2FieldElement)this.RawYCoord;
|
||||
SecP160R2FieldElement X2 = (SecP160R2FieldElement)b.RawXCoord, Y2 = (SecP160R2FieldElement)b.RawYCoord;
|
||||
|
||||
SecP160R2FieldElement Z1 = (SecP160R2FieldElement)this.RawZCoords[0];
|
||||
SecP160R2FieldElement Z2 = (SecP160R2FieldElement)b.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
uint[] tt1 = Nat160.CreateExt();
|
||||
uint[] t2 = Nat160.Create();
|
||||
uint[] t3 = Nat160.Create();
|
||||
uint[] t4 = Nat160.Create();
|
||||
|
||||
bool Z1IsOne = Z1.IsOne;
|
||||
uint[] U2, S2;
|
||||
if (Z1IsOne)
|
||||
{
|
||||
U2 = X2.x;
|
||||
S2 = Y2.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S2 = t3;
|
||||
SecP160R2Field.Square(Z1.x, S2);
|
||||
|
||||
U2 = t2;
|
||||
SecP160R2Field.Multiply(S2, X2.x, U2);
|
||||
|
||||
SecP160R2Field.Multiply(S2, Z1.x, S2);
|
||||
SecP160R2Field.Multiply(S2, Y2.x, S2);
|
||||
}
|
||||
|
||||
bool Z2IsOne = Z2.IsOne;
|
||||
uint[] U1, S1;
|
||||
if (Z2IsOne)
|
||||
{
|
||||
U1 = X1.x;
|
||||
S1 = Y1.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S1 = t4;
|
||||
SecP160R2Field.Square(Z2.x, S1);
|
||||
|
||||
U1 = tt1;
|
||||
SecP160R2Field.Multiply(S1, X1.x, U1);
|
||||
|
||||
SecP160R2Field.Multiply(S1, Z2.x, S1);
|
||||
SecP160R2Field.Multiply(S1, Y1.x, S1);
|
||||
}
|
||||
|
||||
uint[] H = Nat160.Create();
|
||||
SecP160R2Field.Subtract(U1, U2, H);
|
||||
|
||||
uint[] R = t2;
|
||||
SecP160R2Field.Subtract(S1, S2, R);
|
||||
|
||||
// Check if b == this or b == -this
|
||||
if (Nat160.IsZero(H))
|
||||
{
|
||||
if (Nat160.IsZero(R))
|
||||
{
|
||||
// this == b, i.e. this must be doubled
|
||||
return this.Twice();
|
||||
}
|
||||
|
||||
// this == -b, i.e. the result is the point at infinity
|
||||
return curve.Infinity;
|
||||
}
|
||||
|
||||
uint[] HSquared = t3;
|
||||
SecP160R2Field.Square(H, HSquared);
|
||||
|
||||
uint[] G = Nat160.Create();
|
||||
SecP160R2Field.Multiply(HSquared, H, G);
|
||||
|
||||
uint[] V = t3;
|
||||
SecP160R2Field.Multiply(HSquared, U1, V);
|
||||
|
||||
SecP160R2Field.Negate(G, G);
|
||||
Nat160.Mul(S1, G, tt1);
|
||||
|
||||
c = Nat160.AddBothTo(V, V, G);
|
||||
SecP160R2Field.Reduce32(c, G);
|
||||
|
||||
SecP160R2FieldElement X3 = new SecP160R2FieldElement(t4);
|
||||
SecP160R2Field.Square(R, X3.x);
|
||||
SecP160R2Field.Subtract(X3.x, G, X3.x);
|
||||
|
||||
SecP160R2FieldElement Y3 = new SecP160R2FieldElement(G);
|
||||
SecP160R2Field.Subtract(V, X3.x, Y3.x);
|
||||
SecP160R2Field.MultiplyAddToExt(Y3.x, R, tt1);
|
||||
SecP160R2Field.Reduce(tt1, Y3.x);
|
||||
|
||||
SecP160R2FieldElement Z3 = new SecP160R2FieldElement(H);
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
SecP160R2Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
if (!Z2IsOne)
|
||||
{
|
||||
SecP160R2Field.Multiply(Z3.x, Z2.x, Z3.x);
|
||||
}
|
||||
|
||||
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
|
||||
|
||||
return new SecP160K1Point(curve, X3, Y3, zs);
|
||||
}
|
||||
|
||||
// B.3 pg 62
|
||||
public override ECPoint Twice()
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return this;
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SecP160R2FieldElement Y1 = (SecP160R2FieldElement)this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return curve.Infinity;
|
||||
|
||||
SecP160R2FieldElement X1 = (SecP160R2FieldElement)this.RawXCoord, Z1 = (SecP160R2FieldElement)this.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
|
||||
uint[] Y1Squared = Nat160.Create();
|
||||
SecP160R2Field.Square(Y1.x, Y1Squared);
|
||||
|
||||
uint[] T = Nat160.Create();
|
||||
SecP160R2Field.Square(Y1Squared, T);
|
||||
|
||||
uint[] M = Nat160.Create();
|
||||
SecP160R2Field.Square(X1.x, M);
|
||||
c = Nat160.AddBothTo(M, M, M);
|
||||
SecP160R2Field.Reduce32(c, M);
|
||||
|
||||
uint[] S = Y1Squared;
|
||||
SecP160R2Field.Multiply(Y1Squared, X1.x, S);
|
||||
c = Nat.ShiftUpBits(5, S, 2, 0);
|
||||
SecP160R2Field.Reduce32(c, S);
|
||||
|
||||
uint[] t1 = Nat160.Create();
|
||||
c = Nat.ShiftUpBits(5, T, 3, 0, t1);
|
||||
SecP160R2Field.Reduce32(c, t1);
|
||||
|
||||
SecP160R2FieldElement X3 = new SecP160R2FieldElement(T);
|
||||
SecP160R2Field.Square(M, X3.x);
|
||||
SecP160R2Field.Subtract(X3.x, S, X3.x);
|
||||
SecP160R2Field.Subtract(X3.x, S, X3.x);
|
||||
|
||||
SecP160R2FieldElement Y3 = new SecP160R2FieldElement(S);
|
||||
SecP160R2Field.Subtract(S, X3.x, Y3.x);
|
||||
SecP160R2Field.Multiply(Y3.x, M, Y3.x);
|
||||
SecP160R2Field.Subtract(Y3.x, t1, Y3.x);
|
||||
|
||||
SecP160R2FieldElement Z3 = new SecP160R2FieldElement(M);
|
||||
SecP160R2Field.Twice(Y1.x, Z3.x);
|
||||
if (!Z1.IsOne)
|
||||
{
|
||||
SecP160R2Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
|
||||
return new SecP160K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
|
||||
}
|
||||
|
||||
public override ECPoint TwicePlus(ECPoint b)
|
||||
{
|
||||
if (this == b)
|
||||
return ThreeTimes();
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return Twice();
|
||||
|
||||
ECFieldElement Y1 = this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return b;
|
||||
|
||||
return Twice().Add(b);
|
||||
}
|
||||
|
||||
public override ECPoint ThreeTimes()
|
||||
{
|
||||
if (this.IsInfinity || this.RawYCoord.IsZero)
|
||||
return this;
|
||||
|
||||
// NOTE: Be careful about recursions between TwicePlus and threeTimes
|
||||
return Twice().Add(this);
|
||||
}
|
||||
|
||||
public override ECPoint Negate()
|
||||
{
|
||||
if (IsInfinity)
|
||||
return this;
|
||||
|
||||
return new SecP160K1Point(Curve, this.RawXCoord, this.RawYCoord.Negate(), this.RawZCoords);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e8be84848d57df40bf9d4558a98c6e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,175 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP160R1Curve
|
||||
: AbstractFpCurve
|
||||
{
|
||||
public static readonly BigInteger q = SecP160R1FieldElement.Q;
|
||||
|
||||
private const int SECP160R1_DEFAULT_COORDS = COORD_JACOBIAN;
|
||||
private const int SECP160R1_FE_INTS = 5;
|
||||
private static readonly ECFieldElement[] SECP160R1_AFFINE_ZS = new ECFieldElement[] { new SecP160R1FieldElement(BigInteger.One) };
|
||||
|
||||
protected readonly SecP160R1Point m_infinity;
|
||||
|
||||
public SecP160R1Curve()
|
||||
: base(q)
|
||||
{
|
||||
this.m_infinity = new SecP160R1Point(this, null, null);
|
||||
|
||||
this.m_a = FromBigInteger(new BigInteger(1,
|
||||
Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")));
|
||||
this.m_b = FromBigInteger(new BigInteger(1,
|
||||
Hex.DecodeStrict("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")));
|
||||
this.m_order = new BigInteger(1, Hex.DecodeStrict("0100000000000000000001F4C8F927AED3CA752257"));
|
||||
this.m_cofactor = BigInteger.One;
|
||||
|
||||
this.m_coord = SECP160R1_DEFAULT_COORDS;
|
||||
}
|
||||
|
||||
protected override ECCurve CloneCurve()
|
||||
{
|
||||
return new SecP160R1Curve();
|
||||
}
|
||||
|
||||
public override bool SupportsCoordinateSystem(int coord)
|
||||
{
|
||||
switch (coord)
|
||||
{
|
||||
case COORD_JACOBIAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BigInteger Q
|
||||
{
|
||||
get { return q; }
|
||||
}
|
||||
|
||||
public override ECPoint Infinity
|
||||
{
|
||||
get { return m_infinity; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement FromBigInteger(BigInteger x)
|
||||
{
|
||||
return new SecP160R1FieldElement(x);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return new SecP160R1Point(this, x, y);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
{
|
||||
return new SecP160R1Point(this, x, y, zs);
|
||||
}
|
||||
|
||||
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
|
||||
{
|
||||
uint[] table = new uint[len * SECP160R1_FE_INTS * 2];
|
||||
{
|
||||
int pos = 0;
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
ECPoint p = points[off + i];
|
||||
Nat160.Copy(((SecP160R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP160R1_FE_INTS;
|
||||
Nat160.Copy(((SecP160R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP160R1_FE_INTS;
|
||||
}
|
||||
}
|
||||
|
||||
return new SecP160R1LookupTable(this, table, len);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElement(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat160.Create();
|
||||
SecP160R1Field.Random(r, x);
|
||||
return new SecP160R1FieldElement(x);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElementMult(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat160.Create();
|
||||
SecP160R1Field.RandomMult(r, x);
|
||||
return new SecP160R1FieldElement(x);
|
||||
}
|
||||
|
||||
private class SecP160R1LookupTable
|
||||
: AbstractECLookupTable
|
||||
{
|
||||
private readonly SecP160R1Curve m_outer;
|
||||
private readonly uint[] m_table;
|
||||
private readonly int m_size;
|
||||
|
||||
internal SecP160R1LookupTable(SecP160R1Curve outer, uint[] table, int size)
|
||||
{
|
||||
this.m_outer = outer;
|
||||
this.m_table = table;
|
||||
this.m_size = size;
|
||||
}
|
||||
|
||||
public override int Size
|
||||
{
|
||||
get { return m_size; }
|
||||
}
|
||||
|
||||
public override ECPoint Lookup(int index)
|
||||
{
|
||||
uint[] x = Nat160.Create(), y = Nat160.Create();
|
||||
int pos = 0;
|
||||
|
||||
for (int i = 0; i < m_size; ++i)
|
||||
{
|
||||
uint MASK = (uint)(((i ^ index) - 1) >> 31);
|
||||
|
||||
for (int j = 0; j < SECP160R1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] ^= m_table[pos + j] & MASK;
|
||||
y[j] ^= m_table[pos + SECP160R1_FE_INTS + j] & MASK;
|
||||
}
|
||||
|
||||
pos += (SECP160R1_FE_INTS * 2);
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
public override ECPoint LookupVar(int index)
|
||||
{
|
||||
uint[] x = Nat160.Create(), y = Nat160.Create();
|
||||
int pos = index * SECP160R1_FE_INTS * 2;
|
||||
|
||||
for (int j = 0; j < SECP160R1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] = m_table[pos + j];
|
||||
y[j] = m_table[pos + SECP160R1_FE_INTS + j];
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
private ECPoint CreatePoint(uint[] x, uint[] y)
|
||||
{
|
||||
return m_outer.CreateRawPoint(new SecP160R1FieldElement(x), new SecP160R1FieldElement(y), SECP160R1_AFFINE_ZS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ab70ddacc717f914998f8131af159ac2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,228 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP160R1Field
|
||||
{
|
||||
// 2^160 - 2^31 - 1
|
||||
internal static readonly uint[] P = new uint[]{ 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
private static readonly uint[] PExt = new uint[]{ 0x00000001, 0x40000001, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xBFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0x00000001, 0x00000001 };
|
||||
private const uint P4 = 0xFFFFFFFF;
|
||||
private const uint PExt9 = 0xFFFFFFFF;
|
||||
private const uint PInv = 0x80000001;
|
||||
|
||||
public static void Add(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
uint c = Nat160.Add(x, y, z);
|
||||
if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P)))
|
||||
{
|
||||
Nat.AddWordTo(5, PInv, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
|
||||
{
|
||||
uint c = Nat.Add(10, xx, yy, zz);
|
||||
if (c != 0 || (zz[9] == PExt9 && Nat.Gte(10, zz, PExt)))
|
||||
{
|
||||
if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
|
||||
{
|
||||
Nat.IncAt(10, zz, PExtInv.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddOne(uint[] x, uint[] z)
|
||||
{
|
||||
uint c = Nat.Inc(5, x, z);
|
||||
if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P)))
|
||||
{
|
||||
Nat.AddWordTo(5, PInv, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static uint[] FromBigInteger(BigInteger x)
|
||||
{
|
||||
uint[] z = Nat.FromBigInteger(160, x);
|
||||
if (z[4] == P4 && Nat160.Gte(z, P))
|
||||
{
|
||||
Nat160.SubFrom(P, z);
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
public static void Half(uint[] x, uint[] z)
|
||||
{
|
||||
if ((x[0] & 1) == 0)
|
||||
{
|
||||
Nat.ShiftDownBit(5, x, 0, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint c = Nat160.Add(x, P, z);
|
||||
Nat.ShiftDownBit(5, z, c);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Inv(uint[] x, uint[] z)
|
||||
{
|
||||
Mod.CheckedModOddInverse(P, x, z);
|
||||
}
|
||||
|
||||
public static int IsZero(uint[] x)
|
||||
{
|
||||
uint d = 0;
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
d |= x[i];
|
||||
}
|
||||
d = (d >> 1) | (d & 1);
|
||||
return ((int)d - 1) >> 31;
|
||||
}
|
||||
|
||||
public static void Multiply(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
uint[] tt = Nat160.CreateExt();
|
||||
Nat160.Mul(x, y, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
|
||||
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
|
||||
{
|
||||
uint c = Nat160.MulAddTo(x, y, zz);
|
||||
if (c != 0 || (zz[9] == PExt9 && Nat.Gte(10, zz, PExt)))
|
||||
{
|
||||
if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
|
||||
{
|
||||
Nat.IncAt(10, zz, PExtInv.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Negate(uint[] x, uint[] z)
|
||||
{
|
||||
if (0 != IsZero(x))
|
||||
{
|
||||
Nat160.Sub(P, P, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
Nat160.Sub(P, x, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Random(SecureRandom r, uint[] z)
|
||||
{
|
||||
byte[] bb = new byte[5 * 4];
|
||||
do
|
||||
{
|
||||
r.NextBytes(bb);
|
||||
Pack.LE_To_UInt32(bb, 0, z, 0, 5);
|
||||
}
|
||||
while (0 == Nat.LessThan(5, z, P));
|
||||
}
|
||||
|
||||
public static void RandomMult(SecureRandom r, uint[] z)
|
||||
{
|
||||
do
|
||||
{
|
||||
Random(r, z);
|
||||
}
|
||||
while (0 != IsZero(z));
|
||||
}
|
||||
|
||||
public static void Reduce(uint[] xx, uint[] z)
|
||||
{
|
||||
ulong x5 = xx[5], x6 = xx[6], x7 = xx[7], x8 = xx[8], x9 = xx[9];
|
||||
|
||||
ulong c = 0;
|
||||
c += (ulong)xx[0] + x5 + (x5 << 31);
|
||||
z[0] = (uint)c; c >>= 32;
|
||||
c += (ulong)xx[1] + x6 + (x6 << 31);
|
||||
z[1] = (uint)c; c >>= 32;
|
||||
c += (ulong)xx[2] + x7 + (x7 << 31);
|
||||
z[2] = (uint)c; c >>= 32;
|
||||
c += (ulong)xx[3] + x8 + (x8 << 31);
|
||||
z[3] = (uint)c; c >>= 32;
|
||||
c += (ulong)xx[4] + x9 + (x9 << 31);
|
||||
z[4] = (uint)c; c >>= 32;
|
||||
|
||||
Debug.Assert(c >> 32 == 0);
|
||||
|
||||
Reduce32((uint)c, z);
|
||||
}
|
||||
|
||||
public static void Reduce32(uint x, uint[] z)
|
||||
{
|
||||
if ((x != 0 && Nat160.MulWordsAdd(PInv, x, z, 0) != 0)
|
||||
|| (z[4] == P4 && Nat160.Gte(z, P)))
|
||||
{
|
||||
Nat.AddWordTo(5, PInv, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Square(uint[] x, uint[] z)
|
||||
{
|
||||
uint[] tt = Nat160.CreateExt();
|
||||
Nat160.Square(x, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
|
||||
public static void SquareN(uint[] x, int n, uint[] z)
|
||||
{
|
||||
Debug.Assert(n > 0);
|
||||
|
||||
uint[] tt = Nat160.CreateExt();
|
||||
Nat160.Square(x, tt);
|
||||
Reduce(tt, z);
|
||||
|
||||
while (--n > 0)
|
||||
{
|
||||
Nat160.Square(z, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Subtract(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
int c = Nat160.Sub(x, y, z);
|
||||
if (c != 0)
|
||||
{
|
||||
Nat.SubWordFrom(5, PInv, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
|
||||
{
|
||||
int c = Nat.Sub(10, xx, yy, zz);
|
||||
if (c != 0)
|
||||
{
|
||||
if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0)
|
||||
{
|
||||
Nat.DecAt(10, zz, PExtInv.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Twice(uint[] x, uint[] z)
|
||||
{
|
||||
uint c = Nat.ShiftUpBit(5, x, 0, z);
|
||||
if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P)))
|
||||
{
|
||||
Nat.AddWordTo(5, PInv, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d444683aade1525409d6f03a80cd747c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,208 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP160R1FieldElement
|
||||
: AbstractFpFieldElement
|
||||
{
|
||||
public static readonly BigInteger Q = new BigInteger(1,
|
||||
Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"));
|
||||
|
||||
protected internal readonly uint[] x;
|
||||
|
||||
public SecP160R1FieldElement(BigInteger x)
|
||||
{
|
||||
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
|
||||
throw new ArgumentException("value invalid for SecP160R1FieldElement", "x");
|
||||
|
||||
this.x = SecP160R1Field.FromBigInteger(x);
|
||||
}
|
||||
|
||||
public SecP160R1FieldElement()
|
||||
{
|
||||
this.x = Nat160.Create();
|
||||
}
|
||||
|
||||
protected internal SecP160R1FieldElement(uint[] x)
|
||||
{
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public override bool IsZero
|
||||
{
|
||||
get { return Nat160.IsZero(x); }
|
||||
}
|
||||
|
||||
public override bool IsOne
|
||||
{
|
||||
get { return Nat160.IsOne(x); }
|
||||
}
|
||||
|
||||
public override bool TestBitZero()
|
||||
{
|
||||
return Nat160.GetBit(x, 0) == 1;
|
||||
}
|
||||
|
||||
public override BigInteger ToBigInteger()
|
||||
{
|
||||
return Nat160.ToBigInteger(x);
|
||||
}
|
||||
|
||||
public override string FieldName
|
||||
{
|
||||
get { return "SecP160R1Field"; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return Q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement Add(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R1Field.Add(x, ((SecP160R1FieldElement)b).x, z);
|
||||
return new SecP160R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement AddOne()
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R1Field.AddOne(x, z);
|
||||
return new SecP160R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Subtract(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R1Field.Subtract(x, ((SecP160R1FieldElement)b).x, z);
|
||||
return new SecP160R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Multiply(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R1Field.Multiply(x, ((SecP160R1FieldElement)b).x, z);
|
||||
return new SecP160R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Divide(ECFieldElement b)
|
||||
{
|
||||
// return multiply(b.invert());
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R1Field.Inv(((SecP160R1FieldElement)b).x, z);
|
||||
SecP160R1Field.Multiply(z, x, z);
|
||||
return new SecP160R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Negate()
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R1Field.Negate(x, z);
|
||||
return new SecP160R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Square()
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R1Field.Square(x, z);
|
||||
return new SecP160R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Invert()
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R1Field.Inv(x, z);
|
||||
return new SecP160R1FieldElement(z);
|
||||
}
|
||||
|
||||
// D.1.4 91
|
||||
/**
|
||||
* return a sqrt root - the routine verifies that the calculation returns the right value - if
|
||||
* none exists it returns null.
|
||||
*/
|
||||
public override ECFieldElement Sqrt()
|
||||
{
|
||||
/*
|
||||
* Raise this element to the exponent 2^158 - 2^29
|
||||
*
|
||||
* Breaking up the exponent's binary representation into "repunits", we get:
|
||||
* { 129 1s } { 29 0s }
|
||||
*
|
||||
* Therefore we need an addition chain containing 129 (the length of the repunit) We use:
|
||||
* 1, 2, 4, 8, 16, 32, 64, 128, [129]
|
||||
*/
|
||||
|
||||
uint[] x1 = this.x;
|
||||
if (Nat160.IsZero(x1) || Nat160.IsOne(x1))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
uint[] x2 = Nat160.Create();
|
||||
SecP160R1Field.Square(x1, x2);
|
||||
SecP160R1Field.Multiply(x2, x1, x2);
|
||||
uint[] x4 = Nat160.Create();
|
||||
SecP160R1Field.SquareN(x2, 2, x4);
|
||||
SecP160R1Field.Multiply(x4, x2, x4);
|
||||
uint[] x8 = x2;
|
||||
SecP160R1Field.SquareN(x4, 4, x8);
|
||||
SecP160R1Field.Multiply(x8, x4, x8);
|
||||
uint[] x16 = x4;
|
||||
SecP160R1Field.SquareN(x8, 8, x16);
|
||||
SecP160R1Field.Multiply(x16, x8, x16);
|
||||
uint[] x32 = x8;
|
||||
SecP160R1Field.SquareN(x16, 16, x32);
|
||||
SecP160R1Field.Multiply(x32, x16, x32);
|
||||
uint[] x64 = x16;
|
||||
SecP160R1Field.SquareN(x32, 32, x64);
|
||||
SecP160R1Field.Multiply(x64, x32, x64);
|
||||
uint[] x128 = x32;
|
||||
SecP160R1Field.SquareN(x64, 64, x128);
|
||||
SecP160R1Field.Multiply(x128, x64, x128);
|
||||
uint[] x129 = x64;
|
||||
SecP160R1Field.Square(x128, x129);
|
||||
SecP160R1Field.Multiply(x129, x1, x129);
|
||||
|
||||
uint[] t1 = x129;
|
||||
SecP160R1Field.SquareN(t1, 29, t1);
|
||||
|
||||
uint[] t2 = x128;
|
||||
SecP160R1Field.Square(t1, t2);
|
||||
|
||||
return Nat160.Eq(x1, t2) ? new SecP160R1FieldElement(t1) : null;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as SecP160R1FieldElement);
|
||||
}
|
||||
|
||||
public override bool Equals(ECFieldElement other)
|
||||
{
|
||||
return Equals(other as SecP160R1FieldElement);
|
||||
}
|
||||
|
||||
public virtual bool Equals(SecP160R1FieldElement other)
|
||||
{
|
||||
if (this == other)
|
||||
return true;
|
||||
if (null == other)
|
||||
return false;
|
||||
return Nat160.Eq(x, other.x);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07c4fed00202a584c88533f83236ec32
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,249 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP160R1Point
|
||||
: AbstractFpPoint
|
||||
{
|
||||
internal SecP160R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
|
||||
: base(curve, x, y)
|
||||
{
|
||||
}
|
||||
|
||||
internal SecP160R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
: base(curve, x, y, zs)
|
||||
{
|
||||
}
|
||||
|
||||
protected override ECPoint Detach()
|
||||
{
|
||||
return new SecP160R1Point(null, AffineXCoord, AffineYCoord);
|
||||
}
|
||||
|
||||
public override ECPoint Add(ECPoint b)
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return this;
|
||||
if (this == b)
|
||||
return Twice();
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SecP160R1FieldElement X1 = (SecP160R1FieldElement)this.RawXCoord, Y1 = (SecP160R1FieldElement)this.RawYCoord;
|
||||
SecP160R1FieldElement X2 = (SecP160R1FieldElement)b.RawXCoord, Y2 = (SecP160R1FieldElement)b.RawYCoord;
|
||||
|
||||
SecP160R1FieldElement Z1 = (SecP160R1FieldElement)this.RawZCoords[0];
|
||||
SecP160R1FieldElement Z2 = (SecP160R1FieldElement)b.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
uint[] tt1 = Nat160.CreateExt();
|
||||
uint[] t2 = Nat160.Create();
|
||||
uint[] t3 = Nat160.Create();
|
||||
uint[] t4 = Nat160.Create();
|
||||
|
||||
bool Z1IsOne = Z1.IsOne;
|
||||
uint[] U2, S2;
|
||||
if (Z1IsOne)
|
||||
{
|
||||
U2 = X2.x;
|
||||
S2 = Y2.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S2 = t3;
|
||||
SecP160R1Field.Square(Z1.x, S2);
|
||||
|
||||
U2 = t2;
|
||||
SecP160R1Field.Multiply(S2, X2.x, U2);
|
||||
|
||||
SecP160R1Field.Multiply(S2, Z1.x, S2);
|
||||
SecP160R1Field.Multiply(S2, Y2.x, S2);
|
||||
}
|
||||
|
||||
bool Z2IsOne = Z2.IsOne;
|
||||
uint[] U1, S1;
|
||||
if (Z2IsOne)
|
||||
{
|
||||
U1 = X1.x;
|
||||
S1 = Y1.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S1 = t4;
|
||||
SecP160R1Field.Square(Z2.x, S1);
|
||||
|
||||
U1 = tt1;
|
||||
SecP160R1Field.Multiply(S1, X1.x, U1);
|
||||
|
||||
SecP160R1Field.Multiply(S1, Z2.x, S1);
|
||||
SecP160R1Field.Multiply(S1, Y1.x, S1);
|
||||
}
|
||||
|
||||
uint[] H = Nat160.Create();
|
||||
SecP160R1Field.Subtract(U1, U2, H);
|
||||
|
||||
uint[] R = t2;
|
||||
SecP160R1Field.Subtract(S1, S2, R);
|
||||
|
||||
// Check if b == this or b == -this
|
||||
if (Nat160.IsZero(H))
|
||||
{
|
||||
if (Nat160.IsZero(R))
|
||||
{
|
||||
// this == b, i.e. this must be doubled
|
||||
return this.Twice();
|
||||
}
|
||||
|
||||
// this == -b, i.e. the result is the point at infinity
|
||||
return curve.Infinity;
|
||||
}
|
||||
|
||||
uint[] HSquared = t3;
|
||||
SecP160R1Field.Square(H, HSquared);
|
||||
|
||||
uint[] G = Nat160.Create();
|
||||
SecP160R1Field.Multiply(HSquared, H, G);
|
||||
|
||||
uint[] V = t3;
|
||||
SecP160R1Field.Multiply(HSquared, U1, V);
|
||||
|
||||
SecP160R1Field.Negate(G, G);
|
||||
Nat160.Mul(S1, G, tt1);
|
||||
|
||||
c = Nat160.AddBothTo(V, V, G);
|
||||
SecP160R1Field.Reduce32(c, G);
|
||||
|
||||
SecP160R1FieldElement X3 = new SecP160R1FieldElement(t4);
|
||||
SecP160R1Field.Square(R, X3.x);
|
||||
SecP160R1Field.Subtract(X3.x, G, X3.x);
|
||||
|
||||
SecP160R1FieldElement Y3 = new SecP160R1FieldElement(G);
|
||||
SecP160R1Field.Subtract(V, X3.x, Y3.x);
|
||||
SecP160R1Field.MultiplyAddToExt(Y3.x, R, tt1);
|
||||
SecP160R1Field.Reduce(tt1, Y3.x);
|
||||
|
||||
SecP160R1FieldElement Z3 = new SecP160R1FieldElement(H);
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
SecP160R1Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
if (!Z2IsOne)
|
||||
{
|
||||
SecP160R1Field.Multiply(Z3.x, Z2.x, Z3.x);
|
||||
}
|
||||
|
||||
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
|
||||
|
||||
return new SecP160R1Point(curve, X3, Y3, zs);
|
||||
}
|
||||
|
||||
public override ECPoint Twice()
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return this;
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SecP160R1FieldElement Y1 = (SecP160R1FieldElement)this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return curve.Infinity;
|
||||
|
||||
SecP160R1FieldElement X1 = (SecP160R1FieldElement)this.RawXCoord, Z1 = (SecP160R1FieldElement)this.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
uint[] t1 = Nat160.Create();
|
||||
uint[] t2 = Nat160.Create();
|
||||
|
||||
uint[] Y1Squared = Nat160.Create();
|
||||
SecP160R1Field.Square(Y1.x, Y1Squared);
|
||||
|
||||
uint[] T = Nat160.Create();
|
||||
SecP160R1Field.Square(Y1Squared, T);
|
||||
|
||||
bool Z1IsOne = Z1.IsOne;
|
||||
|
||||
uint[] Z1Squared = Z1.x;
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
Z1Squared = t2;
|
||||
SecP160R1Field.Square(Z1.x, Z1Squared);
|
||||
}
|
||||
|
||||
SecP160R1Field.Subtract(X1.x, Z1Squared, t1);
|
||||
|
||||
uint[] M = t2;
|
||||
SecP160R1Field.Add(X1.x, Z1Squared, M);
|
||||
SecP160R1Field.Multiply(M, t1, M);
|
||||
c = Nat160.AddBothTo(M, M, M);
|
||||
SecP160R1Field.Reduce32(c, M);
|
||||
|
||||
uint[] S = Y1Squared;
|
||||
SecP160R1Field.Multiply(Y1Squared, X1.x, S);
|
||||
c = Nat.ShiftUpBits(5, S, 2, 0);
|
||||
SecP160R1Field.Reduce32(c, S);
|
||||
|
||||
c = Nat.ShiftUpBits(5, T, 3, 0, t1);
|
||||
SecP160R1Field.Reduce32(c, t1);
|
||||
|
||||
SecP160R1FieldElement X3 = new SecP160R1FieldElement(T);
|
||||
SecP160R1Field.Square(M, X3.x);
|
||||
SecP160R1Field.Subtract(X3.x, S, X3.x);
|
||||
SecP160R1Field.Subtract(X3.x, S, X3.x);
|
||||
|
||||
SecP160R1FieldElement Y3 = new SecP160R1FieldElement(S);
|
||||
SecP160R1Field.Subtract(S, X3.x, Y3.x);
|
||||
SecP160R1Field.Multiply(Y3.x, M, Y3.x);
|
||||
SecP160R1Field.Subtract(Y3.x, t1, Y3.x);
|
||||
|
||||
SecP160R1FieldElement Z3 = new SecP160R1FieldElement(M);
|
||||
SecP160R1Field.Twice(Y1.x, Z3.x);
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
SecP160R1Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
|
||||
return new SecP160R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
|
||||
}
|
||||
|
||||
public override ECPoint TwicePlus(ECPoint b)
|
||||
{
|
||||
if (this == b)
|
||||
return ThreeTimes();
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return Twice();
|
||||
|
||||
ECFieldElement Y1 = this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return b;
|
||||
|
||||
return Twice().Add(b);
|
||||
}
|
||||
|
||||
public override ECPoint ThreeTimes()
|
||||
{
|
||||
if (this.IsInfinity || this.RawYCoord.IsZero)
|
||||
return this;
|
||||
|
||||
// NOTE: Be careful about recursions between TwicePlus and ThreeTimes
|
||||
return Twice().Add(this);
|
||||
}
|
||||
|
||||
public override ECPoint Negate()
|
||||
{
|
||||
if (IsInfinity)
|
||||
return this;
|
||||
|
||||
return new SecP160R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48035112039046c41b2a437840a8014d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,175 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP160R2Curve
|
||||
: AbstractFpCurve
|
||||
{
|
||||
public static readonly BigInteger q = SecP160R2FieldElement.Q;
|
||||
|
||||
private const int SECP160R2_DEFAULT_COORDS = COORD_JACOBIAN;
|
||||
private const int SECP160R2_FE_INTS = 5;
|
||||
private static readonly ECFieldElement[] SECP160R2_AFFINE_ZS = new ECFieldElement[] { new SecP160R2FieldElement(BigInteger.One) };
|
||||
|
||||
protected readonly SecP160R2Point m_infinity;
|
||||
|
||||
public SecP160R2Curve()
|
||||
: base(q)
|
||||
{
|
||||
this.m_infinity = new SecP160R2Point(this, null, null);
|
||||
|
||||
this.m_a = FromBigInteger(new BigInteger(1,
|
||||
Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70")));
|
||||
this.m_b = FromBigInteger(new BigInteger(1,
|
||||
Hex.DecodeStrict("B4E134D3FB59EB8BAB57274904664D5AF50388BA")));
|
||||
this.m_order = new BigInteger(1, Hex.DecodeStrict("0100000000000000000000351EE786A818F3A1A16B"));
|
||||
this.m_cofactor = BigInteger.One;
|
||||
|
||||
this.m_coord = SECP160R2_DEFAULT_COORDS;
|
||||
}
|
||||
|
||||
protected override ECCurve CloneCurve()
|
||||
{
|
||||
return new SecP160R2Curve();
|
||||
}
|
||||
|
||||
public override bool SupportsCoordinateSystem(int coord)
|
||||
{
|
||||
switch (coord)
|
||||
{
|
||||
case COORD_JACOBIAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BigInteger Q
|
||||
{
|
||||
get { return q; }
|
||||
}
|
||||
|
||||
public override ECPoint Infinity
|
||||
{
|
||||
get { return m_infinity; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement FromBigInteger(BigInteger x)
|
||||
{
|
||||
return new SecP160R2FieldElement(x);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return new SecP160R2Point(this, x, y);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
{
|
||||
return new SecP160R2Point(this, x, y, zs);
|
||||
}
|
||||
|
||||
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
|
||||
{
|
||||
uint[] table = new uint[len * SECP160R2_FE_INTS * 2];
|
||||
{
|
||||
int pos = 0;
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
ECPoint p = points[off + i];
|
||||
Nat160.Copy(((SecP160R2FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP160R2_FE_INTS;
|
||||
Nat160.Copy(((SecP160R2FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP160R2_FE_INTS;
|
||||
}
|
||||
}
|
||||
|
||||
return new SecP160R2LookupTable(this, table, len);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElement(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat160.Create();
|
||||
SecP160R2Field.Random(r, x);
|
||||
return new SecP160R2FieldElement(x);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElementMult(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat160.Create();
|
||||
SecP160R2Field.RandomMult(r, x);
|
||||
return new SecP160R2FieldElement(x);
|
||||
}
|
||||
|
||||
private class SecP160R2LookupTable
|
||||
: AbstractECLookupTable
|
||||
{
|
||||
private readonly SecP160R2Curve m_outer;
|
||||
private readonly uint[] m_table;
|
||||
private readonly int m_size;
|
||||
|
||||
internal SecP160R2LookupTable(SecP160R2Curve outer, uint[] table, int size)
|
||||
{
|
||||
this.m_outer = outer;
|
||||
this.m_table = table;
|
||||
this.m_size = size;
|
||||
}
|
||||
|
||||
public override int Size
|
||||
{
|
||||
get { return m_size; }
|
||||
}
|
||||
|
||||
public override ECPoint Lookup(int index)
|
||||
{
|
||||
uint[] x = Nat160.Create(), y = Nat160.Create();
|
||||
int pos = 0;
|
||||
|
||||
for (int i = 0; i < m_size; ++i)
|
||||
{
|
||||
uint MASK = (uint)(((i ^ index) - 1) >> 31);
|
||||
|
||||
for (int j = 0; j < SECP160R2_FE_INTS; ++j)
|
||||
{
|
||||
x[j] ^= m_table[pos + j] & MASK;
|
||||
y[j] ^= m_table[pos + SECP160R2_FE_INTS + j] & MASK;
|
||||
}
|
||||
|
||||
pos += (SECP160R2_FE_INTS * 2);
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
public override ECPoint LookupVar(int index)
|
||||
{
|
||||
uint[] x = Nat160.Create(), y = Nat160.Create();
|
||||
int pos = index * SECP160R2_FE_INTS * 2;
|
||||
|
||||
for (int j = 0; j < SECP160R2_FE_INTS; ++j)
|
||||
{
|
||||
x[j] = m_table[pos + j];
|
||||
y[j] = m_table[pos + SECP160R2_FE_INTS + j];
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
private ECPoint CreatePoint(uint[] x, uint[] y)
|
||||
{
|
||||
return m_outer.CreateRawPoint(new SecP160R2FieldElement(x), new SecP160R2FieldElement(y), SECP160R2_AFFINE_ZS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d36a6056a9fa51946b70dd3977edfb28
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,220 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP160R2Field
|
||||
{
|
||||
// 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1
|
||||
internal static readonly uint[] P = new uint[]{ 0xFFFFAC73, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
private static readonly uint[] PExt = new uint[]{ 0x1B44BBA9, 0x0000A71A, 0x00000001, 0x00000000, 0x00000000,
|
||||
0xFFFF58E6, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
private static readonly uint[] PExtInv = new uint[]{ 0xE4BB4457, 0xFFFF58E5, 0xFFFFFFFE, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0x0000A719, 0x00000002 };
|
||||
private const uint P4 = 0xFFFFFFFF;
|
||||
private const uint PExt9 = 0xFFFFFFFF;
|
||||
private const uint PInv33 = 0x538D;
|
||||
|
||||
public static void Add(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
uint c = Nat160.Add(x, y, z);
|
||||
if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P)))
|
||||
{
|
||||
Nat.Add33To(5, PInv33, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
|
||||
{
|
||||
uint c = Nat.Add(10, xx, yy, zz);
|
||||
if (c != 0 || (zz[9] == PExt9 && Nat.Gte(10, zz, PExt)))
|
||||
{
|
||||
if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
|
||||
{
|
||||
Nat.IncAt(10, zz, PExtInv.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddOne(uint[] x, uint[] z)
|
||||
{
|
||||
uint c = Nat.Inc(5, x, z);
|
||||
if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P)))
|
||||
{
|
||||
Nat.Add33To(5, PInv33, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static uint[] FromBigInteger(BigInteger x)
|
||||
{
|
||||
uint[] z = Nat.FromBigInteger(160, x);
|
||||
if (z[4] == P4 && Nat160.Gte(z, P))
|
||||
{
|
||||
Nat160.SubFrom(P, z);
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
public static void Half(uint[] x, uint[] z)
|
||||
{
|
||||
if ((x[0] & 1) == 0)
|
||||
{
|
||||
Nat.ShiftDownBit(5, x, 0, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint c = Nat160.Add(x, P, z);
|
||||
Nat.ShiftDownBit(5, z, c);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Inv(uint[] x, uint[] z)
|
||||
{
|
||||
Mod.CheckedModOddInverse(P, x, z);
|
||||
}
|
||||
|
||||
public static int IsZero(uint[] x)
|
||||
{
|
||||
uint d = 0;
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
d |= x[i];
|
||||
}
|
||||
d = (d >> 1) | (d & 1);
|
||||
return ((int)d - 1) >> 31;
|
||||
}
|
||||
|
||||
public static void Multiply(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
uint[] tt = Nat160.CreateExt();
|
||||
Nat160.Mul(x, y, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
|
||||
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
|
||||
{
|
||||
uint c = Nat160.MulAddTo(x, y, zz);
|
||||
if (c != 0 || (zz[9] == PExt9 && Nat.Gte(10, zz, PExt)))
|
||||
{
|
||||
if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
|
||||
{
|
||||
Nat.IncAt(10, zz, PExtInv.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Negate(uint[] x, uint[] z)
|
||||
{
|
||||
if (0 != IsZero(x))
|
||||
{
|
||||
Nat160.Sub(P, P, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
Nat160.Sub(P, x, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Random(SecureRandom r, uint[] z)
|
||||
{
|
||||
byte[] bb = new byte[5 * 4];
|
||||
do
|
||||
{
|
||||
r.NextBytes(bb);
|
||||
Pack.LE_To_UInt32(bb, 0, z, 0, 5);
|
||||
}
|
||||
while (0 == Nat.LessThan(5, z, P));
|
||||
}
|
||||
|
||||
public static void RandomMult(SecureRandom r, uint[] z)
|
||||
{
|
||||
do
|
||||
{
|
||||
Random(r, z);
|
||||
}
|
||||
while (0 != IsZero(z));
|
||||
}
|
||||
|
||||
public static void Reduce(uint[] xx, uint[] z)
|
||||
{
|
||||
ulong cc = Nat160.Mul33Add(PInv33, xx, 5, xx, 0, z, 0);
|
||||
uint c = Nat160.Mul33DWordAdd(PInv33, cc, z, 0);
|
||||
|
||||
Debug.Assert(c == 0 || c == 1);
|
||||
|
||||
if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P)))
|
||||
{
|
||||
Nat.Add33To(5, PInv33, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Reduce32(uint x, uint[] z)
|
||||
{
|
||||
if ((x != 0 && Nat160.Mul33WordAdd(PInv33, x, z, 0) != 0)
|
||||
|| (z[4] == P4 && Nat160.Gte(z, P)))
|
||||
{
|
||||
Nat.Add33To(5, PInv33, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Square(uint[] x, uint[] z)
|
||||
{
|
||||
uint[] tt = Nat160.CreateExt();
|
||||
Nat160.Square(x, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
|
||||
public static void SquareN(uint[] x, int n, uint[] z)
|
||||
{
|
||||
Debug.Assert(n > 0);
|
||||
|
||||
uint[] tt = Nat160.CreateExt();
|
||||
Nat160.Square(x, tt);
|
||||
Reduce(tt, z);
|
||||
|
||||
while (--n > 0)
|
||||
{
|
||||
Nat160.Square(z, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Subtract(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
int c = Nat160.Sub(x, y, z);
|
||||
if (c != 0)
|
||||
{
|
||||
Nat.Sub33From(5, PInv33, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
|
||||
{
|
||||
int c = Nat.Sub(10, xx, yy, zz);
|
||||
if (c != 0)
|
||||
{
|
||||
if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0)
|
||||
{
|
||||
Nat.DecAt(10, zz, PExtInv.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Twice(uint[] x, uint[] z)
|
||||
{
|
||||
uint c = Nat.ShiftUpBit(5, x, 0, z);
|
||||
if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P)))
|
||||
{
|
||||
Nat.Add33To(5, PInv33, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e351f45b5e75bb149baf02e11f068f33
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,223 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP160R2FieldElement
|
||||
: AbstractFpFieldElement
|
||||
{
|
||||
public static readonly BigInteger Q = new BigInteger(1,
|
||||
Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"));
|
||||
|
||||
protected internal readonly uint[] x;
|
||||
|
||||
public SecP160R2FieldElement(BigInteger x)
|
||||
{
|
||||
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
|
||||
throw new ArgumentException("value invalid for SecP160R2FieldElement", "x");
|
||||
|
||||
this.x = SecP160R2Field.FromBigInteger(x);
|
||||
}
|
||||
|
||||
public SecP160R2FieldElement()
|
||||
{
|
||||
this.x = Nat160.Create();
|
||||
}
|
||||
|
||||
protected internal SecP160R2FieldElement(uint[] x)
|
||||
{
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public override bool IsZero
|
||||
{
|
||||
get { return Nat160.IsZero(x); }
|
||||
}
|
||||
|
||||
public override bool IsOne
|
||||
{
|
||||
get { return Nat160.IsOne(x); }
|
||||
}
|
||||
|
||||
public override bool TestBitZero()
|
||||
{
|
||||
return Nat160.GetBit(x, 0) == 1;
|
||||
}
|
||||
|
||||
public override BigInteger ToBigInteger()
|
||||
{
|
||||
return Nat160.ToBigInteger(x);
|
||||
}
|
||||
|
||||
public override string FieldName
|
||||
{
|
||||
get { return "SecP160R2Field"; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return Q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement Add(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R2Field.Add(x, ((SecP160R2FieldElement)b).x, z);
|
||||
return new SecP160R2FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement AddOne()
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R2Field.AddOne(x, z);
|
||||
return new SecP160R2FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Subtract(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R2Field.Subtract(x, ((SecP160R2FieldElement)b).x, z);
|
||||
return new SecP160R2FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Multiply(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R2Field.Multiply(x, ((SecP160R2FieldElement)b).x, z);
|
||||
return new SecP160R2FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Divide(ECFieldElement b)
|
||||
{
|
||||
// return Multiply(b.invert());
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R2Field.Inv(((SecP160R2FieldElement)b).x, z);
|
||||
SecP160R2Field.Multiply(z, x, z);
|
||||
return new SecP160R2FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Negate()
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R2Field.Negate(x, z);
|
||||
return new SecP160R2FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Square()
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R2Field.Square(x, z);
|
||||
return new SecP160R2FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Invert()
|
||||
{
|
||||
uint[] z = Nat160.Create();
|
||||
SecP160R2Field.Inv(x, z);
|
||||
return new SecP160R2FieldElement(z);
|
||||
}
|
||||
|
||||
// D.1.4 91
|
||||
/**
|
||||
* return a sqrt root - the routine verifies that the calculation returns the right value - if
|
||||
* none exists it returns null.
|
||||
*/
|
||||
public override ECFieldElement Sqrt()
|
||||
{
|
||||
/*
|
||||
* Raise this element to the exponent 2^158 - 2^30 - 2^12 - 2^10 - 2^7 - 2^6 - 2^5 - 2^1 - 2^0
|
||||
*
|
||||
* Breaking up the exponent's binary representation into "repunits", we get: { 127 1s } { 1
|
||||
* 0s } { 17 1s } { 1 0s } { 1 1s } { 1 0s } { 2 1s } { 3 0s } { 3 1s } { 1 0s } { 1 1s }
|
||||
*
|
||||
* Therefore we need an Addition chain containing 1, 2, 3, 17, 127 (the lengths of the repunits)
|
||||
* We use: [1], [2], [3], 4, 7, 14, [17], 31, 62, 124, [127]
|
||||
*/
|
||||
|
||||
uint[] x1 = this.x;
|
||||
if (Nat160.IsZero(x1) || Nat160.IsOne(x1))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
uint[] x2 = Nat160.Create();
|
||||
SecP160R2Field.Square(x1, x2);
|
||||
SecP160R2Field.Multiply(x2, x1, x2);
|
||||
uint[] x3 = Nat160.Create();
|
||||
SecP160R2Field.Square(x2, x3);
|
||||
SecP160R2Field.Multiply(x3, x1, x3);
|
||||
uint[] x4 = Nat160.Create();
|
||||
SecP160R2Field.Square(x3, x4);
|
||||
SecP160R2Field.Multiply(x4, x1, x4);
|
||||
uint[] x7 = Nat160.Create();
|
||||
SecP160R2Field.SquareN(x4, 3, x7);
|
||||
SecP160R2Field.Multiply(x7, x3, x7);
|
||||
uint[] x14 = x4;
|
||||
SecP160R2Field.SquareN(x7, 7, x14);
|
||||
SecP160R2Field.Multiply(x14, x7, x14);
|
||||
uint[] x17 = x7;
|
||||
SecP160R2Field.SquareN(x14, 3, x17);
|
||||
SecP160R2Field.Multiply(x17, x3, x17);
|
||||
uint[] x31 = Nat160.Create();
|
||||
SecP160R2Field.SquareN(x17, 14, x31);
|
||||
SecP160R2Field.Multiply(x31, x14, x31);
|
||||
uint[] x62 = x14;
|
||||
SecP160R2Field.SquareN(x31, 31, x62);
|
||||
SecP160R2Field.Multiply(x62, x31, x62);
|
||||
uint[] x124 = x31;
|
||||
SecP160R2Field.SquareN(x62, 62, x124);
|
||||
SecP160R2Field.Multiply(x124, x62, x124);
|
||||
uint[] x127 = x62;
|
||||
SecP160R2Field.SquareN(x124, 3, x127);
|
||||
SecP160R2Field.Multiply(x127, x3, x127);
|
||||
|
||||
uint[] t1 = x127;
|
||||
SecP160R2Field.SquareN(t1, 18, t1);
|
||||
SecP160R2Field.Multiply(t1, x17, t1);
|
||||
SecP160R2Field.SquareN(t1, 2, t1);
|
||||
SecP160R2Field.Multiply(t1, x1, t1);
|
||||
SecP160R2Field.SquareN(t1, 3, t1);
|
||||
SecP160R2Field.Multiply(t1, x2, t1);
|
||||
SecP160R2Field.SquareN(t1, 6, t1);
|
||||
SecP160R2Field.Multiply(t1, x3, t1);
|
||||
SecP160R2Field.SquareN(t1, 2, t1);
|
||||
SecP160R2Field.Multiply(t1, x1, t1);
|
||||
|
||||
uint[] t2 = x2;
|
||||
SecP160R2Field.Square(t1, t2);
|
||||
|
||||
return Nat160.Eq(x1, t2) ? new SecP160R2FieldElement(t1) : null;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as SecP160R2FieldElement);
|
||||
}
|
||||
|
||||
public override bool Equals(ECFieldElement other)
|
||||
{
|
||||
return Equals(other as SecP160R2FieldElement);
|
||||
}
|
||||
|
||||
public virtual bool Equals(SecP160R2FieldElement other)
|
||||
{
|
||||
if (this == other)
|
||||
return true;
|
||||
if (null == other)
|
||||
return false;
|
||||
return Nat160.Eq(x, other.x);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aae5056faf4a481479fc7b296b811965
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,249 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP160R2Point
|
||||
: AbstractFpPoint
|
||||
{
|
||||
internal SecP160R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
|
||||
: base(curve, x, y)
|
||||
{
|
||||
}
|
||||
|
||||
internal SecP160R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
: base(curve, x, y, zs)
|
||||
{
|
||||
}
|
||||
|
||||
protected override ECPoint Detach()
|
||||
{
|
||||
return new SecP160R2Point(null, AffineXCoord, AffineYCoord);
|
||||
}
|
||||
|
||||
public override ECPoint Add(ECPoint b)
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return this;
|
||||
if (this == b)
|
||||
return Twice();
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SecP160R2FieldElement X1 = (SecP160R2FieldElement)this.RawXCoord, Y1 = (SecP160R2FieldElement)this.RawYCoord;
|
||||
SecP160R2FieldElement X2 = (SecP160R2FieldElement)b.RawXCoord, Y2 = (SecP160R2FieldElement)b.RawYCoord;
|
||||
|
||||
SecP160R2FieldElement Z1 = (SecP160R2FieldElement)this.RawZCoords[0];
|
||||
SecP160R2FieldElement Z2 = (SecP160R2FieldElement)b.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
uint[] tt1 = Nat160.CreateExt();
|
||||
uint[] t2 = Nat160.Create();
|
||||
uint[] t3 = Nat160.Create();
|
||||
uint[] t4 = Nat160.Create();
|
||||
|
||||
bool Z1IsOne = Z1.IsOne;
|
||||
uint[] U2, S2;
|
||||
if (Z1IsOne)
|
||||
{
|
||||
U2 = X2.x;
|
||||
S2 = Y2.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S2 = t3;
|
||||
SecP160R2Field.Square(Z1.x, S2);
|
||||
|
||||
U2 = t2;
|
||||
SecP160R2Field.Multiply(S2, X2.x, U2);
|
||||
|
||||
SecP160R2Field.Multiply(S2, Z1.x, S2);
|
||||
SecP160R2Field.Multiply(S2, Y2.x, S2);
|
||||
}
|
||||
|
||||
bool Z2IsOne = Z2.IsOne;
|
||||
uint[] U1, S1;
|
||||
if (Z2IsOne)
|
||||
{
|
||||
U1 = X1.x;
|
||||
S1 = Y1.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S1 = t4;
|
||||
SecP160R2Field.Square(Z2.x, S1);
|
||||
|
||||
U1 = tt1;
|
||||
SecP160R2Field.Multiply(S1, X1.x, U1);
|
||||
|
||||
SecP160R2Field.Multiply(S1, Z2.x, S1);
|
||||
SecP160R2Field.Multiply(S1, Y1.x, S1);
|
||||
}
|
||||
|
||||
uint[] H = Nat160.Create();
|
||||
SecP160R2Field.Subtract(U1, U2, H);
|
||||
|
||||
uint[] R = t2;
|
||||
SecP160R2Field.Subtract(S1, S2, R);
|
||||
|
||||
// Check if b == this or b == -this
|
||||
if (Nat160.IsZero(H))
|
||||
{
|
||||
if (Nat160.IsZero(R))
|
||||
{
|
||||
// this == b, i.e. this must be doubled
|
||||
return this.Twice();
|
||||
}
|
||||
|
||||
// this == -b, i.e. the result is the point at infinity
|
||||
return curve.Infinity;
|
||||
}
|
||||
|
||||
uint[] HSquared = t3;
|
||||
SecP160R2Field.Square(H, HSquared);
|
||||
|
||||
uint[] G = Nat160.Create();
|
||||
SecP160R2Field.Multiply(HSquared, H, G);
|
||||
|
||||
uint[] V = t3;
|
||||
SecP160R2Field.Multiply(HSquared, U1, V);
|
||||
|
||||
SecP160R2Field.Negate(G, G);
|
||||
Nat160.Mul(S1, G, tt1);
|
||||
|
||||
c = Nat160.AddBothTo(V, V, G);
|
||||
SecP160R2Field.Reduce32(c, G);
|
||||
|
||||
SecP160R2FieldElement X3 = new SecP160R2FieldElement(t4);
|
||||
SecP160R2Field.Square(R, X3.x);
|
||||
SecP160R2Field.Subtract(X3.x, G, X3.x);
|
||||
|
||||
SecP160R2FieldElement Y3 = new SecP160R2FieldElement(G);
|
||||
SecP160R2Field.Subtract(V, X3.x, Y3.x);
|
||||
SecP160R2Field.MultiplyAddToExt(Y3.x, R, tt1);
|
||||
SecP160R2Field.Reduce(tt1, Y3.x);
|
||||
|
||||
SecP160R2FieldElement Z3 = new SecP160R2FieldElement(H);
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
SecP160R2Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
if (!Z2IsOne)
|
||||
{
|
||||
SecP160R2Field.Multiply(Z3.x, Z2.x, Z3.x);
|
||||
}
|
||||
|
||||
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
|
||||
|
||||
return new SecP160R2Point(curve, X3, Y3, zs);
|
||||
}
|
||||
|
||||
public override ECPoint Twice()
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return this;
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SecP160R2FieldElement Y1 = (SecP160R2FieldElement)this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return curve.Infinity;
|
||||
|
||||
SecP160R2FieldElement X1 = (SecP160R2FieldElement)this.RawXCoord, Z1 = (SecP160R2FieldElement)this.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
uint[] t1 = Nat160.Create();
|
||||
uint[] t2 = Nat160.Create();
|
||||
|
||||
uint[] Y1Squared = Nat160.Create();
|
||||
SecP160R2Field.Square(Y1.x, Y1Squared);
|
||||
|
||||
uint[] T = Nat160.Create();
|
||||
SecP160R2Field.Square(Y1Squared, T);
|
||||
|
||||
bool Z1IsOne = Z1.IsOne;
|
||||
|
||||
uint[] Z1Squared = Z1.x;
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
Z1Squared = t2;
|
||||
SecP160R2Field.Square(Z1.x, Z1Squared);
|
||||
}
|
||||
|
||||
SecP160R2Field.Subtract(X1.x, Z1Squared, t1);
|
||||
|
||||
uint[] M = t2;
|
||||
SecP160R2Field.Add(X1.x, Z1Squared, M);
|
||||
SecP160R2Field.Multiply(M, t1, M);
|
||||
c = Nat160.AddBothTo(M, M, M);
|
||||
SecP160R2Field.Reduce32(c, M);
|
||||
|
||||
uint[] S = Y1Squared;
|
||||
SecP160R2Field.Multiply(Y1Squared, X1.x, S);
|
||||
c = Nat.ShiftUpBits(5, S, 2, 0);
|
||||
SecP160R2Field.Reduce32(c, S);
|
||||
|
||||
c = Nat.ShiftUpBits(5, T, 3, 0, t1);
|
||||
SecP160R2Field.Reduce32(c, t1);
|
||||
|
||||
SecP160R2FieldElement X3 = new SecP160R2FieldElement(T);
|
||||
SecP160R2Field.Square(M, X3.x);
|
||||
SecP160R2Field.Subtract(X3.x, S, X3.x);
|
||||
SecP160R2Field.Subtract(X3.x, S, X3.x);
|
||||
|
||||
SecP160R2FieldElement Y3 = new SecP160R2FieldElement(S);
|
||||
SecP160R2Field.Subtract(S, X3.x, Y3.x);
|
||||
SecP160R2Field.Multiply(Y3.x, M, Y3.x);
|
||||
SecP160R2Field.Subtract(Y3.x, t1, Y3.x);
|
||||
|
||||
SecP160R2FieldElement Z3 = new SecP160R2FieldElement(M);
|
||||
SecP160R2Field.Twice(Y1.x, Z3.x);
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
SecP160R2Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
|
||||
return new SecP160R2Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
|
||||
}
|
||||
|
||||
public override ECPoint TwicePlus(ECPoint b)
|
||||
{
|
||||
if (this == b)
|
||||
return ThreeTimes();
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return Twice();
|
||||
|
||||
ECFieldElement Y1 = this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return b;
|
||||
|
||||
return Twice().Add(b);
|
||||
}
|
||||
|
||||
public override ECPoint ThreeTimes()
|
||||
{
|
||||
if (this.IsInfinity || this.RawYCoord.IsZero)
|
||||
return this;
|
||||
|
||||
// NOTE: Be careful about recursions between TwicePlus and ThreeTimes
|
||||
return Twice().Add(this);
|
||||
}
|
||||
|
||||
public override ECPoint Negate()
|
||||
{
|
||||
if (IsInfinity)
|
||||
return this;
|
||||
|
||||
return new SecP160R2Point(Curve, this.RawXCoord, this.RawYCoord.Negate(), this.RawZCoords);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 052ed3284b9686047ad51492201a07e6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,172 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP192K1Curve
|
||||
: AbstractFpCurve
|
||||
{
|
||||
public static readonly BigInteger q = SecP192K1FieldElement.Q;
|
||||
|
||||
private const int SECP192K1_DEFAULT_COORDS = COORD_JACOBIAN;
|
||||
private const int SECP192K1_FE_INTS = 6;
|
||||
private static readonly ECFieldElement[] SECP192K1_AFFINE_ZS = new ECFieldElement[] { new SecP192K1FieldElement(BigInteger.One) };
|
||||
|
||||
protected readonly SecP192K1Point m_infinity;
|
||||
|
||||
public SecP192K1Curve()
|
||||
: base(q)
|
||||
{
|
||||
this.m_infinity = new SecP192K1Point(this, null, null);
|
||||
|
||||
this.m_a = FromBigInteger(BigInteger.Zero);
|
||||
this.m_b = FromBigInteger(BigInteger.ValueOf(3));
|
||||
this.m_order = new BigInteger(1, Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"));
|
||||
this.m_cofactor = BigInteger.One;
|
||||
this.m_coord = SECP192K1_DEFAULT_COORDS;
|
||||
}
|
||||
|
||||
protected override ECCurve CloneCurve()
|
||||
{
|
||||
return new SecP192K1Curve();
|
||||
}
|
||||
|
||||
public override bool SupportsCoordinateSystem(int coord)
|
||||
{
|
||||
switch (coord)
|
||||
{
|
||||
case COORD_JACOBIAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BigInteger Q
|
||||
{
|
||||
get { return q; }
|
||||
}
|
||||
|
||||
public override ECPoint Infinity
|
||||
{
|
||||
get { return m_infinity; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement FromBigInteger(BigInteger x)
|
||||
{
|
||||
return new SecP192K1FieldElement(x);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return new SecP192K1Point(this, x, y);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
{
|
||||
return new SecP192K1Point(this, x, y, zs);
|
||||
}
|
||||
|
||||
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
|
||||
{
|
||||
uint[] table = new uint[len * SECP192K1_FE_INTS * 2];
|
||||
{
|
||||
int pos = 0;
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
ECPoint p = points[off + i];
|
||||
Nat192.Copy(((SecP192K1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP192K1_FE_INTS;
|
||||
Nat192.Copy(((SecP192K1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP192K1_FE_INTS;
|
||||
}
|
||||
}
|
||||
|
||||
return new SecP192K1LookupTable(this, table, len);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElement(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat192.Create();
|
||||
SecP192K1Field.Random(r, x);
|
||||
return new SecP192K1FieldElement(x);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElementMult(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat192.Create();
|
||||
SecP192K1Field.RandomMult(r, x);
|
||||
return new SecP192K1FieldElement(x);
|
||||
}
|
||||
|
||||
private class SecP192K1LookupTable
|
||||
: AbstractECLookupTable
|
||||
{
|
||||
private readonly SecP192K1Curve m_outer;
|
||||
private readonly uint[] m_table;
|
||||
private readonly int m_size;
|
||||
|
||||
internal SecP192K1LookupTable(SecP192K1Curve outer, uint[] table, int size)
|
||||
{
|
||||
this.m_outer = outer;
|
||||
this.m_table = table;
|
||||
this.m_size = size;
|
||||
}
|
||||
|
||||
public override int Size
|
||||
{
|
||||
get { return m_size; }
|
||||
}
|
||||
|
||||
public override ECPoint Lookup(int index)
|
||||
{
|
||||
uint[] x = Nat192.Create(), y = Nat192.Create();
|
||||
int pos = 0;
|
||||
|
||||
for (int i = 0; i < m_size; ++i)
|
||||
{
|
||||
uint MASK = (uint)(((i ^ index) - 1) >> 31);
|
||||
|
||||
for (int j = 0; j < SECP192K1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] ^= m_table[pos + j] & MASK;
|
||||
y[j] ^= m_table[pos + SECP192K1_FE_INTS + j] & MASK;
|
||||
}
|
||||
|
||||
pos += (SECP192K1_FE_INTS * 2);
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
public override ECPoint LookupVar(int index)
|
||||
{
|
||||
uint[] x = Nat192.Create(), y = Nat192.Create();
|
||||
int pos = index * SECP192K1_FE_INTS * 2;
|
||||
|
||||
for (int j = 0; j < SECP192K1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] = m_table[pos + j];
|
||||
y[j] = m_table[pos + SECP192K1_FE_INTS + j];
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
private ECPoint CreatePoint(uint[] x, uint[] y)
|
||||
{
|
||||
return m_outer.CreateRawPoint(new SecP192K1FieldElement(x), new SecP192K1FieldElement(y), SECP192K1_AFFINE_ZS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c57242857a693945805fab06e8b8816
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,221 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP192K1Field
|
||||
{
|
||||
// 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1
|
||||
internal static readonly uint[] P = new uint[]{ 0xFFFFEE37, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF };
|
||||
private static readonly uint[] PExt = new uint[]{ 0x013C4FD1, 0x00002392, 0x00000001, 0x00000000, 0x00000000,
|
||||
0x00000000, 0xFFFFDC6E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
private static readonly uint[] PExtInv = new uint[]{ 0xFEC3B02F, 0xFFFFDC6D, 0xFFFFFFFE, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0x00002391, 0x00000002 };
|
||||
private const uint P5 = 0xFFFFFFFF;
|
||||
private const uint PExt11 = 0xFFFFFFFF;
|
||||
private const uint PInv33 = 0x11C9;
|
||||
|
||||
public static void Add(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
uint c = Nat192.Add(x, y, z);
|
||||
if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P)))
|
||||
{
|
||||
Nat.Add33To(6, PInv33, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
|
||||
{
|
||||
uint c = Nat.Add(12, xx, yy, zz);
|
||||
if (c != 0 || (zz[11] == PExt11 && Nat.Gte(12, zz, PExt)))
|
||||
{
|
||||
if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
|
||||
{
|
||||
Nat.IncAt(12, zz, PExtInv.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddOne(uint[] x, uint[] z)
|
||||
{
|
||||
uint c = Nat.Inc(6, x, z);
|
||||
if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P)))
|
||||
{
|
||||
Nat.Add33To(6, PInv33, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static uint[] FromBigInteger(BigInteger x)
|
||||
{
|
||||
uint[] z = Nat.FromBigInteger(192, x);
|
||||
if (z[5] == P5 && Nat192.Gte(z, P))
|
||||
{
|
||||
Nat192.SubFrom(P, z);
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
public static void Half(uint[] x, uint[] z)
|
||||
{
|
||||
if ((x[0] & 1) == 0)
|
||||
{
|
||||
Nat.ShiftDownBit(6, x, 0, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint c = Nat192.Add(x, P, z);
|
||||
Nat.ShiftDownBit(6, z, c);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Inv(uint[] x, uint[] z)
|
||||
{
|
||||
Mod.CheckedModOddInverse(P, x, z);
|
||||
}
|
||||
|
||||
public static int IsZero(uint[] x)
|
||||
{
|
||||
uint d = 0;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
d |= x[i];
|
||||
}
|
||||
d = (d >> 1) | (d & 1);
|
||||
return ((int)d - 1) >> 31;
|
||||
}
|
||||
|
||||
public static void Multiply(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
uint[] tt = Nat192.CreateExt();
|
||||
Nat192.Mul(x, y, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
|
||||
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
|
||||
{
|
||||
uint c = Nat192.MulAddTo(x, y, zz);
|
||||
if (c != 0 || (zz[11] == PExt11 && Nat.Gte(12, zz, PExt)))
|
||||
{
|
||||
if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
|
||||
{
|
||||
Nat.IncAt(12, zz, PExtInv.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Negate(uint[] x, uint[] z)
|
||||
{
|
||||
if (0 != IsZero(x))
|
||||
{
|
||||
Nat192.Sub(P, P, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
Nat192.Sub(P, x, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Random(SecureRandom r, uint[] z)
|
||||
{
|
||||
byte[] bb = new byte[6 * 4];
|
||||
do
|
||||
{
|
||||
r.NextBytes(bb);
|
||||
Pack.LE_To_UInt32(bb, 0, z, 0, 6);
|
||||
}
|
||||
while (0 == Nat.LessThan(6, z, P));
|
||||
}
|
||||
|
||||
public static void RandomMult(SecureRandom r, uint[] z)
|
||||
{
|
||||
do
|
||||
{
|
||||
Random(r, z);
|
||||
}
|
||||
while (0 != IsZero(z));
|
||||
}
|
||||
|
||||
public static void Reduce(uint[] xx, uint[] z)
|
||||
{
|
||||
ulong cc = Nat192.Mul33Add(PInv33, xx, 6, xx, 0, z, 0);
|
||||
uint c = Nat192.Mul33DWordAdd(PInv33, cc, z, 0);
|
||||
|
||||
Debug.Assert(c == 0 || c == 1);
|
||||
|
||||
if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P)))
|
||||
{
|
||||
Nat.Add33To(6, PInv33, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Reduce32(uint x, uint[] z)
|
||||
{
|
||||
if ((x != 0 && Nat192.Mul33WordAdd(PInv33, x, z, 0) != 0)
|
||||
|| (z[5] == P5 && Nat192.Gte(z, P)))
|
||||
{
|
||||
Nat.Add33To(6, PInv33, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Square(uint[] x, uint[] z)
|
||||
{
|
||||
uint[] tt = Nat192.CreateExt();
|
||||
Nat192.Square(x, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
|
||||
public static void SquareN(uint[] x, int n, uint[] z)
|
||||
{
|
||||
Debug.Assert(n > 0);
|
||||
|
||||
uint[] tt = Nat192.CreateExt();
|
||||
Nat192.Square(x, tt);
|
||||
Reduce(tt, z);
|
||||
|
||||
while (--n > 0)
|
||||
{
|
||||
Nat192.Square(z, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Subtract(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
int c = Nat192.Sub(x, y, z);
|
||||
if (c != 0)
|
||||
{
|
||||
Nat.Sub33From(6, PInv33, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
|
||||
{
|
||||
int c = Nat.Sub(12, xx, yy, zz);
|
||||
if (c != 0)
|
||||
{
|
||||
if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0)
|
||||
{
|
||||
Nat.DecAt(12, zz, PExtInv.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Twice(uint[] x, uint[] z)
|
||||
{
|
||||
uint c = Nat.ShiftUpBit(6, x, 0, z);
|
||||
if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P)))
|
||||
{
|
||||
Nat.Add33To(6, PInv33, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 218f3d42a4e59cf4a953af9121236128
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,218 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP192K1FieldElement
|
||||
: AbstractFpFieldElement
|
||||
{
|
||||
public static readonly BigInteger Q = new BigInteger(1,
|
||||
Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"));
|
||||
|
||||
protected internal readonly uint[] x;
|
||||
|
||||
public SecP192K1FieldElement(BigInteger x)
|
||||
{
|
||||
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
|
||||
throw new ArgumentException("value invalid for SecP192K1FieldElement", "x");
|
||||
|
||||
this.x = SecP192K1Field.FromBigInteger(x);
|
||||
}
|
||||
|
||||
public SecP192K1FieldElement()
|
||||
{
|
||||
this.x = Nat192.Create();
|
||||
}
|
||||
|
||||
protected internal SecP192K1FieldElement(uint[] x)
|
||||
{
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public override bool IsZero
|
||||
{
|
||||
get { return Nat192.IsZero(x); }
|
||||
}
|
||||
|
||||
public override bool IsOne
|
||||
{
|
||||
get { return Nat192.IsOne(x); }
|
||||
}
|
||||
|
||||
public override bool TestBitZero()
|
||||
{
|
||||
return Nat192.GetBit(x, 0) == 1;
|
||||
}
|
||||
|
||||
public override BigInteger ToBigInteger()
|
||||
{
|
||||
return Nat192.ToBigInteger(x);
|
||||
}
|
||||
|
||||
public override string FieldName
|
||||
{
|
||||
get { return "SecP192K1Field"; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return Q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement Add(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192K1Field.Add(x, ((SecP192K1FieldElement)b).x, z);
|
||||
return new SecP192K1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement AddOne()
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192K1Field.AddOne(x, z);
|
||||
return new SecP192K1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Subtract(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192K1Field.Subtract(x, ((SecP192K1FieldElement)b).x, z);
|
||||
return new SecP192K1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Multiply(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192K1Field.Multiply(x, ((SecP192K1FieldElement)b).x, z);
|
||||
return new SecP192K1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Divide(ECFieldElement b)
|
||||
{
|
||||
//return Multiply(b.Invert());
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192K1Field.Inv(((SecP192K1FieldElement)b).x, z);
|
||||
SecP192K1Field.Multiply(z, x, z);
|
||||
return new SecP192K1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Negate()
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192K1Field.Negate(x, z);
|
||||
return new SecP192K1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Square()
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192K1Field.Square(x, z);
|
||||
return new SecP192K1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Invert()
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192K1Field.Inv(x, z);
|
||||
return new SecP192K1FieldElement(z);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a sqrt root - the routine verifies that the calculation returns the right value - if
|
||||
* none exists it returns null.
|
||||
*/
|
||||
public override ECFieldElement Sqrt()
|
||||
{
|
||||
/*
|
||||
* Raise this element to the exponent 2^190 - 2^30 - 2^10 - 2^6 - 2^5 - 2^4 - 2^1
|
||||
*
|
||||
* Breaking up the exponent's binary representation into "repunits", we get:
|
||||
* { 159 1s } { 1 0s } { 19 1s } { 1 0s } { 3 1s } { 3 0s } { 3 1s } { 1 0s }
|
||||
*
|
||||
* Therefore we need an addition chain containing 3, 19, 159 (the lengths of the repunits)
|
||||
* We use: 1, 2, [3], 6, 8, 16, [19], 35, 70, 140, [159]
|
||||
*/
|
||||
|
||||
uint[] x1 = this.x;
|
||||
if (Nat192.IsZero(x1) || Nat192.IsOne(x1))
|
||||
return this;
|
||||
|
||||
uint[] x2 = Nat192.Create();
|
||||
SecP192K1Field.Square(x1, x2);
|
||||
SecP192K1Field.Multiply(x2, x1, x2);
|
||||
uint[] x3 = Nat192.Create();
|
||||
SecP192K1Field.Square(x2, x3);
|
||||
SecP192K1Field.Multiply(x3, x1, x3);
|
||||
uint[] x6 = Nat192.Create();
|
||||
SecP192K1Field.SquareN(x3, 3, x6);
|
||||
SecP192K1Field.Multiply(x6, x3, x6);
|
||||
uint[] x8 = x6;
|
||||
SecP192K1Field.SquareN(x6, 2, x8);
|
||||
SecP192K1Field.Multiply(x8, x2, x8);
|
||||
uint[] x16 = x2;
|
||||
SecP192K1Field.SquareN(x8, 8, x16);
|
||||
SecP192K1Field.Multiply(x16, x8, x16);
|
||||
uint[] x19 = x8;
|
||||
SecP192K1Field.SquareN(x16, 3, x19);
|
||||
SecP192K1Field.Multiply(x19, x3, x19);
|
||||
uint[] x35 = Nat192.Create();
|
||||
SecP192K1Field.SquareN(x19, 16, x35);
|
||||
SecP192K1Field.Multiply(x35, x16, x35);
|
||||
uint[] x70 = x16;
|
||||
SecP192K1Field.SquareN(x35, 35, x70);
|
||||
SecP192K1Field.Multiply(x70, x35, x70);
|
||||
uint[] x140 = x35;
|
||||
SecP192K1Field.SquareN(x70, 70, x140);
|
||||
SecP192K1Field.Multiply(x140, x70, x140);
|
||||
uint[] x159 = x70;
|
||||
SecP192K1Field.SquareN(x140, 19, x159);
|
||||
SecP192K1Field.Multiply(x159, x19, x159);
|
||||
|
||||
uint[] t1 = x159;
|
||||
SecP192K1Field.SquareN(t1, 20, t1);
|
||||
SecP192K1Field.Multiply(t1, x19, t1);
|
||||
SecP192K1Field.SquareN(t1, 4, t1);
|
||||
SecP192K1Field.Multiply(t1, x3, t1);
|
||||
SecP192K1Field.SquareN(t1, 6, t1);
|
||||
SecP192K1Field.Multiply(t1, x3, t1);
|
||||
SecP192K1Field.Square(t1, t1);
|
||||
|
||||
uint[] t2 = x3;
|
||||
SecP192K1Field.Square(t1, t2);
|
||||
|
||||
return Nat192.Eq(x1, t2) ? new SecP192K1FieldElement(t1) : null;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as SecP192K1FieldElement);
|
||||
}
|
||||
|
||||
public override bool Equals(ECFieldElement other)
|
||||
{
|
||||
return Equals(other as SecP192K1FieldElement);
|
||||
}
|
||||
|
||||
public virtual bool Equals(SecP192K1FieldElement other)
|
||||
{
|
||||
if (this == other)
|
||||
return true;
|
||||
if (null == other)
|
||||
return false;
|
||||
return Nat192.Eq(x, other.x);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5a7a619c061cd24cafd0a7cdbb3a432
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,236 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP192K1Point
|
||||
: AbstractFpPoint
|
||||
{
|
||||
internal SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
|
||||
: base(curve, x, y)
|
||||
{
|
||||
}
|
||||
|
||||
internal SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
: base(curve, x, y, zs)
|
||||
{
|
||||
}
|
||||
|
||||
protected override ECPoint Detach()
|
||||
{
|
||||
return new SecP192K1Point(null, AffineXCoord, AffineYCoord);
|
||||
}
|
||||
|
||||
public override ECPoint Add(ECPoint b)
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return this;
|
||||
if (this == b)
|
||||
return Twice();
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SecP192K1FieldElement X1 = (SecP192K1FieldElement)this.RawXCoord, Y1 = (SecP192K1FieldElement)this.RawYCoord;
|
||||
SecP192K1FieldElement X2 = (SecP192K1FieldElement)b.RawXCoord, Y2 = (SecP192K1FieldElement)b.RawYCoord;
|
||||
|
||||
SecP192K1FieldElement Z1 = (SecP192K1FieldElement)this.RawZCoords[0];
|
||||
SecP192K1FieldElement Z2 = (SecP192K1FieldElement)b.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
uint[] tt1 = Nat192.CreateExt();
|
||||
uint[] t2 = Nat192.Create();
|
||||
uint[] t3 = Nat192.Create();
|
||||
uint[] t4 = Nat192.Create();
|
||||
|
||||
bool Z1IsOne = Z1.IsOne;
|
||||
uint[] U2, S2;
|
||||
if (Z1IsOne)
|
||||
{
|
||||
U2 = X2.x;
|
||||
S2 = Y2.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S2 = t3;
|
||||
SecP192K1Field.Square(Z1.x, S2);
|
||||
|
||||
U2 = t2;
|
||||
SecP192K1Field.Multiply(S2, X2.x, U2);
|
||||
|
||||
SecP192K1Field.Multiply(S2, Z1.x, S2);
|
||||
SecP192K1Field.Multiply(S2, Y2.x, S2);
|
||||
}
|
||||
|
||||
bool Z2IsOne = Z2.IsOne;
|
||||
uint[] U1, S1;
|
||||
if (Z2IsOne)
|
||||
{
|
||||
U1 = X1.x;
|
||||
S1 = Y1.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S1 = t4;
|
||||
SecP192K1Field.Square(Z2.x, S1);
|
||||
|
||||
U1 = tt1;
|
||||
SecP192K1Field.Multiply(S1, X1.x, U1);
|
||||
|
||||
SecP192K1Field.Multiply(S1, Z2.x, S1);
|
||||
SecP192K1Field.Multiply(S1, Y1.x, S1);
|
||||
}
|
||||
|
||||
uint[] H = Nat192.Create();
|
||||
SecP192K1Field.Subtract(U1, U2, H);
|
||||
|
||||
uint[] R = t2;
|
||||
SecP192K1Field.Subtract(S1, S2, R);
|
||||
|
||||
// Check if b == this or b == -this
|
||||
if (Nat192.IsZero(H))
|
||||
{
|
||||
if (Nat192.IsZero(R))
|
||||
{
|
||||
// this == b, i.e. this must be doubled
|
||||
return this.Twice();
|
||||
}
|
||||
|
||||
// this == -b, i.e. the result is the point at infinity
|
||||
return curve.Infinity;
|
||||
}
|
||||
|
||||
uint[] HSquared = t3;
|
||||
SecP192K1Field.Square(H, HSquared);
|
||||
|
||||
uint[] G = Nat192.Create();
|
||||
SecP192K1Field.Multiply(HSquared, H, G);
|
||||
|
||||
uint[] V = t3;
|
||||
SecP192K1Field.Multiply(HSquared, U1, V);
|
||||
|
||||
SecP192K1Field.Negate(G, G);
|
||||
Nat192.Mul(S1, G, tt1);
|
||||
|
||||
c = Nat192.AddBothTo(V, V, G);
|
||||
SecP192K1Field.Reduce32(c, G);
|
||||
|
||||
SecP192K1FieldElement X3 = new SecP192K1FieldElement(t4);
|
||||
SecP192K1Field.Square(R, X3.x);
|
||||
SecP192K1Field.Subtract(X3.x, G, X3.x);
|
||||
|
||||
SecP192K1FieldElement Y3 = new SecP192K1FieldElement(G);
|
||||
SecP192K1Field.Subtract(V, X3.x, Y3.x);
|
||||
SecP192K1Field.MultiplyAddToExt(Y3.x, R, tt1);
|
||||
SecP192K1Field.Reduce(tt1, Y3.x);
|
||||
|
||||
SecP192K1FieldElement Z3 = new SecP192K1FieldElement(H);
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
SecP192K1Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
if (!Z2IsOne)
|
||||
{
|
||||
SecP192K1Field.Multiply(Z3.x, Z2.x, Z3.x);
|
||||
}
|
||||
|
||||
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
|
||||
|
||||
return new SecP192K1Point(curve, X3, Y3, zs);
|
||||
}
|
||||
|
||||
public override ECPoint Twice()
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return this;
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SecP192K1FieldElement Y1 = (SecP192K1FieldElement)this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return curve.Infinity;
|
||||
|
||||
SecP192K1FieldElement X1 = (SecP192K1FieldElement)this.RawXCoord, Z1 = (SecP192K1FieldElement)this.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
|
||||
uint[] Y1Squared = Nat192.Create();
|
||||
SecP192K1Field.Square(Y1.x, Y1Squared);
|
||||
|
||||
uint[] T = Nat192.Create();
|
||||
SecP192K1Field.Square(Y1Squared, T);
|
||||
|
||||
uint[] M = Nat192.Create();
|
||||
SecP192K1Field.Square(X1.x, M);
|
||||
c = Nat192.AddBothTo(M, M, M);
|
||||
SecP192K1Field.Reduce32(c, M);
|
||||
|
||||
uint[] S = Y1Squared;
|
||||
SecP192K1Field.Multiply(Y1Squared, X1.x, S);
|
||||
c = Nat.ShiftUpBits(6, S, 2, 0);
|
||||
SecP192K1Field.Reduce32(c, S);
|
||||
|
||||
uint[] t1 = Nat192.Create();
|
||||
c = Nat.ShiftUpBits(6, T, 3, 0, t1);
|
||||
SecP192K1Field.Reduce32(c, t1);
|
||||
|
||||
SecP192K1FieldElement X3 = new SecP192K1FieldElement(T);
|
||||
SecP192K1Field.Square(M, X3.x);
|
||||
SecP192K1Field.Subtract(X3.x, S, X3.x);
|
||||
SecP192K1Field.Subtract(X3.x, S, X3.x);
|
||||
|
||||
SecP192K1FieldElement Y3 = new SecP192K1FieldElement(S);
|
||||
SecP192K1Field.Subtract(S, X3.x, Y3.x);
|
||||
SecP192K1Field.Multiply(Y3.x, M, Y3.x);
|
||||
SecP192K1Field.Subtract(Y3.x, t1, Y3.x);
|
||||
|
||||
SecP192K1FieldElement Z3 = new SecP192K1FieldElement(M);
|
||||
SecP192K1Field.Twice(Y1.x, Z3.x);
|
||||
if (!Z1.IsOne)
|
||||
{
|
||||
SecP192K1Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
|
||||
return new SecP192K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
|
||||
}
|
||||
|
||||
public override ECPoint TwicePlus(ECPoint b)
|
||||
{
|
||||
if (this == b)
|
||||
return ThreeTimes();
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return Twice();
|
||||
|
||||
ECFieldElement Y1 = this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return b;
|
||||
|
||||
return Twice().Add(b);
|
||||
}
|
||||
|
||||
public override ECPoint ThreeTimes()
|
||||
{
|
||||
if (this.IsInfinity || this.RawYCoord.IsZero)
|
||||
return this;
|
||||
|
||||
// NOTE: Be careful about recursions between TwicePlus and ThreeTimes
|
||||
return Twice().Add(this);
|
||||
}
|
||||
|
||||
public override ECPoint Negate()
|
||||
{
|
||||
if (IsInfinity)
|
||||
return this;
|
||||
|
||||
return new SecP192K1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d94a23a9df7487e4b8647bb414b5c412
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,175 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP192R1Curve
|
||||
: AbstractFpCurve
|
||||
{
|
||||
public static readonly BigInteger q = SecP192R1FieldElement.Q;
|
||||
|
||||
private const int SECP192R1_DEFAULT_COORDS = COORD_JACOBIAN;
|
||||
private const int SECP192R1_FE_INTS = 6;
|
||||
private static readonly ECFieldElement[] SECP192R1_AFFINE_ZS = new ECFieldElement[] { new SecP192R1FieldElement(BigInteger.One) };
|
||||
|
||||
protected readonly SecP192R1Point m_infinity;
|
||||
|
||||
public SecP192R1Curve()
|
||||
: base(q)
|
||||
{
|
||||
this.m_infinity = new SecP192R1Point(this, null, null);
|
||||
|
||||
this.m_a = FromBigInteger(new BigInteger(1,
|
||||
Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")));
|
||||
this.m_b = FromBigInteger(new BigInteger(1,
|
||||
Hex.DecodeStrict("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")));
|
||||
this.m_order = new BigInteger(1, Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"));
|
||||
this.m_cofactor = BigInteger.One;
|
||||
|
||||
this.m_coord = SECP192R1_DEFAULT_COORDS;
|
||||
}
|
||||
|
||||
protected override ECCurve CloneCurve()
|
||||
{
|
||||
return new SecP192R1Curve();
|
||||
}
|
||||
|
||||
public override bool SupportsCoordinateSystem(int coord)
|
||||
{
|
||||
switch (coord)
|
||||
{
|
||||
case COORD_JACOBIAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BigInteger Q
|
||||
{
|
||||
get { return q; }
|
||||
}
|
||||
|
||||
public override ECPoint Infinity
|
||||
{
|
||||
get { return m_infinity; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement FromBigInteger(BigInteger x)
|
||||
{
|
||||
return new SecP192R1FieldElement(x);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return new SecP192R1Point(this, x, y);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
{
|
||||
return new SecP192R1Point(this, x, y, zs);
|
||||
}
|
||||
|
||||
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
|
||||
{
|
||||
uint[] table = new uint[len * SECP192R1_FE_INTS * 2];
|
||||
{
|
||||
int pos = 0;
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
ECPoint p = points[off + i];
|
||||
Nat192.Copy(((SecP192R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP192R1_FE_INTS;
|
||||
Nat192.Copy(((SecP192R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP192R1_FE_INTS;
|
||||
}
|
||||
}
|
||||
|
||||
return new SecP192R1LookupTable(this, table, len);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElement(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat192.Create();
|
||||
SecP192R1Field.Random(r, x);
|
||||
return new SecP192R1FieldElement(x);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElementMult(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat192.Create();
|
||||
SecP192R1Field.RandomMult(r, x);
|
||||
return new SecP192R1FieldElement(x);
|
||||
}
|
||||
|
||||
private class SecP192R1LookupTable
|
||||
: AbstractECLookupTable
|
||||
{
|
||||
private readonly SecP192R1Curve m_outer;
|
||||
private readonly uint[] m_table;
|
||||
private readonly int m_size;
|
||||
|
||||
internal SecP192R1LookupTable(SecP192R1Curve outer, uint[] table, int size)
|
||||
{
|
||||
this.m_outer = outer;
|
||||
this.m_table = table;
|
||||
this.m_size = size;
|
||||
}
|
||||
|
||||
public override int Size
|
||||
{
|
||||
get { return m_size; }
|
||||
}
|
||||
|
||||
public override ECPoint Lookup(int index)
|
||||
{
|
||||
uint[] x = Nat192.Create(), y = Nat192.Create();
|
||||
int pos = 0;
|
||||
|
||||
for (int i = 0; i < m_size; ++i)
|
||||
{
|
||||
uint MASK = (uint)(((i ^ index) - 1) >> 31);
|
||||
|
||||
for (int j = 0; j < SECP192R1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] ^= m_table[pos + j] & MASK;
|
||||
y[j] ^= m_table[pos + SECP192R1_FE_INTS + j] & MASK;
|
||||
}
|
||||
|
||||
pos += (SECP192R1_FE_INTS * 2);
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
public override ECPoint LookupVar(int index)
|
||||
{
|
||||
uint[] x = Nat192.Create(), y = Nat192.Create();
|
||||
int pos = index * SECP192R1_FE_INTS * 2;
|
||||
|
||||
for (int j = 0; j < SECP192R1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] = m_table[pos + j];
|
||||
y[j] = m_table[pos + SECP192R1_FE_INTS + j];
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
private ECPoint CreatePoint(uint[] x, uint[] y)
|
||||
{
|
||||
return m_outer.CreateRawPoint(new SecP192R1FieldElement(x), new SecP192R1FieldElement(y), SECP192R1_AFFINE_ZS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9051396fd403a4143a8049754bd784c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,326 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP192R1Field
|
||||
{
|
||||
// 2^192 - 2^64 - 1
|
||||
internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF };
|
||||
private static readonly uint[] PExt = new uint[]{ 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001,
|
||||
0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF,
|
||||
0xFFFFFFFE, 0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000002 };
|
||||
private const uint P5 = 0xFFFFFFFF;
|
||||
private const uint PExt11 = 0xFFFFFFFF;
|
||||
|
||||
public static void Add(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
uint c = Nat192.Add(x, y, z);
|
||||
if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P)))
|
||||
{
|
||||
AddPInvTo(z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
|
||||
{
|
||||
uint c = Nat.Add(12, xx, yy, zz);
|
||||
if (c != 0 || (zz[11] == PExt11 && Nat.Gte(12, zz, PExt)))
|
||||
{
|
||||
if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
|
||||
{
|
||||
Nat.IncAt(12, zz, PExtInv.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddOne(uint[] x, uint[] z)
|
||||
{
|
||||
uint c = Nat.Inc(6, x, z);
|
||||
if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P)))
|
||||
{
|
||||
AddPInvTo(z);
|
||||
}
|
||||
}
|
||||
|
||||
public static uint[] FromBigInteger(BigInteger x)
|
||||
{
|
||||
uint[] z = Nat.FromBigInteger(192, x);
|
||||
if (z[5] == P5 && Nat192.Gte(z, P))
|
||||
{
|
||||
Nat192.SubFrom(P, z);
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
public static void Half(uint[] x, uint[] z)
|
||||
{
|
||||
if ((x[0] & 1) == 0)
|
||||
{
|
||||
Nat.ShiftDownBit(6, x, 0, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint c = Nat192.Add(x, P, z);
|
||||
Nat.ShiftDownBit(6, z, c);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Inv(uint[] x, uint[] z)
|
||||
{
|
||||
Mod.CheckedModOddInverse(P, x, z);
|
||||
}
|
||||
|
||||
public static int IsZero(uint[] x)
|
||||
{
|
||||
uint d = 0;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
d |= x[i];
|
||||
}
|
||||
d = (d >> 1) | (d & 1);
|
||||
return ((int)d - 1) >> 31;
|
||||
}
|
||||
|
||||
public static void Multiply(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
uint[] tt = Nat192.CreateExt();
|
||||
Nat192.Mul(x, y, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
|
||||
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
|
||||
{
|
||||
uint c = Nat192.MulAddTo(x, y, zz);
|
||||
if (c != 0 || (zz[11] == PExt11 && Nat.Gte(12, zz, PExt)))
|
||||
{
|
||||
if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
|
||||
{
|
||||
Nat.IncAt(12, zz, PExtInv.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Negate(uint[] x, uint[] z)
|
||||
{
|
||||
if (0 != IsZero(x))
|
||||
{
|
||||
Nat192.Sub(P, P, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
Nat192.Sub(P, x, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Random(SecureRandom r, uint[] z)
|
||||
{
|
||||
byte[] bb = new byte[6 * 4];
|
||||
do
|
||||
{
|
||||
r.NextBytes(bb);
|
||||
Pack.LE_To_UInt32(bb, 0, z, 0, 6);
|
||||
}
|
||||
while (0 == Nat.LessThan(6, z, P));
|
||||
}
|
||||
|
||||
public static void RandomMult(SecureRandom r, uint[] z)
|
||||
{
|
||||
do
|
||||
{
|
||||
Random(r, z);
|
||||
}
|
||||
while (0 != IsZero(z));
|
||||
}
|
||||
|
||||
public static void Reduce(uint[] xx, uint[] z)
|
||||
{
|
||||
ulong xx06 = xx[6], xx07 = xx[7], xx08 = xx[8];
|
||||
ulong xx09 = xx[9], xx10 = xx[10], xx11 = xx[11];
|
||||
|
||||
ulong t0 = xx06 + xx10;
|
||||
ulong t1 = xx07 + xx11;
|
||||
|
||||
ulong cc = 0;
|
||||
cc += (ulong)xx[0] + t0;
|
||||
uint z0 = (uint)cc;
|
||||
cc >>= 32;
|
||||
cc += (ulong)xx[1] + t1;
|
||||
z[1] = (uint)cc;
|
||||
cc >>= 32;
|
||||
|
||||
t0 += xx08;
|
||||
t1 += xx09;
|
||||
|
||||
cc += (ulong)xx[2] + t0;
|
||||
ulong z2 = (uint)cc;
|
||||
cc >>= 32;
|
||||
cc += (ulong)xx[3] + t1;
|
||||
z[3] = (uint)cc;
|
||||
cc >>= 32;
|
||||
|
||||
t0 -= xx06;
|
||||
t1 -= xx07;
|
||||
|
||||
cc += (ulong)xx[4] + t0;
|
||||
z[4] = (uint)cc;
|
||||
cc >>= 32;
|
||||
cc += (ulong)xx[5] + t1;
|
||||
z[5] = (uint)cc;
|
||||
cc >>= 32;
|
||||
|
||||
z2 += cc;
|
||||
|
||||
cc += z0;
|
||||
z[0] = (uint)cc;
|
||||
cc >>= 32;
|
||||
if (cc != 0)
|
||||
{
|
||||
cc += z[1];
|
||||
z[1] = (uint)cc;
|
||||
z2 += cc >> 32;
|
||||
}
|
||||
z[2] = (uint)z2;
|
||||
cc = z2 >> 32;
|
||||
|
||||
Debug.Assert(cc == 0 || cc == 1);
|
||||
|
||||
if ((cc != 0 && Nat.IncAt(6, z, 3) != 0)
|
||||
|| (z[5] == P5 && Nat192.Gte(z, P)))
|
||||
{
|
||||
AddPInvTo(z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Reduce32(uint x, uint[] z)
|
||||
{
|
||||
ulong cc = 0;
|
||||
|
||||
if (x != 0)
|
||||
{
|
||||
cc += (ulong)z[0] + x;
|
||||
z[0] = (uint)cc;
|
||||
cc >>= 32;
|
||||
if (cc != 0)
|
||||
{
|
||||
cc += (ulong)z[1];
|
||||
z[1] = (uint)cc;
|
||||
cc >>= 32;
|
||||
}
|
||||
cc += (ulong)z[2] + x;
|
||||
z[2] = (uint)cc;
|
||||
cc >>= 32;
|
||||
|
||||
Debug.Assert(cc == 0 || cc == 1);
|
||||
}
|
||||
|
||||
if ((cc != 0 && Nat.IncAt(6, z, 3) != 0)
|
||||
|| (z[5] == P5 && Nat192.Gte(z, P)))
|
||||
{
|
||||
AddPInvTo(z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Square(uint[] x, uint[] z)
|
||||
{
|
||||
uint[] tt = Nat192.CreateExt();
|
||||
Nat192.Square(x, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
|
||||
public static void SquareN(uint[] x, int n, uint[] z)
|
||||
{
|
||||
Debug.Assert(n > 0);
|
||||
|
||||
uint[] tt = Nat192.CreateExt();
|
||||
Nat192.Square(x, tt);
|
||||
Reduce(tt, z);
|
||||
|
||||
while (--n > 0)
|
||||
{
|
||||
Nat192.Square(z, tt);
|
||||
Reduce(tt, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Subtract(uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
int c = Nat192.Sub(x, y, z);
|
||||
if (c != 0)
|
||||
{
|
||||
SubPInvFrom(z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
|
||||
{
|
||||
int c = Nat.Sub(12, xx, yy, zz);
|
||||
if (c != 0)
|
||||
{
|
||||
if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0)
|
||||
{
|
||||
Nat.DecAt(12, zz, PExtInv.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Twice(uint[] x, uint[] z)
|
||||
{
|
||||
uint c = Nat.ShiftUpBit(6, x, 0, z);
|
||||
if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P)))
|
||||
{
|
||||
AddPInvTo(z);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddPInvTo(uint[] z)
|
||||
{
|
||||
long c = (long)z[0] + 1;
|
||||
z[0] = (uint)c;
|
||||
c >>= 32;
|
||||
if (c != 0)
|
||||
{
|
||||
c += (long)z[1];
|
||||
z[1] = (uint)c;
|
||||
c >>= 32;
|
||||
}
|
||||
c += (long)z[2] + 1;
|
||||
z[2] = (uint)c;
|
||||
c >>= 32;
|
||||
if (c != 0)
|
||||
{
|
||||
Nat.IncAt(6, z, 3);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SubPInvFrom(uint[] z)
|
||||
{
|
||||
long c = (long)z[0] - 1;
|
||||
z[0] = (uint)c;
|
||||
c >>= 32;
|
||||
if (c != 0)
|
||||
{
|
||||
c += (long)z[1];
|
||||
z[1] = (uint)c;
|
||||
c >>= 32;
|
||||
}
|
||||
c += (long)z[2] - 1;
|
||||
z[2] = (uint)c;
|
||||
c >>= 32;
|
||||
if (c != 0)
|
||||
{
|
||||
Nat.DecAt(6, z, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44fb8f1c5ae47e64caf48325ec0b3902
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,193 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP192R1FieldElement
|
||||
: AbstractFpFieldElement
|
||||
{
|
||||
public static readonly BigInteger Q = new BigInteger(1,
|
||||
Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"));
|
||||
|
||||
protected internal readonly uint[] x;
|
||||
|
||||
public SecP192R1FieldElement(BigInteger x)
|
||||
{
|
||||
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
|
||||
throw new ArgumentException("value invalid for SecP192R1FieldElement", "x");
|
||||
|
||||
this.x = SecP192R1Field.FromBigInteger(x);
|
||||
}
|
||||
|
||||
public SecP192R1FieldElement()
|
||||
{
|
||||
this.x = Nat192.Create();
|
||||
}
|
||||
|
||||
protected internal SecP192R1FieldElement(uint[] x)
|
||||
{
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public override bool IsZero
|
||||
{
|
||||
get { return Nat192.IsZero(x); }
|
||||
}
|
||||
|
||||
public override bool IsOne
|
||||
{
|
||||
get { return Nat192.IsOne(x); }
|
||||
}
|
||||
|
||||
public override bool TestBitZero()
|
||||
{
|
||||
return Nat192.GetBit(x, 0) == 1;
|
||||
}
|
||||
|
||||
public override BigInteger ToBigInteger()
|
||||
{
|
||||
return Nat192.ToBigInteger(x);
|
||||
}
|
||||
|
||||
public override string FieldName
|
||||
{
|
||||
get { return "SecP192R1Field"; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return Q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement Add(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192R1Field.Add(x, ((SecP192R1FieldElement)b).x, z);
|
||||
return new SecP192R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement AddOne()
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192R1Field.AddOne(x, z);
|
||||
return new SecP192R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Subtract(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192R1Field.Subtract(x, ((SecP192R1FieldElement)b).x, z);
|
||||
return new SecP192R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Multiply(ECFieldElement b)
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192R1Field.Multiply(x, ((SecP192R1FieldElement)b).x, z);
|
||||
return new SecP192R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Divide(ECFieldElement b)
|
||||
{
|
||||
//return Multiply(b.Invert());
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192R1Field.Inv(((SecP192R1FieldElement)b).x, z);
|
||||
SecP192R1Field.Multiply(z, x, z);
|
||||
return new SecP192R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Negate()
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192R1Field.Negate(x, z);
|
||||
return new SecP192R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Square()
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192R1Field.Square(x, z);
|
||||
return new SecP192R1FieldElement(z);
|
||||
}
|
||||
|
||||
public override ECFieldElement Invert()
|
||||
{
|
||||
uint[] z = Nat192.Create();
|
||||
SecP192R1Field.Inv(x, z);
|
||||
return new SecP192R1FieldElement(z);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a sqrt root - the routine verifies that the calculation returns the right value - if
|
||||
* none exists it returns null.
|
||||
*/
|
||||
public override ECFieldElement Sqrt()
|
||||
{
|
||||
// Raise this element to the exponent 2^190 - 2^62
|
||||
|
||||
uint[] x1 = this.x;
|
||||
if (Nat192.IsZero(x1) || Nat192.IsOne(x1))
|
||||
return this;
|
||||
|
||||
uint[] t1 = Nat192.Create();
|
||||
uint[] t2 = Nat192.Create();
|
||||
|
||||
SecP192R1Field.Square(x1, t1);
|
||||
SecP192R1Field.Multiply(t1, x1, t1);
|
||||
|
||||
SecP192R1Field.SquareN(t1, 2, t2);
|
||||
SecP192R1Field.Multiply(t2, t1, t2);
|
||||
|
||||
SecP192R1Field.SquareN(t2, 4, t1);
|
||||
SecP192R1Field.Multiply(t1, t2, t1);
|
||||
|
||||
SecP192R1Field.SquareN(t1, 8, t2);
|
||||
SecP192R1Field.Multiply(t2, t1, t2);
|
||||
|
||||
SecP192R1Field.SquareN(t2, 16, t1);
|
||||
SecP192R1Field.Multiply(t1, t2, t1);
|
||||
|
||||
SecP192R1Field.SquareN(t1, 32, t2);
|
||||
SecP192R1Field.Multiply(t2, t1, t2);
|
||||
|
||||
SecP192R1Field.SquareN(t2, 64, t1);
|
||||
SecP192R1Field.Multiply(t1, t2, t1);
|
||||
|
||||
SecP192R1Field.SquareN(t1, 62, t1);
|
||||
SecP192R1Field.Square(t1, t2);
|
||||
|
||||
return Nat192.Eq(x1, t2) ? new SecP192R1FieldElement(t1) : null;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as SecP192R1FieldElement);
|
||||
}
|
||||
|
||||
public override bool Equals(ECFieldElement other)
|
||||
{
|
||||
return Equals(other as SecP192R1FieldElement);
|
||||
}
|
||||
|
||||
public virtual bool Equals(SecP192R1FieldElement other)
|
||||
{
|
||||
if (this == other)
|
||||
return true;
|
||||
if (null == other)
|
||||
return false;
|
||||
return Nat192.Eq(x, other.x);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1a07149a2b0efd429eb787280af3bc0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,249 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP192R1Point
|
||||
: AbstractFpPoint
|
||||
{
|
||||
internal SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
|
||||
: base(curve, x, y)
|
||||
{
|
||||
}
|
||||
|
||||
internal SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
: base(curve, x, y, zs)
|
||||
{
|
||||
}
|
||||
|
||||
protected override ECPoint Detach()
|
||||
{
|
||||
return new SecP192R1Point(null, AffineXCoord, AffineYCoord);
|
||||
}
|
||||
|
||||
public override ECPoint Add(ECPoint b)
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return this;
|
||||
if (this == b)
|
||||
return Twice();
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SecP192R1FieldElement X1 = (SecP192R1FieldElement)this.RawXCoord, Y1 = (SecP192R1FieldElement)this.RawYCoord;
|
||||
SecP192R1FieldElement X2 = (SecP192R1FieldElement)b.RawXCoord, Y2 = (SecP192R1FieldElement)b.RawYCoord;
|
||||
|
||||
SecP192R1FieldElement Z1 = (SecP192R1FieldElement)this.RawZCoords[0];
|
||||
SecP192R1FieldElement Z2 = (SecP192R1FieldElement)b.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
uint[] tt1 = Nat192.CreateExt();
|
||||
uint[] t2 = Nat192.Create();
|
||||
uint[] t3 = Nat192.Create();
|
||||
uint[] t4 = Nat192.Create();
|
||||
|
||||
bool Z1IsOne = Z1.IsOne;
|
||||
uint[] U2, S2;
|
||||
if (Z1IsOne)
|
||||
{
|
||||
U2 = X2.x;
|
||||
S2 = Y2.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S2 = t3;
|
||||
SecP192R1Field.Square(Z1.x, S2);
|
||||
|
||||
U2 = t2;
|
||||
SecP192R1Field.Multiply(S2, X2.x, U2);
|
||||
|
||||
SecP192R1Field.Multiply(S2, Z1.x, S2);
|
||||
SecP192R1Field.Multiply(S2, Y2.x, S2);
|
||||
}
|
||||
|
||||
bool Z2IsOne = Z2.IsOne;
|
||||
uint[] U1, S1;
|
||||
if (Z2IsOne)
|
||||
{
|
||||
U1 = X1.x;
|
||||
S1 = Y1.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
S1 = t4;
|
||||
SecP192R1Field.Square(Z2.x, S1);
|
||||
|
||||
U1 = tt1;
|
||||
SecP192R1Field.Multiply(S1, X1.x, U1);
|
||||
|
||||
SecP192R1Field.Multiply(S1, Z2.x, S1);
|
||||
SecP192R1Field.Multiply(S1, Y1.x, S1);
|
||||
}
|
||||
|
||||
uint[] H = Nat192.Create();
|
||||
SecP192R1Field.Subtract(U1, U2, H);
|
||||
|
||||
uint[] R = t2;
|
||||
SecP192R1Field.Subtract(S1, S2, R);
|
||||
|
||||
// Check if b == this or b == -this
|
||||
if (Nat192.IsZero(H))
|
||||
{
|
||||
if (Nat192.IsZero(R))
|
||||
{
|
||||
// this == b, i.e. this must be doubled
|
||||
return this.Twice();
|
||||
}
|
||||
|
||||
// this == -b, i.e. the result is the point at infinity
|
||||
return curve.Infinity;
|
||||
}
|
||||
|
||||
uint[] HSquared = t3;
|
||||
SecP192R1Field.Square(H, HSquared);
|
||||
|
||||
uint[] G = Nat192.Create();
|
||||
SecP192R1Field.Multiply(HSquared, H, G);
|
||||
|
||||
uint[] V = t3;
|
||||
SecP192R1Field.Multiply(HSquared, U1, V);
|
||||
|
||||
SecP192R1Field.Negate(G, G);
|
||||
Nat192.Mul(S1, G, tt1);
|
||||
|
||||
c = Nat192.AddBothTo(V, V, G);
|
||||
SecP192R1Field.Reduce32(c, G);
|
||||
|
||||
SecP192R1FieldElement X3 = new SecP192R1FieldElement(t4);
|
||||
SecP192R1Field.Square(R, X3.x);
|
||||
SecP192R1Field.Subtract(X3.x, G, X3.x);
|
||||
|
||||
SecP192R1FieldElement Y3 = new SecP192R1FieldElement(G);
|
||||
SecP192R1Field.Subtract(V, X3.x, Y3.x);
|
||||
SecP192R1Field.MultiplyAddToExt(Y3.x, R, tt1);
|
||||
SecP192R1Field.Reduce(tt1, Y3.x);
|
||||
|
||||
SecP192R1FieldElement Z3 = new SecP192R1FieldElement(H);
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
SecP192R1Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
if (!Z2IsOne)
|
||||
{
|
||||
SecP192R1Field.Multiply(Z3.x, Z2.x, Z3.x);
|
||||
}
|
||||
|
||||
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
|
||||
|
||||
return new SecP192R1Point(curve, X3, Y3, zs);
|
||||
}
|
||||
|
||||
public override ECPoint Twice()
|
||||
{
|
||||
if (this.IsInfinity)
|
||||
return this;
|
||||
|
||||
ECCurve curve = this.Curve;
|
||||
|
||||
SecP192R1FieldElement Y1 = (SecP192R1FieldElement)this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return curve.Infinity;
|
||||
|
||||
SecP192R1FieldElement X1 = (SecP192R1FieldElement)this.RawXCoord, Z1 = (SecP192R1FieldElement)this.RawZCoords[0];
|
||||
|
||||
uint c;
|
||||
uint[] t1 = Nat192.Create();
|
||||
uint[] t2 = Nat192.Create();
|
||||
|
||||
uint[] Y1Squared = Nat192.Create();
|
||||
SecP192R1Field.Square(Y1.x, Y1Squared);
|
||||
|
||||
uint[] T = Nat192.Create();
|
||||
SecP192R1Field.Square(Y1Squared, T);
|
||||
|
||||
bool Z1IsOne = Z1.IsOne;
|
||||
|
||||
uint[] Z1Squared = Z1.x;
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
Z1Squared = t2;
|
||||
SecP192R1Field.Square(Z1.x, Z1Squared);
|
||||
}
|
||||
|
||||
SecP192R1Field.Subtract(X1.x, Z1Squared, t1);
|
||||
|
||||
uint[] M = t2;
|
||||
SecP192R1Field.Add(X1.x, Z1Squared, M);
|
||||
SecP192R1Field.Multiply(M, t1, M);
|
||||
c = Nat192.AddBothTo(M, M, M);
|
||||
SecP192R1Field.Reduce32(c, M);
|
||||
|
||||
uint[] S = Y1Squared;
|
||||
SecP192R1Field.Multiply(Y1Squared, X1.x, S);
|
||||
c = Nat.ShiftUpBits(6, S, 2, 0);
|
||||
SecP192R1Field.Reduce32(c, S);
|
||||
|
||||
c = Nat.ShiftUpBits(6, T, 3, 0, t1);
|
||||
SecP192R1Field.Reduce32(c, t1);
|
||||
|
||||
SecP192R1FieldElement X3 = new SecP192R1FieldElement(T);
|
||||
SecP192R1Field.Square(M, X3.x);
|
||||
SecP192R1Field.Subtract(X3.x, S, X3.x);
|
||||
SecP192R1Field.Subtract(X3.x, S, X3.x);
|
||||
|
||||
SecP192R1FieldElement Y3 = new SecP192R1FieldElement(S);
|
||||
SecP192R1Field.Subtract(S, X3.x, Y3.x);
|
||||
SecP192R1Field.Multiply(Y3.x, M, Y3.x);
|
||||
SecP192R1Field.Subtract(Y3.x, t1, Y3.x);
|
||||
|
||||
SecP192R1FieldElement Z3 = new SecP192R1FieldElement(M);
|
||||
SecP192R1Field.Twice(Y1.x, Z3.x);
|
||||
if (!Z1IsOne)
|
||||
{
|
||||
SecP192R1Field.Multiply(Z3.x, Z1.x, Z3.x);
|
||||
}
|
||||
|
||||
return new SecP192R1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
|
||||
}
|
||||
|
||||
public override ECPoint TwicePlus(ECPoint b)
|
||||
{
|
||||
if (this == b)
|
||||
return ThreeTimes();
|
||||
if (this.IsInfinity)
|
||||
return b;
|
||||
if (b.IsInfinity)
|
||||
return Twice();
|
||||
|
||||
ECFieldElement Y1 = this.RawYCoord;
|
||||
if (Y1.IsZero)
|
||||
return b;
|
||||
|
||||
return Twice().Add(b);
|
||||
}
|
||||
|
||||
public override ECPoint ThreeTimes()
|
||||
{
|
||||
if (this.IsInfinity || this.RawYCoord.IsZero)
|
||||
return this;
|
||||
|
||||
// NOTE: Be careful about recursions between TwicePlus and ThreeTimes
|
||||
return Twice().Add(this);
|
||||
}
|
||||
|
||||
public override ECPoint Negate()
|
||||
{
|
||||
if (IsInfinity)
|
||||
return this;
|
||||
|
||||
return new SecP192R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5084e06d37760694d9392014cb72ba23
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,172 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
|
||||
{
|
||||
internal class SecP224K1Curve
|
||||
: AbstractFpCurve
|
||||
{
|
||||
public static readonly BigInteger q = SecP224K1FieldElement.Q;
|
||||
|
||||
private const int SECP224K1_DEFAULT_COORDS = COORD_JACOBIAN;
|
||||
private const int SECP224K1_FE_INTS = 7;
|
||||
private static readonly ECFieldElement[] SECP224K1_AFFINE_ZS = new ECFieldElement[] { new SecP224K1FieldElement(BigInteger.One) };
|
||||
|
||||
protected readonly SecP224K1Point m_infinity;
|
||||
|
||||
public SecP224K1Curve()
|
||||
: base(q)
|
||||
{
|
||||
this.m_infinity = new SecP224K1Point(this, null, null);
|
||||
|
||||
this.m_a = FromBigInteger(BigInteger.Zero);
|
||||
this.m_b = FromBigInteger(BigInteger.ValueOf(5));
|
||||
this.m_order = new BigInteger(1, Hex.DecodeStrict("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7"));
|
||||
this.m_cofactor = BigInteger.One;
|
||||
this.m_coord = SECP224K1_DEFAULT_COORDS;
|
||||
}
|
||||
|
||||
protected override ECCurve CloneCurve()
|
||||
{
|
||||
return new SecP224K1Curve();
|
||||
}
|
||||
|
||||
public override bool SupportsCoordinateSystem(int coord)
|
||||
{
|
||||
switch (coord)
|
||||
{
|
||||
case COORD_JACOBIAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BigInteger Q
|
||||
{
|
||||
get { return q; }
|
||||
}
|
||||
|
||||
public override ECPoint Infinity
|
||||
{
|
||||
get { return m_infinity; }
|
||||
}
|
||||
|
||||
public override int FieldSize
|
||||
{
|
||||
get { return q.BitLength; }
|
||||
}
|
||||
|
||||
public override ECFieldElement FromBigInteger(BigInteger x)
|
||||
{
|
||||
return new SecP224K1FieldElement(x);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
return new SecP224K1Point(this, x, y);
|
||||
}
|
||||
|
||||
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
|
||||
{
|
||||
return new SecP224K1Point(this, x, y, zs);
|
||||
}
|
||||
|
||||
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
|
||||
{
|
||||
uint[] table = new uint[len * SECP224K1_FE_INTS * 2];
|
||||
{
|
||||
int pos = 0;
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
ECPoint p = points[off + i];
|
||||
Nat224.Copy(((SecP224K1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP224K1_FE_INTS;
|
||||
Nat224.Copy(((SecP224K1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP224K1_FE_INTS;
|
||||
}
|
||||
}
|
||||
|
||||
return new SecP224K1LookupTable(this, table, len);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElement(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat224.Create();
|
||||
SecP224K1Field.Random(r, x);
|
||||
return new SecP224K1FieldElement(x);
|
||||
}
|
||||
|
||||
public override ECFieldElement RandomFieldElementMult(SecureRandom r)
|
||||
{
|
||||
uint[] x = Nat224.Create();
|
||||
SecP224K1Field.RandomMult(r, x);
|
||||
return new SecP224K1FieldElement(x);
|
||||
}
|
||||
|
||||
private class SecP224K1LookupTable
|
||||
: AbstractECLookupTable
|
||||
{
|
||||
private readonly SecP224K1Curve m_outer;
|
||||
private readonly uint[] m_table;
|
||||
private readonly int m_size;
|
||||
|
||||
internal SecP224K1LookupTable(SecP224K1Curve outer, uint[] table, int size)
|
||||
{
|
||||
this.m_outer = outer;
|
||||
this.m_table = table;
|
||||
this.m_size = size;
|
||||
}
|
||||
|
||||
public override int Size
|
||||
{
|
||||
get { return m_size; }
|
||||
}
|
||||
|
||||
public override ECPoint Lookup(int index)
|
||||
{
|
||||
uint[] x = Nat224.Create(), y = Nat224.Create();
|
||||
int pos = 0;
|
||||
|
||||
for (int i = 0; i < m_size; ++i)
|
||||
{
|
||||
uint MASK = (uint)(((i ^ index) - 1) >> 31);
|
||||
|
||||
for (int j = 0; j < SECP224K1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] ^= m_table[pos + j] & MASK;
|
||||
y[j] ^= m_table[pos + SECP224K1_FE_INTS + j] & MASK;
|
||||
}
|
||||
|
||||
pos += (SECP224K1_FE_INTS * 2);
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
public override ECPoint LookupVar(int index)
|
||||
{
|
||||
uint[] x = Nat224.Create(), y = Nat224.Create();
|
||||
int pos = index * SECP224K1_FE_INTS * 2;
|
||||
|
||||
for (int j = 0; j < SECP224K1_FE_INTS; ++j)
|
||||
{
|
||||
x[j] = m_table[pos + j];
|
||||
y[j] = m_table[pos + SECP224K1_FE_INTS + j];
|
||||
}
|
||||
|
||||
return CreatePoint(x, y);
|
||||
}
|
||||
|
||||
private ECPoint CreatePoint(uint[] x, uint[] y)
|
||||
{
|
||||
return m_outer.CreateRawPoint(new SecP224K1FieldElement(x), new SecP224K1FieldElement(y), SECP224K1_AFFINE_ZS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1233e0816ad5b44f9f27e6b791d2e97
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user