提交Unity 联机Pro

This commit is contained in:
PC-20230316NUNE\Administrator
2024-08-17 14:27:18 +08:00
parent f00193b000
commit 894100ae37
7448 changed files with 854473 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 192ce040c8f883047926a9f104e89219
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f7607b79d7fda4b4fb7452bd465e4f1a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1d60220356cda474badfff94d625ad9d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2ba3b2a3c2430914fbced44c7df90596
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c83e7d57be27b5d428630a56b05d18a1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0708bb98a46600e47b0eee7ea6b0d44d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c64005ee201237e4fb747b16625d3307
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7aaf91c41b94fe94abe7ac7eb28506c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9dfd9f72fc2d48e42b878a2169f7e4d4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6dba7a7d14e9d61449311c3d6c5af9a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c0012fa428aef224e95dfcbacde294a1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 31b37f390092cbf49912e6eec081a533
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 40e69c1e558a62e4cb5a52d30eb8fdfd
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 90b2a6bdef50756439d9f47423252e4b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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
* &#964;-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>&#945;<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>&#945;<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>&#945;<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>&#945;<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>&#945;<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>&#955;</code> of
* <code><b>Z</b>[&#964;]</code>.
* @param mu The parameter <code>&#956;</code> of the elliptic curve.
* @param lambda The element <code>&#955;</code> of
* <code><b>Z</b>[&#964;]</code>.
* @return The norm of <code>&#955;</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>&#955;</code> of
* <code><b>R</b>[&#964;]</code>, where <code>&#955; = u + v&#964;</code>
* and <code>u</code> and <code>u</code> are real numbers (elements of
* <code><b>R</b></code>).
* @param mu The parameter <code>&#956;</code> of the elliptic curve.
* @param u The real part of the element <code>&#955;</code> of
* <code><b>R</b>[&#964;]</code>.
* @param v The <code>&#964;</code>-adic part of the element
* <code>&#955;</code> of <code><b>R</b>[&#964;]</code>.
* @return The norm of <code>&#955;</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>&#955;</code> of <code><b>R</b>[&#964;]</code>
* to an element of <code><b>Z</b>[&#964;]</code>, such that their difference
* has minimal norm. <code>&#955;</code> is given as
* <code>&#955; = &#955;<sub>0</sub> + &#955;<sub>1</sub>&#964;</code>.
* @param lambda0 The component <code>&#955;<sub>0</sub></code>.
* @param lambda1 The component <code>&#955;<sub>1</sub></code>.
* @param mu The parameter <code>&#956;</code> of the elliptic curve. Must
* equal 1 or -1.
* @return The rounded element of <code><b>Z</b>[&#964;]</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>&#955; = 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>&#955; = 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>&#964;</code>-adic NAF (non-adjacent form) of an
* element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>.
* @param mu The parameter <code>&#956;</code> of the elliptic curve.
* @param lambda The element <code>&#955;</code> of
* <code><b>Z</b>[&#964;]</code>.
* @return The <code>&#964;</code>-adic NAF of <code>&#955;</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>&#964;()</code> to an
* <code>AbstractF2mPoint</code>.
* @param p The AbstractF2mPoint to which <code>&#964;()</code> is applied.
* @return <code>&#964;(p)</code>
*/
public static AbstractF2mPoint Tau(AbstractF2mPoint p)
{
return p.Tau();
}
/**
* Returns the parameter <code>&#956;</code> of the elliptic curve.
* @param curve The elliptic curve from which to obtain <code>&#956;</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>&#956;</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>&#956;</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>&#956;</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>(&#964;<sup>m</sup> - 1)/(&#964; - 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 &#956; of the elliptic curve.
* @param c The precision (number of bits of accuracy) of the partial
* modular reduction.
* @return <code>&#961; := k partmod (&#964;<sup>m</sup> - 1)/(&#964; - 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>&#964;</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>&#955;</code> of <code><b>Z</b>[&#964;]</code>
* using the <code>&#964;</code>-adic NAF (TNAF) method.
* @param p The AbstractF2mPoint to Multiply.
* @param lambda The element <code>&#955;</code> of
* <code><b>Z</b>[&#964;]</code>.
* @return <code>&#955; * 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>&#955;</code> of <code><b>Z</b>[&#964;]</code>
* using the <code>&#964;</code>-adic NAF (TNAF) method, given the TNAF
* of <code>&#955;</code>.
* @param p The AbstractF2mPoint to Multiply.
* @param u The the TNAF of <code>&#955;</code>..
* @return <code>&#955; * 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>[&#964;]</code>-adic window NAF of an element
* <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>.
* @param mu The parameter &#956; of the elliptic curve.
* @param lambda The element <code>&#955;</code> of
* <code><b>Z</b>[&#964;]</code> of which to compute the
* <code>[&#964;]</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>&#945;<sub>u</sub></code>'s for the window width.
* @return The <code>[&#964;]</code>-adic window NAF of
* <code>&#955;</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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c350a1fcb33886749ad8b6d264d92746
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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>[&#964;]</code>. Let
* <code>&#955;</code> be an element of <code><b>Z</b>[&#964;]</code>. Then
* <code>&#955;</code> is given as <code>&#955; = u + v&#964;</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 &quot;real&quot; part of <code>&#955;</code>.
*/
public readonly BigInteger u;
/**
* The &quot;<code>&#964;</code>-adic&quot; part of <code>&#955;</code>.
*/
public readonly BigInteger v;
/**
* Constructor for an element <code>&#955;</code> of
* <code><b>Z</b>[&#964;]</code>.
* @param u The &quot;real&quot; part of <code>&#955;</code>.
* @param v The &quot;<code>&#964;</code>-adic&quot; part of
* <code>&#955;</code>.
*/
public ZTauElement(BigInteger u, BigInteger v)
{
this.u = u;
this.v = v;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 06f1426762adf7a4a814250bf4084ce7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f13f8a0df1a5e424796c38a3c077a81c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a38ef3f332029e945bb971d37bccd8a4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fd030ecdc7871c74ca192e7bf4c31075
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2bc45dc149a92fe4d934ea8137fa7174
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 055f8fc08106e0646a52547e1a32b372
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: acbfba639c7e65d4093f380a4ba84523
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b192a254f279cb545b0e25c31042094e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 73006e3eaec93cb44a4d004d03e84862
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7c6a52fc113d5c74a839cb2861ce100d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: edf4874c4cb236144b35b46e9a8037ad
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 07d11740bf1c5f949b70c6663eb822ad
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f9d092c55e0cd03418fa2b044ec88ff3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f1b6f52fadd8950438dcf90df281b600
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b719fcfaca4697a499481a1ec81e4e74
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1150199688daf104cb227e8776202137
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5e8be84848d57df40bf9d4558a98c6e7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ab70ddacc717f914998f8131af159ac2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d444683aade1525409d6f03a80cd747c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 07c4fed00202a584c88533f83236ec32
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 48035112039046c41b2a437840a8014d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d36a6056a9fa51946b70dd3977edfb28
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e351f45b5e75bb149baf02e11f068f33
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aae5056faf4a481479fc7b296b811965
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 052ed3284b9686047ad51492201a07e6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4c57242857a693945805fab06e8b8816
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 218f3d42a4e59cf4a953af9121236128
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d5a7a619c061cd24cafd0a7cdbb3a432
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d94a23a9df7487e4b8647bb414b5c412
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9051396fd403a4143a8049754bd784c1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 44fb8f1c5ae47e64caf48325ec0b3902
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d1a07149a2b0efd429eb787280af3bc0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5084e06d37760694d9392014cb72ba23
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -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