فهرست منبع

Replace internal BouncyCastle with NuGet package (#1370)

* Replace internal BouncyCastle with NuGet package

* fix NullReference in KeyExchangeECDH

for some reason d24fe2006fdfa0caa3965c6897ed369f1752f801 introduced
its own names here which (as far as I can see) were never part
of the original BouncyCastle.

Switched to the correct names.

* Update to BouncyCastle 2.3.1

* Update to BouncyCastle 2.4.0

* fix Conflict between Zlib class and BouncyCastle namespace

CA1724: The type name Zlib conflicts in whole or in part with the namespace name 'Org.BouncyCastle.Utilities.Zlib'. Change either name to eliminate the conflict.

We can't change either, so suppress the warning.

---------

Co-authored-by: Rob Hague <rob.hague00@gmail.com>
mus65 1 سال پیش
والد
کامیت
9a950b56fe
79فایلهای تغییر یافته به همراه28 افزوده شده و 18134 حذف شده
  1. 2 0
      src/Renci.SshNet/Compression/Zlib.cs
  2. 4 0
      src/Renci.SshNet/Renci.SshNet.csproj
  3. 0 10
      src/Renci.SshNet/Security/BouncyCastle/.editorconfig
  4. 0 121
      src/Renci.SshNet/Security/BouncyCastle/asn1/sec/SECNamedCurves.cs
  5. 0 40
      src/Renci.SshNet/Security/BouncyCastle/asn1/x9/X9Curve.cs
  6. 0 93
      src/Renci.SshNet/Security/BouncyCastle/asn1/x9/X9ECParameters.cs
  7. 0 25
      src/Renci.SshNet/Security/BouncyCastle/asn1/x9/X9ECParametersHolder.cs
  8. 0 57
      src/Renci.SshNet/Security/BouncyCastle/asn1/x9/X9ECPoint.cs
  9. 0 33
      src/Renci.SshNet/Security/BouncyCastle/crypto/AsymmetricCipherKeyPair.cs
  10. 0 42
      src/Renci.SshNet/Security/BouncyCastle/crypto/AsymmetricKeyParameter.cs
  11. 0 9
      src/Renci.SshNet/Security/BouncyCastle/crypto/IAsymmetricCipherKeyPairGenerator.cs
  12. 0 61
      src/Renci.SshNet/Security/BouncyCastle/crypto/IDigest.cs
  13. 0 56
      src/Renci.SshNet/Security/BouncyCastle/crypto/KeyGenerationParameters.cs
  14. 0 39
      src/Renci.SshNet/Security/BouncyCastle/crypto/License.html
  15. 0 46
      src/Renci.SshNet/Security/BouncyCastle/crypto/agreement/ECDHCBasicAgreement.cs
  16. 0 129
      src/Renci.SshNet/Security/BouncyCastle/crypto/digests/GeneralDigest.cs
  17. 0 280
      src/Renci.SshNet/Security/BouncyCastle/crypto/digests/Sha256Digest.cs
  18. 0 91
      src/Renci.SshNet/Security/BouncyCastle/crypto/generators/ECKeyPairGenerator.cs
  19. 0 91
      src/Renci.SshNet/Security/BouncyCastle/crypto/parameters/ECDomainParameters.cs
  20. 0 23
      src/Renci.SshNet/Security/BouncyCastle/crypto/parameters/ECKeyGenerationParameters.cs
  21. 0 79
      src/Renci.SshNet/Security/BouncyCastle/crypto/parameters/ECKeyParameters.cs
  22. 0 61
      src/Renci.SshNet/Security/BouncyCastle/crypto/parameters/ECPrivateKeyParameters.cs
  23. 0 60
      src/Renci.SshNet/Security/BouncyCastle/crypto/parameters/ECPublicKeyParameters.cs
  24. 0 59
      src/Renci.SshNet/Security/BouncyCastle/crypto/prng/CryptoApiRandomGenerator.cs
  25. 0 117
      src/Renci.SshNet/Security/BouncyCastle/crypto/prng/DigestRandomGenerator.cs
  26. 0 26
      src/Renci.SshNet/Security/BouncyCastle/crypto/prng/IRandomGenerator.cs
  27. 0 345
      src/Renci.SshNet/Security/BouncyCastle/crypto/util/Pack.cs
  28. 0 3605
      src/Renci.SshNet/Security/BouncyCastle/math/BigInteger.cs
  29. 0 496
      src/Renci.SshNet/Security/BouncyCastle/math/ec/ECAlgorithms.cs
  30. 0 1278
      src/Renci.SshNet/Security/BouncyCastle/math/ec/ECCurve.cs
  31. 0 972
      src/Renci.SshNet/Security/BouncyCastle/math/ec/ECFieldElement.cs
  32. 0 10
      src/Renci.SshNet/Security/BouncyCastle/math/ec/ECLookupTable.cs
  33. 0 2122
      src/Renci.SshNet/Security/BouncyCastle/math/ec/ECPoint.cs
  34. 0 9
      src/Renci.SshNet/Security/BouncyCastle/math/ec/ECPointMap.cs
  35. 0 2206
      src/Renci.SshNet/Security/BouncyCastle/math/ec/LongArray.cs
  36. 0 241
      src/Renci.SshNet/Security/BouncyCastle/math/ec/abc/SimpleBigDecimal.cs
  37. 0 845
      src/Renci.SshNet/Security/BouncyCastle/math/ec/abc/Tnaf.cs
  38. 0 36
      src/Renci.SshNet/Security/BouncyCastle/math/ec/abc/ZTauElement.cs
  39. 0 11
      src/Renci.SshNet/Security/BouncyCastle/math/ec/endo/ECEndomorphism.cs
  40. 0 10
      src/Renci.SshNet/Security/BouncyCastle/math/ec/endo/GlvEndomorphism.cs
  41. 0 29
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/AbstractECMultiplier.cs
  42. 0 18
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/ECMultiplier.cs
  43. 0 58
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/FixedPointCombMultiplier.cs
  44. 0 43
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/FixedPointPreCompInfo.cs
  45. 0 95
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/FixedPointUtilities.cs
  46. 0 40
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/GlvMultiplier.cs
  47. 0 9
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/IPreCompCallback.cs
  48. 0 11
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/PreCompInfo.cs
  49. 0 44
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/ValidityPreCompInfo.cs
  50. 0 98
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/WNafL2RMultiplier.cs
  51. 0 46
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/WNafPreCompInfo.cs
  52. 0 579
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/WNafUtilities.cs
  53. 0 138
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/WTauNafMultiplier.cs
  54. 0 24
      src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/WTauNafPreCompInfo.cs
  55. 0 54
      src/Renci.SshNet/Security/BouncyCastle/math/field/FiniteFields.cs
  56. 0 46
      src/Renci.SshNet/Security/BouncyCastle/math/field/GF2Polynomial.cs
  57. 0 63
      src/Renci.SshNet/Security/BouncyCastle/math/field/GenericPolynomialExtensionField.cs
  58. 0 12
      src/Renci.SshNet/Security/BouncyCastle/math/field/IExtensionField.cs
  59. 0 11
      src/Renci.SshNet/Security/BouncyCastle/math/field/IFiniteField.cs
  60. 0 13
      src/Renci.SshNet/Security/BouncyCastle/math/field/IPolynomial.cs
  61. 0 8
      src/Renci.SshNet/Security/BouncyCastle/math/field/IPolynomialExtensionField.cs
  62. 0 42
      src/Renci.SshNet/Security/BouncyCastle/math/field/PrimeField.cs
  63. 0 185
      src/Renci.SshNet/Security/BouncyCastle/math/raw/Mod.cs
  64. 0 1153
      src/Renci.SshNet/Security/BouncyCastle/math/raw/Nat.cs
  65. 0 34
      src/Renci.SshNet/Security/BouncyCastle/security/DigestUtilities.cs
  66. 0 179
      src/Renci.SshNet/Security/BouncyCastle/security/SecureRandom.cs
  67. 0 36
      src/Renci.SshNet/Security/BouncyCastle/security/SecurityUtilityException.cs
  68. 0 718
      src/Renci.SshNet/Security/BouncyCastle/util/Arrays.cs
  69. 0 95
      src/Renci.SshNet/Security/BouncyCastle/util/BigIntegers.cs
  70. 0 29
      src/Renci.SshNet/Security/BouncyCastle/util/IMemoable.cs
  71. 0 27
      src/Renci.SshNet/Security/BouncyCastle/util/Integers.cs
  72. 0 27
      src/Renci.SshNet/Security/BouncyCastle/util/MemoableResetException.cs
  73. 0 14
      src/Renci.SshNet/Security/BouncyCastle/util/Times.cs
  74. 0 129
      src/Renci.SshNet/Security/BouncyCastle/util/encoders/Hex.cs
  75. 0 174
      src/Renci.SshNet/Security/BouncyCastle/util/encoders/HexEncoder.cs
  76. 7 7
      src/Renci.SshNet/Security/KeyExchangeECDH.cs
  77. 5 4
      src/Renci.SshNet/Security/KeyExchangeECDH256.cs
  78. 5 4
      src/Renci.SshNet/Security/KeyExchangeECDH384.cs
  79. 5 4
      src/Renci.SshNet/Security/KeyExchangeECDH521.cs

+ 2 - 0
src/Renci.SshNet/Compression/Zlib.cs

@@ -7,7 +7,9 @@ namespace Renci.SshNet.Compression
     /// <summary>
     /// Represents the "zlib" compression algorithm.
     /// </summary>
+#pragma warning disable CA1724 // Type names should not match namespaces
     public class Zlib : Compressor
+#pragma warning restore CA1724 // Type names should not match namespaces
     {
         private readonly ZLibStream _compressor;
         private readonly ZLibStream _decompressor;

+ 4 - 0
src/Renci.SshNet/Renci.SshNet.csproj

@@ -40,6 +40,10 @@
     <PackageReference Include="System.Memory" Version="4.5.5" />
   </ItemGroup>
 
+  <ItemGroup>
+    <PackageReference Include="BouncyCastle.Cryptography" Version="[2.4.0,)" />
+  </ItemGroup>
+
   <ItemGroup>
     <None Include="..\..\images\logo\png\SS-NET-icon-h500.png">
       <Pack>True</Pack>

+ 0 - 10
src/Renci.SshNet/Security/BouncyCastle/.editorconfig

@@ -1,10 +0,0 @@
-[*.cs]
-
-generated_code = true
-
-# Do not reported any diagnostics for "imported" code
-dotnet_analyzer_diagnostic.severity = none
-
-# IDE0005: Remove unnecessary using directives
-# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0005
-dotnet_diagnostic.IDE0005.severity = none

+ 0 - 121
src/Renci.SshNet/Security/BouncyCastle/asn1/sec/SECNamedCurves.cs

@@ -1,121 +0,0 @@
-using Renci.SshNet.Security.Org.BouncyCastle.Asn1.X9;
-using Renci.SshNet.Security.Org.BouncyCastle.Math;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC;
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities.Encoders;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Asn1.Sec
-{
-    internal sealed class SecNamedCurves
-    {
-        /*
-         * secp256r1
-         */
-        internal class Secp256r1Holder
-            : X9ECParametersHolder
-        {
-            private Secp256r1Holder() {}
-
-            internal static readonly X9ECParametersHolder Instance = new Secp256r1Holder();
-
-            protected override X9ECParameters CreateParameters()
-            {
-                // p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1
-                BigInteger p = FromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF");
-                BigInteger a = FromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC");
-                BigInteger b = FromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B");
-                byte[] S = Hex.Decode("C49D360886E704936A6678E1139D26B7819F7E90");
-                BigInteger n = FromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
-                BigInteger h = BigInteger.One;
-
-                ECCurve curve = new FpCurve(p, a, b, n, h);
-                X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04"
-                    + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
-                    + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"));
-
-                return new X9ECParameters(curve, G, n, h, S);
-            }
-        }
-
-        /*
-         * secp384r1
-         */
-        internal class Secp384r1Holder
-            : X9ECParametersHolder
-        {
-            private Secp384r1Holder() {}
-
-            internal static readonly X9ECParametersHolder Instance = new Secp384r1Holder();
-
-            protected override X9ECParameters CreateParameters()
-            {
-                // p = 2^384 - 2^128 - 2^96 + 2^32 - 1
-                BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF");
-                BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC");
-                BigInteger b = FromHex("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF");
-                byte[] S = Hex.Decode("A335926AA319A27A1D00896A6773A4827ACDAC73");
-                BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973");
-                BigInteger h = BigInteger.One;
-
-                ECCurve curve = new FpCurve(p, a, b, n, h);
-                X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04"
-                    + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
-                    + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"));
-
-                return new X9ECParameters(curve, G, n, h, S);
-            }
-        }
-
-        /*
-         * secp521r1
-         */
-        internal class Secp521r1Holder
-            : X9ECParametersHolder
-        {
-            private Secp521r1Holder() {}
-
-            internal static readonly X9ECParametersHolder Instance = new Secp521r1Holder();
-
-            protected override X9ECParameters CreateParameters()
-            {
-                // p = 2^521 - 1
-                BigInteger p = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
-                BigInteger a = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC");
-                BigInteger b = FromHex("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00");
-                byte[] S = Hex.Decode("D09E8800291CB85396CC6717393284AAA0DA64BA");
-                BigInteger n = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409");
-                BigInteger h = BigInteger.One;
-
-                ECCurve curve = new FpCurve(p, a, b, n, h);
-                X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04"
-                    + "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
-                    + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"));
-
-                return new X9ECParameters(curve, G, n, h, S);
-            }
-        }
-
-        public static X9ECParameters GetByName(
-            string name)
-        {
-            switch(name)
-            {
-                case "P-256":
-                case "secp256r1":
-                    return Secp256r1Holder.Instance.Parameters;
-                case "P-384":
-                case "secp384r1":
-                    return Secp384r1Holder.Instance.Parameters;
-                case "P-521":
-                case "secp521r1":
-                    return Secp521r1Holder.Instance.Parameters;
-            }
-
-            return null;
-        }
-
-        private static BigInteger FromHex(string hex)
-        {
-            return new BigInteger(1, Hex.Decode(hex));
-        }
-    }
-}

+ 0 - 40
src/Renci.SshNet/Security/BouncyCastle/asn1/x9/X9Curve.cs

@@ -1,40 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC;
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Asn1.X9
-{
-    internal class X9Curve
-    {
-        private readonly ECCurve curve;
-        private readonly byte[] seed;
-
-        public X9Curve(
-            ECCurve curve)
-            : this(curve, null)
-        {
-        }
-
-        public X9Curve(
-            ECCurve	curve,
-            byte[]	seed)
-        {
-            if (curve == null)
-                throw new ArgumentNullException("curve");
-
-            this.curve = curve;
-            this.seed = Arrays.Clone(seed);
-        }
-
-        public ECCurve Curve
-        {
-            get { return curve; }
-        }
-
-        public byte[] GetSeed()
-        {
-            return Arrays.Clone(seed);
-        }
-    }
-}

+ 0 - 93
src/Renci.SshNet/Security/BouncyCastle/asn1/x9/X9ECParameters.cs

@@ -1,93 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Asn1.X9
-{
-    internal class X9ECParameters
-    {
-        private byte[]		seed;
-
-		public static X9ECParameters GetInstance(Object obj)
-		{
-			if (obj is X9ECParameters)
-				return (X9ECParameters)obj;
-
-            return null;
-		}
-
-        public X9ECParameters(
-            ECCurve		curve,
-            ECPoint		g,
-            BigInteger	n)
-            : this(curve, g, n, null, null)
-        {
-        }
-
-        public X9ECParameters(
-            ECCurve     curve,
-            X9ECPoint   g,
-            BigInteger  n,
-            BigInteger  h)
-            : this(curve, g, n, h, null)
-        {
-        }
-
-        public X9ECParameters(
-            ECCurve		curve,
-            ECPoint		g,
-            BigInteger	n,
-            BigInteger	h)
-            : this(curve, g, n, h, null)
-        {
-        }
-
-        public X9ECParameters(
-            ECCurve		curve,
-            ECPoint		g,
-            BigInteger	n,
-            BigInteger	h,
-            byte[]		seed)
-            : this(curve, new X9ECPoint(g), n, h, seed)
-        {
-        }
-
-        public X9ECParameters(
-            ECCurve     curve,
-            X9ECPoint   g,
-            BigInteger  n,
-            BigInteger  h,
-            byte[]      seed)
-        {
-            this.Curve = curve;
-            this.BaseEntry = g;
-            this.N = n;
-            this.H = h;
-            this.seed = seed;
-        }
-
-        public ECCurve Curve { get; private set; }
-
-        public ECPoint G
-        {
-            get { return BaseEntry.Point; }
-        }
-
-        public BigInteger N { get; private set; }
-
-        public BigInteger H { get; private set; }
-
-        public byte[] GetSeed()
-        {
-            return seed;
-        }
-
-        public X9Curve CurveEntry
-        {
-            get { return new X9Curve(Curve, seed); }
-        }
-
-        public X9ECPoint BaseEntry { get; private set; }
-    }
-}

+ 0 - 25
src/Renci.SshNet/Security/BouncyCastle/asn1/x9/X9ECParametersHolder.cs

@@ -1,25 +0,0 @@
-namespace Renci.SshNet.Security.Org.BouncyCastle.Asn1.X9
-{
-	internal abstract class X9ECParametersHolder
-	{
-		private X9ECParameters parameters;
-
-		public X9ECParameters Parameters
-		{
-			get
-			{
-                lock (this)
-                {
-                    if (parameters == null)
-                    {
-                        parameters = CreateParameters();
-                    }
-
-                    return parameters;
-                }
-            }
-        }
-
-		protected abstract X9ECParameters CreateParameters();
-	}
-}

+ 0 - 57
src/Renci.SshNet/Security/BouncyCastle/asn1/x9/X9ECPoint.cs

@@ -1,57 +0,0 @@
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC;
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Asn1.X9
-{
-    internal class X9ECPoint
-    {
-        private readonly byte[] encoding;
-
-        private ECCurve c;
-        private ECPoint p;
-
-        public X9ECPoint(ECPoint p)
-            : this(p, false)
-        {
-        }
-
-        public X9ECPoint(ECPoint p, bool compressed)
-        {
-            this.p = p.Normalize();
-            this.encoding = p.GetEncoded(compressed);
-        }
-
-        public X9ECPoint(ECCurve c, byte[] encoding)
-        {
-            this.c = c;
-            this.encoding = Arrays.Clone(encoding);
-        }
-
-        public byte[] GetPointEncoding()
-        {
-            return Arrays.Clone(encoding);
-        }
-
-        public ECPoint Point
-        {
-            get
-            {
-                if (p == null)
-                {
-                    p = c.DecodePoint(encoding).Normalize();
-                }
-
-                return p;
-            }
-        }
-
-        public bool IsPointCompressed
-        {
-            get
-            {
-                byte[] octets = encoding;
-                return octets != null && octets.Length > 0 && (octets[0] == 2 || octets[0] == 3);
-            }
-        }
-    }
-}

+ 0 - 33
src/Renci.SshNet/Security/BouncyCastle/crypto/AsymmetricCipherKeyPair.cs

@@ -1,33 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto
-{
-    internal class AsymmetricCipherKeyPair
-    {
-        private readonly AsymmetricKeyParameter publicParameter;
-        private readonly AsymmetricKeyParameter privateParameter;
-
-        public AsymmetricCipherKeyPair(
-            AsymmetricKeyParameter    publicParameter,
-            AsymmetricKeyParameter    privateParameter)
-        {
-			if (publicParameter.IsPrivate)
-				throw new ArgumentException("Expected a public key", "publicParameter");
-			if (!privateParameter.IsPrivate)
-				throw new ArgumentException("Expected a private key", "privateParameter");
-
-			this.publicParameter = publicParameter;
-            this.privateParameter = privateParameter;
-        }
-
-        public AsymmetricKeyParameter Public
-        {
-            get { return publicParameter; }
-        }
-
-        public AsymmetricKeyParameter Private
-        {
-            get { return privateParameter; }
-        }
-    }
-}

+ 0 - 42
src/Renci.SshNet/Security/BouncyCastle/crypto/AsymmetricKeyParameter.cs

@@ -1,42 +0,0 @@
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto
-{
-    internal abstract class AsymmetricKeyParameter
-    {
-        private readonly bool privateKey;
-
-        protected AsymmetricKeyParameter(
-            bool privateKey)
-        {
-            this.privateKey = privateKey;
-        }
-
-		public bool IsPrivate
-        {
-            get { return privateKey; }
-        }
-
-		public override bool Equals(
-			object obj)
-		{
-			AsymmetricKeyParameter other = obj as AsymmetricKeyParameter;
-
-			if (other == null)
-			{
-				return false;
-			}
-
-			return Equals(other);
-		}
-
-		protected bool Equals(
-			AsymmetricKeyParameter other)
-		{
-			return privateKey == other.privateKey;
-		}
-
-		public override int GetHashCode()
-		{
-			return privateKey.GetHashCode();
-		}
-    }
-}

+ 0 - 9
src/Renci.SshNet/Security/BouncyCastle/crypto/IAsymmetricCipherKeyPairGenerator.cs

@@ -1,9 +0,0 @@
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto
-{
-    internal interface IAsymmetricCipherKeyPairGenerator
-    {
-        void Init(KeyGenerationParameters parameters);
-
-        AsymmetricCipherKeyPair GenerateKeyPair();
-    }
-}

+ 0 - 61
src/Renci.SshNet/Security/BouncyCastle/crypto/IDigest.cs

@@ -1,61 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto
-{
-    /**
-     * interface that a message digest conforms to.
-     */
-    internal interface IDigest
-    {
-        /**
-         * return the algorithm name
-         *
-         * @return the algorithm name
-         */
-        string AlgorithmName { get; }
-
-		/**
-         * return the size, in bytes, of the digest produced by this message digest.
-         *
-         * @return the size, in bytes, of the digest produced by this message digest.
-         */
-		int GetDigestSize();
-
-		/**
-         * return the size, in bytes, of the internal buffer used by this digest.
-         *
-         * @return the size, in bytes, of the internal buffer used by this digest.
-         */
-		int GetByteLength();
-
-		/**
-         * update the message digest with a single byte.
-         *
-         * @param inByte the input byte to be entered.
-         */
-        void Update(byte input);
-
-        /**
-         * update the message digest with a block of bytes.
-         *
-         * @param input the byte array containing the data.
-         * @param inOff the offset into the byte array where the data starts.
-         * @param len the length of the data.
-         */
-        void BlockUpdate(byte[] input, int inOff, int length);
-
-        /**
-         * Close the digest, producing the final digest value. The doFinal
-         * call leaves the digest reset.
-         *
-         * @param output the array the digest is to be copied into.
-         * @param outOff the offset into the out array the digest is to start at.
-         */
-        int DoFinal(byte[] output, int outOff);
-
-        /**
-         * reset the digest back to it's initial state.
-         */
-        void Reset();
-    }
-}

+ 0 - 56
src/Renci.SshNet/Security/BouncyCastle/crypto/KeyGenerationParameters.cs

@@ -1,56 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Security;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto
-{
-    /**
-     * The base class for parameters to key generators.
-     */
-    internal class KeyGenerationParameters
-    {
-        private SecureRandom	random;
-        private int				strength;
-
-        /**
-         * initialise the generator with a source of randomness
-         * and a strength (in bits).
-         *
-         * @param random the random byte source.
-         * @param strength the size, in bits, of the keys we want to produce.
-         */
-        public KeyGenerationParameters(
-            SecureRandom	random,
-            int				strength)
-        {
-			if (random == null)
-				throw new ArgumentNullException("random");
-			if (strength < 1)
-				throw new ArgumentException("strength must be a positive value", "strength");
-
-			this.random = random;
-            this.strength = strength;
-        }
-
-		/**
-         * return the random source associated with this
-         * generator.
-         *
-         * @return the generators random source.
-         */
-        public SecureRandom Random
-        {
-            get { return random; }
-        }
-
-		/**
-         * return the bit strength for keys produced by this generator,
-         *
-         * @return the strength of the keys this generator produces (in bits).
-         */
-        public int Strength
-        {
-            get { return strength; }
-        }
-    }
-}

+ 0 - 39
src/Renci.SshNet/Security/BouncyCastle/crypto/License.html

@@ -1,39 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta content="text/html; charset=ISO-8859-1"
- http-equiv="content-type">
-  <title>License</title>
-</head>
-<body>
-<h2>The Bouncy Castle Cryptographic C#&reg; API</h2>
-<h3>License:</h3>
-The Bouncy Castle License<br>
-Copyright (c) 2000-2018 The Legion of the Bouncy Castle Inc.
-(https://www.bouncycastle.org)<br>
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"), to deal in the
-Software without restriction, including without limitation the rights to use, copy, modify, merge,
-publish, distribute, sub license, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:<br>
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.<br>
-<span style="font-weight: bold;">THE SOFTWARE IS PROVIDED "AS IS",
-WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,</span><br
- style="font-weight: bold;">
-<span style="font-weight: bold;">INCLUDING BUT NOT LIMITED TO THE
-WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR</span><br
- style="font-weight: bold;">
-<span style="font-weight: bold;">PURPOSE AND NONINFRINGEMENT. IN NO
-EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE</span><br
- style="font-weight: bold;">
-<span style="font-weight: bold;">LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR</span><br
- style="font-weight: bold;">
-<span style="font-weight: bold;">OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER</span><br
- style="font-weight: bold;">
-<span style="font-weight: bold;">DEALINGS IN THE SOFTWARE.<br>
-<br>
-</span>
-</body>
-</html>

+ 0 - 46
src/Renci.SshNet/Security/BouncyCastle/crypto/agreement/ECDHCBasicAgreement.cs

@@ -1,46 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC;
-using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Parameters;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Agreement
-{
-    internal class ECDHCBasicAgreement
-    {
-        private ECPrivateKeyParameters privKey;
-
-        public virtual void Init(
-            AsymmetricKeyParameter parameters)
-        {
-            this.privKey = (ECPrivateKeyParameters)parameters;
-        }
-
-        public virtual int GetFieldSize()
-        {
-            return (privKey.Parameters.Curve.FieldSize + 7) / 8;
-        }
-
-        public virtual BigInteger CalculateAgreement(
-            ECPublicKeyParameters pubKey)
-        {
-            ECPublicKeyParameters pub = pubKey;
-            ECDomainParameters dp = privKey.Parameters;
-            if (!dp.Equals(pub.Parameters))
-                throw new InvalidOperationException("ECDHC public key has wrong domain parameters");
-
-            BigInteger hd = dp.H.Multiply(privKey.D).Mod(dp.N);
-
-            // Always perform calculations on the exact curve specified by our private key's parameters
-            ECPoint pubPoint = ECAlgorithms.CleanPoint(dp.Curve, pub.Q);
-            if (pubPoint.IsInfinity)
-                throw new InvalidOperationException("Infinity is not a valid public key for ECDHC");
-
-            ECPoint P = pubPoint.Multiply(hd).Normalize();
-            if (P.IsInfinity)
-                throw new InvalidOperationException("Infinity is not a valid agreement value for ECDHC");
-
-            return P.AffineXCoord.ToBigInteger();
-        }
-    }
-}

+ 0 - 129
src/Renci.SshNet/Security/BouncyCastle/crypto/digests/GeneralDigest.cs

@@ -1,129 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Digests
-{
-    internal abstract class GeneralDigest
-		: IDigest, IMemoable
-    {
-        private const int BYTE_LENGTH = 64;
-
-        private byte[]  xBuf;
-        private int     xBufOff;
-
-        private long    byteCount;
-
-        internal GeneralDigest()
-        {
-            xBuf = new byte[4];
-        }
-
-        internal GeneralDigest(GeneralDigest t)
-		{
-			xBuf = new byte[t.xBuf.Length];
-			CopyIn(t);
-		}
-
-		protected void CopyIn(GeneralDigest t)
-		{
-            Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length);
-
-            xBufOff = t.xBufOff;
-            byteCount = t.byteCount;
-        }
-
-        public void Update(byte input)
-        {
-            xBuf[xBufOff++] = input;
-
-            if (xBufOff == xBuf.Length)
-            {
-                ProcessWord(xBuf, 0);
-                xBufOff = 0;
-            }
-
-            byteCount++;
-        }
-
-        public void BlockUpdate(
-            byte[]  input,
-            int     inOff,
-            int     length)
-        {
-            length = System.Math.Max(0, length);
-
-            //
-            // fill the current word
-            //
-            int i = 0;
-            if (xBufOff != 0)
-            {
-                while (i < length)
-                {
-                    xBuf[xBufOff++] = input[inOff + i++];
-                    if (xBufOff == 4)
-                    {
-                        ProcessWord(xBuf, 0);
-                        xBufOff = 0;
-                        break;
-                    }
-                }
-            }
-
-            //
-            // process whole words.
-            //
-            int limit = ((length - i) & ~3) + i;
-            for (; i < limit; i += 4)
-            {
-                ProcessWord(input, inOff + i);
-            }
-
-            //
-            // load in the remainder.
-            //
-            while (i < length)
-            {
-                xBuf[xBufOff++] = input[inOff + i++];
-            }
-
-            byteCount += length;
-        }
-
-        public void Finish()
-        {
-            long    bitLength = (byteCount << 3);
-
-            //
-            // add the pad bytes.
-            //
-            Update((byte)128);
-
-            while (xBufOff != 0) Update((byte)0);
-            ProcessLength(bitLength);
-            ProcessBlock();
-        }
-
-        public virtual void Reset()
-        {
-            byteCount = 0;
-            xBufOff = 0;
-			Array.Clear(xBuf, 0, xBuf.Length);
-        }
-
-		public int GetByteLength()
-		{
-			return BYTE_LENGTH;
-		}
-
-		internal abstract void ProcessWord(byte[] input, int inOff);
-        internal abstract void ProcessLength(long bitLength);
-        internal abstract void ProcessBlock();
-        public abstract string AlgorithmName { get; }
-		public abstract int GetDigestSize();
-        public abstract int DoFinal(byte[] output, int outOff);
-		public abstract IMemoable Copy();
-		public abstract void Reset(IMemoable t);
-    }
-}

+ 0 - 280
src/Renci.SshNet/Security/BouncyCastle/crypto/digests/Sha256Digest.cs

@@ -1,280 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Utilities;
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Digests
-{
-    internal class Sha256Digest
-		: GeneralDigest
-    {
-        private const int DigestLength = 32;
-
-        private uint H1, H2, H3, H4, H5, H6, H7, H8;
-        private uint[] X = new uint[64];
-        private int xOff;
-
-        public Sha256Digest()
-        {
-			initHs();
-        }
-
-        /**
-        * Copy constructor.  This will copy the state of the provided
-        * message digest.
-        */
-        public Sha256Digest(Sha256Digest t) : base(t)
-        {
-			CopyIn(t);
-		}
-
-		private void CopyIn(Sha256Digest t)
-		{
-			base.CopyIn(t);
-
-            H1 = t.H1;
-            H2 = t.H2;
-            H3 = t.H3;
-            H4 = t.H4;
-            H5 = t.H5;
-            H6 = t.H6;
-            H7 = t.H7;
-            H8 = t.H8;
-
-            Array.Copy(t.X, 0, X, 0, t.X.Length);
-            xOff = t.xOff;
-        }
-
-        public override string AlgorithmName
-		{
-			get { return "SHA-256"; }
-		}
-
-		public override int GetDigestSize()
-		{
-			return DigestLength;
-		}
-
-		internal override void ProcessWord(
-            byte[]  input,
-            int     inOff)
-		{
-			X[xOff] = Pack.BE_To_UInt32(input, inOff);
-
-			if (++xOff == 16)
-            {
-                ProcessBlock();
-            }
-        }
-
-		internal override void ProcessLength(
-            long bitLength)
-        {
-            if (xOff > 14)
-            {
-                ProcessBlock();
-            }
-
-            X[14] = (uint)((ulong)bitLength >> 32);
-            X[15] = (uint)((ulong)bitLength);
-        }
-
-        public override int DoFinal(
-            byte[]  output,
-            int     outOff)
-        {
-            Finish();
-
-            Pack.UInt32_To_BE((uint)H1, output, outOff);
-            Pack.UInt32_To_BE((uint)H2, output, outOff + 4);
-            Pack.UInt32_To_BE((uint)H3, output, outOff + 8);
-            Pack.UInt32_To_BE((uint)H4, output, outOff + 12);
-            Pack.UInt32_To_BE((uint)H5, output, outOff + 16);
-            Pack.UInt32_To_BE((uint)H6, output, outOff + 20);
-            Pack.UInt32_To_BE((uint)H7, output, outOff + 24);
-            Pack.UInt32_To_BE((uint)H8, output, outOff + 28);
-
-            Reset();
-
-            return DigestLength;
-        }
-
-        public override void Reset()
-        {
-            base.Reset();
-
-			initHs();
-
-            xOff = 0;
-			Array.Clear(X, 0, X.Length);
-        }
-
-		private void initHs()
-		{
-            /* SHA-256 initial hash value
-            * The first 32 bits of the fractional parts of the square roots
-            * of the first eight prime numbers
-            */
-            H1 = 0x6a09e667;
-            H2 = 0xbb67ae85;
-            H3 = 0x3c6ef372;
-            H4 = 0xa54ff53a;
-            H5 = 0x510e527f;
-            H6 = 0x9b05688c;
-            H7 = 0x1f83d9ab;
-            H8 = 0x5be0cd19;
-		}
-
-        internal override void ProcessBlock()
-        {
-            //
-            // expand 16 word block into 64 word blocks.
-            //
-            for (int ti = 16; ti <= 63; ti++)
-            {
-                X[ti] = Theta1(X[ti - 2]) + X[ti - 7] + Theta0(X[ti - 15]) + X[ti - 16];
-            }
-
-            //
-            // set up working variables.
-            //
-            uint a = H1;
-            uint b = H2;
-            uint c = H3;
-            uint d = H4;
-            uint e = H5;
-            uint f = H6;
-            uint g = H7;
-            uint h = H8;
-
-			int t = 0;
-			for(int i = 0; i < 8; ++i)
-			{
-				// t = 8 * i
-				h += Sum1Ch(e, f, g) + K[t] + X[t];
-				d += h;
-				h += Sum0Maj(a, b, c);
-				++t;
-
-				// t = 8 * i + 1
-				g += Sum1Ch(d, e, f) + K[t] + X[t];
-				c += g;
-				g += Sum0Maj(h, a, b);
-				++t;
-
-				// t = 8 * i + 2
-				f += Sum1Ch(c, d, e) + K[t] + X[t];
-				b += f;
-				f += Sum0Maj(g, h, a);
-				++t;
-
-				// t = 8 * i + 3
-				e += Sum1Ch(b, c, d) + K[t] + X[t];
-				a += e;
-				e += Sum0Maj(f, g, h);
-				++t;
-
-				// t = 8 * i + 4
-				d += Sum1Ch(a, b, c) + K[t] + X[t];
-				h += d;
-				d += Sum0Maj(e, f, g);
-				++t;
-
-				// t = 8 * i + 5
-				c += Sum1Ch(h, a, b) + K[t] + X[t];
-				g += c;
-				c += Sum0Maj(d, e, f);
-				++t;
-
-				// t = 8 * i + 6
-				b += Sum1Ch(g, h, a) + K[t] + X[t];
-				f += b;
-				b += Sum0Maj(c, d, e);
-				++t;
-
-				// t = 8 * i + 7
-				a += Sum1Ch(f, g, h) + K[t] + X[t];
-				e += a;
-				a += Sum0Maj(b, c, d);
-				++t;
-			}
-
-			H1 += a;
-            H2 += b;
-            H3 += c;
-            H4 += d;
-            H5 += e;
-            H6 += f;
-            H7 += g;
-            H8 += h;
-
-            //
-            // reset the offset and clean out the word buffer.
-            //
-            xOff = 0;
-			Array.Clear(X, 0, 16);
-        }
-
-		private static uint Sum1Ch(
-            uint    x,
-            uint    y,
-            uint    z)
-		{
-	        return (((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7)))
-				+ ((x & y) ^ ((~x) & z));
-		}
-
-		private static uint Sum0Maj(
-            uint	x,
-            uint    y,
-            uint    z)
-		{
-	        return (((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10)))
-				+ ((x & y) ^ (x & z) ^ (y & z));
-		}
-
-        private static uint Theta0(
-            uint x)
-        {
-	        return ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3);
-        }
-
-        private static uint Theta1(
-            uint x)
-        {
-	        return ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10);
-        }
-
-        private static readonly uint[] K = {
-            0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
-			0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
-            0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
-            0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
-            0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
-            0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-            0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
-            0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
-            0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
-            0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
-            0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
-            0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
-            0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
-            0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
-            0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
-            0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-        };
-		
-		public override IMemoable Copy()
-		{
-			return new Sha256Digest(this);
-		}
-
-		public override void Reset(IMemoable other)
-		{
-			Sha256Digest d = (Sha256Digest)other;
-
-			CopyIn(d);
-		}
-
-    }
-}

+ 0 - 91
src/Renci.SshNet/Security/BouncyCastle/crypto/generators/ECKeyPairGenerator.cs

@@ -1,91 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Parameters;
-using Renci.SshNet.Security.Org.BouncyCastle.Math;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier;
-using Renci.SshNet.Security.Org.BouncyCastle.Security;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Generators
-{
-    internal class ECKeyPairGenerator
-        : IAsymmetricCipherKeyPairGenerator
-    {
-        private readonly string algorithm;
-
-        private ECDomainParameters parameters;
-        private SecureRandom random;
-
-        public ECKeyPairGenerator()
-            : this("EC")
-        {
-        }
-
-        public ECKeyPairGenerator(
-            string algorithm)
-        {
-            if (algorithm == null)
-                throw new ArgumentNullException("algorithm");
-
-            this.algorithm = ECKeyParameters.VerifyAlgorithmName(algorithm);
-        }
-
-        public void Init(
-            KeyGenerationParameters parameters)
-        {
-            if (parameters is ECKeyGenerationParameters)
-            {
-                ECKeyGenerationParameters ecP = (ECKeyGenerationParameters) parameters;
-
-                this.parameters = ecP.DomainParameters;
-            }
-
-            this.random = parameters.Random;
-
-            if (this.random == null)
-            {
-                this.random = new SecureRandom();
-            }
-        }
-
-        public AsymmetricCipherKeyPair GenerateKeyPair()
-        {
-            BigInteger n = parameters.N;
-            BigInteger d;
-            int minWeight = n.BitLength >> 2;
-
-            for (;;)
-            {
-                d = new BigInteger(n.BitLength, random);
-
-                if (d.CompareTo(BigInteger.Two) < 0 || d.CompareTo(n) >= 0)
-                    continue;
-
-                if (WNafUtilities.GetNafWeight(d) < minWeight)
-                    continue;
-
-                break;
-            }
-
-            ECPoint q = CreateBasePointMultiplier().Multiply(parameters.G, d);
-
-            return new AsymmetricCipherKeyPair(
-                new ECPublicKeyParameters(algorithm, q, parameters),
-                new ECPrivateKeyParameters(algorithm, d, parameters));
-        }
-
-        protected virtual ECMultiplier CreateBasePointMultiplier()
-        {
-            return new FixedPointCombMultiplier();
-        }
-
-        internal static ECPublicKeyParameters GetCorrespondingPublicKey(
-            ECPrivateKeyParameters privKey)
-        {
-            ECDomainParameters ec = privKey.Parameters;
-            ECPoint q = new FixedPointCombMultiplier().Multiply(ec.G, privKey.D);
-
-            return new ECPublicKeyParameters(privKey.AlgorithmName, q, ec);
-        }
-    }
-}

+ 0 - 91
src/Renci.SshNet/Security/BouncyCastle/crypto/parameters/ECDomainParameters.cs

@@ -1,91 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC;
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Parameters
-{
-    internal class ECDomainParameters
-    {
-        internal ECCurve     curve;
-        internal byte[]      seed;
-        internal ECPoint     g;
-        internal BigInteger  n;
-        internal BigInteger  h;
-        internal BigInteger  hInv;
-
-        public ECDomainParameters(
-            ECCurve     curve,
-            ECPoint     g,
-            BigInteger  n,
-            BigInteger  h,
-            byte[]      seed)
-        {
-            if (curve == null)
-                throw new ArgumentNullException("curve");
-            if (g == null)
-                throw new ArgumentNullException("g");
-            if (n == null)
-                throw new ArgumentNullException("n");
-            // we can't check for h == null here as h is optional in X9.62 as it is not required for ECDSA
-
-            this.curve = curve;
-            this.g = Validate(curve, g);
-            this.n = n;
-            this.h = h;
-            this.seed = Arrays.Clone(seed);
-        }
-
-        public ECCurve Curve
-        {
-            get { return curve; }
-        }
-
-        public ECPoint G
-        {
-            get { return g; }
-        }
-
-        public BigInteger N
-        {
-            get { return n; }
-        }
-
-        public BigInteger H
-        {
-            get { return h; }
-        }
-
-        public BigInteger HInv
-        {
-            get
-            {
-                lock (this)
-                {
-                    if (hInv == null)
-                    {
-                        hInv = h.ModInverse(n);
-                    }
-                    return hInv;
-                }
-            }
-        }
-
-        internal static ECPoint Validate(ECCurve c, ECPoint q)
-        {
-            if (q == null)
-                throw new ArgumentException("Point has null value", "q");
-
-            q = ECAlgorithms.ImportPoint(c, q).Normalize();
-
-            if (q.IsInfinity)
-                throw new ArgumentException("Point at infinity", "q");
-
-            if (!q.IsValid())
-                throw new ArgumentException("Point not on curve", "q");
-
-            return q;
-        }
-    }
-}

+ 0 - 23
src/Renci.SshNet/Security/BouncyCastle/crypto/parameters/ECKeyGenerationParameters.cs

@@ -1,23 +0,0 @@
-using Renci.SshNet.Security.Org.BouncyCastle.Security;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Parameters
-{
-    internal class ECKeyGenerationParameters
-		: KeyGenerationParameters
-    {
-        private readonly ECDomainParameters domainParams;
-
-		public ECKeyGenerationParameters(
-			ECDomainParameters	domainParameters,
-			SecureRandom		random)
-			: base(random, domainParameters.N.BitLength)
-        {
-            this.domainParams = domainParameters;
-        }
-
-		public ECDomainParameters DomainParameters
-        {
-			get { return domainParams; }
-        }
-    }
-}

+ 0 - 79
src/Renci.SshNet/Security/BouncyCastle/crypto/parameters/ECKeyParameters.cs

@@ -1,79 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Security;
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Parameters
-{
-    internal abstract class ECKeyParameters
-        : AsymmetricKeyParameter
-    {
-        private static readonly string[] algorithms = { "EC", "ECDH" };
-
-        private readonly string algorithm;
-        private readonly ECDomainParameters parameters;
-
-        protected ECKeyParameters(
-            string				algorithm,
-            bool				isPrivate,
-            ECDomainParameters	parameters)
-            : base(isPrivate)
-        {
-            if (algorithm == null)
-                throw new ArgumentNullException("algorithm");
-            if (parameters == null)
-                throw new ArgumentNullException("parameters");
-
-            this.algorithm = VerifyAlgorithmName(algorithm);
-            this.parameters = parameters;
-        }
-
-        public string AlgorithmName
-        {
-            get { return algorithm; }
-        }
-
-        public ECDomainParameters Parameters
-        {
-            get { return parameters; }
-        }
-
-        public override bool Equals(
-            object obj)
-        {
-            if (obj == this)
-                return true;
-
-            ECDomainParameters other = obj as ECDomainParameters;
-
-            if (other == null)
-                return false;
-
-            return Equals(other);
-        }
-
-        protected bool Equals(
-            ECKeyParameters other)
-        {
-            return parameters.Equals(other.parameters) && base.Equals(other);
-        }
-
-        public override int GetHashCode()
-        {
-            return parameters.GetHashCode() ^ base.GetHashCode();
-        }
-
-        internal ECKeyGenerationParameters CreateKeyGenerationParameters(
-            SecureRandom random)
-        {
-            return new ECKeyGenerationParameters(parameters, random);
-        }
-
-        internal static string VerifyAlgorithmName(string algorithm)
-        {
-            if (Array.IndexOf(algorithms, algorithm, 0, algorithms.Length) < 0)
-                throw new ArgumentException("unrecognised algorithm: " + algorithm, "algorithm");
-            return algorithm.ToUpper();
-        }
-    }
-}

+ 0 - 61
src/Renci.SshNet/Security/BouncyCastle/crypto/parameters/ECPrivateKeyParameters.cs

@@ -1,61 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Parameters
-{
-    internal class ECPrivateKeyParameters
-        : ECKeyParameters
-    {
-        private readonly BigInteger d;
-
-        public ECPrivateKeyParameters(
-            BigInteger			d,
-            ECDomainParameters	parameters)
-            : this("EC", d, parameters)
-        {
-        }
-
-        public ECPrivateKeyParameters(
-            string				algorithm,
-            BigInteger			d,
-            ECDomainParameters	parameters)
-            : base(algorithm, true, parameters)
-        {
-            if (d == null)
-                throw new ArgumentNullException("d");
-
-            this.d = d;
-        }
-
-        public BigInteger D
-        {
-            get { return d; }
-        }
-
-        public override bool Equals(
-            object obj)
-        {
-            if (obj == this)
-                return true;
-
-            ECPrivateKeyParameters other = obj as ECPrivateKeyParameters;
-
-            if (other == null)
-                return false;
-
-            return Equals(other);
-        }
-
-        protected bool Equals(
-            ECPrivateKeyParameters other)
-        {
-            return d.Equals(other.d) && base.Equals(other);
-        }
-
-        public override int GetHashCode()
-        {
-            return d.GetHashCode() ^ base.GetHashCode();
-        }
-    }
-}

+ 0 - 60
src/Renci.SshNet/Security/BouncyCastle/crypto/parameters/ECPublicKeyParameters.cs

@@ -1,60 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Parameters
-{
-    internal class ECPublicKeyParameters
-        : ECKeyParameters
-    {
-        private readonly ECPoint q;
-
-        public ECPublicKeyParameters(
-            ECPoint				q,
-            ECDomainParameters	parameters)
-            : this("EC", q, parameters)
-        {
-        }
-
-        public ECPublicKeyParameters(
-            string				algorithm,
-            ECPoint				q,
-            ECDomainParameters	parameters)
-            : base(algorithm, false, parameters)
-        {
-            if (q == null)
-                throw new ArgumentNullException("q");
-
-            this.q = ECDomainParameters.Validate(Parameters.Curve, q);
-        }
-
-        public ECPoint Q
-        {
-            get { return q; }
-        }
-
-        public override bool Equals(object obj)
-        {
-            if (obj == this)
-                return true;
-
-            ECPublicKeyParameters other = obj as ECPublicKeyParameters;
-
-            if (other == null)
-                return false;
-
-            return Equals(other);
-        }
-
-        protected bool Equals(
-            ECPublicKeyParameters other)
-        {
-            return q.Equals(other.q) && base.Equals(other);
-        }
-
-        public override int GetHashCode()
-        {
-            return q.GetHashCode() ^ base.GetHashCode();
-        }
-    }
-}

+ 0 - 59
src/Renci.SshNet/Security/BouncyCastle/crypto/prng/CryptoApiRandomGenerator.cs

@@ -1,59 +0,0 @@
-using System;
-using System.Security.Cryptography;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Prng
-{
-    internal class CryptoApiRandomGenerator
-        : IRandomGenerator
-    {
-        private readonly RandomNumberGenerator rndProv;
-
-        public CryptoApiRandomGenerator()
-            : this(Abstractions.CryptoAbstraction.CreateRandomNumberGenerator())
-        {
-        }
-
-        public CryptoApiRandomGenerator(RandomNumberGenerator rng)
-        {
-            this.rndProv = rng;
-        }
-
-        #region IRandomGenerator Members
-
-        public virtual void AddSeedMaterial(byte[] seed)
-        {
-            // We don't care about the seed
-        }
-
-        public virtual void AddSeedMaterial(long seed)
-        {
-            // We don't care about the seed
-        }
-
-        public virtual void NextBytes(byte[] bytes)
-        {
-            rndProv.GetBytes(bytes);
-        }
-
-        public virtual void NextBytes(byte[] bytes, int start, int len)
-        {
-            if (start < 0)
-                throw new ArgumentException("Start offset cannot be negative", "start");
-            if (bytes.Length < (start + len))
-                throw new ArgumentException("Byte array too small for requested offset and length");
-
-            if (bytes.Length == len && start == 0) 
-            {
-                NextBytes(bytes);
-            }
-            else 
-            {
-                byte[] tmpBuf = new byte[len];
-                NextBytes(tmpBuf);
-                Array.Copy(tmpBuf, 0, bytes, start, len);
-            }
-        }
-
-        #endregion
-    }
-}

+ 0 - 117
src/Renci.SshNet/Security/BouncyCastle/crypto/prng/DigestRandomGenerator.cs

@@ -1,117 +0,0 @@
-using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Prng
-{
-	internal class DigestRandomGenerator
-		: IRandomGenerator
-	{
-		private const long CYCLE_COUNT = 10;
-
-		private long	stateCounter;
-		private long	seedCounter;
-		private IDigest	digest;
-		private byte[]	state;
-		private byte[]	seed;
-
-		public DigestRandomGenerator(
-			IDigest digest)
-		{
-			this.digest = digest;
-
-			this.seed = new byte[digest.GetDigestSize()];
-			this.seedCounter = 1;
-
-			this.state = new byte[digest.GetDigestSize()];
-			this.stateCounter = 1;
-		}
-
-		public void AddSeedMaterial(
-			byte[] inSeed)
-		{
-			lock (this)
-			{
-				DigestUpdate(inSeed);
-				DigestUpdate(seed);
-				DigestDoFinal(seed);
-			}
-		}
-
-		public void AddSeedMaterial(
-			long rSeed)
-		{
-			lock (this)
-			{
-				DigestAddCounter(rSeed);
-				DigestUpdate(seed);
-				DigestDoFinal(seed);
-			}
-		}
-
-		public void NextBytes(
-			byte[] bytes)
-		{
-			NextBytes(bytes, 0, bytes.Length);
-		}
-
-		public void NextBytes(
-			byte[]	bytes,
-			int		start,
-			int		len)
-		{
-			lock (this)
-			{
-				int stateOff = 0;
-
-				GenerateState();
-
-				int end = start + len;
-				for (int i = start; i < end; ++i)
-				{
-					if (stateOff == state.Length)
-					{
-						GenerateState();
-						stateOff = 0;
-					}
-					bytes[i] = state[stateOff++];
-				}
-			}
-		}
-
-		private void CycleSeed()
-		{
-			DigestUpdate(seed);
-			DigestAddCounter(seedCounter++);
-			DigestDoFinal(seed);
-		}
-
-		private void GenerateState()
-		{
-			DigestAddCounter(stateCounter++);
-			DigestUpdate(state);
-			DigestUpdate(seed);
-			DigestDoFinal(state);
-
-			if ((stateCounter % CYCLE_COUNT) == 0)
-			{
-				CycleSeed();
-			}
-		}
-
-		private void DigestAddCounter(long seedVal)
-		{
-            byte[] bytes = new byte[8];
-            Pack.UInt64_To_LE((ulong)seedVal, bytes);
-            digest.BlockUpdate(bytes, 0, bytes.Length);
-		}
-
-        private void DigestUpdate(byte[] inSeed)
-		{
-			digest.BlockUpdate(inSeed, 0, inSeed.Length);
-		}
-
-		private void DigestDoFinal(byte[] result)
-		{
-			digest.DoFinal(result, 0);
-		}
-	}
-}

+ 0 - 26
src/Renci.SshNet/Security/BouncyCastle/crypto/prng/IRandomGenerator.cs

@@ -1,26 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Prng
-{
-	/// <remarks>Generic interface for objects generating random bytes.</remarks>
-	internal interface IRandomGenerator
-	{
-		/// <summary>Add more seed material to the generator.</summary>
-		/// <param name="seed">A byte array to be mixed into the generator's state.</param>
-		void AddSeedMaterial(byte[] seed);
-
-		/// <summary>Add more seed material to the generator.</summary>
-		/// <param name="seed">A long value to be mixed into the generator's state.</param>
-		void AddSeedMaterial(long seed);
-
-		/// <summary>Fill byte array with random values.</summary>
-		/// <param name="bytes">Array to be filled.</param>
-		void NextBytes(byte[] bytes);
-
-		/// <summary>Fill byte array with random values.</summary>
-		/// <param name="bytes">Array to receive bytes.</param>
-		/// <param name="start">Index to start filling at.</param>
-		/// <param name="len">Length of segment to fill.</param>
-		void NextBytes(byte[] bytes, int start, int len);
-	}
-}

+ 0 - 345
src/Renci.SshNet/Security/BouncyCastle/crypto/util/Pack.cs

@@ -1,345 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Utilities
-{
-    internal sealed class Pack
-    {
-        private Pack()
-        {
-        }
-
-        internal static void UInt16_To_BE(ushort n, byte[] bs)
-        {
-            bs[0] = (byte)(n >> 8);
-            bs[1] = (byte)(n);
-        }
-
-        internal static void UInt16_To_BE(ushort n, byte[] bs, int off)
-        {
-            bs[off] = (byte)(n >> 8);
-            bs[off + 1] = (byte)(n);
-        }
-
-        internal static ushort BE_To_UInt16(byte[] bs)
-        {
-            uint n = (uint)bs[0] << 8
-                | (uint)bs[1];
-            return (ushort)n;
-        }
-
-        internal static ushort BE_To_UInt16(byte[] bs, int off)
-        {
-            uint n = (uint)bs[off] << 8
-                | (uint)bs[off + 1];
-            return (ushort)n;
-        }
-
-        internal static byte[] UInt32_To_BE(uint n)
-        {
-            byte[] bs = new byte[4];
-            UInt32_To_BE(n, bs, 0);
-            return bs;
-        }
-
-        internal static void UInt32_To_BE(uint n, byte[] bs)
-        {
-            bs[0] = (byte)(n >> 24);
-            bs[1] = (byte)(n >> 16);
-            bs[2] = (byte)(n >> 8);
-            bs[3] = (byte)(n);
-        }
-
-        internal static void UInt32_To_BE(uint n, byte[] bs, int off)
-        {
-            bs[off] = (byte)(n >> 24);
-            bs[off + 1] = (byte)(n >> 16);
-            bs[off + 2] = (byte)(n >> 8);
-            bs[off + 3] = (byte)(n);
-        }
-
-        internal static byte[] UInt32_To_BE(uint[] ns)
-        {
-            byte[] bs = new byte[4 * ns.Length];
-            UInt32_To_BE(ns, bs, 0);
-            return bs;
-        }
-
-        internal static void UInt32_To_BE(uint[] ns, byte[] bs, int off)
-        {
-            for (int i = 0; i < ns.Length; ++i)
-            {
-                UInt32_To_BE(ns[i], bs, off);
-                off += 4;
-            }
-        }
-
-        internal static uint BE_To_UInt32(byte[] bs)
-        {
-            return (uint)bs[0] << 24
-                | (uint)bs[1] << 16
-                | (uint)bs[2] << 8
-                | (uint)bs[3];
-        }
-
-        internal static uint BE_To_UInt32(byte[] bs, int off)
-        {
-            return (uint)bs[off] << 24
-                | (uint)bs[off + 1] << 16
-                | (uint)bs[off + 2] << 8
-                | (uint)bs[off + 3];
-        }
-
-        internal static void BE_To_UInt32(byte[] bs, int off, uint[] ns)
-        {
-            for (int i = 0; i < ns.Length; ++i)
-            {
-                ns[i] = BE_To_UInt32(bs, off);
-                off += 4;
-            }
-        }
-
-        internal static byte[] UInt64_To_BE(ulong n)
-        {
-            byte[] bs = new byte[8];
-            UInt64_To_BE(n, bs, 0);
-            return bs;
-        }
-
-        internal static void UInt64_To_BE(ulong n, byte[] bs)
-        {
-            UInt32_To_BE((uint)(n >> 32), bs);
-            UInt32_To_BE((uint)(n), bs, 4);
-        }
-
-        internal static void UInt64_To_BE(ulong n, byte[] bs, int off)
-        {
-            UInt32_To_BE((uint)(n >> 32), bs, off);
-            UInt32_To_BE((uint)(n), bs, off + 4);
-        }
-
-        internal static byte[] UInt64_To_BE(ulong[] ns)
-        {
-            byte[] bs = new byte[8 * ns.Length];
-            UInt64_To_BE(ns, bs, 0);
-            return bs;
-        }
-
-        internal static void UInt64_To_BE(ulong[] ns, byte[] bs, int off)
-        {
-            for (int i = 0; i < ns.Length; ++i)
-            {
-                UInt64_To_BE(ns[i], bs, off);
-                off += 8;
-            }
-        }
-
-        internal static ulong BE_To_UInt64(byte[] bs)
-        {
-            uint hi = BE_To_UInt32(bs);
-            uint lo = BE_To_UInt32(bs, 4);
-            return ((ulong)hi << 32) | (ulong)lo;
-        }
-
-        internal static ulong BE_To_UInt64(byte[] bs, int off)
-        {
-            uint hi = BE_To_UInt32(bs, off);
-            uint lo = BE_To_UInt32(bs, off + 4);
-            return ((ulong)hi << 32) | (ulong)lo;
-        }
-
-        internal static void BE_To_UInt64(byte[] bs, int off, ulong[] ns)
-        {
-            for (int i = 0; i < ns.Length; ++i)
-            {
-                ns[i] = BE_To_UInt64(bs, off);
-                off += 8;
-            }
-        }
-
-        internal static void UInt16_To_LE(ushort n, byte[] bs)
-        {
-            bs[0] = (byte)(n);
-            bs[1] = (byte)(n >> 8);
-        }
-
-        internal static void UInt16_To_LE(ushort n, byte[] bs, int off)
-        {
-            bs[off] = (byte)(n);
-            bs[off + 1] = (byte)(n >> 8);
-        }
-
-        internal static ushort LE_To_UInt16(byte[] bs)
-        {
-            uint n = (uint)bs[0]
-                | (uint)bs[1] << 8;
-            return (ushort)n;
-        }
-
-        internal static ushort LE_To_UInt16(byte[] bs, int off)
-        {
-            uint n = (uint)bs[off]
-                | (uint)bs[off + 1] << 8;
-            return (ushort)n;
-        }
-
-        internal static byte[] UInt32_To_LE(uint n)
-        {
-            byte[] bs = new byte[4];
-            UInt32_To_LE(n, bs, 0);
-            return bs;
-        }
-
-        internal static void UInt32_To_LE(uint n, byte[] bs)
-        {
-            bs[0] = (byte)(n);
-            bs[1] = (byte)(n >> 8);
-            bs[2] = (byte)(n >> 16);
-            bs[3] = (byte)(n >> 24);
-        }
-
-        internal static void UInt32_To_LE(uint n, byte[] bs, int off)
-        {
-            bs[off] = (byte)(n);
-            bs[off + 1] = (byte)(n >> 8);
-            bs[off + 2] = (byte)(n >> 16);
-            bs[off + 3] = (byte)(n >> 24);
-        }
-
-        internal static byte[] UInt32_To_LE(uint[] ns)
-        {
-            byte[] bs = new byte[4 * ns.Length];
-            UInt32_To_LE(ns, bs, 0);
-            return bs;
-        }
-
-        internal static void UInt32_To_LE(uint[] ns, byte[] bs, int off)
-        {
-            for (int i = 0; i < ns.Length; ++i)
-            {
-                UInt32_To_LE(ns[i], bs, off);
-                off += 4;
-            }
-        }
-
-        internal static uint LE_To_UInt32(byte[] bs)
-        {
-            return (uint)bs[0]
-                | (uint)bs[1] << 8
-                | (uint)bs[2] << 16
-                | (uint)bs[3] << 24;
-        }
-
-        internal static uint LE_To_UInt32(byte[] bs, int off)
-        {
-            return (uint)bs[off]
-                | (uint)bs[off + 1] << 8
-                | (uint)bs[off + 2] << 16
-                | (uint)bs[off + 3] << 24;
-        }
-
-        internal static void LE_To_UInt32(byte[] bs, int off, uint[] ns)
-        {
-            for (int i = 0; i < ns.Length; ++i)
-            {
-                ns[i] = LE_To_UInt32(bs, off);
-                off += 4;
-            }
-        }
-
-        internal static void LE_To_UInt32(byte[] bs, int bOff, uint[] ns, int nOff, int count)
-        {
-            for (int i = 0; i < count; ++i)
-            {
-                ns[nOff + i] = LE_To_UInt32(bs, bOff);
-                bOff += 4;
-            }
-        }
-
-        internal static uint[] LE_To_UInt32(byte[] bs, int off, int count)
-        {
-            uint[] ns = new uint[count];
-            for (int i = 0; i < ns.Length; ++i)
-            {
-                ns[i] = LE_To_UInt32(bs, off);
-                off += 4;
-            }
-            return ns;
-        }
-
-        internal static byte[] UInt64_To_LE(ulong n)
-        {
-            byte[] bs = new byte[8];
-            UInt64_To_LE(n, bs, 0);
-            return bs;
-        }
-
-        internal static void UInt64_To_LE(ulong n, byte[] bs)
-        {
-            UInt32_To_LE((uint)(n), bs);
-            UInt32_To_LE((uint)(n >> 32), bs, 4);
-        }
-
-        internal static void UInt64_To_LE(ulong n, byte[] bs, int off)
-        {
-            UInt32_To_LE((uint)(n), bs, off);
-            UInt32_To_LE((uint)(n >> 32), bs, off + 4);
-        }
-
-        internal static byte[] UInt64_To_LE(ulong[] ns)
-        {
-            byte[] bs = new byte[8 * ns.Length];
-            UInt64_To_LE(ns, bs, 0);
-            return bs;
-        }
-
-        internal static void UInt64_To_LE(ulong[] ns, byte[] bs, int off)
-        {
-            for (int i = 0; i < ns.Length; ++i)
-            {
-                UInt64_To_LE(ns[i], bs, off);
-                off += 8;
-            }
-        }
-
-        internal static void UInt64_To_LE(ulong[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
-        {
-            for (int i = 0; i < nsLen; ++i)
-            {
-                UInt64_To_LE(ns[nsOff + i], bs, bsOff);
-                bsOff += 8;
-            }
-        }
-
-        internal static ulong LE_To_UInt64(byte[] bs)
-        {
-            uint lo = LE_To_UInt32(bs);
-            uint hi = LE_To_UInt32(bs, 4);
-            return ((ulong)hi << 32) | (ulong)lo;
-        }
-
-        internal static ulong LE_To_UInt64(byte[] bs, int off)
-        {
-            uint lo = LE_To_UInt32(bs, off);
-            uint hi = LE_To_UInt32(bs, off + 4);
-            return ((ulong)hi << 32) | (ulong)lo;
-        }
-
-        internal static void LE_To_UInt64(byte[] bs, int off, ulong[] ns)
-        {
-            for (int i = 0; i < ns.Length; ++i)
-            {
-                ns[i] = LE_To_UInt64(bs, off);
-                off += 8;
-            }
-        }
-
-        internal static void LE_To_UInt64(byte[] bs, int bsOff, ulong[] ns, int nsOff, int nsLen)
-        {
-            for (int i = 0; i < nsLen; ++i)
-            {
-                ns[nsOff + i] = LE_To_UInt64(bs, bsOff);
-                bsOff += 8;
-            }
-        }
-    }
-}

+ 0 - 3605
src/Renci.SshNet/Security/BouncyCastle/math/BigInteger.cs

@@ -1,3605 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.Text;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Security;
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math
-{
-#if NETFRAMEWORK
-    [Serializable]
-#endif
-    internal class BigInteger
-    {
-        // The first few odd primes
-        /*
-                3   5   7   11  13  17  19  23  29
-            31  37  41  43  47  53  59  61  67  71
-            73  79  83  89  97  101 103 107 109 113
-            127 131 137 139 149 151 157 163 167 173
-            179 181 191 193 197 199 211 223 227 229
-            233 239 241 251 257 263 269 271 277 281
-            283 293 307 311 313 317 331 337 347 349
-            353 359 367 373 379 383 389 397 401 409
-            419 421 431 433 439 443 449 457 461 463
-            467 479 487 491 499 503 509 521 523 541
-            547 557 563 569 571 577 587 593 599 601
-            607 613 617 619 631 641 643 647 653 659
-            661 673 677 683 691 701 709 719 727 733
-            739 743 751 757 761 769 773 787 797 809
-            811 821 823 827 829 839 853 857 859 863
-            877 881 883 887 907 911 919 929 937 941
-            947 953 967 971 977 983 991 997 1009
-            1013 1019 1021 1031 1033 1039 1049 1051
-            1061 1063 1069 1087 1091 1093 1097 1103
-            1109 1117 1123 1129 1151 1153 1163 1171
-            1181 1187 1193 1201 1213 1217 1223 1229
-            1231 1237 1249 1259 1277 1279 1283 1289
-        */
-
-        // Each list has a product < 2^31
-        internal static readonly int[][] primeLists = new int[][]
-        {
-            new int[]{ 3, 5, 7, 11, 13, 17, 19, 23 },
-            new int[]{ 29, 31, 37, 41, 43 },
-            new int[]{ 47, 53, 59, 61, 67 },
-            new int[]{ 71, 73, 79, 83 },
-            new int[]{ 89, 97, 101, 103 },
-
-            new int[]{ 107, 109, 113, 127 },
-            new int[]{ 131, 137, 139, 149 },
-            new int[]{ 151, 157, 163, 167 },
-            new int[]{ 173, 179, 181, 191 },
-            new int[]{ 193, 197, 199, 211 },
-
-            new int[]{ 223, 227, 229 },
-            new int[]{ 233, 239, 241 },
-            new int[]{ 251, 257, 263 },
-            new int[]{ 269, 271, 277 },
-            new int[]{ 281, 283, 293 },
-
-            new int[]{ 307, 311, 313 },
-            new int[]{ 317, 331, 337 },
-            new int[]{ 347, 349, 353 },
-            new int[]{ 359, 367, 373 },
-            new int[]{ 379, 383, 389 },
-
-            new int[]{ 397, 401, 409 },
-            new int[]{ 419, 421, 431 },
-            new int[]{ 433, 439, 443 },
-            new int[]{ 449, 457, 461 },
-            new int[]{ 463, 467, 479 },
-
-            new int[]{ 487, 491, 499 },
-            new int[]{ 503, 509, 521 },
-            new int[]{ 523, 541, 547 },
-            new int[]{ 557, 563, 569 },
-            new int[]{ 571, 577, 587 },
-
-            new int[]{ 593, 599, 601 },
-            new int[]{ 607, 613, 617 },
-            new int[]{ 619, 631, 641 },
-            new int[]{ 643, 647, 653 },
-            new int[]{ 659, 661, 673 },
-
-            new int[]{ 677, 683, 691 },
-            new int[]{ 701, 709, 719 },
-            new int[]{ 727, 733, 739 },
-            new int[]{ 743, 751, 757 },
-            new int[]{ 761, 769, 773 },
-
-            new int[]{ 787, 797, 809 },
-            new int[]{ 811, 821, 823 },
-            new int[]{ 827, 829, 839 },
-            new int[]{ 853, 857, 859 },
-            new int[]{ 863, 877, 881 },
-
-            new int[]{ 883, 887, 907 },
-            new int[]{ 911, 919, 929 },
-            new int[]{ 937, 941, 947 },
-            new int[]{ 953, 967, 971 },
-            new int[]{ 977, 983, 991 },
-
-            new int[]{ 997, 1009, 1013 },
-            new int[]{ 1019, 1021, 1031 },
-            new int[]{ 1033, 1039, 1049 },
-            new int[]{ 1051, 1061, 1063 },
-            new int[]{ 1069, 1087, 1091 },
-
-            new int[]{ 1093, 1097, 1103 },
-            new int[]{ 1109, 1117, 1123 },
-            new int[]{ 1129, 1151, 1153 },
-            new int[]{ 1163, 1171, 1181 },
-            new int[]{ 1187, 1193, 1201 },
-
-            new int[]{ 1213, 1217, 1223 },
-            new int[]{ 1229, 1231, 1237 },
-            new int[]{ 1249, 1259, 1277 },
-            new int[]{ 1279, 1283, 1289 },
-        };
-
-        internal static readonly int[] primeProducts;
-
-        private const long IMASK = 0xFFFFFFFFL;
-        private const ulong UIMASK = 0xFFFFFFFFUL;
-
-        private static readonly int[] ZeroMagnitude = new int[0];
-        private static readonly byte[] ZeroEncoding = new byte[0];
-
-        private static readonly BigInteger[] SMALL_CONSTANTS = new BigInteger[17];
-        public static readonly BigInteger Zero;
-        public static readonly BigInteger One;
-        public static readonly BigInteger Two;
-        public static readonly BigInteger Three;
-        public static readonly BigInteger Ten;
-
-        //private readonly static byte[] BitCountTable =
-        //{
-        //    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
-        //    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-        //    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-        //    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-        //    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-        //    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-        //    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-        //    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-        //    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-        //    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-        //    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-        //    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-        //    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-        //    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-        //    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-        //    4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
-        //};
-
-        private readonly static byte[] BitLengthTable =
-        {
-            0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
-        };
-
-        // TODO Parse radix-2 64 bits at a time and radix-8 63 bits at a time
-        private const int chunk2 = 1, chunk8 = 1, chunk10 = 19, chunk16 = 16;
-        private static readonly BigInteger radix2, radix2E, radix8, radix8E, radix10, radix10E, radix16, radix16E;
-
-        private static readonly SecureRandom RandomSource = new SecureRandom();
-
-        /*
-         * These are the threshold bit-lengths (of an exponent) where we increase the window size.
-         * They are calculated according to the expected savings in multiplications.
-         * Some squares will also be saved on average, but we offset these against the extra storage costs.
-         */
-        private static readonly int[] ExpWindowThresholds = { 7, 25, 81, 241, 673, 1793, 4609, Int32.MaxValue };
-
-        private const int BitsPerByte = 8;
-        private const int BitsPerInt = 32;
-        private const int BytesPerInt = 4;
-
-        static BigInteger()
-        {
-            Zero = new BigInteger(0, ZeroMagnitude, false);
-            Zero.nBits = 0; Zero.nBitLength = 0;
-
-            SMALL_CONSTANTS[0] = Zero;
-            for (uint i = 1; i < SMALL_CONSTANTS.Length; ++i)
-            {
-                SMALL_CONSTANTS[i] = CreateUValueOf(i);
-            }
-
-            One = SMALL_CONSTANTS[1];
-            Two = SMALL_CONSTANTS[2];
-            Three = SMALL_CONSTANTS[3];
-            Ten = SMALL_CONSTANTS[10];
-
-            radix2 = ValueOf(2);
-            radix2E = radix2.Pow(chunk2);
-
-            radix8 = ValueOf(8);
-            radix8E = radix8.Pow(chunk8);
-
-            radix10 = ValueOf(10);
-            radix10E = radix10.Pow(chunk10);
-
-            radix16 = ValueOf(16);
-            radix16E = radix16.Pow(chunk16);
-
-            primeProducts = new int[primeLists.Length];
-
-            for (int i = 0; i < primeLists.Length; ++i)
-            {
-                int[] primeList = primeLists[i];
-                int product = primeList[0];
-                for (int j = 1; j < primeList.Length; ++j)
-                {
-                    product *= primeList[j];
-                }
-                primeProducts[i] = product;
-            }
-        }
-
-        private int[] magnitude; // array of ints with [0] being the most significant
-        private int sign; // -1 means -ve; +1 means +ve; 0 means 0;
-        private int nBits = -1; // cache BitCount() value
-        private int nBitLength = -1; // cache BitLength() value
-        private int mQuote = 0; // -m^(-1) mod b, b = 2^32 (see Montgomery mult.), 0 when uninitialised
-
-        private static int GetByteLength(
-            int nBits)
-        {
-            return (nBits + BitsPerByte - 1) / BitsPerByte;
-        }
-
-        internal static BigInteger Arbitrary(int sizeInBits)
-        {
-            return new BigInteger(sizeInBits, RandomSource);
-        }
-
-        private BigInteger(
-            int		signum,
-            int[]	mag,
-            bool	checkMag)
-        {
-            if (checkMag)
-            {
-                int i = 0;
-                while (i < mag.Length && mag[i] == 0)
-                {
-                    ++i;
-                }
-
-                if (i == mag.Length)
-                {
-                    this.sign = 0;
-                    this.magnitude = ZeroMagnitude;
-                }
-                else
-                {
-                    this.sign = signum;
-
-                    if (i == 0)
-                    {
-                        this.magnitude = mag;
-                    }
-                    else
-                    {
-                        // strip leading 0 words
-                        this.magnitude = new int[mag.Length - i];
-                        Array.Copy(mag, i, this.magnitude, 0, this.magnitude.Length);
-                    }
-                }
-            }
-            else
-            {
-                this.sign = signum;
-                this.magnitude = mag;
-            }
-        }
-
-        public BigInteger(
-            string value)
-            : this(value, 10)
-        {
-        }
-
-        public BigInteger(
-            string	str,
-            int		radix)
-        {
-            if (str.Length == 0)
-                throw new FormatException("Zero length BigInteger");
-
-            NumberStyles style;
-            int chunk;
-            BigInteger r;
-            BigInteger rE;
-
-            switch (radix)
-            {
-                case 2:
-                    // Is there anyway to restrict to binary digits?
-                    style = NumberStyles.Integer;
-                    chunk = chunk2;
-                    r = radix2;
-                    rE = radix2E;
-                    break;
-                case 8:
-                    // Is there anyway to restrict to octal digits?
-                    style = NumberStyles.Integer;
-                    chunk = chunk8;
-                    r = radix8;
-                    rE = radix8E;
-                    break;
-                case 10:
-                    // This style seems to handle spaces and minus sign already (our processing redundant?)
-                    style = NumberStyles.Integer;
-                    chunk = chunk10;
-                    r = radix10;
-                    rE = radix10E;
-                    break;
-                case 16:
-                    // TODO Should this be HexNumber?
-                    style = NumberStyles.AllowHexSpecifier;
-                    chunk = chunk16;
-                    r = radix16;
-                    rE = radix16E;
-                    break;
-                default:
-                    throw new FormatException("Only bases 2, 8, 10, or 16 allowed");
-            }
-
-
-            int index = 0;
-            sign = 1;
-
-            if (str[0] == '-')
-            {
-                if (str.Length == 1)
-                    throw new FormatException("Zero length BigInteger");
-
-                sign = -1;
-                index = 1;
-            }
-
-            // strip leading zeros from the string str
-            while (index < str.Length && Int32.Parse(str[index].ToString(), style) == 0)
-            {
-                index++;
-            }
-
-            if (index >= str.Length)
-            {
-                // zero value - we're done
-                sign = 0;
-                magnitude = ZeroMagnitude;
-                return;
-            }
-
-            //////
-            // could we work out the max number of ints required to store
-            // str.Length digits in the given base, then allocate that
-            // storage in one hit?, then Generate the magnitude in one hit too?
-            //////
-
-            BigInteger b = Zero;
-
-
-            int next = index + chunk;
-
-            if (next <= str.Length)
-            {
-                do
-                {
-                    string s = str.Substring(index, chunk);
-                    ulong i = ulong.Parse(s, style);
-                    BigInteger bi = CreateUValueOf(i);
-
-                    switch (radix)
-                    {
-                        case 2:
-                            // TODO Need this because we are parsing in radix 10 above
-                            if (i >= 2)
-                                throw new FormatException("Bad character in radix 2 string: " + s);
-
-                            // TODO Parse 64 bits at a time
-                            b = b.ShiftLeft(1);
-                            break;
-                        case 8:
-                            // TODO Need this because we are parsing in radix 10 above
-                            if (i >= 8)
-                                throw new FormatException("Bad character in radix 8 string: " + s);
-
-                            // TODO Parse 63 bits at a time
-                            b = b.ShiftLeft(3);
-                            break;
-                        case 16:
-                            b = b.ShiftLeft(64);
-                            break;
-                        default:
-                            b = b.Multiply(rE);
-                            break;
-                    }
-
-                    b = b.Add(bi);
-
-                    index = next;
-                    next += chunk;
-                }
-                while (next <= str.Length);
-            }
-
-            if (index < str.Length)
-            {
-                string s = str.Substring(index);
-                ulong i = ulong.Parse(s, style);
-                BigInteger bi = CreateUValueOf(i);
-
-                if (b.sign > 0)
-                {
-                    if (radix == 2)
-                    {
-                        // NB: Can't reach here since we are parsing one char at a time
-                        Debug.Assert(false);
-
-                        // TODO Parse all bits at once
-//						b = b.ShiftLeft(s.Length);
-                    }
-                    else if (radix == 8)
-                    {
-                        // NB: Can't reach here since we are parsing one char at a time
-                        Debug.Assert(false);
-
-                        // TODO Parse all bits at once
-//						b = b.ShiftLeft(s.Length * 3);
-                    }
-                    else if (radix == 16)
-                    {
-                        b = b.ShiftLeft(s.Length << 2);
-                    }
-                    else
-                    {
-                        b = b.Multiply(r.Pow(s.Length));
-                    }
-
-                    b = b.Add(bi);
-                }
-                else
-                {
-                    b = bi;
-                }
-            }
-
-            // Note: This is the previous (slower) algorithm
-//			while (index < value.Length)
-//            {
-//				char c = value[index];
-//				string s = c.ToString();
-//				int i = Int32.Parse(s, style);
-//
-//                b = b.Multiply(r).Add(ValueOf(i));
-//                index++;
-//            }
-
-            magnitude = b.magnitude;
-        }
-
-        public BigInteger(
-            byte[] bytes)
-            : this(bytes, 0, bytes.Length)
-        {
-        }
-
-        public BigInteger(
-            byte[]	bytes,
-            int		offset,
-            int		length)
-        {
-            if (length == 0)
-                throw new FormatException("Zero length BigInteger");
-
-            // TODO Move this processing into MakeMagnitude (provide sign argument)
-            if ((sbyte)bytes[offset] < 0)
-            {
-                this.sign = -1;
-
-                int end = offset + length;
-
-                int iBval;
-                // strip leading sign bytes
-                for (iBval = offset; iBval < end && ((sbyte)bytes[iBval] == -1); iBval++)
-                {
-                }
-
-                if (iBval >= end)
-                {
-                    this.magnitude = One.magnitude;
-                }
-                else
-                {
-                    int numBytes = end - iBval;
-                    byte[] inverse = new byte[numBytes];
-
-                    int index = 0;
-                    while (index < numBytes)
-                    {
-                        inverse[index++] = (byte)~bytes[iBval++];
-                    }
-
-                    Debug.Assert(iBval == end);
-
-                    while (inverse[--index] == byte.MaxValue)
-                    {
-                        inverse[index] = byte.MinValue;
-                    }
-
-                    inverse[index]++;
-
-                    this.magnitude = MakeMagnitude(inverse, 0, inverse.Length);
-                }
-            }
-            else
-            {
-                // strip leading zero bytes and return magnitude bytes
-                this.magnitude = MakeMagnitude(bytes, offset, length);
-                this.sign = this.magnitude.Length > 0 ? 1 : 0;
-            }
-        }
-
-        private static int[] MakeMagnitude(
-            byte[]	bytes,
-            int		offset,
-            int		length)
-        {
-            int end = offset + length;
-
-            // strip leading zeros
-            int firstSignificant;
-            for (firstSignificant = offset; firstSignificant < end
-                && bytes[firstSignificant] == 0; firstSignificant++)
-            {
-            }
-
-            if (firstSignificant >= end)
-            {
-                return ZeroMagnitude;
-            }
-
-            int nInts = (end - firstSignificant + 3) / BytesPerInt;
-            int bCount = (end - firstSignificant) % BytesPerInt;
-            if (bCount == 0)
-            {
-                bCount = BytesPerInt;
-            }
-
-            if (nInts < 1)
-            {
-                return ZeroMagnitude;
-            }
-
-            int[] mag = new int[nInts];
-
-            int v = 0;
-            int magnitudeIndex = 0;
-            for (int i = firstSignificant; i < end; ++i)
-            {
-                v <<= 8;
-                v |= bytes[i] & 0xff;
-                bCount--;
-                if (bCount <= 0)
-                {
-                    mag[magnitudeIndex] = v;
-                    magnitudeIndex++;
-                    bCount = BytesPerInt;
-                    v = 0;
-                }
-            }
-
-            if (magnitudeIndex < mag.Length)
-            {
-                mag[magnitudeIndex] = v;
-            }
-
-            return mag;
-        }
-
-        public BigInteger(
-            int		sign,
-            byte[]	bytes)
-            : this(sign, bytes, 0, bytes.Length)
-        {
-        }
-
-        public BigInteger(
-            int		sign,
-            byte[]	bytes,
-            int		offset,
-            int		length)
-        {
-            if (sign < -1 || sign > 1)
-                throw new FormatException("Invalid sign value");
-
-            if (sign == 0)
-            {
-                this.sign = 0;
-                this.magnitude = ZeroMagnitude;
-            }
-            else
-            {
-                // copy bytes
-                this.magnitude = MakeMagnitude(bytes, offset, length);
-                this.sign = this.magnitude.Length < 1 ? 0 : sign;
-            }
-        }
-
-        public BigInteger(
-            int		sizeInBits,
-            Random	random)
-        {
-            if (sizeInBits < 0)
-                throw new ArgumentException("sizeInBits must be non-negative");
-
-            this.nBits = -1;
-            this.nBitLength = -1;
-
-            if (sizeInBits == 0)
-            {
-                this.sign = 0;
-                this.magnitude = ZeroMagnitude;
-                return;
-            }
-
-            int nBytes = GetByteLength(sizeInBits);
-            byte[] b = new byte[nBytes];
-#pragma warning disable CA5394 // Do not use insecure randomness
-            random.NextBytes(b);
-#pragma warning restore CA5394 // Do not use insecure randomness
-
-            // strip off any excess bits in the MSB
-            int xBits = BitsPerByte * nBytes - sizeInBits;
-            b[0] &= (byte)(255U >> xBits);
-
-            this.magnitude = MakeMagnitude(b, 0, b.Length);
-            this.sign = this.magnitude.Length < 1 ? 0 : 1;
-        }
-
-#pragma warning disable CA5394 // Do not use insecure randomness
-        public BigInteger(
-            int		bitLength,
-            int		certainty,
-            Random	random)
-        {
-            if (bitLength < 2)
-                throw new ArithmeticException("bitLength < 2");
-
-            this.sign = 1;
-            this.nBitLength = bitLength;
-
-            if (bitLength == 2)
-            {
-                this.magnitude = random.Next(2) == 0
-                    ?	Two.magnitude
-                    :	Three.magnitude;
-                return;
-            }
-             
-            int nBytes = GetByteLength(bitLength);
-            byte[] b = new byte[nBytes];
-
-            int xBits = BitsPerByte * nBytes - bitLength;
-            byte mask = (byte)(255U >> xBits);
-            byte lead = (byte)(1 << (7 - xBits));
-
-            for (;;)
-            {
-                random.NextBytes(b);
-
-                // strip off any excess bits in the MSB
-                b[0] &= mask;
-
-                // ensure the leading bit is 1 (to meet the strength requirement)
-                b[0] |= lead;
-
-                // ensure the trailing bit is 1 (i.e. must be odd)
-                b[nBytes - 1] |= 1;
-
-                this.magnitude = MakeMagnitude(b, 0, b.Length);
-                this.nBits = -1;
-                this.mQuote = 0;
-
-                if (certainty < 1)
-                    break;
-
-                if (CheckProbablePrime(certainty, random, true))
-                    break;
-
-                for (int j = 1; j < (magnitude.Length - 1); ++j)
-                {
-                    this.magnitude[j] ^= random.Next();
-
-                    if (CheckProbablePrime(certainty, random, true))
-                        return;
-                }
-            }
-        }
-#pragma warning restore CA5394 // Do not use insecure randomness
-
-        public BigInteger Abs()
-        {
-            return sign >= 0 ? this : Negate();
-        }
-
-        /**
-         * return a = a + b - b preserved.
-         */
-        private static int[] AddMagnitudes(
-            int[] a,
-            int[] b)
-        {
-            int tI = a.Length - 1;
-            int vI = b.Length - 1;
-            long m = 0;
-
-            while (vI >= 0)
-            {
-                m += ((long)(uint)a[tI] + (long)(uint)b[vI--]);
-                a[tI--] = (int)m;
-                m = (long)((ulong)m >> 32);
-            }
-
-            if (m != 0)
-            {
-                while (tI >= 0 && ++a[tI--] == 0)
-                {
-                }
-            }
-
-            return a;
-        }
-
-        public BigInteger Add(
-            BigInteger value)
-        {
-            if (this.sign == 0)
-                return value;
-
-            if (this.sign != value.sign)
-            {
-                if (value.sign == 0)
-                    return this;
-
-                if (value.sign < 0)
-                    return Subtract(value.Negate());
-
-                return value.Subtract(Negate());
-            }
-
-            return AddToMagnitude(value.magnitude);
-        }
-
-        private BigInteger AddToMagnitude(
-            int[] magToAdd)
-        {
-            int[] big, small;
-            if (this.magnitude.Length < magToAdd.Length)
-            {
-                big = magToAdd;
-                small = this.magnitude;
-            }
-            else
-            {
-                big = this.magnitude;
-                small = magToAdd;
-            }
-
-            // Conservatively avoid over-allocation when no overflow possible
-            uint limit = uint.MaxValue;
-            if (big.Length == small.Length)
-                limit -= (uint) small[0];
-
-            bool possibleOverflow = (uint) big[0] >= limit;
-
-            int[] bigCopy;
-            if (possibleOverflow)
-            {
-                bigCopy = new int[big.Length + 1];
-                big.CopyTo(bigCopy, 1);
-            }
-            else
-            {
-                bigCopy = (int[]) big.Clone();
-            }
-
-            bigCopy = AddMagnitudes(bigCopy, small);
-
-            return new BigInteger(this.sign, bigCopy, possibleOverflow);
-        }
-
-        public BigInteger And(
-            BigInteger value)
-        {
-            if (this.sign == 0 || value.sign == 0)
-            {
-                return Zero;
-            }
-
-            int[] aMag = this.sign > 0
-                ? this.magnitude
-                : Add(One).magnitude;
-
-            int[] bMag = value.sign > 0
-                ? value.magnitude
-                : value.Add(One).magnitude;
-
-            bool resultNeg = sign < 0 && value.sign < 0;
-            int resultLength = System.Math.Max(aMag.Length, bMag.Length);
-            int[] resultMag = new int[resultLength];
-
-            int aStart = resultMag.Length - aMag.Length;
-            int bStart = resultMag.Length - bMag.Length;
-
-            for (int i = 0; i < resultMag.Length; ++i)
-            {
-                int aWord = i >= aStart ? aMag[i - aStart] : 0;
-                int bWord = i >= bStart ? bMag[i - bStart] : 0;
-
-                if (this.sign < 0)
-                {
-                    aWord = ~aWord;
-                }
-
-                if (value.sign < 0)
-                {
-                    bWord = ~bWord;
-                }
-
-                resultMag[i] = aWord & bWord;
-
-                if (resultNeg)
-                {
-                    resultMag[i] = ~resultMag[i];
-                }
-            }
-
-            BigInteger result = new BigInteger(1, resultMag, true);
-
-            // TODO Optimise this case
-            if (resultNeg)
-            {
-                result = result.Not();
-            }
-
-            return result;
-        }
-
-        public BigInteger AndNot(
-            BigInteger val)
-        {
-            return And(val.Not());
-        }
-
-        public int BitCount
-        {
-            get
-            {
-                if (nBits == -1)
-                {
-                    if (sign < 0)
-                    {
-                        // TODO Optimise this case
-                        nBits = Not().BitCount;
-                    }
-                    else
-                    {
-                        int sum = 0;
-                        for (int i = 0; i < magnitude.Length; ++i)
-                        {
-                            sum += BitCnt(magnitude[i]);
-                        }
-                        nBits = sum;
-                    }
-                }
-
-                return nBits;
-            }
-        }
-
-        public static int BitCnt(int i)
-        {
-            uint u = (uint)i;
-            u = u - ((u >> 1) & 0x55555555);
-            u = (u & 0x33333333) + ((u >> 2) & 0x33333333);
-            u = (u + (u >> 4)) & 0x0f0f0f0f;
-            u += (u >> 8);
-            u += (u >> 16);
-            u &= 0x3f;
-            return (int)u;
-        }
-
-        private static int CalcBitLength(int sign, int indx, int[]	mag)
-        {
-            for (;;)
-            {
-                if (indx >= mag.Length)
-                    return 0;
-
-                if (mag[indx] != 0)
-                    break;
-
-                ++indx;
-            }
-
-            // bit length for everything after the first int
-            int bitLength = 32 * ((mag.Length - indx) - 1);
-
-            // and determine bitlength of first int
-            int firstMag = mag[indx];
-            bitLength += BitLen(firstMag);
-
-            // Check for negative powers of two
-            if (sign < 0 && ((firstMag & -firstMag) == firstMag))
-            {
-                do
-                {
-                    if (++indx >= mag.Length)
-                    {
-                        --bitLength;
-                        break;
-                    }
-                }
-                while (mag[indx] == 0);
-            }
-
-            return bitLength;
-        }
-
-        public int BitLength
-        {
-            get
-            {
-                if (nBitLength == -1)
-                {
-                    nBitLength = sign == 0
-                        ? 0
-                        : CalcBitLength(sign, 0, magnitude);
-                }
-
-                return nBitLength;
-            }
-        }
-
-        //
-        // BitLen(value) is the number of bits in value.
-        //
-        internal static int BitLen(int w)
-        {
-            uint v = (uint)w;
-            uint t = v >> 24;
-            if (t != 0)
-                return 24 + BitLengthTable[t];
-            t = v >> 16;
-            if (t != 0)
-                return 16 + BitLengthTable[t];
-            t = v >> 8;
-            if (t != 0)
-                return 8 + BitLengthTable[t];
-            return BitLengthTable[v];
-        }
-
-        private bool QuickPow2Check()
-        {
-            return sign > 0 && nBits == 1;
-        }
-
-        public int CompareTo(
-            object obj)
-        {
-            return CompareTo((BigInteger)obj);
-        }
-
-        /**
-         * unsigned comparison on two arrays - note the arrays may
-         * start with leading zeros.
-         */
-        private static int CompareTo(
-            int		xIndx,
-            int[]	x,
-            int		yIndx,
-            int[]	y)
-        {
-            while (xIndx != x.Length && x[xIndx] == 0)
-            {
-                xIndx++;
-            }
-
-            while (yIndx != y.Length && y[yIndx] == 0)
-            {
-                yIndx++;
-            }
-
-            return CompareNoLeadingZeroes(xIndx, x, yIndx, y);
-        }
-
-        private static int CompareNoLeadingZeroes(
-            int		xIndx,
-            int[]	x,
-            int		yIndx,
-            int[]	y)
-        {
-            int diff = (x.Length - y.Length) - (xIndx - yIndx);
-
-            if (diff != 0)
-            {
-                return diff < 0 ? -1 : 1;
-            }
-
-            // lengths of magnitudes the same, test the magnitude values
-
-            while (xIndx < x.Length)
-            {
-                uint v1 = (uint)x[xIndx++];
-                uint v2 = (uint)y[yIndx++];
-
-                if (v1 != v2)
-                    return v1 < v2 ? -1 : 1;
-            }
-
-            return 0;
-        }
-
-        public int CompareTo(
-            BigInteger value)
-        {
-            return sign < value.sign ? -1
-                : sign > value.sign ? 1
-                : sign == 0 ? 0
-                : sign * CompareNoLeadingZeroes(0, magnitude, 0, value.magnitude);
-        }
-
-        /**
-         * return z = x / y - done in place (z value preserved, x contains the
-         * remainder)
-         */
-        private int[] Divide(
-            int[]	x,
-            int[]	y)
-        {
-            int xStart = 0;
-            while (xStart < x.Length && x[xStart] == 0)
-            {
-                ++xStart;
-            }
-
-            int yStart = 0;
-            while (yStart < y.Length && y[yStart] == 0)
-            {
-                ++yStart;
-            }
-
-            Debug.Assert(yStart < y.Length);
-
-            int xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y);
-            int[] count;
-
-            if (xyCmp > 0)
-            {
-                int yBitLength = CalcBitLength(1, yStart, y);
-                int xBitLength = CalcBitLength(1, xStart, x);
-                int shift = xBitLength - yBitLength;
-
-                int[] iCount;
-                int iCountStart = 0;
-
-                int[] c;
-                int cStart = 0;
-                int cBitLength = yBitLength;
-                if (shift > 0)
-                {
-//					iCount = ShiftLeft(One.magnitude, shift);
-                    iCount = new int[(shift >> 5) + 1];
-                    iCount[0] = 1 << (shift % 32);
-
-                    c = ShiftLeft(y, shift);
-                    cBitLength += shift;
-                }
-                else
-                {
-                    iCount = new int[] { 1 };
-
-                    int len = y.Length - yStart;
-                    c = new int[len];
-                    Array.Copy(y, yStart, c, 0, len);
-                }
-
-                count = new int[iCount.Length];
-
-                for (;;)
-                {
-                    if (cBitLength < xBitLength
-                        || CompareNoLeadingZeroes(xStart, x, cStart, c) >= 0)
-                    {
-                        Subtract(xStart, x, cStart, c);
-                        AddMagnitudes(count, iCount);
-
-                        while (x[xStart] == 0)
-                        {
-                            if (++xStart == x.Length)
-                                return count;
-                        }
-
-                        //xBitLength = CalcBitLength(xStart, x);
-                        xBitLength = 32 * (x.Length - xStart - 1) + BitLen(x[xStart]);
-
-                        if (xBitLength <= yBitLength)
-                        {
-                            if (xBitLength < yBitLength)
-                                return count;
-
-                            xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y);
-
-                            if (xyCmp <= 0)
-                                break;
-                        }
-                    }
-
-                    shift = cBitLength - xBitLength;
-
-                    // NB: The case where c[cStart] is 1-bit is harmless
-                    if (shift == 1)
-                    {
-                        uint firstC = (uint) c[cStart] >> 1;
-                        uint firstX = (uint) x[xStart];
-                        if (firstC > firstX)
-                            ++shift;
-                    }
-
-                    if (shift < 2)
-                    {
-                        ShiftRightOneInPlace(cStart, c);
-                        --cBitLength;
-                        ShiftRightOneInPlace(iCountStart, iCount);
-                    }
-                    else
-                    {
-                        ShiftRightInPlace(cStart, c, shift);
-                        cBitLength -= shift;
-                        ShiftRightInPlace(iCountStart, iCount, shift);
-                    }
-
-                    //cStart = c.Length - ((cBitLength + 31) / 32);
-                    while (c[cStart] == 0)
-                    {
-                        ++cStart;
-                    }
-
-                    while (iCount[iCountStart] == 0)
-                    {
-                        ++iCountStart;
-                    }
-                }
-            }
-            else
-            {
-                count = new int[1];
-            }
-
-            if (xyCmp == 0)
-            {
-                AddMagnitudes(count, One.magnitude);
-                Array.Clear(x, xStart, x.Length - xStart);
-            }
-
-            return count;
-        }
-
-        public BigInteger Divide(
-            BigInteger val)
-        {
-            if (val.sign == 0)
-                throw new ArithmeticException("Division by zero error");
-
-            if (sign == 0)
-                return Zero;
-
-            if (val.QuickPow2Check()) // val is power of two
-            {
-                BigInteger result = this.Abs().ShiftRight(val.Abs().BitLength - 1);
-                return val.sign == this.sign ? result : result.Negate();
-            }
-
-            int[] mag = (int[]) this.magnitude.Clone();
-
-            return new BigInteger(this.sign * val.sign, Divide(mag, val.magnitude), true);
-        }
-
-        public BigInteger[] DivideAndRemainder(
-            BigInteger val)
-        {
-            if (val.sign == 0)
-                throw new ArithmeticException("Division by zero error");
-
-            BigInteger[] biggies = new BigInteger[2];
-
-            if (sign == 0)
-            {
-                biggies[0] = Zero;
-                biggies[1] = Zero;
-            }
-            else if (val.QuickPow2Check()) // val is power of two
-            {
-                int e = val.Abs().BitLength - 1;
-                BigInteger quotient = this.Abs().ShiftRight(e);
-                int[] remainder = this.LastNBits(e);
-
-                biggies[0] = val.sign == this.sign ? quotient : quotient.Negate();
-                biggies[1] = new BigInteger(this.sign, remainder, true);
-            }
-            else
-            {
-                int[] remainder = (int[]) this.magnitude.Clone();
-                int[] quotient = Divide(remainder, val.magnitude);
-
-                biggies[0] = new BigInteger(this.sign * val.sign, quotient, true);
-                biggies[1] = new BigInteger(this.sign, remainder, true);
-            }
-
-            return biggies;
-        }
-
-        public override bool Equals(
-            object obj)
-        {
-            if (obj == this)
-                return true;
-
-            BigInteger biggie = obj as BigInteger;
-            if (biggie == null)
-                return false;
-
-            return sign == biggie.sign && IsEqualMagnitude(biggie);
-        }
-
-        private bool IsEqualMagnitude(BigInteger x)
-        {
-            int[] xMag = x.magnitude;
-            if (magnitude.Length != x.magnitude.Length)
-                return false;
-            for (int i = 0; i < magnitude.Length; i++)
-            {
-                if (magnitude[i] != x.magnitude[i])
-                    return false;
-            }
-            return true;
-        }
-
-        public BigInteger Gcd(
-            BigInteger value)
-        {
-            if (value.sign == 0)
-                return Abs();
-
-            if (sign == 0)
-                return value.Abs();
-
-            BigInteger r;
-            BigInteger u = this;
-            BigInteger v = value;
-
-            while (v.sign != 0)
-            {
-                r = u.Mod(v);
-                u = v;
-                v = r;
-            }
-
-            return u;
-        }
-
-        public override int GetHashCode()
-        {
-            int hc = magnitude.Length;
-            if (magnitude.Length > 0)
-            {
-                hc ^= magnitude[0];
-
-                if (magnitude.Length > 1)
-                {
-                    hc ^= magnitude[magnitude.Length - 1];
-                }
-            }
-
-            return sign < 0 ? ~hc : hc;
-        }
-
-        // TODO Make public?
-        private BigInteger Inc()
-        {
-            if (this.sign == 0)
-                return One;
-
-            if (this.sign < 0)
-                return new BigInteger(-1, doSubBigLil(this.magnitude, One.magnitude), true);
-
-            return AddToMagnitude(One.magnitude);
-        }
-
-        public int IntValue
-        {
-            get
-            {
-                if (sign == 0)
-                    return 0;
-
-                int n = magnitude.Length;
-
-                int v = magnitude[n - 1];
-
-                return sign < 0 ? -v : v;
-            }
-        }
-
-        /**
-         * return whether or not a BigInteger is probably prime with a
-         * probability of 1 - (1/2)**certainty.
-         * <p>From Knuth Vol 2, pg 395.</p>
-         */
-        public bool IsProbablePrime(int certainty)
-        {
-            return IsProbablePrime(certainty, false);
-        }
-
-        internal bool IsProbablePrime(int certainty, bool randomlySelected)
-        {
-            if (certainty <= 0)
-                return true;
-
-            BigInteger n = Abs();
-
-            if (!n.TestBit(0))
-                return n.Equals(Two);
-
-            if (n.Equals(One))
-                return false;
-
-            return n.CheckProbablePrime(certainty, RandomSource, randomlySelected);
-        }
-
-        private bool CheckProbablePrime(int certainty, Random random, bool randomlySelected)
-        {
-            Debug.Assert(certainty > 0);
-            Debug.Assert(CompareTo(Two) > 0);
-            Debug.Assert(TestBit(0));
-
-
-            // Try to reduce the penalty for really small numbers
-            int numLists = System.Math.Min(BitLength - 1, primeLists.Length);
-
-            for (int i = 0; i < numLists; ++i)
-            {
-                int test = Remainder(primeProducts[i]);
-
-                int[] primeList = primeLists[i];
-                for (int j = 0; j < primeList.Length; ++j)
-                {
-                    int prime = primeList[j];
-                    int qRem = test % prime;
-                    if (qRem == 0)
-                    {
-                        // We may find small numbers in the list
-                        return BitLength < 16 && IntValue == prime;
-                    }
-                }
-            }
-
-
-            // TODO Special case for < 10^16 (RabinMiller fixed list)
-//			if (BitLength < 30)
-//			{
-//				RabinMiller against 2, 3, 5, 7, 11, 13, 23 is sufficient
-//			}
-
-
-            // TODO Is it worth trying to create a hybrid of these two?
-            return RabinMillerTest(certainty, random, randomlySelected);
-//			return SolovayStrassenTest(certainty, random);
-
-//			bool rbTest = RabinMillerTest(certainty, random);
-//			bool ssTest = SolovayStrassenTest(certainty, random);
-//
-//			Debug.Assert(rbTest == ssTest);
-//
-//			return rbTest;
-        }
-
-        public bool RabinMillerTest(int certainty, Random random)
-        {
-            return RabinMillerTest(certainty, random, false);
-        }
-
-        internal bool RabinMillerTest(int certainty, Random random, bool randomlySelected)
-        {
-            int bits = BitLength;
-
-            Debug.Assert(certainty > 0);
-            Debug.Assert(bits > 2);
-            Debug.Assert(TestBit(0));
-
-            int iterations = ((certainty - 1) / 2) + 1;
-            if (randomlySelected)
-            {
-                int itersFor100Cert = bits >= 1024 ?  4
-                                    : bits >= 512  ?  8
-                                    : bits >= 256  ? 16
-                                    : 50;
-
-                if (certainty < 100)
-                {
-                    iterations = System.Math.Min(itersFor100Cert, iterations);
-                }
-                else
-                {
-                    iterations -= 50;
-                    iterations += itersFor100Cert;
-                }
-            }
-
-            // let n = 1 + d . 2^s
-            BigInteger n = this;
-            int s = n.GetLowestSetBitMaskFirst(-1 << 1);
-            Debug.Assert(s >= 1);
-            BigInteger r = n.ShiftRight(s);
-
-            // NOTE: Avoid conversion to/from Montgomery form and check for R/-R as result instead
-
-            BigInteger montRadix = One.ShiftLeft(32 * n.magnitude.Length).Remainder(n);
-            BigInteger minusMontRadix = n.Subtract(montRadix);
-
-            do
-            {
-                BigInteger a;
-                do
-                {
-                    a = new BigInteger(n.BitLength, random);
-                }
-                while (a.sign == 0 || a.CompareTo(n) >= 0
-                    || a.IsEqualMagnitude(montRadix) || a.IsEqualMagnitude(minusMontRadix));
-
-                BigInteger y = ModPowMonty(a, r, n, false);
-
-                if (!y.Equals(montRadix))
-                {
-                    int j = 0;
-                    while (!y.Equals(minusMontRadix))
-                    {
-                        if (++j == s)
-                            return false;
-
-                        y = ModPowMonty(y, Two, n, false);
-
-                        if (y.Equals(montRadix))
-                            return false;
-                    }
-                }
-            }
-            while (--iterations > 0);
-
-            return true;
-        }
-
-//		private bool SolovayStrassenTest(
-//			int		certainty,
-//			Random	random)
-//		{
-//			Debug.Assert(certainty > 0);
-//			Debug.Assert(CompareTo(Two) > 0);
-//			Debug.Assert(TestBit(0));
-//
-//			BigInteger n = this;
-//			BigInteger nMinusOne = n.Subtract(One);
-//			BigInteger e = nMinusOne.ShiftRight(1);
-//
-//			do
-//			{
-//				BigInteger a;
-//				do
-//				{
-//					a = new BigInteger(nBitLength, random);
-//				}
-//				// NB: Spec says 0 < x < n, but 1 is trivial
-//				while (a.CompareTo(One) <= 0 || a.CompareTo(n) >= 0);
-//
-//
-//				// TODO Check this is redundant given the way Jacobi() works?
-////				if (!a.Gcd(n).Equals(One))
-////					return false;
-//
-//				int x = Jacobi(a, n);
-//
-//				if (x == 0)
-//					return false;
-//
-//				BigInteger check = a.ModPow(e, n);
-//
-//				if (x == 1 && !check.Equals(One))
-//					return false;
-//
-//				if (x == -1 && !check.Equals(nMinusOne))
-//					return false;
-//
-//				--certainty;
-//			}
-//			while (certainty > 0);
-//
-//			return true;
-//		}
-//
-//		private static int Jacobi(
-//			BigInteger	a,
-//			BigInteger	b)
-//		{
-//			Debug.Assert(a.sign >= 0);
-//			Debug.Assert(b.sign > 0);
-//			Debug.Assert(b.TestBit(0));
-//			Debug.Assert(a.CompareTo(b) < 0);
-//
-//			int totalS = 1;
-//			for (;;)
-//			{
-//				if (a.sign == 0)
-//					return 0;
-//
-//				if (a.Equals(One))
-//					break;
-//
-//				int e = a.GetLowestSetBit();
-//
-//				int bLsw = b.magnitude[b.magnitude.Length - 1];
-//				if ((e & 1) != 0 && ((bLsw & 7) == 3 || (bLsw & 7) == 5))
-//					totalS = -totalS;
-//
-//				// TODO Confirm this is faster than later a1.Equals(One) test
-//				if (a.BitLength == e + 1)
-//					break;
-//				BigInteger a1 = a.ShiftRight(e);
-////				if (a1.Equals(One))
-////					break;
-//
-//				int a1Lsw = a1.magnitude[a1.magnitude.Length - 1];
-//				if ((bLsw & 3) == 3 && (a1Lsw & 3) == 3)
-//					totalS = -totalS;
-//
-////				a = b.Mod(a1);
-//				a = b.Remainder(a1);
-//				b = a1;
-//			}
-//			return totalS;
-//		}
-
-        public long LongValue
-        {
-            get
-            {
-                if (sign == 0)
-                    return 0;
-
-                int n = magnitude.Length;
-
-                long v = magnitude[n - 1] & IMASK;
-                if (n > 1)
-                {
-                    v |= (magnitude[n - 2] & IMASK) << 32;
-                }
-
-                return sign < 0 ? -v : v;
-            }
-        }
-
-        public BigInteger Max(
-            BigInteger value)
-        {
-            return CompareTo(value) > 0 ? this : value;
-        }
-
-        public BigInteger Min(
-            BigInteger value)
-        {
-            return CompareTo(value) < 0 ? this : value;
-        }
-
-        public BigInteger Mod(
-            BigInteger m)
-        {
-            if (m.sign < 1)
-                throw new ArithmeticException("Modulus must be positive");
-
-            BigInteger biggie = Remainder(m);
-
-            return (biggie.sign >= 0 ? biggie : biggie.Add(m));
-        }
-
-        public BigInteger ModInverse(
-            BigInteger m)
-        {
-            if (m.sign < 1)
-                throw new ArithmeticException("Modulus must be positive");
-
-            // TODO Too slow at the moment
-//			// "Fast Key Exchange with Elliptic Curve Systems" R.Schoeppel
-//			if (m.TestBit(0))
-//			{
-//				//The Almost Inverse Algorithm
-//				int k = 0;
-//				BigInteger B = One, C = Zero, F = this, G = m, tmp;
-//
-//				for (;;)
-//				{
-//					// While F is even, do F=F/u, C=C*u, k=k+1.
-//					int zeroes = F.GetLowestSetBit();
-//					if (zeroes > 0)
-//					{
-//						F = F.ShiftRight(zeroes);
-//						C = C.ShiftLeft(zeroes);
-//						k += zeroes;
-//					}
-//
-//					// If F = 1, then return B,k.
-//					if (F.Equals(One))
-//					{
-//						BigInteger half = m.Add(One).ShiftRight(1);
-//						BigInteger halfK = half.ModPow(BigInteger.ValueOf(k), m);
-//						return B.Multiply(halfK).Mod(m);
-//					}
-//
-//					if (F.CompareTo(G) < 0)
-//					{
-//						tmp = G; G = F; F = tmp;
-//						tmp = B; B = C; C = tmp;
-//					}
-//
-//					F = F.Add(G);
-//					B = B.Add(C);
-//				}
-//			}
-
-            if (m.QuickPow2Check())
-            {
-                return ModInversePow2(m);
-            }
-
-            BigInteger d = this.Remainder(m);
-            BigInteger x;
-            BigInteger gcd = ExtEuclid(d, m, out x);
-
-            if (!gcd.Equals(One))
-                throw new ArithmeticException("Numbers not relatively prime.");
-
-            if (x.sign < 0)
-            {
-                x = x.Add(m);
-            }
-
-            return x;
-        }
-
-        private BigInteger ModInversePow2(BigInteger m)
-        {
-            Debug.Assert(m.SignValue > 0);
-            Debug.Assert(m.BitCount == 1);
-
-            if (!TestBit(0))
-            {
-                throw new ArithmeticException("Numbers not relatively prime.");
-            }
-
-            int pow = m.BitLength - 1;
-
-            long inv64 = ModInverse64(LongValue);
-            if (pow < 64)
-            {
-                inv64 &= ((1L << pow) - 1);
-            }
-
-            BigInteger x = BigInteger.ValueOf(inv64);
-
-            if (pow > 64)
-            {
-                BigInteger d = this.Remainder(m);
-                int bitsCorrect = 64;
-
-                do
-                {
-                    BigInteger t = x.Multiply(d).Remainder(m);
-                    x = x.Multiply(Two.Subtract(t)).Remainder(m);
-                    bitsCorrect <<= 1;
-                }
-                while (bitsCorrect < pow);
-            }
-
-            if (x.sign < 0)
-            {
-                x = x.Add(m);
-            }
-
-            return x;
-        }
-
-        private static int ModInverse32(int d)
-        {
-            // Newton's method with initial estimate "correct to 4 bits"
-            Debug.Assert((d & 1) != 0);
-            int x = d + (((d + 1) & 4) << 1);   // d.x == 1 mod 2**4
-            Debug.Assert(((d * x) & 15) == 1);
-            x *= 2 - d * x;                     // d.x == 1 mod 2**8
-            x *= 2 - d * x;                     // d.x == 1 mod 2**16
-            x *= 2 - d * x;                     // d.x == 1 mod 2**32
-            Debug.Assert(d * x == 1);
-            return x;
-        }
-
-        private static long ModInverse64(long d)
-        {
-            // Newton's method with initial estimate "correct to 4 bits"
-            Debug.Assert((d & 1L) != 0);
-            long x = d + (((d + 1L) & 4L) << 1);    // d.x == 1 mod 2**4
-            Debug.Assert(((d * x) & 15L) == 1L);
-            x *= 2 - d * x;                         // d.x == 1 mod 2**8
-            x *= 2 - d * x;                         // d.x == 1 mod 2**16
-            x *= 2 - d * x;                         // d.x == 1 mod 2**32
-            x *= 2 - d * x;                         // d.x == 1 mod 2**64
-            Debug.Assert(d * x == 1L);
-            return x;
-        }
-
-        /**
-         * Calculate the numbers u1, u2, and u3 such that:
-         *
-         * u1 * a + u2 * b = u3
-         *
-         * where u3 is the greatest common divider of a and b.
-         * a and b using the extended Euclid algorithm (refer p. 323
-         * of The Art of Computer Programming vol 2, 2nd ed).
-         * This also seems to have the side effect of calculating
-         * some form of multiplicative inverse.
-         *
-         * @param a    First number to calculate gcd for
-         * @param b    Second number to calculate gcd for
-         * @param u1Out      the return object for the u1 value
-         * @return     The greatest common divisor of a and b
-         */
-        private static BigInteger ExtEuclid(BigInteger a, BigInteger b, out BigInteger u1Out)
-        {
-            BigInteger u1 = One, v1 = Zero;
-            BigInteger u3 = a, v3 = b;
-
-            if (v3.sign > 0)
-            {
-                for (;;)
-                {
-                    BigInteger[] q = u3.DivideAndRemainder(v3);
-                    u3 = v3;
-                    v3 = q[1];
-
-                    BigInteger oldU1 = u1;
-                    u1 = v1;
-
-                    if (v3.sign <= 0)
-                        break;
-
-                    v1 = oldU1.Subtract(v1.Multiply(q[0]));
-                }
-            }
-
-            u1Out = u1;
-
-            return u3;
-        }
-
-        private static void ZeroOut(
-            int[] x)
-        {
-            Array.Clear(x, 0, x.Length);
-        }
-
-        public BigInteger ModPow(BigInteger e, BigInteger m)
-        {
-            if (m.sign < 1)
-                throw new ArithmeticException("Modulus must be positive");
-
-            if (m.Equals(One))
-                return Zero;
-
-            if (e.sign == 0)
-                return One;
-
-            if (sign == 0)
-                return Zero;
-
-            bool negExp = e.sign < 0;
-            if (negExp)
-                e = e.Negate();
-
-            BigInteger result = this.Mod(m);
-            if (!e.Equals(One))
-            {
-                if ((m.magnitude[m.magnitude.Length - 1] & 1) == 0)
-                {
-                    result = ModPowBarrett(result, e, m);
-                }
-                else
-                {
-                    result = ModPowMonty(result, e, m, true);
-                }
-            }
-
-            if (negExp)
-                result = result.ModInverse(m);
-
-            return result;
-        }
-
-        private static BigInteger ModPowBarrett(BigInteger b, BigInteger e, BigInteger m)
-        {
-            int k = m.magnitude.Length;
-            BigInteger mr = One.ShiftLeft((k + 1) << 5);
-            BigInteger yu = One.ShiftLeft(k << 6).Divide(m);
-
-            // Sliding window from MSW to LSW
-            int extraBits = 0, expLength = e.BitLength;
-            while (expLength > ExpWindowThresholds[extraBits])
-            {
-                ++extraBits;
-            }
-
-            int numPowers = 1 << extraBits;
-            BigInteger[] oddPowers = new BigInteger[numPowers];
-            oddPowers[0] = b;
-
-            BigInteger b2 = ReduceBarrett(b.Square(), m, mr, yu);
-
-            for (int i = 1; i < numPowers; ++i)
-            {
-                oddPowers[i] = ReduceBarrett(oddPowers[i - 1].Multiply(b2), m, mr, yu);
-            }
-
-            int[] windowList = GetWindowList(e.magnitude, extraBits);
-            Debug.Assert(windowList.Length > 0);
-
-            int window = windowList[0];
-            int mult = window & 0xFF, lastZeroes = window >> 8;
-
-            BigInteger y;
-            if (mult == 1)
-            {
-                y = b2;
-                --lastZeroes;
-            }
-            else
-            {
-                y = oddPowers[mult >> 1];
-            }
-
-            int windowPos = 1;
-            while ((window = windowList[windowPos++]) != -1)
-            {
-                mult = window & 0xFF;
-
-                int bits = lastZeroes + BitLengthTable[mult];
-                for (int j = 0; j < bits; ++j)
-                {
-                    y = ReduceBarrett(y.Square(), m, mr, yu);
-                }
-
-                y = ReduceBarrett(y.Multiply(oddPowers[mult >> 1]), m, mr, yu);
-
-                lastZeroes = window >> 8;
-            }
-
-            for (int i = 0; i < lastZeroes; ++i)
-            {
-                y = ReduceBarrett(y.Square(), m, mr, yu);
-            }
-
-            return y;
-        }
-
-        private static BigInteger ReduceBarrett(BigInteger x, BigInteger m, BigInteger mr, BigInteger yu)
-        {
-            int xLen = x.BitLength, mLen = m.BitLength;
-            if (xLen < mLen)
-                return x;
-
-            if (xLen - mLen > 1)
-            {
-                int k = m.magnitude.Length;
-
-                BigInteger q1 = x.DivideWords(k - 1);
-                BigInteger q2 = q1.Multiply(yu); // TODO Only need partial multiplication here
-                BigInteger q3 = q2.DivideWords(k + 1);
-
-                BigInteger r1 = x.RemainderWords(k + 1);
-                BigInteger r2 = q3.Multiply(m); // TODO Only need partial multiplication here
-                BigInteger r3 = r2.RemainderWords(k + 1);
-
-                x = r1.Subtract(r3);
-                if (x.sign < 0)
-                {
-                    x = x.Add(mr);
-                }
-            }
-
-            while (x.CompareTo(m) >= 0)
-            {
-                x = x.Subtract(m);
-            }
-
-            return x;
-        }
-
-        private static BigInteger ModPowMonty(BigInteger b, BigInteger e, BigInteger m, bool convert)
-        {
-            int n = m.magnitude.Length;
-            int powR = 32 * n;
-            bool smallMontyModulus = m.BitLength + 2 <= powR;
-            uint mDash = (uint)m.GetMQuote();
-
-            // tmp = this * R mod m
-            if (convert)
-            {
-                b = b.ShiftLeft(powR).Remainder(m);
-            }
-
-            int[] yAccum = new int[n + 1];
-
-            int[] zVal = b.magnitude;
-            Debug.Assert(zVal.Length <= n);
-            if (zVal.Length < n)
-            {
-                int[] tmp = new int[n];
-                zVal.CopyTo(tmp, n - zVal.Length);
-                zVal = tmp;
-            }
-
-            // Sliding window from MSW to LSW
-
-            int extraBits = 0;
-
-            // Filter the common case of small RSA exponents with few bits set
-            if (e.magnitude.Length > 1 || e.BitCount > 2)
-            {
-                int expLength = e.BitLength;
-                while (expLength > ExpWindowThresholds[extraBits])
-                {
-                    ++extraBits;
-                }
-            }
-
-            int numPowers = 1 << extraBits;
-            int[][] oddPowers = new int[numPowers][];
-            oddPowers[0] = zVal;
-
-            int[] zSquared = Arrays.Clone(zVal);
-            SquareMonty(yAccum, zSquared, m.magnitude, mDash, smallMontyModulus);
-
-            for (int i = 1; i < numPowers; ++i)
-            {
-                oddPowers[i] = Arrays.Clone(oddPowers[i - 1]);
-                MultiplyMonty(yAccum, oddPowers[i], zSquared, m.magnitude, mDash, smallMontyModulus);
-            }
-
-            int[] windowList = GetWindowList(e.magnitude, extraBits);
-            Debug.Assert(windowList.Length > 1);
-
-            int window = windowList[0];
-            int mult = window & 0xFF, lastZeroes = window >> 8;
-
-            int[] yVal;
-            if (mult == 1)
-            {
-                yVal = zSquared;
-                --lastZeroes;
-            }
-            else
-            {
-                yVal = Arrays.Clone(oddPowers[mult >> 1]);
-            }
-
-            int windowPos = 1;
-            while ((window = windowList[windowPos++]) != -1)
-            {
-                mult = window & 0xFF;
-
-                int bits = lastZeroes + BitLengthTable[mult];
-                for (int j = 0; j < bits; ++j)
-                {
-                    SquareMonty(yAccum, yVal, m.magnitude, mDash, smallMontyModulus);
-                }
-
-                MultiplyMonty(yAccum, yVal, oddPowers[mult >> 1], m.magnitude, mDash, smallMontyModulus);
-
-                lastZeroes = window >> 8;
-            }
-
-            for (int i = 0; i < lastZeroes; ++i)
-            {
-                SquareMonty(yAccum, yVal, m.magnitude, mDash, smallMontyModulus);
-            }
-
-            if (convert)
-            {
-                // Return y * R^(-1) mod m
-                MontgomeryReduce(yVal, m.magnitude, mDash);
-            }
-            else if (smallMontyModulus && CompareTo(0, yVal, 0, m.magnitude) >= 0)
-            {
-                Subtract(0, yVal, 0, m.magnitude);
-            }
-
-            return new BigInteger(1, yVal, true);
-        }
-
-        private static int[] GetWindowList(int[] mag, int extraBits)
-        {
-            int v = mag[0];
-            Debug.Assert(v != 0);
-
-            int leadingBits = BitLen(v);
-
-            int resultSize = (((mag.Length - 1) << 5) + leadingBits) / (1 + extraBits) + 2;
-            int[] result = new int[resultSize];
-            int resultPos = 0;
-
-            int bitPos = 33 - leadingBits;
-            v <<= bitPos;
-
-            int mult = 1, multLimit = 1 << extraBits;
-            int zeroes = 0;
-
-            int i = 0;
-            for (; ; )
-            {
-                for (; bitPos < 32; ++bitPos)
-                {
-                    if (mult < multLimit)
-                    {
-                        mult = (mult << 1) | (int)((uint)v >> 31);
-                    }
-                    else if (v < 0)
-                    {
-                        result[resultPos++] = CreateWindowEntry(mult, zeroes);
-                        mult = 1;
-                        zeroes = 0;
-                    }
-                    else
-                    {
-                        ++zeroes;
-                    }
-
-                    v <<= 1;
-                }
-
-                if (++i == mag.Length)
-                {
-                    result[resultPos++] = CreateWindowEntry(mult, zeroes);
-                    break;
-                }
-
-                v = mag[i];
-                bitPos = 0;
-            }
-
-            result[resultPos] = -1;
-            return result;
-        }
-
-        private static int CreateWindowEntry(int mult, int zeroes)
-        {
-            while ((mult & 1) == 0)
-            {
-                mult >>= 1;
-                ++zeroes;
-            }
-
-            return mult | (zeroes << 8);
-        }
-
-        /**
-         * return w with w = x * x - w is assumed to have enough space.
-         */
-        private static int[] Square(
-            int[]	w,
-            int[]	x)
-        {
-            // Note: this method allows w to be only (2 * x.Length - 1) words if result will fit
-//			if (w.Length != 2 * x.Length)
-//				throw new ArgumentException("no I don't think so...");
-
-            ulong c;
-
-            int wBase = w.Length - 1;
-
-            for (int i = x.Length - 1; i > 0; --i)
-            {
-                ulong v = (uint)x[i];
-
-                c = v * v + (uint)w[wBase];
-                w[wBase] = (int)c;
-                c >>= 32;
-
-                for (int j = i - 1; j >= 0; --j)
-                {
-                    ulong prod = v * (uint)x[j];
-
-                    c += ((uint)w[--wBase] & UIMASK) + ((uint)prod << 1);
-                    w[wBase] = (int)c;
-                    c = (c >> 32) + (prod >> 31);
-                }
-
-                c += (uint)w[--wBase];
-                w[wBase] = (int)c;
-
-                if (--wBase >= 0)
-                {
-                    w[wBase] = (int)(c >> 32);
-                }
-                else
-                {
-                    Debug.Assert((c >> 32) == 0);
-                }
-
-                wBase += i;
-            }
-
-            c = (uint)x[0];
-
-            c = c * c + (uint)w[wBase];
-            w[wBase] = (int)c;
-
-            if (--wBase >= 0)
-            {
-                w[wBase] += (int)(c >> 32);
-            }
-            else
-            {
-                Debug.Assert((c >> 32) == 0);
-            }
-
-            return w;
-        }
-
-        /**
-         * return x with x = y * z - x is assumed to have enough space.
-         */
-        private static int[] Multiply(int[]	x, int[] y, int[] z)
-        {
-            int i = z.Length;
-
-            if (i < 1)
-                return x;
-
-            int xBase = x.Length - y.Length;
-
-            do
-            {
-                long a = z[--i] & IMASK;
-                long val = 0;
-
-                if (a != 0)
-                {
-                    for (int j = y.Length - 1; j >= 0; j--)
-                    {
-                        val += a * (y[j] & IMASK) + (x[xBase + j] & IMASK);
-    
-                        x[xBase + j] = (int)val;
-    
-                        val = (long)((ulong)val >> 32);
-                    }
-                }
-
-                --xBase;
-
-                if (xBase >= 0)
-                {
-                    x[xBase] = (int)val;
-                }
-                else
-                {
-                    Debug.Assert(val == 0);
-                }
-            }
-            while (i > 0);
-
-            return x;
-        }
-
-        /**
-         * Calculate mQuote = -m^(-1) mod b with b = 2^32 (32 = word size)
-         */
-        private int GetMQuote()
-        {
-            if (mQuote != 0)
-            {
-                return mQuote; // already calculated
-            }
-
-            Debug.Assert(this.sign > 0);
-
-            int d = -magnitude[magnitude.Length - 1];
-
-            Debug.Assert((d & 1) != 0);
-
-            return mQuote = ModInverse32(d);
-        }
-
-        private static void MontgomeryReduce(int[] x, int[] m, uint mDash) // mDash = -m^(-1) mod b
-        {
-            // NOTE: Not a general purpose reduction (which would allow x up to twice the bitlength of m)
-            Debug.Assert(x.Length == m.Length);
-
-            int n = m.Length;
-
-            for (int i = n - 1; i >= 0; --i)
-            {
-                uint x0 = (uint)x[n - 1];
-                ulong t = x0 * mDash;
-
-                ulong carry = t * (uint)m[n - 1] + x0;
-                Debug.Assert((uint)carry == 0);
-                carry >>= 32;
-
-                for (int j = n - 2; j >= 0; --j)
-                {
-                    carry += t * (uint)m[j] + (uint)x[j];
-                    x[j + 1] = (int)carry;
-                    carry >>= 32;
-                }
-
-                x[0] = (int)carry;
-                Debug.Assert(carry >> 32 == 0);
-            }
-
-            if (CompareTo(0, x, 0, m) >= 0)
-            {
-                Subtract(0, x, 0, m);
-            }
-        }
-
-        /**
-         * Montgomery multiplication: a = x * y * R^(-1) mod m
-         * <br/>
-         * Based algorithm 14.36 of Handbook of Applied Cryptography.
-         * <br/>
-         * <li> m, x, y should have length n </li>
-         * <li> a should have length (n + 1) </li>
-         * <li> b = 2^32, R = b^n </li>
-         * <br/>
-         * The result is put in x
-         * <br/>
-         * NOTE: the indices of x, y, m, a different in HAC and in Java
-         */
-        private static void MultiplyMonty(int[]	a, int[] x, int[] y, int[] m, uint mDash, bool smallMontyModulus)
-            // mDash = -m^(-1) mod b
-        {
-            int n = m.Length;
-
-            if (n == 1)
-            {
-                x[0] = (int)MultiplyMontyNIsOne((uint)x[0], (uint)y[0], (uint)m[0], mDash);
-                return;
-            }
-
-            uint y0 = (uint)y[n - 1];
-            int aMax;
-
-            {
-                ulong xi = (uint)x[n - 1];
-
-                ulong carry = xi * y0;
-                ulong t = (uint)carry * mDash;
-
-                ulong prod2 = t * (uint)m[n - 1];
-                carry += (uint)prod2;
-                Debug.Assert((uint)carry == 0);
-                carry = (carry >> 32) + (prod2 >> 32);
-
-                for (int j = n - 2; j >= 0; --j)
-                {
-                    ulong prod1 = xi * (uint)y[j];
-                    prod2 = t * (uint)m[j];
-
-                    carry += (prod1 & UIMASK) + (uint)prod2;
-                    a[j + 2] = (int)carry;
-                    carry = (carry >> 32) + (prod1 >> 32) + (prod2 >> 32);
-                }
-
-                a[1] = (int)carry;
-                aMax = (int)(carry >> 32);
-            }
-
-            for (int i = n - 2; i >= 0; --i)
-            {
-                uint a0 = (uint)a[n];
-                ulong xi = (uint)x[i];
-
-                ulong prod1 = xi * y0;
-                ulong carry = (prod1 & UIMASK) + a0;
-                ulong t = (uint)carry * mDash;
-
-                ulong prod2 = t * (uint)m[n - 1];
-                carry += (uint)prod2;
-                Debug.Assert((uint)carry == 0);
-                carry = (carry >> 32) + (prod1 >> 32) + (prod2 >> 32);
-
-                for (int j = n - 2; j >= 0; --j)
-                {
-                    prod1 = xi * (uint)y[j];
-                    prod2 = t * (uint)m[j];
-
-                    carry += (prod1 & UIMASK) + (uint)prod2 + (uint)a[j + 1];
-                    a[j + 2] = (int)carry;
-                    carry = (carry >> 32) + (prod1 >> 32) + (prod2 >> 32);
-                }
-
-                carry += (uint)aMax;
-                a[1] = (int)carry;
-                aMax = (int)(carry >> 32);
-            }
-
-            a[0] = aMax;
-
-            if (!smallMontyModulus && CompareTo(0, a, 0, m) >= 0)
-            {
-                Subtract(0, a, 0, m);
-            }
-
-            Array.Copy(a, 1, x, 0, n);
-        }
-
-        private static void SquareMonty(int[] a, int[] x, int[] m, uint mDash, bool smallMontyModulus)
-            // mDash = -m^(-1) mod b
-        {
-            int n = m.Length;
-
-            if (n == 1)
-            {
-                uint xVal = (uint)x[0];
-                x[0] = (int)MultiplyMontyNIsOne(xVal, xVal, (uint)m[0], mDash);
-                return;
-            }
-
-            ulong x0 = (uint)x[n - 1];
-            int aMax;
-
-            {
-                ulong carry = x0 * x0;
-                ulong t = (uint)carry * mDash;
-
-                ulong prod2 = t * (uint)m[n - 1];
-                carry += (uint)prod2;
-                Debug.Assert((uint)carry == 0);
-                carry = (carry >> 32) + (prod2 >> 32);
-
-                for (int j = n - 2; j >= 0; --j)
-                {
-                    ulong prod1 = x0 * (uint)x[j];
-                    prod2 = t * (uint)m[j];
-
-                    carry += (prod2 & UIMASK) + ((uint)prod1 << 1);
-                    a[j + 2] = (int)carry;
-                    carry = (carry >> 32) + (prod1 >> 31) + (prod2 >> 32);
-                }
-
-                a[1] = (int)carry;
-                aMax = (int)(carry >> 32);
-            }
-
-            for (int i = n - 2; i >= 0; --i)
-            {
-                uint a0 = (uint)a[n];
-                ulong t = a0 * mDash;
-
-                ulong carry = t * (uint)m[n - 1] + a0;
-                Debug.Assert((uint)carry == 0);
-                carry >>= 32;
-
-                for (int j = n - 2; j > i; --j)
-                {
-                    carry += t * (uint)m[j] + (uint)a[j + 1];
-                    a[j + 2] = (int)carry;
-                    carry >>= 32;
-                }
-
-                ulong xi = (uint)x[i];
-
-                {
-                    ulong prod1 = xi * xi;
-                    ulong prod2 = t * (uint)m[i];
-
-                    carry += (prod1 & UIMASK) + (uint)prod2 + (uint)a[i + 1];
-                    a[i + 2] = (int)carry;
-                    carry = (carry >> 32) + (prod1 >> 32) + (prod2 >> 32);
-                }
-
-                for (int j = i - 1; j >= 0; --j)
-                {
-                    ulong prod1 = xi * (uint)x[j];
-                    ulong prod2 = t * (uint)m[j];
-
-                    carry += (prod2 & UIMASK) + ((uint)prod1 << 1) + (uint)a[j + 1];
-                    a[j + 2] = (int)carry;
-                    carry = (carry >> 32) + (prod1 >> 31) + (prod2 >> 32);
-                }
-
-                carry += (uint)aMax;
-                a[1] = (int)carry;
-                aMax = (int)(carry >> 32);
-            }
-
-            a[0] = aMax;
-
-            if (!smallMontyModulus && CompareTo(0, a, 0, m) >= 0)
-            {
-                Subtract(0, a, 0, m);
-            }
-
-            Array.Copy(a, 1, x, 0, n);
-        }
-
-        private static uint MultiplyMontyNIsOne(uint x, uint y, uint m, uint mDash)
-        {
-            ulong carry = (ulong)x * y;
-            uint t = (uint)carry * mDash;
-            ulong um = m;
-            ulong prod2 = um * t;
-            carry += (uint)prod2;
-            Debug.Assert((uint)carry == 0);
-            carry = (carry >> 32) + (prod2 >> 32);
-            if (carry > um)
-            {
-                carry -= um;
-            }
-            Debug.Assert(carry < um);
-            return (uint)carry;
-        }
-
-        public BigInteger Multiply(
-            BigInteger val)
-        {
-            if (val == this)
-                return Square();
-
-            if ((sign & val.sign) == 0)
-                return Zero;
-
-            if (val.QuickPow2Check()) // val is power of two
-            {
-                BigInteger result = this.ShiftLeft(val.Abs().BitLength - 1);
-                return val.sign > 0 ? result : result.Negate();
-            }
-
-            if (this.QuickPow2Check()) // this is power of two
-            {
-                BigInteger result = val.ShiftLeft(this.Abs().BitLength - 1);
-                return this.sign > 0 ? result : result.Negate();
-            }
-
-            int resLength = magnitude.Length + val.magnitude.Length;
-            int[] res = new int[resLength];
-
-            Multiply(res, this.magnitude, val.magnitude);
-
-            int resSign = sign ^ val.sign ^ 1;
-            return new BigInteger(resSign, res, true);
-        }
-
-        public BigInteger Square()
-        {
-            if (sign == 0)
-                return Zero;
-            if (this.QuickPow2Check())
-                return ShiftLeft(Abs().BitLength - 1);
-            int resLength = magnitude.Length << 1;
-            if ((uint)magnitude[0] >> 16 == 0)
-                --resLength;
-            int[] res = new int[resLength];
-            Square(res, magnitude);
-            return new BigInteger(1, res, false);
-        }
-
-        public BigInteger Negate()
-        {
-            if (sign == 0)
-                return this;
-
-            return new BigInteger(-sign, magnitude, false);
-        }
-
-        public BigInteger NextProbablePrime()
-        {
-            if (sign < 0)
-                throw new ArithmeticException("Cannot be called on value < 0");
-
-            if (CompareTo(Two) < 0)
-                return Two;
-
-            BigInteger n = Inc().SetBit(0);
-
-            while (!n.CheckProbablePrime(100, RandomSource, false))
-            {
-                n = n.Add(Two);
-            }
-
-            return n;
-        }
-
-        public BigInteger Not()
-        {
-            return Inc().Negate();
-        }
-
-        public BigInteger Pow(int exp)
-        {
-            if (exp <= 0)
-            {
-                if (exp < 0)
-                    throw new ArithmeticException("Negative exponent");
-
-                return One;
-            }
-
-            if (sign == 0)
-            {
-                return this;
-            }
-
-            if (QuickPow2Check())
-            {
-                long powOf2 = (long)exp * (BitLength - 1);
-                if (powOf2 > Int32.MaxValue)
-                {
-                    throw new ArithmeticException("Result too large");
-                }
-                return One.ShiftLeft((int)powOf2); 
-            }
-
-            BigInteger y = One;
-            BigInteger z = this;
-
-            for (;;)
-            {
-                if ((exp & 0x1) == 1)
-                {
-                    y = y.Multiply(z);
-                }
-                exp >>= 1;
-                if (exp == 0) break;
-                z = z.Multiply(z);
-            }
-
-            return y;
-        }
-
-        public static BigInteger ProbablePrime(
-            int bitLength,
-            Random random)
-        {
-            return new BigInteger(bitLength, 100, random);
-        }
-
-        private int Remainder(
-            int m)
-        {
-            Debug.Assert(m > 0);
-
-            long acc = 0;
-            for (int pos = 0; pos < magnitude.Length; ++pos)
-            {
-                long posVal = (uint) magnitude[pos];
-                acc = (acc << 32 | posVal) % m;
-            }
-
-            return (int) acc;
-        }
-
-        /**
-         * return x = x % y - done in place (y value preserved)
-         */
-        private static int[] Remainder(
-            int[] x,
-            int[] y)
-        {
-            int xStart = 0;
-            while (xStart < x.Length && x[xStart] == 0)
-            {
-                ++xStart;
-            }
-
-            int yStart = 0;
-            while (yStart < y.Length && y[yStart] == 0)
-            {
-                ++yStart;
-            }
-
-            Debug.Assert(yStart < y.Length);
-
-            int xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y);
-
-            if (xyCmp > 0)
-            {
-                int yBitLength = CalcBitLength(1, yStart, y);
-                int xBitLength = CalcBitLength(1, xStart, x);
-                int shift = xBitLength - yBitLength;
-
-                int[] c;
-                int cStart = 0;
-                int cBitLength = yBitLength;
-                if (shift > 0)
-                {
-                    c = ShiftLeft(y, shift);
-                    cBitLength += shift;
-                    Debug.Assert(c[0] != 0);
-                }
-                else
-                {
-                    int len = y.Length - yStart;
-                    c = new int[len];
-                    Array.Copy(y, yStart, c, 0, len);
-                }
-
-                for (;;)
-                {
-                    if (cBitLength < xBitLength
-                        || CompareNoLeadingZeroes(xStart, x, cStart, c) >= 0)
-                    {
-                        Subtract(xStart, x, cStart, c);
-
-                        while (x[xStart] == 0)
-                        {
-                            if (++xStart == x.Length)
-                                return x;
-                        }
-
-                        //xBitLength = CalcBitLength(xStart, x);
-                        xBitLength = 32 * (x.Length - xStart - 1) + BitLen(x[xStart]);
-
-                        if (xBitLength <= yBitLength)
-                        {
-                            if (xBitLength < yBitLength)
-                                return x;
-
-                            xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y);
-
-                            if (xyCmp <= 0)
-                                break;
-                        }
-                    }
-
-                    shift = cBitLength - xBitLength;
-
-                    // NB: The case where c[cStart] is 1-bit is harmless
-                    if (shift == 1)
-                    {
-                        uint firstC = (uint) c[cStart] >> 1;
-                        uint firstX = (uint) x[xStart];
-                        if (firstC > firstX)
-                            ++shift;
-                    }
-
-                    if (shift < 2)
-                    {
-                        ShiftRightOneInPlace(cStart, c);
-                        --cBitLength;
-                    }
-                    else
-                    {
-                        ShiftRightInPlace(cStart, c, shift);
-                        cBitLength -= shift;
-                    }
-
-                    //cStart = c.Length - ((cBitLength + 31) / 32);
-                    while (c[cStart] == 0)
-                    {
-                        ++cStart;
-                    }
-                }
-            }
-
-            if (xyCmp == 0)
-            {
-                Array.Clear(x, xStart, x.Length - xStart);
-            }
-
-            return x;
-        }
-
-        public BigInteger Remainder(
-            BigInteger n)
-        {
-            if (n.sign == 0)
-                throw new ArithmeticException("Division by zero error");
-
-            if (this.sign == 0)
-                return Zero;
-
-            // For small values, use fast remainder method
-            if (n.magnitude.Length == 1)
-            {
-                int val = n.magnitude[0];
-
-                if (val > 0)
-                {
-                    if (val == 1)
-                        return Zero;
-
-                    // TODO Make this func work on uint, and handle val == 1?
-                    int rem = Remainder(val);
-
-                    return rem == 0
-                        ?	Zero
-                        :	new BigInteger(sign, new int[]{ rem }, false);
-                }
-            }
-
-            if (CompareNoLeadingZeroes(0, magnitude, 0, n.magnitude) < 0)
-                return this;
-
-            int[] result;
-            if (n.QuickPow2Check())  // n is power of two
-            {
-                // TODO Move before small values branch above?
-                result = LastNBits(n.Abs().BitLength - 1);
-            }
-            else
-            {
-                result = (int[]) this.magnitude.Clone();
-                result = Remainder(result, n.magnitude);
-            }
-
-            return new BigInteger(sign, result, true);
-        }
-
-        private int[] LastNBits(
-            int n)
-        {
-            if (n < 1)
-                return ZeroMagnitude;
-
-            int numWords = (n + BitsPerInt - 1) / BitsPerInt;
-            numWords = System.Math.Min(numWords, this.magnitude.Length);
-            int[] result = new int[numWords];
-
-            Array.Copy(this.magnitude, this.magnitude.Length - numWords, result, 0, numWords);
-
-            int excessBits = (numWords << 5) - n;
-            if (excessBits > 0)
-            {
-                result[0] &= (int)(UInt32.MaxValue >> excessBits);
-            }
-
-            return result;
-        }
-
-        private BigInteger DivideWords(int w)
-        {
-            Debug.Assert(w >= 0);
-            int n = magnitude.Length;
-            if (w >= n)
-                return Zero;
-            int[] mag = new int[n - w];
-            Array.Copy(magnitude, 0, mag, 0, n - w);
-            return new BigInteger(sign, mag, false);
-        }
-
-        private BigInteger RemainderWords(int w)
-        {
-            Debug.Assert(w >= 0);
-            int n = magnitude.Length;
-            if (w >= n)
-                return this;
-            int[] mag = new int[w];
-            Array.Copy(magnitude, n - w, mag, 0, w);
-            return new BigInteger(sign, mag, false);
-        }
-
-        /**
-         * do a left shift - this returns a new array.
-         */
-        private static int[] ShiftLeft(
-            int[]	mag,
-            int		n)
-        {
-            int nInts = (int)((uint)n >> 5);
-            int nBits = n & 0x1f;
-            int magLen = mag.Length;
-            int[] newMag;
-
-            if (nBits == 0)
-            {
-                newMag = new int[magLen + nInts];
-                mag.CopyTo(newMag, 0);
-            }
-            else
-            {
-                int i = 0;
-                int nBits2 = 32 - nBits;
-                int highBits = (int)((uint)mag[0] >> nBits2);
-
-                if (highBits != 0)
-                {
-                    newMag = new int[magLen + nInts + 1];
-                    newMag[i++] = highBits;
-                }
-                else
-                {
-                    newMag = new int[magLen + nInts];
-                }
-
-                int m = mag[0];
-                for (int j = 0; j < magLen - 1; j++)
-                {
-                    int next = mag[j + 1];
-
-                    newMag[i++] = (m << nBits) | (int)((uint)next >> nBits2);
-                    m = next;
-                }
-
-                newMag[i] = mag[magLen - 1] << nBits;
-            }
-
-            return newMag;
-        }
-
-        private static int ShiftLeftOneInPlace(int[] x, int carry)
-        {
-            Debug.Assert(carry == 0 || carry == 1);
-            int pos = x.Length;
-            while (--pos >= 0)
-            {
-                uint val = (uint)x[pos];
-                x[pos] = (int)(val << 1) | carry;
-                carry = (int)(val >> 31);
-            }
-            return carry;
-        }
-
-        public BigInteger ShiftLeft(
-            int n)
-        {
-            if (sign == 0 || magnitude.Length == 0)
-                return Zero;
-
-            if (n == 0)
-                return this;
-
-            if (n < 0)
-                return ShiftRight(-n);
-
-            BigInteger result = new BigInteger(sign, ShiftLeft(magnitude, n), true);
-
-            if (this.nBits != -1)
-            {
-                result.nBits = sign > 0
-                    ?	this.nBits
-                    :	this.nBits + n;
-            }
-
-            if (this.nBitLength != -1)
-            {
-                result.nBitLength = this.nBitLength + n;
-            }
-
-            return result;
-        }
-
-        /**
-         * do a right shift - this does it in place.
-         */
-        private static void ShiftRightInPlace(
-            int		start,
-            int[]	mag,
-            int		n)
-        {
-            int nInts = (int)((uint)n >> 5) + start;
-            int nBits = n & 0x1f;
-            int magEnd = mag.Length - 1;
-
-            if (nInts != start)
-            {
-                int delta = (nInts - start);
-
-                for (int i = magEnd; i >= nInts; i--)
-                {
-                    mag[i] = mag[i - delta];
-                }
-                for (int i = nInts - 1; i >= start; i--)
-                {
-                    mag[i] = 0;
-                }
-            }
-
-            if (nBits != 0)
-            {
-                int nBits2 = 32 - nBits;
-                int m = mag[magEnd];
-
-                for (int i = magEnd; i > nInts; --i)
-                {
-                    int next = mag[i - 1];
-
-                    mag[i] = (int)((uint)m >> nBits) | (next << nBits2);
-                    m = next;
-                }
-
-                mag[nInts] = (int)((uint)mag[nInts] >> nBits);
-            }
-        }
-
-        /**
-         * do a right shift by one - this does it in place.
-         */
-        private static void ShiftRightOneInPlace(
-            int		start,
-            int[]	mag)
-        {
-            int i = mag.Length;
-            int m = mag[i - 1];
-
-            while (--i > start)
-            {
-                int next = mag[i - 1];
-                mag[i] = ((int)((uint)m >> 1)) | (next << 31);
-                m = next;
-            }
-
-            mag[start] = (int)((uint)mag[start] >> 1);
-        }
-
-        public BigInteger ShiftRight(
-            int n)
-        {
-            if (n == 0)
-                return this;
-
-            if (n < 0)
-                return ShiftLeft(-n);
-
-            if (n >= BitLength)
-                return (this.sign < 0 ? One.Negate() : Zero);
-
-//			int[] res = (int[]) this.magnitude.Clone();
-//
-//			ShiftRightInPlace(0, res, n);
-//
-//			return new BigInteger(this.sign, res, true);
-
-            int resultLength = (BitLength - n + 31) >> 5;
-            int[] res = new int[resultLength];
-
-            int numInts = n >> 5;
-            int numBits = n & 31;
-
-            if (numBits == 0)
-            {
-                Array.Copy(this.magnitude, 0, res, 0, res.Length);
-            }
-            else
-            {
-                int numBits2 = 32 - numBits;
-
-                int magPos = this.magnitude.Length - 1 - numInts;
-                for (int i = resultLength - 1; i >= 0; --i)
-                {
-                    res[i] = (int)((uint) this.magnitude[magPos--] >> numBits);
-
-                    if (magPos >= 0)
-                    {
-                        res[i] |= this.magnitude[magPos] << numBits2;
-                    }
-                }
-            }
-
-            Debug.Assert(res[0] != 0);
-
-            return new BigInteger(this.sign, res, false);
-        }
-
-        public int SignValue
-        {
-            get { return sign; }
-        }
-
-        /**
-         * returns x = x - y - we assume x is >= y
-         */
-        private static int[] Subtract(
-            int		xStart,
-            int[]	x,
-            int		yStart,
-            int[]	y)
-        {
-            Debug.Assert(yStart < y.Length);
-            Debug.Assert(x.Length - xStart >= y.Length - yStart);
-
-            int iT = x.Length;
-            int iV = y.Length;
-            long m;
-            int borrow = 0;
-
-            do
-            {
-                m = (x[--iT] & IMASK) - (y[--iV] & IMASK) + borrow;
-                x[iT] = (int) m;
-
-//				borrow = (m < 0) ? -1 : 0;
-                borrow = (int)(m >> 63);
-            }
-            while (iV > yStart);
-
-            if (borrow != 0)
-            {
-                while (--x[--iT] == -1)
-                {
-                }
-            }
-
-            return x;
-        }
-
-        public BigInteger Subtract(
-            BigInteger n)
-        {
-            if (n.sign == 0)
-                return this;
-
-            if (this.sign == 0)
-                return n.Negate();
-
-            if (this.sign != n.sign)
-                return Add(n.Negate());
-
-            int compare = CompareNoLeadingZeroes(0, magnitude, 0, n.magnitude);
-            if (compare == 0)
-                return Zero;
-
-            BigInteger bigun, lilun;
-            if (compare < 0)
-            {
-                bigun = n;
-                lilun = this;
-            }
-            else
-            {
-                bigun = this;
-                lilun = n;
-            }
-
-            return new BigInteger(this.sign * compare, doSubBigLil(bigun.magnitude, lilun.magnitude), true);
-        }
-
-        private static int[] doSubBigLil(
-            int[]	bigMag,
-            int[]	lilMag)
-        {
-            int[] res = (int[]) bigMag.Clone();
-
-            return Subtract(0, res, 0, lilMag);
-        }
-
-        public byte[] ToByteArray()
-        {
-            return ToByteArray(false);
-        }
-
-        public byte[] ToByteArrayUnsigned()
-        {
-            return ToByteArray(true);
-        }
-
-        private byte[] ToByteArray(
-            bool unsigned)
-        {
-            if (sign == 0)
-                return unsigned ? ZeroEncoding : new byte[1];
-
-            int nBits = (unsigned && sign > 0)
-                ?	BitLength
-                :	BitLength + 1;
-
-            int nBytes = GetByteLength(nBits);
-            byte[] bytes = new byte[nBytes];
-
-            int magIndex = magnitude.Length;
-            int bytesIndex = bytes.Length;
-
-            if (sign > 0)
-            {
-                while (magIndex > 1)
-                {
-                    uint mag = (uint) magnitude[--magIndex];
-                    bytes[--bytesIndex] = (byte) mag;
-                    bytes[--bytesIndex] = (byte)(mag >> 8);
-                    bytes[--bytesIndex] = (byte)(mag >> 16);
-                    bytes[--bytesIndex] = (byte)(mag >> 24);
-                }
-
-                uint lastMag = (uint) magnitude[0];
-                while (lastMag > byte.MaxValue)
-                {
-                    bytes[--bytesIndex] = (byte) lastMag;
-                    lastMag >>= 8;
-                }
-
-                bytes[--bytesIndex] = (byte) lastMag;
-            }
-            else // sign < 0
-            {
-                bool carry = true;
-
-                while (magIndex > 1)
-                {
-                    uint mag = ~((uint) magnitude[--magIndex]);
-
-                    if (carry)
-                    {
-                        carry = (++mag == uint.MinValue);
-                    }
-
-                    bytes[--bytesIndex] = (byte) mag;
-                    bytes[--bytesIndex] = (byte)(mag >> 8);
-                    bytes[--bytesIndex] = (byte)(mag >> 16);
-                    bytes[--bytesIndex] = (byte)(mag >> 24);
-                }
-
-                uint lastMag = (uint) magnitude[0];
-
-                if (carry)
-                {
-                    // Never wraps because magnitude[0] != 0
-                    --lastMag;
-                }
-
-                while (lastMag > byte.MaxValue)
-                {
-                    bytes[--bytesIndex] = (byte) ~lastMag;
-                    lastMag >>= 8;
-                }
-
-                bytes[--bytesIndex] = (byte) ~lastMag;
-
-                if (bytesIndex > 0)
-                {
-                    bytes[--bytesIndex] = byte.MaxValue;
-                }
-            }
-
-            return bytes;
-        }
-
-        public override string ToString()
-        {
-            return ToString(10);
-        }
-
-        public string ToString(int radix)
-        {
-            // TODO Make this method work for other radices (ideally 2 <= radix <= 36 as in Java)
-
-            switch (radix)
-            {
-                case 2:
-                case 8:
-                case 10:
-                case 16:
-                    break;
-                default:
-                    throw new FormatException("Only bases 2, 8, 10, 16 are allowed");
-            }
-
-            // NB: Can only happen to internally managed instances
-            if (magnitude == null)
-                return "null";
-
-            if (sign == 0)
-                return "0";
-
-
-            // NOTE: This *should* be unnecessary, since the magnitude *should* never have leading zero digits
-            int firstNonZero = 0;
-            while (firstNonZero < magnitude.Length)
-            {
-                if (magnitude[firstNonZero] != 0)
-                {
-                    break;
-                }
-                ++firstNonZero;
-            }
-
-            if (firstNonZero == magnitude.Length)
-            {
-                return "0";
-            }
-
-
-            StringBuilder sb = new StringBuilder();
-            if (sign == -1)
-            {
-                sb.Append('-');
-            }
-
-            switch (radix)
-            {
-            case 2:
-            {
-                int pos = firstNonZero;
-                sb.Append(Convert.ToString(magnitude[pos], 2));
-                while (++pos < magnitude.Length)
-                {
-                    AppendZeroExtendedString(sb, Convert.ToString(magnitude[pos], 2), 32);
-                }
-                break;
-            }
-            case 8:
-            {
-                int mask = (1 << 30) - 1;
-                BigInteger u = this.Abs();
-                int bits = u.BitLength;
-                IList S = new List<object>();
-                while (bits > 30)
-                {
-                    S.Add(Convert.ToString(u.IntValue & mask, 8));
-                    u = u.ShiftRight(30);
-                    bits -= 30;
-                }
-                sb.Append(Convert.ToString(u.IntValue, 8));
-                for (int i = S.Count - 1; i >= 0; --i)
-                {
-                    AppendZeroExtendedString(sb, (string)S[i], 10);
-                }
-                break;
-            }
-            case 16:
-            {
-                int pos = firstNonZero;
-                sb.Append(Convert.ToString(magnitude[pos], 16));
-                while (++pos < magnitude.Length)
-                {
-                    AppendZeroExtendedString(sb, Convert.ToString(magnitude[pos], 16), 8);
-                }
-                break;
-            }
-            // TODO This could work for other radices if there is an alternative to Convert.ToString method
-            //default:
-            case 10:
-            {
-                BigInteger q = this.Abs();
-                if (q.BitLength < 64)
-                {
-                    sb.Append(Convert.ToString(q.LongValue, radix));
-                    break;
-                }
-
-                // TODO Could cache the moduli for each radix (soft reference?)
-                IList moduli = new List<object>();
-                BigInteger R = BigInteger.ValueOf(radix);
-                while (R.CompareTo(q) <= 0)
-                {
-                    moduli.Add(R);
-                    R = R.Square();
-                }
-
-                int scale = moduli.Count;
-                sb.EnsureCapacity(sb.Length + (1 << scale));
-
-                ToString(sb, radix, moduli, scale, q);
-
-                break;
-            }
-            }
-
-            return sb.ToString();
-        }
-
-        private static void ToString(StringBuilder sb, int radix, IList moduli, int scale, BigInteger pos)
-        {
-            if (pos.BitLength < 64)
-            {
-                string s = Convert.ToString(pos.LongValue, radix);
-                if (sb.Length > 1 || (sb.Length == 1 && sb[0] != '-'))
-                {
-                    AppendZeroExtendedString(sb, s, 1 << scale);
-                }
-                else if (pos.SignValue != 0)
-                {
-                    sb.Append(s);
-                }
-                return;
-            }
-
-            BigInteger[] qr = pos.DivideAndRemainder((BigInteger)moduli[--scale]);
-
-            ToString(sb, radix, moduli, scale, qr[0]);
-            ToString(sb, radix, moduli, scale, qr[1]);
-        }
-
-        private static void AppendZeroExtendedString(StringBuilder sb, string s, int minLength)
-        {
-            for (int len = s.Length; len < minLength; ++len)
-            {
-                sb.Append('0');
-            }
-            sb.Append(s);
-        }
-
-        private static BigInteger CreateUValueOf(
-            ulong value)
-        {
-            int msw = (int)(value >> 32);
-            int lsw = (int)value;
-
-            if (msw != 0)
-                return new BigInteger(1, new int[] { msw, lsw }, false);
-
-            if (lsw != 0)
-            {
-                BigInteger n = new BigInteger(1, new int[] { lsw }, false);
-                // Check for a power of two
-                if ((lsw & -lsw) == lsw)
-                {
-                    n.nBits = 1;
-                }
-                return n;
-            }
-
-            return Zero;
-        }
-
-        private static BigInteger CreateValueOf(
-            long value)
-        {
-            if (value < 0)
-            {
-                if (value == long.MinValue)
-                    return CreateValueOf(~value).Not();
-
-                return CreateValueOf(-value).Negate();
-            }
-
-            return CreateUValueOf((ulong)value);
-        }
-
-        public static BigInteger ValueOf(
-            long value)
-        {
-            if (value >= 0 && value < SMALL_CONSTANTS.Length)
-            {
-                return SMALL_CONSTANTS[value];
-            }
-
-            return CreateValueOf(value);
-        }
-
-        public int GetLowestSetBit()
-        {
-            if (this.sign == 0)
-                return -1;
-
-            return GetLowestSetBitMaskFirst(-1);
-        }
-
-        private int GetLowestSetBitMaskFirst(int firstWordMask)
-        {
-            int w = magnitude.Length, offset = 0;
-
-            uint word = (uint)(magnitude[--w] & firstWordMask);
-            Debug.Assert(magnitude[0] != 0);
-
-            while (word == 0)
-            {
-                word = (uint)magnitude[--w];
-                offset += 32;
-            }
-
-            while ((word & 0xFF) == 0)
-            {
-                word >>= 8;
-                offset += 8;
-            }
-
-            while ((word & 1) == 0)
-            {
-                word >>= 1;
-                ++offset;
-            }
-
-            return offset;
-        }
-
-        public bool TestBit(
-            int n)
-        {
-            if (n < 0)
-                throw new ArithmeticException("Bit position must not be negative");
-
-            if (sign < 0)
-                return !Not().TestBit(n);
-
-            int wordNum = n / 32;
-            if (wordNum >= magnitude.Length)
-                return false;
-
-            int word = magnitude[magnitude.Length - 1 - wordNum];
-            return ((word >> (n % 32)) & 1) > 0;
-        }
-
-        public BigInteger Or(
-            BigInteger value)
-        {
-            if (this.sign == 0)
-                return value;
-
-            if (value.sign == 0)
-                return this;
-
-            int[] aMag = this.sign > 0
-                ? this.magnitude
-                : Add(One).magnitude;
-
-            int[] bMag = value.sign > 0
-                ? value.magnitude
-                : value.Add(One).magnitude;
-
-            bool resultNeg = sign < 0 || value.sign < 0;
-            int resultLength = System.Math.Max(aMag.Length, bMag.Length);
-            int[] resultMag = new int[resultLength];
-
-            int aStart = resultMag.Length - aMag.Length;
-            int bStart = resultMag.Length - bMag.Length;
-
-            for (int i = 0; i < resultMag.Length; ++i)
-            {
-                int aWord = i >= aStart ? aMag[i - aStart] : 0;
-                int bWord = i >= bStart ? bMag[i - bStart] : 0;
-
-                if (this.sign < 0)
-                {
-                    aWord = ~aWord;
-                }
-
-                if (value.sign < 0)
-                {
-                    bWord = ~bWord;
-                }
-
-                resultMag[i] = aWord | bWord;
-
-                if (resultNeg)
-                {
-                    resultMag[i] = ~resultMag[i];
-                }
-            }
-
-            BigInteger result = new BigInteger(1, resultMag, true);
-
-            // TODO Optimise this case
-            if (resultNeg)
-            {
-                result = result.Not();
-            }
-
-            return result;
-        }
-
-        public BigInteger Xor(
-            BigInteger value)
-        {
-            if (this.sign == 0)
-                return value;
-
-            if (value.sign == 0)
-                return this;
-
-            int[] aMag = this.sign > 0
-                ? this.magnitude
-                : Add(One).magnitude;
-
-            int[] bMag = value.sign > 0
-                ? value.magnitude
-                : value.Add(One).magnitude;
-
-            // TODO Can just replace with sign != value.sign?
-            bool resultNeg = (sign < 0 && value.sign >= 0) || (sign >= 0 && value.sign < 0);
-            int resultLength = System.Math.Max(aMag.Length, bMag.Length);
-            int[] resultMag = new int[resultLength];
-
-            int aStart = resultMag.Length - aMag.Length;
-            int bStart = resultMag.Length - bMag.Length;
-
-            for (int i = 0; i < resultMag.Length; ++i)
-            {
-                int aWord = i >= aStart ? aMag[i - aStart] : 0;
-                int bWord = i >= bStart ? bMag[i - bStart] : 0;
-
-                if (this.sign < 0)
-                {
-                    aWord = ~aWord;
-                }
-
-                if (value.sign < 0)
-                {
-                    bWord = ~bWord;
-                }
-
-                resultMag[i] = aWord ^ bWord;
-
-                if (resultNeg)
-                {
-                    resultMag[i] = ~resultMag[i];
-                }
-            }
-
-            BigInteger result = new BigInteger(1, resultMag, true);
-
-            // TODO Optimise this case
-            if (resultNeg)
-            {
-                result = result.Not();
-            }
-
-            return result;
-        }
-
-        public BigInteger SetBit(
-            int n)
-        {
-            if (n < 0)
-                throw new ArithmeticException("Bit address less than zero");
-
-            if (TestBit(n))
-                return this;
-
-            // TODO Handle negative values and zero
-            if (sign > 0 && n < (BitLength - 1))
-                return FlipExistingBit(n);
-
-            return Or(One.ShiftLeft(n));
-        }
-
-        public BigInteger ClearBit(
-            int n)
-        {
-            if (n < 0)
-                throw new ArithmeticException("Bit address less than zero");
-
-            if (!TestBit(n))
-                return this;
-
-            // TODO Handle negative values
-            if (sign > 0 && n < (BitLength - 1))
-                return FlipExistingBit(n);
-
-            return AndNot(One.ShiftLeft(n));
-        }
-
-        public BigInteger FlipBit(
-            int n)
-        {
-            if (n < 0)
-                throw new ArithmeticException("Bit address less than zero");
-
-            // TODO Handle negative values and zero
-            if (sign > 0 && n < (BitLength - 1))
-                return FlipExistingBit(n);
-
-            return Xor(One.ShiftLeft(n));
-        }
-
-        private BigInteger FlipExistingBit(
-            int n)
-        {
-            Debug.Assert(sign > 0);
-            Debug.Assert(n >= 0);
-            Debug.Assert(n < BitLength - 1);
-
-            int[] mag = (int[]) this.magnitude.Clone();
-            mag[mag.Length - 1 - (n >> 5)] ^= (1 << (n & 31)); // Flip bit
-            //mag[mag.Length - 1 - (n / 32)] ^= (1 << (n % 32));
-            return new BigInteger(this.sign, mag, false);
-        }
-    }
-}

+ 0 - 496
src/Renci.SshNet/Security/BouncyCastle/math/ec/ECAlgorithms.cs

@@ -1,496 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Endo;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.Field;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC
-{
-    internal 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.
-         * 
-         * @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", "p");
-
-            return c.DecodePoint(p.GetEncoded(false));
-        }
-
-        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;
-
-            k = k.Abs();
-            l = l.Abs();
-
-            int widthP = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(k.BitLength)));
-            int widthQ = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(l.BitLength)));
-
-            WNafPreCompInfo infoP = WNafUtilities.Precompute(P, widthP, true);
-            WNafPreCompInfo infoQ = WNafUtilities.Precompute(Q, widthQ, true);
-
-            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);
-        }
-
-        internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k, ECPointMap pointMapQ, BigInteger l)
-        {
-            bool negK = k.SignValue < 0, negL = l.SignValue < 0;
-
-            k = k.Abs();
-            l = l.Abs();
-
-            int width = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(System.Math.Max(k.BitLength, l.BitLength))));
-
-            ECPoint Q = WNafUtilities.MapPointWithPrecomp(P, width, true, pointMapQ);
-            WNafPreCompInfo infoP = WNafUtilities.GetWNafPreCompInfo(P);
-            WNafPreCompInfo infoQ = WNafUtilities.GetWNafPreCompInfo(Q);
-
-            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(width, k);
-            byte[] wnafQ = WNafUtilities.GenerateWindowNaf(width, 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 width = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(ki.BitLength)));
-                infos[i] = WNafUtilities.Precompute(ps[i], width, true);
-                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];
-            }
-
-            ECPointMap pointMap = glvEndomorphism.PointMap;
-            if (glvEndomorphism.HasEfficientPointMap)
-            {
-                return ECAlgorithms.ImplSumOfMultiplies(ps, pointMap, abs);
-            }
-
-            ECPoint[] pqs = new ECPoint[len << 1];
-            for (int i = 0, j = 0; i < len; ++i)
-            {
-                ECPoint p = ps[i], q = pointMap.Map(p);
-                pqs[j++] = p;
-                pqs[j++] = q;
-            }
-
-            return ECAlgorithms.ImplSumOfMultiplies(pqs, abs);
-        }
-
-        internal static ECPoint ImplSumOfMultiplies(ECPoint[] ps, ECPointMap pointMap, BigInteger[] ks)
-        {
-            int halfCount = ps.Length, fullCount = halfCount << 1;
-
-            bool[] negs = new bool[fullCount];
-            WNafPreCompInfo[] infos = new WNafPreCompInfo[fullCount];
-            byte[][] wnafs = new byte[fullCount][];
-
-            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 width = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(System.Math.Max(kj0.BitLength, kj1.BitLength))));
-
-                ECPoint P = ps[i], Q = WNafUtilities.MapPointWithPrecomp(P, width, true, pointMap);
-                infos[j0] = WNafUtilities.GetWNafPreCompInfo(P);
-                infos[j1] = WNafUtilities.GetWNafPreCompInfo(Q);
-                wnafs[j0] = WNafUtilities.GenerateWindowNaf(width, kj0);
-                wnafs[j1] = WNafUtilities.GenerateWindowNaf(width, 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;
-        }
-    }
-}

+ 0 - 1278
src/Renci.SshNet/Security/BouncyCastle/math/ec/ECCurve.cs

@@ -1,1278 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Abc;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Endo;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.Field;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.Raw;
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC
-{
-    /// <remarks>Base class for an elliptic curve.</remarks>
-    internal abstract class ECCurve
-    {
-        public const int COORD_AFFINE = 0;
-        public const int COORD_HOMOGENEOUS = 1;
-        public const int COORD_JACOBIAN = 2;
-        public const int COORD_JACOBIAN_CHUDNOVSKY = 3;
-        public const int COORD_JACOBIAN_MODIFIED = 4;
-        public const int COORD_LAMBDA_AFFINE = 5;
-        public const int COORD_LAMBDA_PROJECTIVE = 6;
-        public const int COORD_SKEWED = 7;
-
-        public static int[] GetAllCoordinateSystems()
-        {
-            return new int[]{ COORD_AFFINE, COORD_HOMOGENEOUS, COORD_JACOBIAN, COORD_JACOBIAN_CHUDNOVSKY,
-                COORD_JACOBIAN_MODIFIED, COORD_LAMBDA_AFFINE, COORD_LAMBDA_PROJECTIVE, COORD_SKEWED };
-        }
-
-        internal class Config
-        {
-            protected ECCurve outer;
-            protected int coord;
-            protected ECEndomorphism endomorphism;
-            protected ECMultiplier multiplier;
-
-            internal Config(ECCurve outer, int coord, ECEndomorphism endomorphism, ECMultiplier multiplier)
-            {
-                this.outer = outer;
-                this.coord = coord;
-                this.endomorphism = endomorphism;
-                this.multiplier = multiplier;
-            }
-
-            public Config SetCoordinateSystem(int coord)
-            {
-                this.coord = coord;
-                return this;
-            }
-
-            public Config SetEndomorphism(ECEndomorphism endomorphism)
-            {
-                this.endomorphism = endomorphism;
-                return this;
-            }
-
-            public Config SetMultiplier(ECMultiplier multiplier)
-            {
-                this.multiplier = multiplier;
-                return this;
-            }
-
-            public ECCurve Create()
-            {
-                if (!outer.SupportsCoordinateSystem(coord))
-                {
-                    throw new InvalidOperationException("unsupported coordinate system");
-                }
-
-                ECCurve c = outer.CloneCurve();
-                if (c == outer)
-                {
-                    throw new InvalidOperationException("implementation returned current curve");
-                }
-
-                c.m_coord = coord;
-                c.m_endomorphism = endomorphism;
-                c.m_multiplier = multiplier;
-
-                return c;
-            }
-        }
-
-        protected readonly IFiniteField m_field;
-        protected ECFieldElement m_a, m_b;
-        protected BigInteger m_order, m_cofactor;
-
-        protected int m_coord = COORD_AFFINE;
-        protected ECEndomorphism m_endomorphism = null;
-        protected ECMultiplier m_multiplier = null;
-
-        protected ECCurve(IFiniteField field)
-        {
-            this.m_field = field;
-        }
-
-        public abstract int FieldSize { get; }
-        public abstract ECFieldElement FromBigInteger(BigInteger x);
-        public abstract bool IsValidFieldElement(BigInteger x);
-
-        public virtual Config Configure()
-        {
-            return new Config(this, this.m_coord, this.m_endomorphism, this.m_multiplier);
-        }
-
-        public virtual ECPoint ValidatePoint(BigInteger x, BigInteger y)
-        {
-            ECPoint p = CreatePoint(x, y);
-            if (!p.IsValid())
-            {
-                throw new ArgumentException("Invalid point coordinates");
-            }
-            return p;
-        }
-
-        public virtual ECPoint ValidatePoint(BigInteger x, BigInteger y, bool withCompression)
-        {
-            ECPoint p = CreatePoint(x, y, withCompression);
-            if (!p.IsValid())
-            {
-                throw new ArgumentException("Invalid point coordinates");
-            }
-            return p;
-        }
-
-        public virtual ECPoint CreatePoint(BigInteger x, BigInteger y)
-        {
-            return CreatePoint(x, y, false);
-        }
-
-        public virtual ECPoint CreatePoint(BigInteger x, BigInteger y, bool withCompression)
-        {
-            return CreateRawPoint(FromBigInteger(x), FromBigInteger(y), withCompression);
-        }
-
-        protected abstract ECCurve CloneCurve();
-
-        protected internal abstract ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression);
-
-        protected internal abstract ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression);
-
-        protected virtual ECMultiplier CreateDefaultMultiplier()
-        {
-            GlvEndomorphism glvEndomorphism = m_endomorphism as GlvEndomorphism;
-            if (glvEndomorphism != null)
-            {
-                return new GlvMultiplier(this, glvEndomorphism);
-            }
-
-            return new WNafL2RMultiplier();
-        }
-
-        public virtual bool SupportsCoordinateSystem(int coord)
-        {
-            return coord == COORD_AFFINE;
-        }
-
-        public virtual PreCompInfo GetPreCompInfo(ECPoint point, string name)
-        {
-            CheckPoint(point);
-
-            IDictionary table;
-            lock (point)
-            {
-                table = point.m_preCompTable;
-            }
-
-            if (null == table)
-                return null;
-
-            lock (table)
-            {
-                return (PreCompInfo)table[name];
-            }
-        }
-
-        /**
-         * Compute a <code>PreCompInfo</code> for a point on this curve, under a given name. Used by
-         * <code>ECMultiplier</code>s to save the precomputation for this <code>ECPoint</code> for use
-         * by subsequent multiplication.
-         * 
-         * @param point
-         *            The <code>ECPoint</code> to store precomputations for.
-         * @param name
-         *            A <code>String</code> used to index precomputations of different types.
-         * @param callback
-         *            Called to calculate the <code>PreCompInfo</code>.
-         */
-        public virtual PreCompInfo Precompute(ECPoint point, string name, IPreCompCallback callback)
-        {
-            CheckPoint(point);
-
-            IDictionary table;
-            lock (point)
-            {
-                table = point.m_preCompTable;
-                if (null == table)
-                {
-                    point.m_preCompTable = table = new Dictionary<object, object>(4);
-                }
-            }
-
-            lock (table)
-            {
-                PreCompInfo existing = (PreCompInfo)table[name];
-                PreCompInfo result = callback.Precompute(existing);
-
-                if (result != existing)
-                {
-                    table[name] = result;
-                }
-
-                return result;
-            }
-        }
-
-        public virtual ECPoint ImportPoint(ECPoint p)
-        {
-            if (this == p.Curve)
-            {
-                return p;
-            }
-            if (p.IsInfinity)
-            {
-                return Infinity;
-            }
-
-            // TODO Default behaviour could be improved if the two curves have the same coordinate system by copying any Z coordinates.
-            p = p.Normalize();
-
-            return CreatePoint(p.XCoord.ToBigInteger(), p.YCoord.ToBigInteger(), p.IsCompressed);
-        }
-
-        /**
-         * Normalization ensures that any projective coordinate is 1, and therefore that the x, y
-         * coordinates reflect those of the equivalent point in an affine coordinate system. Where more
-         * than one point is to be normalized, this method will generally be more efficient than
-         * normalizing each point separately.
-         * 
-         * @param points
-         *            An array of points that will be updated in place with their normalized versions,
-         *            where necessary
-         */
-        public virtual void NormalizeAll(ECPoint[] points)
-        {
-            NormalizeAll(points, 0, points.Length, null);
-        }
-
-        /**
-         * Normalization ensures that any projective coordinate is 1, and therefore that the x, y
-         * coordinates reflect those of the equivalent point in an affine coordinate system. Where more
-         * than one point is to be normalized, this method will generally be more efficient than
-         * normalizing each point separately. An (optional) z-scaling factor can be applied; effectively
-         * each z coordinate is scaled by this value prior to normalization (but only one
-         * actual multiplication is needed).
-         * 
-         * @param points
-         *            An array of points that will be updated in place with their normalized versions,
-         *            where necessary
-         * @param off
-         *            The start of the range of points to normalize
-         * @param len
-         *            The length of the range of points to normalize
-         * @param iso
-         *            The (optional) z-scaling factor - can be null
-         */
-        public virtual void NormalizeAll(ECPoint[] points, int off, int len, ECFieldElement iso)
-        {
-            CheckPoints(points, off, len);
-
-            switch (this.CoordinateSystem)
-            {
-                case ECCurve.COORD_AFFINE:
-                case ECCurve.COORD_LAMBDA_AFFINE:
-                {
-                    if (iso != null)
-                        throw new ArgumentException("not valid for affine coordinates", "iso");
-
-                    return;
-                }
-            }
-
-            /*
-             * Figure out which of the points actually need to be normalized
-             */
-            ECFieldElement[] zs = new ECFieldElement[len];
-            int[] indices = new int[len];
-            int count = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                ECPoint p = points[off + i];
-                if (null != p && (iso != null || !p.IsNormalized()))
-                {
-                    zs[count] = p.GetZCoord(0);
-                    indices[count++] = off + i;
-                }
-            }
-
-            if (count == 0)
-            {
-                return;
-            }
-
-            ECAlgorithms.MontgomeryTrick(zs, 0, count, iso);
-
-            for (int j = 0; j < count; ++j)
-            {
-                int index = indices[j];
-                points[index] = points[index].Normalize(zs[j]);
-            }
-        }
-
-        public abstract ECPoint Infinity { get; }
-
-        public virtual IFiniteField Field
-        {
-            get { return m_field; }
-        }
-
-        public virtual ECFieldElement A
-        {
-            get { return m_a; }
-        }
-
-        public virtual ECFieldElement B
-        {
-            get { return m_b; }
-        }
-
-        public virtual BigInteger Order
-        {
-            get { return m_order; }
-        }
-
-        public virtual BigInteger Cofactor
-        {
-            get { return m_cofactor; }
-        }
-
-        public virtual int CoordinateSystem
-        {
-            get { return m_coord; }
-        }
-
-        /**
-         * Create a cache-safe lookup table for the specified sequence of points. All the points MUST
-         * belong to this <code>ECCurve</code> instance, and MUST already be normalized.
-         */
-        public virtual ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
-        {
-            int FE_BYTES = (FieldSize + 7) / 8;
-            byte[] table = new byte[len * FE_BYTES * 2];
-            {
-                int pos = 0;
-                for (int i = 0; i < len; ++i)
-                {
-                    ECPoint p = points[off + i];
-                    byte[] px = p.RawXCoord.ToBigInteger().ToByteArray();
-                    byte[] py = p.RawYCoord.ToBigInteger().ToByteArray();
-
-                    int pxStart = px.Length > FE_BYTES ? 1 : 0, pxLen = px.Length - pxStart;
-                    int pyStart = py.Length > FE_BYTES ? 1 : 0, pyLen = py.Length - pyStart;
-
-                    Array.Copy(px, pxStart, table, pos + FE_BYTES - pxLen, pxLen); pos += FE_BYTES;
-                    Array.Copy(py, pyStart, table, pos + FE_BYTES - pyLen, pyLen); pos += FE_BYTES;
-                }
-            }
-
-            return new DefaultLookupTable(this, table, len);
-        }
-
-        protected virtual void CheckPoint(ECPoint point)
-        {
-            if (null == point || (this != point.Curve))
-                throw new ArgumentException("must be non-null and on this curve", "point");
-        }
-
-        protected virtual void CheckPoints(ECPoint[] points)
-        {
-            CheckPoints(points, 0, points.Length);
-        }
-
-        protected virtual void CheckPoints(ECPoint[] points, int off, int len)
-        {
-            if (points == null)
-                throw new ArgumentNullException("points");
-            if (off < 0 || len < 0 || (off > (points.Length - len)))
-                throw new ArgumentException("invalid range specified", "points");
-
-            for (int i = 0; i < len; ++i)
-            {
-                ECPoint point = points[off + i];
-                if (null != point && this != point.Curve)
-                    throw new ArgumentException("entries must be null or on this curve", "points");
-            }
-        }
-
-        public virtual bool Equals(ECCurve other)
-        {
-            if (this == other)
-                return true;
-            if (null == other)
-                return false;
-            return Field.Equals(other.Field)
-                && A.ToBigInteger().Equals(other.A.ToBigInteger())
-                && B.ToBigInteger().Equals(other.B.ToBigInteger());
-        }
-
-        public override bool Equals(object obj) 
-        {
-            return Equals(obj as ECCurve);
-        }
-
-        public override int GetHashCode()
-        {
-            return Field.GetHashCode()
-                ^ Integers.RotateLeft(A.ToBigInteger().GetHashCode(), 8)
-                ^ Integers.RotateLeft(B.ToBigInteger().GetHashCode(), 16);
-        }
-
-        protected abstract ECPoint DecompressPoint(int yTilde, BigInteger X1);
-
-        public virtual ECEndomorphism GetEndomorphism()
-        {
-            return m_endomorphism;
-        }
-
-        /**
-         * Sets the default <code>ECMultiplier</code>, unless already set. 
-         */
-        public virtual ECMultiplier GetMultiplier()
-        {
-            lock (this)
-            {
-                if (this.m_multiplier == null)
-                {
-                    this.m_multiplier = CreateDefaultMultiplier();
-                }
-                return this.m_multiplier;
-            }
-        }
-
-        /**
-         * Decode a point on this curve from its ASN.1 encoding. The different
-         * encodings are taken account of, including point compression for
-         * <code>F<sub>p</sub></code> (X9.62 s 4.2.1 pg 17).
-         * @return The decoded point.
-         */
-        public virtual ECPoint DecodePoint(byte[] encoded)
-        {
-            ECPoint p = null;
-            int expectedLength = (FieldSize + 7) / 8;
-
-            byte type = encoded[0];
-            switch (type)
-            {
-                case 0x00: // infinity
-                {
-                    if (encoded.Length != 1)
-                        throw new ArgumentException("Incorrect length for infinity encoding", "encoded");
-
-                    p = Infinity;
-                    break;
-                }
-
-                case 0x02: // compressed
-                case 0x03: // compressed
-                {
-                    if (encoded.Length != (expectedLength + 1))
-                        throw new ArgumentException("Incorrect length for compressed encoding", "encoded");
-
-                    int yTilde = type & 1;
-                    BigInteger X = new BigInteger(1, encoded, 1, expectedLength);
-
-                    p = DecompressPoint(yTilde, X);
-                    if (!p.ImplIsValid(true, true))
-                        throw new ArgumentException("Invalid point");
-
-                    break;
-                }
-
-                case 0x04: // uncompressed
-                {
-                    if (encoded.Length != (2 * expectedLength + 1))
-                        throw new ArgumentException("Incorrect length for uncompressed encoding", "encoded");
-
-                    BigInteger X = new BigInteger(1, encoded, 1, expectedLength);
-                    BigInteger Y = new BigInteger(1, encoded, 1 + expectedLength, expectedLength);
-
-                    p = ValidatePoint(X, Y);
-                    break;
-                }
-
-                case 0x06: // hybrid
-                case 0x07: // hybrid
-                {
-                    if (encoded.Length != (2 * expectedLength + 1))
-                        throw new ArgumentException("Incorrect length for hybrid encoding", "encoded");
-
-                    BigInteger X = new BigInteger(1, encoded, 1, expectedLength);
-                    BigInteger Y = new BigInteger(1, encoded, 1 + expectedLength, expectedLength);
-
-                    if (Y.TestBit(0) != (type == 0x07))
-                        throw new ArgumentException("Inconsistent Y coordinate in hybrid encoding", "encoded");
-
-                    p = ValidatePoint(X, Y);
-                    break;
-                }
-
-                default:
-                    throw new FormatException("Invalid point encoding " + type);
-            }
-
-            if (type != 0x00 && p.IsInfinity)
-                throw new ArgumentException("Invalid infinity encoding", "encoded");
-
-            return p;
-        }
-
-        private class DefaultLookupTable
-            : ECLookupTable
-        {
-            private readonly ECCurve m_outer;
-            private readonly byte[] m_table;
-            private readonly int m_size;
-
-            internal DefaultLookupTable(ECCurve outer, byte[] table, int size)
-            {
-                this.m_outer = outer;
-                this.m_table = table;
-                this.m_size = size;
-            }
-
-            public virtual int Size
-            {
-                get { return m_size; }
-            }
-
-            public virtual ECPoint Lookup(int index)
-            {
-                int FE_BYTES = (m_outer.FieldSize + 7) / 8;
-                byte[] x = new byte[FE_BYTES], y = new byte[FE_BYTES];
-                int pos = 0;
-
-                for (int i = 0; i < m_size; ++i)
-                {
-                    byte MASK = (byte)(((i ^ index) - 1) >> 31);
-
-                    for (int j = 0; j < FE_BYTES; ++j)
-                    {
-                        x[j] ^= (byte)(m_table[pos + j] & MASK);
-                        y[j] ^= (byte)(m_table[pos + FE_BYTES + j] & MASK);
-                    }
-
-                    pos += (FE_BYTES * 2);
-                }
-
-                ECFieldElement X = m_outer.FromBigInteger(new BigInteger(1, x));
-                ECFieldElement Y = m_outer.FromBigInteger(new BigInteger(1, y));
-                return m_outer.CreateRawPoint(X, Y, false);
-            }
-        }
-    }
-
-    internal abstract class AbstractFpCurve
-        : ECCurve
-    {
-        protected AbstractFpCurve(BigInteger q)
-            : base(FiniteFields.GetPrimeField(q))
-        {
-        }
-
-        public override bool IsValidFieldElement(BigInteger x)
-        {
-            return x != null && x.SignValue >= 0 && x.CompareTo(Field.Characteristic) < 0;
-        }
-
-        protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
-        {
-            ECFieldElement x = FromBigInteger(X1);
-            ECFieldElement rhs = x.Square().Add(A).Multiply(x).Add(B);
-            ECFieldElement y = rhs.Sqrt();
-
-            /*
-             * If y is not a square, then we haven't got a point on the curve
-             */
-            if (y == null)
-                throw new ArgumentException("Invalid point compression");
-
-            if (y.TestBitZero() != (yTilde == 1))
-            {
-                // Use the other root
-                y = y.Negate();
-            }
-
-            return CreateRawPoint(x, y, true);
-        }
-    }
-
-    /**
-     * Elliptic curve over Fp
-     */
-    internal class FpCurve
-        : AbstractFpCurve
-    {
-        private const int FP_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED;
-
-        protected readonly BigInteger m_q, m_r;
-        protected readonly FpPoint m_infinity;
-
-        public FpCurve(BigInteger q, BigInteger a, BigInteger b)
-            : this(q, a, b, null, null)
-        {
-        }
-
-        public FpCurve(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor)
-            : base(q)
-        {
-            this.m_q = q;
-            this.m_r = FpFieldElement.CalculateResidue(q);
-            this.m_infinity = new FpPoint(this, null, null, false);
-
-            this.m_a = FromBigInteger(a);
-            this.m_b = FromBigInteger(b);
-            this.m_order = order;
-            this.m_cofactor = cofactor;
-            this.m_coord = FP_DEFAULT_COORDS;
-        }
-
-        protected FpCurve(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b)
-            : this(q, r, a, b, null, null)
-        {
-        }
-
-        protected FpCurve(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor)
-            : base(q)
-        {
-            this.m_q = q;
-            this.m_r = r;
-            this.m_infinity = new FpPoint(this, null, null, false);
-
-            this.m_a = a;
-            this.m_b = b;
-            this.m_order = order;
-            this.m_cofactor = cofactor;
-            this.m_coord = FP_DEFAULT_COORDS;
-        }
-
-        protected override ECCurve CloneCurve()
-        {
-            return new FpCurve(m_q, m_r, m_a, m_b, m_order, m_cofactor);
-        }
-
-        public override bool SupportsCoordinateSystem(int coord)
-        {
-            switch (coord)
-            {
-                case COORD_AFFINE:
-                case COORD_HOMOGENEOUS:
-                case COORD_JACOBIAN:
-                case COORD_JACOBIAN_MODIFIED:
-                    return true;
-                default:
-                    return false;
-            }
-        }
-
-        public virtual BigInteger Q
-        {
-            get { return m_q; }
-        }
-
-        public override ECPoint Infinity
-        {
-            get { return m_infinity; }
-        }
-
-        public override int FieldSize
-        {
-            get { return m_q.BitLength; }
-        }
-
-        public override ECFieldElement FromBigInteger(BigInteger x)
-        {
-            return new FpFieldElement(this.m_q, this.m_r, x);
-        }
-
-        protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
-        {
-            return new FpPoint(this, x, y, withCompression);
-        }
-
-        protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
-        {
-            return new FpPoint(this, x, y, zs, withCompression);
-        }
-
-        public override ECPoint ImportPoint(ECPoint p)
-        {
-            if (this != p.Curve && this.CoordinateSystem == COORD_JACOBIAN && !p.IsInfinity)
-            {
-                switch (p.Curve.CoordinateSystem)
-                {
-                    case COORD_JACOBIAN:
-                    case COORD_JACOBIAN_CHUDNOVSKY:
-                    case COORD_JACOBIAN_MODIFIED:
-                        return new FpPoint(this,
-                            FromBigInteger(p.RawXCoord.ToBigInteger()),
-                            FromBigInteger(p.RawYCoord.ToBigInteger()),
-                            new ECFieldElement[] { FromBigInteger(p.GetZCoord(0).ToBigInteger()) },
-                            p.IsCompressed);
-                    default:
-                        break;
-                }
-            }
-
-            return base.ImportPoint(p);
-        }
-    }
-
-    internal abstract class AbstractF2mCurve
-        : ECCurve
-    {
-        public static BigInteger Inverse(int m, int[] ks, BigInteger x)
-        {
-            return new LongArray(x).ModInverse(m, ks).ToBigInteger();
-        }
-
-        /**
-         * The auxiliary values <code>s<sub>0</sub></code> and
-         * <code>s<sub>1</sub></code> used for partial modular reduction for
-         * Koblitz curves.
-         */
-        private BigInteger[] si = null;
-
-        private static IFiniteField BuildField(int m, int k1, int k2, int k3)
-        {
-            if (k1 == 0)
-            {
-                throw new ArgumentException("k1 must be > 0");
-            }
-
-            if (k2 == 0)
-            {
-                if (k3 != 0)
-                {
-                    throw new ArgumentException("k3 must be 0 if k2 == 0");
-                }
-
-                return FiniteFields.GetBinaryExtensionField(new int[]{ 0, k1, m });
-            }
-
-            if (k2 <= k1)
-            {
-                throw new ArgumentException("k2 must be > k1");
-            }
-
-            if (k3 <= k2)
-            {
-                throw new ArgumentException("k3 must be > k2");
-            }
-
-            return FiniteFields.GetBinaryExtensionField(new int[]{ 0, k1, k2, k3, m });
-        }
-
-        protected AbstractF2mCurve(int m, int k1, int k2, int k3)
-            : base(BuildField(m, k1, k2, k3))
-        {
-        }
-
-        public override bool IsValidFieldElement(BigInteger x)
-        {
-            return x != null && x.SignValue >= 0 && x.BitLength <= FieldSize;
-        }
-
-        public override ECPoint CreatePoint(BigInteger x, BigInteger y, bool withCompression)
-        {
-            ECFieldElement X = FromBigInteger(x), Y = FromBigInteger(y);
-
-            switch (this.CoordinateSystem)
-            {
-                case COORD_LAMBDA_AFFINE:
-                case COORD_LAMBDA_PROJECTIVE:
-                {
-                    if (X.IsZero)
-                    {
-                        if (!Y.Square().Equals(B))
-                            throw new ArgumentException();
-                    }
-                    else
-                    {
-                        // Y becomes Lambda (X + Y/X) here
-                        Y = Y.Divide(X).Add(X);
-                    }
-                    break;
-                }
-                default:
-                {
-                    break;
-                }
-            }
-
-            return CreateRawPoint(X, Y, withCompression);
-        }
-
-        protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
-        {
-            ECFieldElement xp = FromBigInteger(X1), yp = null;
-            if (xp.IsZero)
-            {
-                yp = B.Sqrt();
-            }
-            else
-            {
-                ECFieldElement beta = xp.Square().Invert().Multiply(B).Add(A).Add(xp);
-                ECFieldElement z = SolveQuadraticEquation(beta);
-
-                if (z != null)
-                {
-                    if (z.TestBitZero() != (yTilde == 1))
-                    {
-                        z = z.AddOne();
-                    }
-
-                    switch (this.CoordinateSystem)
-                    {
-                        case COORD_LAMBDA_AFFINE:
-                        case COORD_LAMBDA_PROJECTIVE:
-                        {
-                            yp = z.Add(xp);
-                            break;
-                        }
-                        default:
-                        {
-                            yp = z.Multiply(xp);
-                            break;
-                        }
-                    }
-                }
-            }
-
-            if (yp == null)
-                throw new ArgumentException("Invalid point compression");
-
-            return CreateRawPoint(xp, yp, true);
-        }
-
-        /**
-         * Solves a quadratic equation <code>z<sup>2</sup> + z = beta</code>(X9.62
-         * D.1.6) The other solution is <code>z + 1</code>.
-         *
-         * @param beta
-         *            The value to solve the quadratic equation for.
-         * @return the solution for <code>z<sup>2</sup> + z = beta</code> or
-         *         <code>null</code> if no solution exists.
-         */
-        internal ECFieldElement SolveQuadraticEquation(ECFieldElement beta)
-        {
-            if (beta.IsZero)
-                return beta;
-
-            ECFieldElement gamma, z, zeroElement = FromBigInteger(BigInteger.Zero);
-
-            int m = FieldSize;
-            do
-            {
-                ECFieldElement t = FromBigInteger(BigInteger.Arbitrary(m));
-                z = zeroElement;
-                ECFieldElement w = beta;
-                for (int i = 1; i < m; i++)
-                {
-                    ECFieldElement w2 = w.Square();
-                    z = z.Square().Add(w2.Multiply(t));
-                    w = w2.Add(beta);
-                }
-                if (!w.IsZero)
-                {
-                    return null;
-                }
-                gamma = z.Square().Add(z);
-            }
-            while (gamma.IsZero);
-
-            return z;
-        }
-
-        /**
-         * @return the auxiliary values <code>s<sub>0</sub></code> and
-         * <code>s<sub>1</sub></code> used for partial modular reduction for
-         * Koblitz curves.
-         */
-        internal virtual BigInteger[] GetSi()
-        {
-            if (si == null)
-            {
-                lock (this)
-                {
-                    if (si == null)
-                    {
-                        si = Tnaf.GetSi(this);
-                    }
-                }
-            }
-            return si;
-        }
-
-        /**
-         * Returns true if this is a Koblitz curve (ABC curve).
-         * @return true if this is a Koblitz curve (ABC curve), false otherwise
-         */
-        public virtual bool IsKoblitz
-        {
-            get
-            {
-                return m_order != null && m_cofactor != null && m_b.IsOne && (m_a.IsZero || m_a.IsOne);
-            }
-        }
-    }
-
-    /**
-     * Elliptic curves over F2m. The Weierstrass equation is given by
-     * <code>y<sup>2</sup> + xy = x<sup>3</sup> + ax<sup>2</sup> + b</code>.
-     */
-    internal class F2mCurve
-        : AbstractF2mCurve
-    {
-        private const int F2M_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE;
-
-        /**
-         * The exponent <code>m</code> of <code>F<sub>2<sup>m</sup></sub></code>.
-         */
-        private readonly int m;
-
-        /**
-         * 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/>
-         */
-        private readonly int k1;
-
-        /**
-         * TPB: Always set to <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/>
-         */
-        private readonly int k2;
-
-        /**
-         * 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/>
-         */
-        private readonly int k3;
-
-        /**
-         * The point at infinity on this curve.
-         */
-        protected readonly F2mPoint m_infinity;
-
-        /**
-         * Constructor for Trinomial Polynomial Basis (TPB).
-         * @param m  The exponent <code>m</code> of
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         * @param k 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>.
-         * @param a The coefficient <code>a</code> in the Weierstrass equation
-         * for non-supersingular elliptic curves over
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         * @param b The coefficient <code>b</code> in the Weierstrass equation
-         * for non-supersingular elliptic curves over
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         */
-        [Obsolete("Use constructor taking order/cofactor")]
-        public F2mCurve(
-            int			m,
-            int			k,
-            BigInteger	a,
-            BigInteger	b)
-            : this(m, k, 0, 0, a, b, null, null)
-        {
-        }
-
-        /**
-         * Constructor for Trinomial Polynomial Basis (TPB).
-         * @param m  The exponent <code>m</code> of
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         * @param k 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>.
-         * @param a The coefficient <code>a</code> in the Weierstrass equation
-         * for non-supersingular elliptic curves over
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         * @param b The coefficient <code>b</code> in the Weierstrass equation
-         * for non-supersingular elliptic curves over
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         * @param order The order of the main subgroup of the elliptic curve.
-         * @param cofactor The cofactor of the elliptic curve, i.e.
-         * <code>#E<sub>a</sub>(F<sub>2<sup>m</sup></sub>) = h * n</code>.
-         */
-        public F2mCurve(
-            int			m, 
-            int			k, 
-            BigInteger	a, 
-            BigInteger	b,
-            BigInteger	order,
-            BigInteger	cofactor)
-            : this(m, k, 0, 0, a, b, order, cofactor)
-        {
-        }
-
-        /**
-         * Constructor for Pentanomial Polynomial Basis (PPB).
-         * @param m  The exponent <code>m</code> of
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         * @param k1 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>.
-         * @param k2 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>.
-         * @param k3 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>.
-         * @param a The coefficient <code>a</code> in the Weierstrass equation
-         * for non-supersingular elliptic curves over
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         * @param b The coefficient <code>b</code> in the Weierstrass equation
-         * for non-supersingular elliptic curves over
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         */
-        [Obsolete("Use constructor taking order/cofactor")]
-        public F2mCurve(
-            int			m,
-            int			k1,
-            int			k2,
-            int			k3,
-            BigInteger	a,
-            BigInteger	b)
-            : this(m, k1, k2, k3, a, b, null, null)
-        {
-        }
-
-        /**
-         * Constructor for Pentanomial Polynomial Basis (PPB).
-         * @param m  The exponent <code>m</code> of
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         * @param k1 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>.
-         * @param k2 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>.
-         * @param k3 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>.
-         * @param a The coefficient <code>a</code> in the Weierstrass equation
-         * for non-supersingular elliptic curves over
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         * @param b The coefficient <code>b</code> in the Weierstrass equation
-         * for non-supersingular elliptic curves over
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         * @param order The order of the main subgroup of the elliptic curve.
-         * @param cofactor The cofactor of the elliptic curve, i.e.
-         * <code>#E<sub>a</sub>(F<sub>2<sup>m</sup></sub>) = h * n</code>.
-         */
-        public F2mCurve(
-            int			m, 
-            int			k1, 
-            int			k2, 
-            int			k3,
-            BigInteger	a, 
-            BigInteger	b,
-            BigInteger	order,
-            BigInteger	cofactor)
-            : base(m, k1, k2, k3)
-        {
-            this.m = m;
-            this.k1 = k1;
-            this.k2 = k2;
-            this.k3 = k3;
-            this.m_order = order;
-            this.m_cofactor = cofactor;
-            this.m_infinity = new F2mPoint(this, null, null, false);
-
-            if (k1 == 0)
-                throw new ArgumentException("k1 must be > 0");
-
-            if (k2 == 0)
-            {
-                if (k3 != 0)
-                    throw new ArgumentException("k3 must be 0 if k2 == 0");
-            }
-            else
-            {
-                if (k2 <= k1)
-                    throw new ArgumentException("k2 must be > k1");
-
-                if (k3 <= k2)
-                    throw new ArgumentException("k3 must be > k2");
-            }
-
-            this.m_a = FromBigInteger(a);
-            this.m_b = FromBigInteger(b);
-            this.m_coord = F2M_DEFAULT_COORDS;
-        }
-
-        protected F2mCurve(int m, int k1, int k2, int k3, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor)
-            : base(m, k1, k2, k3)
-        {
-            this.m = m;
-            this.k1 = k1;
-            this.k2 = k2;
-            this.k3 = k3;
-            this.m_order = order;
-            this.m_cofactor = cofactor;
-
-            this.m_infinity = new F2mPoint(this, null, null, false);
-            this.m_a = a;
-            this.m_b = b;
-            this.m_coord = F2M_DEFAULT_COORDS;
-        }
-
-        protected override ECCurve CloneCurve()
-        {
-            return new F2mCurve(m, k1, k2, k3, m_a, m_b, m_order, m_cofactor);
-        }
-
-        public override bool SupportsCoordinateSystem(int coord)
-        {
-            switch (coord)
-            {
-                case COORD_AFFINE:
-                case COORD_HOMOGENEOUS:
-                case COORD_LAMBDA_PROJECTIVE:
-                    return true;
-                default:
-                    return false;
-            }
-        }
-
-        protected override ECMultiplier CreateDefaultMultiplier()
-        {
-            if (IsKoblitz)
-            {
-                return new WTauNafMultiplier();
-            }
-
-            return base.CreateDefaultMultiplier();
-        }
-
-        public override int FieldSize
-        {
-            get { return m; }
-        }
-
-        public override ECFieldElement FromBigInteger(BigInteger x)
-        {
-            return new F2mFieldElement(this.m, this.k1, this.k2, this.k3, x);
-        }
-
-        protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
-        {
-            return new F2mPoint(this, x, y, withCompression);
-        }
-
-        protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
-        {
-            return new F2mPoint(this, x, y, zs, withCompression);
-        }
-
-        public override ECPoint Infinity
-        {
-            get { return m_infinity; }
-        }
-
-        public int M
-        {
-            get { return m; }
-        }
-
-        /**
-         * Return true if curve uses a Trinomial basis.
-         *
-         * @return true if curve Trinomial, false otherwise.
-         */
-        public bool IsTrinomial()
-        {
-            return k2 == 0 && k3 == 0;
-        }
-
-        public int K1
-        {
-            get { return k1; }
-        }
-
-        public int K2
-        {
-            get { return k2; }
-        }
-
-        public int K3
-        {
-            get { return k3; }
-        }
-
-        public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
-        {
-            int FE_LONGS = (m + 63) / 64;
-
-            long[] table = new long[len * FE_LONGS * 2];
-            {
-                int pos = 0;
-                for (int i = 0; i < len; ++i)
-                {
-                    ECPoint p = points[off + i];
-                    ((F2mFieldElement)p.RawXCoord).x.CopyTo(table, pos); pos += FE_LONGS;
-                    ((F2mFieldElement)p.RawYCoord).x.CopyTo(table, pos); pos += FE_LONGS;
-                }
-            }
-
-            return new DefaultF2mLookupTable(this, table, len);
-        }
-
-        private class DefaultF2mLookupTable
-            : ECLookupTable
-        {
-            private readonly F2mCurve m_outer;
-            private readonly long[] m_table;
-            private readonly int m_size;
-
-            internal DefaultF2mLookupTable(F2mCurve outer, long[] table, int size)
-            {
-                this.m_outer = outer;
-                this.m_table = table;
-                this.m_size = size;
-            }
-
-            public virtual int Size
-            {
-                get { return m_size; }
-            }
-
-            public virtual ECPoint Lookup(int index)
-            {
-                int m = m_outer.m;
-                int[] ks = m_outer.IsTrinomial() ? new int[]{ m_outer.k1 } : new int[]{ m_outer.k1, m_outer.k2, m_outer.k3 }; 
-
-                int FE_LONGS = (m_outer.m + 63) / 64;
-                long[] x = new long[FE_LONGS], y = new long[FE_LONGS];
-                int pos = 0;
-
-                for (int i = 0; i < m_size; ++i)
-                {
-                    long MASK =((i ^ index) - 1) >> 31;
-
-                    for (int j = 0; j < FE_LONGS; ++j)
-                    {
-                        x[j] ^= m_table[pos + j] & MASK;
-                        y[j] ^= m_table[pos + FE_LONGS + j] & MASK;
-                    }
-
-                    pos += (FE_LONGS * 2);
-                }
-
-                ECFieldElement X = new F2mFieldElement(m, ks, new LongArray(x));
-                ECFieldElement Y = new F2mFieldElement(m, ks, new LongArray(y));
-                return m_outer.CreateRawPoint(X, Y, false);
-            }
-        }
-    }
-}

+ 0 - 972
src/Renci.SshNet/Security/BouncyCastle/math/ec/ECFieldElement.cs

@@ -1,972 +0,0 @@
-using System;
-using System.Diagnostics;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math.Raw;
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC
-{
-    internal 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((FieldSize + 7) / 8, ToBigInteger());
-        }
-    }
-
-    internal abstract class AbstractFpFieldElement
-        : ECFieldElement
-    {
-    }
-
-    internal 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;
-        }
-
-        [Obsolete("Use ECCurve.FromBigInteger to construct field elements")]
-        public FpFieldElement(BigInteger q, BigInteger x)
-            : this(q, CalculateResidue(q), x)
-        {
-        }
-
-        internal FpFieldElement(BigInteger q, BigInteger r, BigInteger x)
-        {
-            if (x == null || x.SignValue < 0 || x.CompareTo(q) >= 0)
-                throw new ArgumentException("value invalid in Fp field element", "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)
-        {
-            int bits = FieldSize;
-            int len = (bits + 31) >> 5;
-            uint[] p = Nat.FromBigInteger(bits, q);
-            uint[] n = Nat.FromBigInteger(bits, x);
-            uint[] z = Nat.Create(len);
-            Mod.Invert(p, n, z);
-            return Nat.ToBigInteger(len, z);
-        }
-
-        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();
-        }
-    }
-
-    internal 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 fe = this;
-            ECFieldElement ht = fe;
-            for (int i = 2; i < m; i += 2)
-            {
-                fe = fe.SquarePow(2);
-                ht = ht.Add(fe);
-            }
-
-            return ht;
-        }
-
-        public virtual int Trace()
-        {
-            int m = FieldSize;
-            ECFieldElement fe = this;
-            ECFieldElement tr = fe;
-            for (int i = 1; i < m; ++i)
-            {
-                fe = fe.Square();
-                tr = tr.Add(fe);
-            }
-            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.
-     */
-    internal 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;
-
-        /**
-         * Constructor for Ppb.
-         * @param m  The exponent <code>m</code> of
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         * @param k1 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>.
-         * @param k2 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>.
-         * @param k3 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>.
-         * @param x The BigInteger representing the value of the field element.
-         */
-        public F2mFieldElement(
-            int			m,
-            int			k1,
-            int			k2,
-            int			k3,
-            BigInteger	x)
-        {
-            if (x == null || x.SignValue < 0 || x.BitLength > m)
-                throw new ArgumentException("value invalid in F2m field element", "x");
-
-            if ((k2 == 0) && (k3 == 0))
-            {
-                this.representation = Tpb;
-                this.ks = new int[] { k1 };
-            }
-            else
-            {
-                if (k2 >= k3)
-                    throw new ArgumentException("k2 must be smaller than k3");
-                if (k2 <= 0)
-                    throw new ArgumentException("k2 must be larger than 0");
-
-                this.representation = Ppb;
-                this.ks = new int[] { k1, k2, k3 };
-            }
-
-            this.m = m;
-            this.x = new LongArray(x);
-        }
-
-        /**
-         * Constructor for Tpb.
-         * @param m  The exponent <code>m</code> of
-         * <code>F<sub>2<sup>m</sup></sub></code>.
-         * @param k 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>.
-         * @param x The BigInteger representing the value of the field element.
-         */
-        public F2mFieldElement(
-            int			m,
-            int			k,
-            BigInteger	x)
-            : this(m, k, 0, 0, x)
-        {
-            // Set k1 to k, and set k2 and k3 to 0
-        }
-
-        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 (ab == ax || ab == bx)
-            {
-                ab = (LongArray)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 (aa == ax)
-            {
-                aa = (LongArray)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);
-        }
-    }
-}

+ 0 - 10
src/Renci.SshNet/Security/BouncyCastle/math/ec/ECLookupTable.cs

@@ -1,10 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC
-{
-    internal interface ECLookupTable
-    {
-        int Size { get; }
-        ECPoint Lookup(int index);
-    }
-}

+ 0 - 2122
src/Renci.SshNet/Security/BouncyCastle/math/ec/ECPoint.cs

@@ -1,2122 +0,0 @@
-using System;
-using System.Collections;
-using System.Diagnostics;
-using System.Text;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC
-{
-    /**
-     * base class for points on elliptic curves.
-     */
-    internal abstract class ECPoint
-    {
-        protected static ECFieldElement[] EMPTY_ZS = new ECFieldElement[0];
-
-        protected static ECFieldElement[] GetInitialZCoords(ECCurve curve)
-        {
-            // Cope with null curve, most commonly used by implicitlyCa
-            int coord = null == curve ? ECCurve.COORD_AFFINE : curve.CoordinateSystem;
-
-            switch (coord)
-            {
-                case ECCurve.COORD_AFFINE:
-                case ECCurve.COORD_LAMBDA_AFFINE:
-                    return EMPTY_ZS;
-                default:
-                    break;
-            }
-
-            ECFieldElement one = curve.FromBigInteger(BigInteger.One);
-
-            switch (coord)
-            {
-                case ECCurve.COORD_HOMOGENEOUS:
-                case ECCurve.COORD_JACOBIAN:
-                case ECCurve.COORD_LAMBDA_PROJECTIVE:
-                    return new ECFieldElement[] { one };
-                case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
-                    return new ECFieldElement[] { one, one, one };
-                case ECCurve.COORD_JACOBIAN_MODIFIED:
-                    return new ECFieldElement[] { one, curve.A };
-                default:
-                    throw new ArgumentException("unknown coordinate system");
-            }
-        }
-
-        protected internal readonly ECCurve m_curve;
-        protected internal readonly ECFieldElement m_x, m_y;
-        protected internal readonly ECFieldElement[] m_zs;
-        protected internal readonly bool m_withCompression;
-
-        // Dictionary is (string -> PreCompInfo)
-        protected internal IDictionary m_preCompTable = null;
-
-        protected ECPoint(ECCurve curve, ECFieldElement	x, ECFieldElement y, bool withCompression)
-            : this(curve, x, y, GetInitialZCoords(curve), withCompression)
-        {
-        }
-
-        internal ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
-        {
-            this.m_curve = curve;
-            this.m_x = x;
-            this.m_y = y;
-            this.m_zs = zs;
-            this.m_withCompression = withCompression;
-        }
-
-        protected abstract bool SatisfiesCurveEquation();
-
-        protected virtual bool SatisfiesOrder()
-        {
-            if (BigInteger.One.Equals(Curve.Cofactor))
-                return true;
-
-            BigInteger n = Curve.Order;
-
-            // TODO Require order to be available for all curves
-
-            return n == null || ECAlgorithms.ReferenceMultiply(this, n).IsInfinity;
-        }
-
-        public ECPoint GetDetachedPoint()
-        {
-            return Normalize().Detach();
-        }
-
-        public virtual ECCurve Curve
-        {
-            get { return m_curve; }
-        }
-
-        protected abstract ECPoint Detach();
-
-        protected virtual int CurveCoordinateSystem
-        {
-            get
-            {
-                // Cope with null curve, most commonly used by implicitlyCa
-                return null == m_curve ? ECCurve.COORD_AFFINE : m_curve.CoordinateSystem;
-            }
-        }
-
-        /**
-         * Returns the affine x-coordinate after checking that this point is normalized.
-         * 
-         * @return The affine x-coordinate of this point
-         * @throws IllegalStateException if the point is not normalized
-         */
-        public virtual ECFieldElement AffineXCoord
-        {
-            get
-            {
-                CheckNormalized();
-                return XCoord;
-            }
-        }
-
-        /**
-         * Returns the affine y-coordinate after checking that this point is normalized
-         * 
-         * @return The affine y-coordinate of this point
-         * @throws IllegalStateException if the point is not normalized
-         */
-        public virtual ECFieldElement AffineYCoord
-        {
-            get
-            {
-                CheckNormalized();
-                return YCoord;
-            }
-        }
-
-        /**
-         * Returns the x-coordinate.
-         * 
-         * Caution: depending on the curve's coordinate system, this may not be the same value as in an
-         * affine coordinate system; use Normalize() to get a point where the coordinates have their
-         * affine values, or use AffineXCoord if you expect the point to already have been normalized.
-         * 
-         * @return the x-coordinate of this point
-         */
-        public virtual ECFieldElement XCoord
-        {
-            get { return m_x; }
-        }
-
-        /**
-         * Returns the y-coordinate.
-         * 
-         * Caution: depending on the curve's coordinate system, this may not be the same value as in an
-         * affine coordinate system; use Normalize() to get a point where the coordinates have their
-         * affine values, or use AffineYCoord if you expect the point to already have been normalized.
-         * 
-         * @return the y-coordinate of this point
-         */
-        public virtual ECFieldElement YCoord
-        {
-            get { return m_y; }
-        }
-
-        public virtual ECFieldElement GetZCoord(int index)
-        {
-            return (index < 0 || index >= m_zs.Length) ? null : m_zs[index];
-        }
-
-        public virtual ECFieldElement[] GetZCoords()
-        {
-            int zsLen = m_zs.Length;
-            if (zsLen == 0)
-            {
-                return m_zs;
-            }
-            ECFieldElement[] copy = new ECFieldElement[zsLen];
-            Array.Copy(m_zs, 0, copy, 0, zsLen);
-            return copy;
-        }
-
-        protected internal ECFieldElement RawXCoord
-        {
-            get { return m_x; }
-        }
-
-        protected internal ECFieldElement RawYCoord
-        {
-            get { return m_y; }
-        }
-
-        protected internal ECFieldElement[] RawZCoords
-        {
-            get { return m_zs; }
-        }
-
-        protected virtual void CheckNormalized()
-        {
-            if (!IsNormalized())
-                throw new InvalidOperationException("point not in normal form");
-        }
-
-        public virtual bool IsNormalized()
-        {
-            int coord = this.CurveCoordinateSystem;
-
-            return coord == ECCurve.COORD_AFFINE
-                || coord == ECCurve.COORD_LAMBDA_AFFINE
-                || IsInfinity
-                || RawZCoords[0].IsOne;
-        }
-
-        /**
-         * Normalization ensures that any projective coordinate is 1, and therefore that the x, y
-         * coordinates reflect those of the equivalent point in an affine coordinate system.
-         * 
-         * @return a new ECPoint instance representing the same point, but with normalized coordinates
-         */
-        public virtual ECPoint Normalize()
-        {
-            if (this.IsInfinity)
-            {
-                return this;
-            }
-
-            switch (this.CurveCoordinateSystem)
-            {
-                case ECCurve.COORD_AFFINE:
-                case ECCurve.COORD_LAMBDA_AFFINE:
-                {
-                    return this;
-                }
-                default:
-                {
-                    ECFieldElement Z1 = RawZCoords[0];
-                    if (Z1.IsOne)
-                    {
-                        return this;
-                    }
-
-                    return Normalize(Z1.Invert());
-                }
-            }
-        }
-
-        internal virtual ECPoint Normalize(ECFieldElement zInv)
-        {
-            switch (this.CurveCoordinateSystem)
-            {
-                case ECCurve.COORD_HOMOGENEOUS:
-                case ECCurve.COORD_LAMBDA_PROJECTIVE:
-                {
-                    return CreateScaledPoint(zInv, zInv);
-                }
-                case ECCurve.COORD_JACOBIAN:
-                case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
-                case ECCurve.COORD_JACOBIAN_MODIFIED:
-                {
-                    ECFieldElement zInv2 = zInv.Square(), zInv3 = zInv2.Multiply(zInv);
-                    return CreateScaledPoint(zInv2, zInv3);
-                }
-                default:
-                {
-                    throw new InvalidOperationException("not a projective coordinate system");
-                }
-            }
-        }
-
-        protected virtual ECPoint CreateScaledPoint(ECFieldElement sx, ECFieldElement sy)
-        {
-            return Curve.CreateRawPoint(RawXCoord.Multiply(sx), RawYCoord.Multiply(sy), IsCompressed);
-        }
-
-        public bool IsInfinity
-        {
-            get { return m_x == null && m_y == null; }
-        }
-
-        public bool IsCompressed
-        {
-            get { return m_withCompression; }
-        }
-
-        public bool IsValid()
-        {
-            return ImplIsValid(false, true);
-        }
-
-        internal bool IsValidPartial()
-        {
-            return ImplIsValid(false, false);
-        }
-
-        internal bool ImplIsValid(bool decompressed, bool checkOrder)
-        {
-            if (IsInfinity)
-                return true;
-
-            ValidityCallback callback = new ValidityCallback(this, decompressed, checkOrder);
-            ValidityPreCompInfo validity = (ValidityPreCompInfo)Curve.Precompute(this, ValidityPreCompInfo.PRECOMP_NAME, callback);
-            return !validity.HasFailed();
-        }
-
-        public virtual ECPoint ScaleX(ECFieldElement scale)
-        {
-            return IsInfinity
-                ? this
-                : Curve.CreateRawPoint(RawXCoord.Multiply(scale), RawYCoord, RawZCoords, IsCompressed);
-        }
-
-        public virtual ECPoint ScaleY(ECFieldElement scale)
-        {
-            return IsInfinity
-                ? this
-                : Curve.CreateRawPoint(RawXCoord, RawYCoord.Multiply(scale), RawZCoords, IsCompressed);
-        }
-
-        public override bool Equals(object obj)
-        {
-            return Equals(obj as ECPoint);
-        }
-
-        public virtual bool Equals(ECPoint other)
-        {
-            if (this == other)
-                return true;
-            if (null == other)
-                return false;
-
-            ECCurve c1 = this.Curve, c2 = other.Curve;
-            bool n1 = (null == c1), n2 = (null == c2);
-            bool i1 = IsInfinity, i2 = other.IsInfinity;
-
-            if (i1 || i2)
-            {
-                return (i1 && i2) && (n1 || n2 || c1.Equals(c2));
-            }
-
-            ECPoint p1 = this, p2 = other;
-            if (n1 && n2)
-            {
-                // Points with null curve are in affine form, so already normalized
-            }
-            else if (n1)
-            {
-                p2 = p2.Normalize();
-            }
-            else if (n2)
-            {
-                p1 = p1.Normalize();
-            }
-            else if (!c1.Equals(c2))
-            {
-                return false;
-            }
-            else
-            {
-                // TODO Consider just requiring already normalized, to avoid silent performance degradation
-
-                ECPoint[] points = new ECPoint[] { this, c1.ImportPoint(p2) };
-
-                // TODO This is a little strong, really only requires coZNormalizeAll to get Zs equal
-                c1.NormalizeAll(points);
-
-                p1 = points[0];
-                p2 = points[1];
-            }
-
-            return p1.XCoord.Equals(p2.XCoord) && p1.YCoord.Equals(p2.YCoord);
-        }
-
-        public override int GetHashCode()
-        {
-            ECCurve c = this.Curve;
-            int hc = (null == c) ? 0 : ~c.GetHashCode();
-
-            if (!this.IsInfinity)
-            {
-                // TODO Consider just requiring already normalized, to avoid silent performance degradation
-
-                ECPoint p = Normalize();
-
-                hc ^= p.XCoord.GetHashCode() * 17;
-                hc ^= p.YCoord.GetHashCode() * 257;
-            }
-
-            return hc;
-        }
-
-        public override string ToString()
-        {
-            if (this.IsInfinity)
-            {
-                return "INF";
-            }
-
-            StringBuilder sb = new StringBuilder();
-            sb.Append('(');
-            sb.Append(RawXCoord);
-            sb.Append(',');
-            sb.Append(RawYCoord);
-            for (int i = 0; i < m_zs.Length; ++i)
-            {
-                sb.Append(',');
-                sb.Append(m_zs[i]);
-            }
-            sb.Append(')');
-            return sb.ToString();
-        }
-
-        public virtual byte[] GetEncoded()
-        {
-            return GetEncoded(m_withCompression);
-        }
-
-        public abstract byte[] GetEncoded(bool compressed);
-
-        protected internal abstract bool CompressionYTilde { get; }
-
-        public abstract ECPoint Add(ECPoint b);
-        public abstract ECPoint Subtract(ECPoint b);
-        public abstract ECPoint Negate();
-
-        public virtual ECPoint TimesPow2(int e)
-        {
-            if (e < 0)
-                throw new ArgumentException("cannot be negative", "e");
-
-            ECPoint p = this;
-            while (--e >= 0)
-            {
-                p = p.Twice();
-            }
-            return p;
-        }
-
-        public abstract ECPoint Twice();
-        public abstract ECPoint Multiply(BigInteger b);
-
-        public virtual ECPoint TwicePlus(ECPoint b)
-        {
-            return Twice().Add(b);
-        }
-
-        public virtual ECPoint ThreeTimes()
-        {
-            return TwicePlus(this);
-        }
-
-        private class ValidityCallback
-            : IPreCompCallback
-        {
-            private readonly ECPoint m_outer;
-            private readonly bool m_decompressed, m_checkOrder;
-
-            internal ValidityCallback(ECPoint outer, bool decompressed, bool checkOrder)
-            {
-                this.m_outer = outer;
-                this.m_decompressed = decompressed;
-                this.m_checkOrder = checkOrder;
-            }
-
-            public PreCompInfo Precompute(PreCompInfo existing)
-            {
-                ValidityPreCompInfo info = existing as ValidityPreCompInfo;
-                if (info == null)
-                {
-                    info = new ValidityPreCompInfo();
-                }
-
-                if (info.HasFailed())
-                    return info;
-
-                if (!info.HasCurveEquationPassed())
-                {
-                    if (!m_decompressed && !m_outer.SatisfiesCurveEquation())
-                    {
-                        info.ReportFailed();
-                        return info;
-                    }
-                    info.ReportCurveEquationPassed();
-                }
-                if (m_checkOrder && !info.HasOrderPassed())
-                {
-                    if (!m_outer.SatisfiesOrder())
-                    {
-                        info.ReportFailed();
-                        return info;
-                    }
-                    info.ReportOrderPassed();
-                }
-                return info;
-            }
-        }
-    }
-
-    internal abstract class ECPointBase
-        : ECPoint
-    {
-        protected internal ECPointBase(
-            ECCurve			curve,
-            ECFieldElement	x,
-            ECFieldElement	y,
-            bool			withCompression)
-            : base(curve, x, y, withCompression)
-        {
-        }
-
-        protected internal ECPointBase(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
-            : base(curve, x, y, zs, withCompression)
-        {
-        }
-
-        /**
-         * return the field element encoded with point compression. (S 4.3.6)
-         */
-        public override byte[] GetEncoded(bool compressed)
-        {
-            if (this.IsInfinity)
-            {
-                return new byte[1];
-            }
-
-            ECPoint normed = Normalize();
-
-            byte[] X = normed.XCoord.GetEncoded();
-
-            if (compressed)
-            {
-                byte[] PO = new byte[X.Length + 1];
-                PO[0] = (byte)(normed.CompressionYTilde ? 0x03 : 0x02);
-                Array.Copy(X, 0, PO, 1, X.Length);
-                return PO;
-            }
-
-            byte[] Y = normed.YCoord.GetEncoded();
-
-            {
-                byte[] PO = new byte[X.Length + Y.Length + 1];
-                PO[0] = 0x04;
-                Array.Copy(X, 0, PO, 1, X.Length);
-                Array.Copy(Y, 0, PO, X.Length + 1, Y.Length);
-                return PO;
-            }
-        }
-
-        /**
-         * Multiplies this <code>ECPoint</code> by the given number.
-         * @param k The multiplicator.
-         * @return <code>k * this</code>.
-         */
-        public override ECPoint Multiply(BigInteger k)
-        {
-            return this.Curve.GetMultiplier().Multiply(this, k);
-        }
-    }
-
-    internal abstract class AbstractFpPoint
-        : ECPointBase
-    {
-        protected AbstractFpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
-            : base(curve, x, y, withCompression)
-        {
-        }
-
-        protected AbstractFpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
-            : base(curve, x, y, zs, withCompression)
-        {
-        }
-
-        protected internal override bool CompressionYTilde
-        {
-            get { return this.AffineYCoord.TestBitZero(); }
-        }
-
-        protected override bool SatisfiesCurveEquation()
-        {
-            ECFieldElement X = this.RawXCoord, Y = this.RawYCoord, A = Curve.A, B = Curve.B;
-            ECFieldElement lhs = Y.Square();
-
-            switch (CurveCoordinateSystem)
-            {
-            case ECCurve.COORD_AFFINE:
-                break;
-            case ECCurve.COORD_HOMOGENEOUS:
-            {
-                ECFieldElement Z = this.RawZCoords[0];
-                if (!Z.IsOne)
-                {
-                    ECFieldElement Z2 = Z.Square(), Z3 = Z.Multiply(Z2);
-                    lhs = lhs.Multiply(Z);
-                    A = A.Multiply(Z2);
-                    B = B.Multiply(Z3);
-                }
-                break;
-            }
-            case ECCurve.COORD_JACOBIAN:
-            case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
-            case ECCurve.COORD_JACOBIAN_MODIFIED:
-            {
-                ECFieldElement Z = this.RawZCoords[0];
-                if (!Z.IsOne)
-                {
-                    ECFieldElement Z2 = Z.Square(), Z4 = Z2.Square(), Z6 = Z2.Multiply(Z4);
-                    A = A.Multiply(Z4);
-                    B = B.Multiply(Z6);
-                }
-                break;
-            }
-            default:
-                throw new InvalidOperationException("unsupported coordinate system");
-            }
-
-            ECFieldElement rhs = X.Square().Add(A).Multiply(X).Add(B);
-            return lhs.Equals(rhs);
-        }
-
-        public override ECPoint Subtract(ECPoint b)
-        {
-            if (b.IsInfinity)
-                return this;
-
-            // Add -b
-            return Add(b.Negate());
-        }
-    }
-
-    /**
-     * Elliptic curve points over Fp
-     */
-    internal class FpPoint
-        : AbstractFpPoint
-    {
-        /**
-         * Create a point which encodes without point compression.
-         *
-         * @param curve the curve to use
-         * @param x affine x co-ordinate
-         * @param y affine y co-ordinate
-         */
-        public FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y)
-            : this(curve, x, y, false)
-        {
-        }
-
-        /**
-         * Create a point that encodes with or without point compression.
-         *
-         * @param curve the curve to use
-         * @param x affine x co-ordinate
-         * @param y affine y co-ordinate
-         * @param withCompression if true encode with point compression
-         */
-        public FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
-            : base(curve, x, y, withCompression)
-        {
-            if ((x == null) != (y == null))
-                throw new ArgumentException("Exactly one of the field elements is null");
-        }
-
-        internal FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
-            : base(curve, x, y, zs, withCompression)
-        {
-        }
-
-        protected override ECPoint Detach()
-        {
-            return new FpPoint(null, AffineXCoord, AffineYCoord, false);
-        }
-
-        public override ECFieldElement GetZCoord(int index)
-        {
-            if (index == 1 && ECCurve.COORD_JACOBIAN_MODIFIED == this.CurveCoordinateSystem)
-            {
-                return GetJacobianModifiedW();
-            }
-
-            return base.GetZCoord(index);
-        }
-
-        // 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;
-            int coord = curve.CoordinateSystem;
-
-            ECFieldElement X1 = this.RawXCoord, Y1 = this.RawYCoord;
-            ECFieldElement X2 = b.RawXCoord, Y2 = b.RawYCoord;
-
-            switch (coord)
-            {
-                case ECCurve.COORD_AFFINE:
-                {
-                    ECFieldElement dx = X2.Subtract(X1), dy = Y2.Subtract(Y1);
-
-                    if (dx.IsZero)
-                    {
-                        if (dy.IsZero)
-                        {
-                            // this == b, i.e. this must be doubled
-                            return Twice();
-                        }
-
-                        // this == -b, i.e. the result is the point at infinity
-                        return Curve.Infinity;
-                    }
-
-                    ECFieldElement gamma = dy.Divide(dx);
-                    ECFieldElement X3 = gamma.Square().Subtract(X1).Subtract(X2);
-                    ECFieldElement Y3 = gamma.Multiply(X1.Subtract(X3)).Subtract(Y1);
-
-                    return new FpPoint(Curve, X3, Y3, IsCompressed);
-                }
-
-                case ECCurve.COORD_HOMOGENEOUS:
-                {
-                    ECFieldElement Z1 = this.RawZCoords[0];
-                    ECFieldElement Z2 = b.RawZCoords[0];
-
-                    bool Z1IsOne = Z1.IsOne;
-                    bool Z2IsOne = Z2.IsOne;
-
-                    ECFieldElement u1 = Z1IsOne ? Y2 : Y2.Multiply(Z1);
-                    ECFieldElement u2 = Z2IsOne ? Y1 : Y1.Multiply(Z2);
-                    ECFieldElement u = u1.Subtract(u2);
-                    ECFieldElement v1 = Z1IsOne ? X2 : X2.Multiply(Z1);
-                    ECFieldElement v2 = Z2IsOne ? X1 : X1.Multiply(Z2);
-                    ECFieldElement v = v1.Subtract(v2);
-
-                    // Check if b == this or b == -this
-                    if (v.IsZero)
-                    {
-                        if (u.IsZero)
-                        {
-                            // 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;
-                    }
-
-                    // TODO Optimize for when w == 1
-                    ECFieldElement w = Z1IsOne ? Z2 : Z2IsOne ? Z1 : Z1.Multiply(Z2);
-                    ECFieldElement vSquared = v.Square();
-                    ECFieldElement vCubed = vSquared.Multiply(v);
-                    ECFieldElement vSquaredV2 = vSquared.Multiply(v2);
-                    ECFieldElement A = u.Square().Multiply(w).Subtract(vCubed).Subtract(Two(vSquaredV2));
-
-                    ECFieldElement X3 = v.Multiply(A);
-                    ECFieldElement Y3 = vSquaredV2.Subtract(A).MultiplyMinusProduct(u, u2, vCubed);
-                    ECFieldElement Z3 = vCubed.Multiply(w);
-
-                    return new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed);
-                }
-
-                case ECCurve.COORD_JACOBIAN:
-                case ECCurve.COORD_JACOBIAN_MODIFIED:
-                {
-                    ECFieldElement Z1 = this.RawZCoords[0];
-                    ECFieldElement Z2 = b.RawZCoords[0];
-
-                    bool Z1IsOne = Z1.IsOne;
-
-                    ECFieldElement X3, Y3, Z3, Z3Squared = null;
-
-                    if (!Z1IsOne && Z1.Equals(Z2))
-                    {
-                        // TODO Make this available as public method coZAdd?
-
-                        ECFieldElement dx = X1.Subtract(X2), dy = Y1.Subtract(Y2);
-                        if (dx.IsZero)
-                        {
-                            if (dy.IsZero)
-                            {
-                                return Twice();
-                            }
-                            return curve.Infinity;
-                        }
-
-                        ECFieldElement C = dx.Square();
-                        ECFieldElement W1 = X1.Multiply(C), W2 = X2.Multiply(C);
-                        ECFieldElement A1 = W1.Subtract(W2).Multiply(Y1);
-
-                        X3 = dy.Square().Subtract(W1).Subtract(W2);
-                        Y3 = W1.Subtract(X3).Multiply(dy).Subtract(A1);
-                        Z3 = dx;
-
-                        if (Z1IsOne)
-                        {
-                            Z3Squared = C;
-                        }
-                        else
-                        {
-                            Z3 = Z3.Multiply(Z1);
-                        }
-                    }
-                    else
-                    {
-                        ECFieldElement Z1Squared, U2, S2;
-                        if (Z1IsOne)
-                        {
-                            Z1Squared = Z1; U2 = X2; S2 = Y2;
-                        }
-                        else
-                        {
-                            Z1Squared = Z1.Square();
-                            U2 = Z1Squared.Multiply(X2);
-                            ECFieldElement Z1Cubed = Z1Squared.Multiply(Z1);
-                            S2 = Z1Cubed.Multiply(Y2);
-                        }
-
-                        bool Z2IsOne = Z2.IsOne;
-                        ECFieldElement Z2Squared, U1, S1;
-                        if (Z2IsOne)
-                        {
-                            Z2Squared = Z2; U1 = X1; S1 = Y1;
-                        }
-                        else
-                        {
-                            Z2Squared = Z2.Square();
-                            U1 = Z2Squared.Multiply(X1);
-                            ECFieldElement Z2Cubed = Z2Squared.Multiply(Z2);
-                            S1 = Z2Cubed.Multiply(Y1);
-                        }
-
-                        ECFieldElement H = U1.Subtract(U2);
-                        ECFieldElement R = S1.Subtract(S2);
-
-                        // Check if b == this or b == -this
-                        if (H.IsZero)
-                        {
-                            if (R.IsZero)
-                            {
-                                // 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;
-                        }
-
-                        ECFieldElement HSquared = H.Square();
-                        ECFieldElement G = HSquared.Multiply(H);
-                        ECFieldElement V = HSquared.Multiply(U1);
-
-                        X3 = R.Square().Add(G).Subtract(Two(V));
-                        Y3 = V.Subtract(X3).MultiplyMinusProduct(R, G, S1);
-
-                        Z3 = H;
-                        if (!Z1IsOne)
-                        {
-                            Z3 = Z3.Multiply(Z1);
-                        }
-                        if (!Z2IsOne)
-                        {
-                            Z3 = Z3.Multiply(Z2);
-                        }
-
-                        // Alternative calculation of Z3 using fast square
-                        //X3 = four(X3);
-                        //Y3 = eight(Y3);
-                        //Z3 = doubleProductFromSquares(Z1, Z2, Z1Squared, Z2Squared).Multiply(H);
-
-                        if (Z3 == H)
-                        {
-                            Z3Squared = HSquared;
-                        }
-                    }
-
-                    ECFieldElement[] zs;
-                    if (coord == ECCurve.COORD_JACOBIAN_MODIFIED)
-                    {
-                        // TODO If the result will only be used in a subsequent addition, we don't need W3
-                        ECFieldElement W3 = CalculateJacobianModifiedW(Z3, Z3Squared);
-
-                        zs = new ECFieldElement[] { Z3, W3 };
-                    }
-                    else
-                    {
-                        zs = new ECFieldElement[] { Z3 };
-                    }
-
-                    return new FpPoint(curve, X3, Y3, zs, IsCompressed);
-                }
-
-                default:
-                {
-                    throw new InvalidOperationException("unsupported coordinate system");
-                }
-            }
-        }
-
-        // B.3 pg 62
-        public override ECPoint Twice()
-        {
-            if (this.IsInfinity)
-                return this;
-
-            ECCurve curve = this.Curve;
-
-            ECFieldElement Y1 = this.RawYCoord;
-            if (Y1.IsZero) 
-                return curve.Infinity;
-
-            int coord = curve.CoordinateSystem;
-
-            ECFieldElement X1 = this.RawXCoord;
-
-            switch (coord)
-            {
-                case ECCurve.COORD_AFFINE:
-                {
-                    ECFieldElement X1Squared = X1.Square();
-                    ECFieldElement gamma = Three(X1Squared).Add(this.Curve.A).Divide(Two(Y1));
-                    ECFieldElement X3 = gamma.Square().Subtract(Two(X1));
-                    ECFieldElement Y3 = gamma.Multiply(X1.Subtract(X3)).Subtract(Y1);
-
-                    return new FpPoint(Curve, X3, Y3, IsCompressed);
-                }
-
-                case ECCurve.COORD_HOMOGENEOUS:
-                {
-                    ECFieldElement Z1 = this.RawZCoords[0];
-
-                    bool Z1IsOne = Z1.IsOne;
-
-                    // TODO Optimize for small negative a4 and -3
-                    ECFieldElement w = curve.A;
-                    if (!w.IsZero && !Z1IsOne)
-                    {
-                        w = w.Multiply(Z1.Square());
-                    }
-                    w = w.Add(Three(X1.Square()));
-
-                    ECFieldElement s = Z1IsOne ? Y1 : Y1.Multiply(Z1);
-                    ECFieldElement t = Z1IsOne ? Y1.Square() : s.Multiply(Y1);
-                    ECFieldElement B = X1.Multiply(t);
-                    ECFieldElement _4B = Four(B);
-                    ECFieldElement h = w.Square().Subtract(Two(_4B));
-
-                    ECFieldElement _2s = Two(s);
-                    ECFieldElement X3 = h.Multiply(_2s);
-                    ECFieldElement _2t = Two(t);
-                    ECFieldElement Y3 = _4B.Subtract(h).Multiply(w).Subtract(Two(_2t.Square()));
-                    ECFieldElement _4sSquared = Z1IsOne ? Two(_2t) : _2s.Square();
-                    ECFieldElement Z3 = Two(_4sSquared).Multiply(s);
-
-                    return new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed);
-                }
-
-                case ECCurve.COORD_JACOBIAN:
-                {
-                    ECFieldElement Z1 = this.RawZCoords[0];
-
-                    bool Z1IsOne = Z1.IsOne;
-
-                    ECFieldElement Y1Squared = Y1.Square();
-                    ECFieldElement T = Y1Squared.Square();
-
-                    ECFieldElement a4 = curve.A;
-                    ECFieldElement a4Neg = a4.Negate();
-
-                    ECFieldElement M, S;
-                    if (a4Neg.ToBigInteger().Equals(BigInteger.ValueOf(3)))
-                    {
-                        ECFieldElement Z1Squared = Z1IsOne ? Z1 : Z1.Square();
-                        M = Three(X1.Add(Z1Squared).Multiply(X1.Subtract(Z1Squared)));
-                        S = Four(Y1Squared.Multiply(X1));
-                    }
-                    else
-                    {
-                        ECFieldElement X1Squared = X1.Square();
-                        M = Three(X1Squared);
-                        if (Z1IsOne)
-                        {
-                            M = M.Add(a4);
-                        }
-                        else if (!a4.IsZero)
-                        {
-                            ECFieldElement Z1Squared = Z1IsOne ? Z1 : Z1.Square();
-                            ECFieldElement Z1Pow4 = Z1Squared.Square();
-                            if (a4Neg.BitLength < a4.BitLength)
-                            {
-                                M = M.Subtract(Z1Pow4.Multiply(a4Neg));
-                            }
-                            else
-                            {
-                                M = M.Add(Z1Pow4.Multiply(a4));
-                            }
-                        }
-                        //S = two(doubleProductFromSquares(X1, Y1Squared, X1Squared, T));
-                        S = Four(X1.Multiply(Y1Squared));
-                    }
-
-                    ECFieldElement X3 = M.Square().Subtract(Two(S));
-                    ECFieldElement Y3 = S.Subtract(X3).Multiply(M).Subtract(Eight(T));
-
-                    ECFieldElement Z3 = Two(Y1);
-                    if (!Z1IsOne)
-                    {
-                        Z3 = Z3.Multiply(Z1);
-                    }
-
-                    // Alternative calculation of Z3 using fast square
-                    //ECFieldElement Z3 = doubleProductFromSquares(Y1, Z1, Y1Squared, Z1Squared);
-
-                    return new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed);
-                }
-
-                case ECCurve.COORD_JACOBIAN_MODIFIED:
-                {
-                    return TwiceJacobianModified(true);
-                }
-
-                default:
-                {
-                    throw new InvalidOperationException("unsupported coordinate system");
-                }
-            }
-        }
-
-        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;
-
-            ECCurve curve = this.Curve;
-            int coord = curve.CoordinateSystem;
-
-            switch (coord)
-            {
-                case ECCurve.COORD_AFFINE:
-                {
-                    ECFieldElement X1 = this.RawXCoord;
-                    ECFieldElement X2 = b.RawXCoord, Y2 = b.RawYCoord;
-
-                    ECFieldElement dx = X2.Subtract(X1), dy = Y2.Subtract(Y1);
-
-                    if (dx.IsZero)
-                    {
-                        if (dy.IsZero)
-                        {
-                            // this == b i.e. the result is 3P
-                            return ThreeTimes();
-                        }
-
-                        // this == -b, i.e. the result is P
-                        return this;
-                    }
-
-                    /*
-                     * Optimized calculation of 2P + Q, as described in "Trading Inversions for
-                     * Multiplications in Elliptic Curve Cryptography", by Ciet, Joye, Lauter, Montgomery.
-                     */
-
-                    ECFieldElement X = dx.Square(), Y = dy.Square();
-                    ECFieldElement d = X.Multiply(Two(X1).Add(X2)).Subtract(Y);
-                    if (d.IsZero)
-                    {
-                        return Curve.Infinity;
-                    }
-
-                    ECFieldElement D = d.Multiply(dx);
-                    ECFieldElement I = D.Invert();
-                    ECFieldElement L1 = d.Multiply(I).Multiply(dy);
-                    ECFieldElement L2 = Two(Y1).Multiply(X).Multiply(dx).Multiply(I).Subtract(L1);
-                    ECFieldElement X4 = (L2.Subtract(L1)).Multiply(L1.Add(L2)).Add(X2);
-                    ECFieldElement Y4 = (X1.Subtract(X4)).Multiply(L2).Subtract(Y1);
-
-                    return new FpPoint(Curve, X4, Y4, IsCompressed);
-                }
-                case ECCurve.COORD_JACOBIAN_MODIFIED:
-                {
-                    return TwiceJacobianModified(false).Add(b);
-                }
-                default:
-                {
-                    return Twice().Add(b);
-                }
-            }
-        }
-
-        public override ECPoint ThreeTimes()
-        {
-            if (this.IsInfinity)
-                return this;
-
-            ECFieldElement Y1 = this.RawYCoord;
-            if (Y1.IsZero)
-                return this;
-
-            ECCurve curve = this.Curve;
-            int coord = curve.CoordinateSystem;
-
-            switch (coord)
-            {
-                case ECCurve.COORD_AFFINE:
-                {
-                    ECFieldElement X1 = this.RawXCoord;
-
-                    ECFieldElement _2Y1 = Two(Y1);
-                    ECFieldElement X = _2Y1.Square();
-                    ECFieldElement Z = Three(X1.Square()).Add(Curve.A);
-                    ECFieldElement Y = Z.Square();
-
-                    ECFieldElement d = Three(X1).Multiply(X).Subtract(Y);
-                    if (d.IsZero)
-                    {
-                        return Curve.Infinity;
-                    }
-
-                    ECFieldElement D = d.Multiply(_2Y1);
-                    ECFieldElement I = D.Invert();
-                    ECFieldElement L1 = d.Multiply(I).Multiply(Z);
-                    ECFieldElement L2 = X.Square().Multiply(I).Subtract(L1);
-
-                    ECFieldElement X4 = (L2.Subtract(L1)).Multiply(L1.Add(L2)).Add(X1);
-                    ECFieldElement Y4 = (X1.Subtract(X4)).Multiply(L2).Subtract(Y1);
-                    return new FpPoint(Curve, X4, Y4, IsCompressed);
-                }
-                case ECCurve.COORD_JACOBIAN_MODIFIED:
-                {
-                    return TwiceJacobianModified(false).Add(this);
-                }
-                default:
-                {
-                    // NOTE: Be careful about recursions between TwicePlus and ThreeTimes
-                    return Twice().Add(this);
-                }
-            }
-        }
-
-        public override ECPoint TimesPow2(int e)
-        {
-            if (e < 0)
-                throw new ArgumentException("cannot be negative", "e");
-            if (e == 0 || this.IsInfinity)
-                return this;
-            if (e == 1)
-                return Twice();
-
-            ECCurve curve = this.Curve;
-
-            ECFieldElement Y1 = this.RawYCoord;
-            if (Y1.IsZero) 
-                return curve.Infinity;
-
-            int coord = curve.CoordinateSystem;
-
-            ECFieldElement W1 = curve.A;
-            ECFieldElement X1 = this.RawXCoord;
-            ECFieldElement Z1 = this.RawZCoords.Length < 1 ? curve.FromBigInteger(BigInteger.One) : this.RawZCoords[0];
-
-            if (!Z1.IsOne)
-            {
-                switch (coord)
-                {
-                case ECCurve.COORD_HOMOGENEOUS:
-                    ECFieldElement Z1Sq = Z1.Square();
-                    X1 = X1.Multiply(Z1);
-                    Y1 = Y1.Multiply(Z1Sq);
-                    W1 = CalculateJacobianModifiedW(Z1, Z1Sq);
-                    break;
-                case ECCurve.COORD_JACOBIAN:
-                    W1 = CalculateJacobianModifiedW(Z1, null);
-                    break;
-                case ECCurve.COORD_JACOBIAN_MODIFIED:
-                    W1 = GetJacobianModifiedW();
-                    break;
-                }
-            }
-
-            for (int i = 0; i < e; ++i)
-            {
-                if (Y1.IsZero) 
-                    return curve.Infinity;
-
-                ECFieldElement X1Squared = X1.Square();
-                ECFieldElement M = Three(X1Squared);
-                ECFieldElement _2Y1 = Two(Y1);
-                ECFieldElement _2Y1Squared = _2Y1.Multiply(Y1);
-                ECFieldElement S = Two(X1.Multiply(_2Y1Squared));
-                ECFieldElement _4T = _2Y1Squared.Square();
-                ECFieldElement _8T = Two(_4T);
-
-                if (!W1.IsZero)
-                {
-                    M = M.Add(W1);
-                    W1 = Two(_8T.Multiply(W1));
-                }
-
-                X1 = M.Square().Subtract(Two(S));
-                Y1 = M.Multiply(S.Subtract(X1)).Subtract(_8T);
-                Z1 = Z1.IsOne ? _2Y1 : _2Y1.Multiply(Z1);
-            }
-
-            switch (coord)
-            {
-            case ECCurve.COORD_AFFINE:
-                ECFieldElement zInv = Z1.Invert(), zInv2 = zInv.Square(), zInv3 = zInv2.Multiply(zInv);
-                return new FpPoint(curve, X1.Multiply(zInv2), Y1.Multiply(zInv3), IsCompressed);
-            case ECCurve.COORD_HOMOGENEOUS:
-                X1 = X1.Multiply(Z1);
-                Z1 = Z1.Multiply(Z1.Square());
-                return new FpPoint(curve, X1, Y1, new ECFieldElement[] { Z1 }, IsCompressed);
-            case ECCurve.COORD_JACOBIAN:
-                return new FpPoint(curve, X1, Y1, new ECFieldElement[] { Z1 }, IsCompressed);
-            case ECCurve.COORD_JACOBIAN_MODIFIED:
-                return new FpPoint(curve, X1, Y1, new ECFieldElement[] { Z1, W1 }, IsCompressed);
-            default:
-                throw new InvalidOperationException("unsupported coordinate system");
-            }
-        }
-
-        protected virtual ECFieldElement Two(ECFieldElement x)
-        {
-            return x.Add(x);
-        }
-
-        protected virtual ECFieldElement Three(ECFieldElement x)
-        {
-            return Two(x).Add(x);
-        }
-
-        protected virtual ECFieldElement Four(ECFieldElement x)
-        {
-            return Two(Two(x));
-        }
-
-        protected virtual ECFieldElement Eight(ECFieldElement x)
-        {
-            return Four(Two(x));
-        }
-
-        protected virtual ECFieldElement DoubleProductFromSquares(ECFieldElement a, ECFieldElement b,
-            ECFieldElement aSquared, ECFieldElement bSquared)
-        {
-            /*
-             * NOTE: If squaring in the field is faster than multiplication, then this is a quicker
-             * way to calculate 2.A.B, if A^2 and B^2 are already known.
-             */
-            return a.Add(b).Square().Subtract(aSquared).Subtract(bSquared);
-        }
-
-        public override ECPoint Negate()
-        {
-            if (IsInfinity)
-                return this;
-
-            ECCurve curve = Curve;
-            int coord = curve.CoordinateSystem;
-
-            if (ECCurve.COORD_AFFINE != coord)
-            {
-                return new FpPoint(curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed);
-            }
-
-            return new FpPoint(curve, RawXCoord, RawYCoord.Negate(), IsCompressed);
-        }
-
-        protected virtual ECFieldElement CalculateJacobianModifiedW(ECFieldElement Z, ECFieldElement ZSquared)
-        {
-            ECFieldElement a4 = this.Curve.A;
-            if (a4.IsZero || Z.IsOne)
-                return a4;
-
-            if (ZSquared == null)
-            {
-                ZSquared = Z.Square();
-            }
-
-            ECFieldElement W = ZSquared.Square();
-            ECFieldElement a4Neg = a4.Negate();
-            if (a4Neg.BitLength < a4.BitLength)
-            {
-                W = W.Multiply(a4Neg).Negate();
-            }
-            else
-            {
-                W = W.Multiply(a4);
-            }
-            return W;
-        }
-
-        protected virtual ECFieldElement GetJacobianModifiedW()
-        {
-            ECFieldElement[] ZZ = this.RawZCoords;
-            ECFieldElement W = ZZ[1];
-            if (W == null)
-            {
-                // NOTE: Rarely, TwicePlus will result in the need for a lazy W1 calculation here
-                ZZ[1] = W = CalculateJacobianModifiedW(ZZ[0], null);
-            }
-            return W;
-        }
-
-        protected virtual FpPoint TwiceJacobianModified(bool calculateW)
-        {
-            ECFieldElement X1 = this.RawXCoord, Y1 = this.RawYCoord, Z1 = this.RawZCoords[0], W1 = GetJacobianModifiedW();
-
-            ECFieldElement X1Squared = X1.Square();
-            ECFieldElement M = Three(X1Squared).Add(W1);
-            ECFieldElement _2Y1 = Two(Y1);
-            ECFieldElement _2Y1Squared = _2Y1.Multiply(Y1);
-            ECFieldElement S = Two(X1.Multiply(_2Y1Squared));
-            ECFieldElement X3 = M.Square().Subtract(Two(S));
-            ECFieldElement _4T = _2Y1Squared.Square();
-            ECFieldElement _8T = Two(_4T);
-            ECFieldElement Y3 = M.Multiply(S.Subtract(X3)).Subtract(_8T);
-            ECFieldElement W3 = calculateW ? Two(_8T.Multiply(W1)) : null;
-            ECFieldElement Z3 = Z1.IsOne ? _2Y1 : _2Y1.Multiply(Z1);
-
-            return new FpPoint(this.Curve, X3, Y3, new ECFieldElement[] { Z3, W3 }, IsCompressed);
-        }
-    }
-
-    internal abstract class AbstractF2mPoint 
-        : ECPointBase
-    {
-        protected AbstractF2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
-            : base(curve, x, y, withCompression)
-        {
-        }
-
-        protected AbstractF2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
-            : base(curve, x, y, zs, withCompression)
-        {
-        }
-
-        protected override bool SatisfiesCurveEquation()
-        {
-            ECCurve curve = Curve;
-            ECFieldElement X = this.RawXCoord, Y = this.RawYCoord, A = curve.A, B = curve.B;
-            ECFieldElement lhs, rhs;
-
-            int coord = curve.CoordinateSystem;
-            if (coord == ECCurve.COORD_LAMBDA_PROJECTIVE)
-            {
-                ECFieldElement Z = this.RawZCoords[0];
-                bool ZIsOne = Z.IsOne;
-
-                if (X.IsZero)
-                {
-                    // NOTE: For x == 0, we expect the affine-y instead of the lambda-y 
-                    lhs = Y.Square();
-                    rhs = B;
-                    if (!ZIsOne)
-                    {
-                        ECFieldElement Z2 = Z.Square();
-                        rhs = rhs.Multiply(Z2);
-                    }
-                }
-                else
-                {
-                    ECFieldElement L = Y, X2 = X.Square();
-                    if (ZIsOne)
-                    {
-                        lhs = L.Square().Add(L).Add(A);
-                        rhs = X2.Square().Add(B);
-                    }
-                    else
-                    {
-                        ECFieldElement Z2 = Z.Square(), Z4 = Z2.Square();
-                        lhs = L.Add(Z).MultiplyPlusProduct(L, A, Z2);
-                        // TODO If sqrt(b) is precomputed this can be simplified to a single square
-                        rhs = X2.SquarePlusProduct(B, Z4);
-                    }
-                    lhs = lhs.Multiply(X2);
-                }
-            }
-            else
-            {
-                lhs = Y.Add(X).Multiply(Y);
-
-                switch (coord)
-                {
-                    case ECCurve.COORD_AFFINE:
-                        break;
-                    case ECCurve.COORD_HOMOGENEOUS:
-                        {
-                            ECFieldElement Z = this.RawZCoords[0];
-                            if (!Z.IsOne)
-                            {
-                                ECFieldElement Z2 = Z.Square(), Z3 = Z.Multiply(Z2);
-                                lhs = lhs.Multiply(Z);
-                                A = A.Multiply(Z);
-                                B = B.Multiply(Z3);
-                            }
-                            break;
-                        }
-                    default:
-                        throw new InvalidOperationException("unsupported coordinate system");
-                }
-
-                rhs = X.Add(A).Multiply(X.Square()).Add(B);
-            }
-
-            return lhs.Equals(rhs);
-        }
-
-        protected override bool SatisfiesOrder()
-        {
-            ECCurve curve = Curve;
-            BigInteger cofactor = curve.Cofactor;
-            if (BigInteger.Two.Equals(cofactor))
-            {
-                /*
-                 *  Check that the trace of (X + A) is 0, then there exists a solution to L^2 + L = X + A,
-                 *  and so a halving is possible, so this point is the double of another.  
-                 */
-                ECPoint N = this.Normalize();
-                ECFieldElement X = N.AffineXCoord;
-                ECFieldElement rhs = X.Add(curve.A);
-                return ((AbstractF2mFieldElement)rhs).Trace() == 0;
-            }
-            if (BigInteger.ValueOf(4).Equals(cofactor))
-            {
-                /*
-                 * Solve L^2 + L = X + A to find the half of this point, if it exists (fail if not).
-                 * Generate both possibilities for the square of the half-point's x-coordinate (w),
-                 * and check if Tr(w + A) == 0 for at least one; then a second halving is possible
-                 * (see comments for cofactor 2 above), so this point is four times another.
-                 * 
-                 * Note: Tr(x^2) == Tr(x). 
-                 */
-                ECPoint N = this.Normalize();
-                ECFieldElement X = N.AffineXCoord;
-                ECFieldElement lambda = ((AbstractF2mCurve)curve).SolveQuadraticEquation(X.Add(curve.A));
-                if (lambda == null)
-                    return false;
-
-                ECFieldElement w = X.Multiply(lambda).Add(N.AffineYCoord);
-                ECFieldElement t = w.Add(curve.A);
-                return ((AbstractF2mFieldElement)t).Trace() == 0
-                    || ((AbstractF2mFieldElement)(t.Add(X))).Trace() == 0;
-            }
-
-            return base.SatisfiesOrder();
-        }
-
-        public override ECPoint ScaleX(ECFieldElement scale)
-        {
-            if (this.IsInfinity)
-                return this;
-
-            switch (CurveCoordinateSystem)
-            {
-            case ECCurve.COORD_LAMBDA_AFFINE:
-            {
-                // Y is actually Lambda (X + Y/X) here
-                ECFieldElement X = RawXCoord, L = RawYCoord;
-
-                ECFieldElement X2 = X.Multiply(scale);
-                ECFieldElement L2 = L.Add(X).Divide(scale).Add(X2);
-
-                return Curve.CreateRawPoint(X, L2, RawZCoords, IsCompressed);
-            }
-            case ECCurve.COORD_LAMBDA_PROJECTIVE:
-            {
-                // Y is actually Lambda (X + Y/X) here
-                ECFieldElement X = RawXCoord, L = RawYCoord, Z = RawZCoords[0];
-
-                // We scale the Z coordinate also, to avoid an inversion
-                ECFieldElement X2 = X.Multiply(scale.Square());
-                ECFieldElement L2 = L.Add(X).Add(X2);
-                ECFieldElement Z2 = Z.Multiply(scale);
-
-                return Curve.CreateRawPoint(X, L2, new ECFieldElement[] { Z2 }, IsCompressed);
-            }
-            default:
-            {
-                return base.ScaleX(scale);
-            }
-            }
-        }
-
-        public override ECPoint ScaleY(ECFieldElement scale)
-        {
-            if (this.IsInfinity)
-                return this;
-
-            switch (CurveCoordinateSystem)
-            {
-            case ECCurve.COORD_LAMBDA_AFFINE:
-            case ECCurve.COORD_LAMBDA_PROJECTIVE:
-            {
-                ECFieldElement X = RawXCoord, L = RawYCoord;
-
-                // Y is actually Lambda (X + Y/X) here
-                ECFieldElement L2 = L.Add(X).Multiply(scale).Add(X);
-
-                return Curve.CreateRawPoint(X, L2, RawZCoords, IsCompressed);
-            }
-            default:
-            {
-                return base.ScaleY(scale);
-            }
-            }
-        }
-
-        public override ECPoint Subtract(ECPoint b)
-        {
-            if (b.IsInfinity)
-                return this;
-
-            // Add -b
-            return Add(b.Negate());
-        }
-
-        public virtual AbstractF2mPoint Tau()
-        {
-            if (this.IsInfinity)
-                return this;
-
-            ECCurve curve = this.Curve;
-            int coord = curve.CoordinateSystem;
-
-            ECFieldElement X1 = this.RawXCoord;
-
-            switch (coord)
-            {
-            case ECCurve.COORD_AFFINE:
-            case ECCurve.COORD_LAMBDA_AFFINE:
-            {
-                ECFieldElement Y1 = this.RawYCoord;
-                return (AbstractF2mPoint)curve.CreateRawPoint(X1.Square(), Y1.Square(), IsCompressed);
-            }
-            case ECCurve.COORD_HOMOGENEOUS:
-            case ECCurve.COORD_LAMBDA_PROJECTIVE:
-            {
-                ECFieldElement Y1 = this.RawYCoord, Z1 = this.RawZCoords[0];
-                return (AbstractF2mPoint)curve.CreateRawPoint(X1.Square(), Y1.Square(),
-                    new ECFieldElement[] { Z1.Square() }, IsCompressed);
-            }
-            default:
-            {
-                throw new InvalidOperationException("unsupported coordinate system");
-            }
-            }
-        }
-
-        public virtual AbstractF2mPoint TauPow(int pow)
-        {
-            if (this.IsInfinity)
-                return this;
-
-            ECCurve curve = this.Curve;
-            int coord = curve.CoordinateSystem;
-
-            ECFieldElement X1 = this.RawXCoord;
-
-            switch (coord)
-            {
-            case ECCurve.COORD_AFFINE:
-            case ECCurve.COORD_LAMBDA_AFFINE:
-            {
-                ECFieldElement Y1 = this.RawYCoord;
-                return (AbstractF2mPoint)curve.CreateRawPoint(X1.SquarePow(pow), Y1.SquarePow(pow), IsCompressed);
-            }
-            case ECCurve.COORD_HOMOGENEOUS:
-            case ECCurve.COORD_LAMBDA_PROJECTIVE:
-            {
-                ECFieldElement Y1 = this.RawYCoord, Z1 = this.RawZCoords[0];
-                return (AbstractF2mPoint)curve.CreateRawPoint(X1.SquarePow(pow), Y1.SquarePow(pow),
-                    new ECFieldElement[] { Z1.SquarePow(pow) }, IsCompressed);
-            }
-            default:
-            {
-                throw new InvalidOperationException("unsupported coordinate system");
-            }
-            }
-        }
-    }
-
-    /**
-     * Elliptic curve points over F2m
-     */
-    internal class F2mPoint
-        : AbstractF2mPoint
-    {
-        /**
-         * @param curve base curve
-         * @param x x point
-         * @param y y point
-         */
-        public F2mPoint(
-            ECCurve			curve,
-            ECFieldElement	x,
-            ECFieldElement	y)
-            :  this(curve, x, y, false)
-        {
-        }
-
-        /**
-         * @param curve base curve
-         * @param x x point
-         * @param y y point
-         * @param withCompression true if encode with point compression.
-         */
-        public F2mPoint(
-            ECCurve			curve,
-            ECFieldElement	x,
-            ECFieldElement	y,
-            bool			withCompression)
-            : base(curve, x, y, withCompression)
-        {
-            if ((x == null) != (y == null))
-            {
-                throw new ArgumentException("Exactly one of the field elements is null");
-            }
-
-            if (x != null)
-            {
-                // Check if x and y are elements of the same field
-                F2mFieldElement.CheckFieldElements(x, y);
-
-                // Check if x and a are elements of the same field
-                if (curve != null)
-                {
-                    F2mFieldElement.CheckFieldElements(x, curve.A);
-                }
-            }
-        }
-
-        internal F2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
-            : base(curve, x, y, zs, withCompression)
-        {
-        }
-
-        protected override ECPoint Detach()
-        {
-            return new F2mPoint(null, AffineXCoord, AffineYCoord, false);
-        }
-
-        public override ECFieldElement YCoord
-        {
-            get
-            {
-                int coord = this.CurveCoordinateSystem;
-
-                switch (coord)
-                {
-                    case ECCurve.COORD_LAMBDA_AFFINE:
-                    case ECCurve.COORD_LAMBDA_PROJECTIVE:
-                    {
-                        ECFieldElement X = RawXCoord, L = RawYCoord;
-
-                        if (this.IsInfinity || X.IsZero)
-                            return L;
-
-                        // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly
-                        ECFieldElement Y = L.Add(X).Multiply(X);
-                        if (ECCurve.COORD_LAMBDA_PROJECTIVE == coord)
-                        {
-                            ECFieldElement Z = RawZCoords[0];
-                            if (!Z.IsOne)
-                            {
-                                Y = Y.Divide(Z);
-                            }
-                        }
-                        return Y;
-                    }
-                    default:
-                    {
-                        return RawYCoord;
-                    }
-                }
-            }
-        }
-
-        protected internal override bool CompressionYTilde
-        {
-            get
-            {
-                ECFieldElement X = this.RawXCoord;
-                if (X.IsZero)
-                {
-                    return false;
-                }
-
-                ECFieldElement Y = this.RawYCoord;
-
-                switch (this.CurveCoordinateSystem)
-                {
-                    case ECCurve.COORD_LAMBDA_AFFINE:
-                    case ECCurve.COORD_LAMBDA_PROJECTIVE:
-                    {
-                        // Y is actually Lambda (X + Y/X) here
-                        return Y.TestBitZero() != X.TestBitZero();
-                    }
-                    default:
-                    {
-                        return Y.Divide(X).TestBitZero();
-                    }
-                }
-            }
-        }
-
-        public override ECPoint Add(ECPoint b)
-        {
-            if (this.IsInfinity)
-                return b;
-            if (b.IsInfinity)
-                return this;
-
-            ECCurve curve = this.Curve;
-            int coord = curve.CoordinateSystem;
-
-            ECFieldElement X1 = this.RawXCoord;
-            ECFieldElement X2 = b.RawXCoord;
-
-            switch (coord)
-            {
-                case ECCurve.COORD_AFFINE:
-                {
-                    ECFieldElement Y1 = this.RawYCoord;
-                    ECFieldElement Y2 = b.RawYCoord;
-
-                    ECFieldElement dx = X1.Add(X2), dy = Y1.Add(Y2);
-                    if (dx.IsZero)
-                    {
-                        if (dy.IsZero)
-                        {
-                            return Twice();
-                        }
-
-                        return curve.Infinity;
-                    }
-
-                    ECFieldElement L = dy.Divide(dx);
-
-                    ECFieldElement X3 = L.Square().Add(L).Add(dx).Add(curve.A);
-                    ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1);
-
-                    return new F2mPoint(curve, X3, Y3, IsCompressed);
-                }
-                case ECCurve.COORD_HOMOGENEOUS:
-                {
-                    ECFieldElement Y1 = this.RawYCoord, Z1 = this.RawZCoords[0];
-                    ECFieldElement Y2 = b.RawYCoord, Z2 = b.RawZCoords[0];
-
-                    bool Z1IsOne = Z1.IsOne;
-                    ECFieldElement U1 = Y2, V1 = X2;
-                    if (!Z1IsOne)
-                    {
-                        U1 = U1.Multiply(Z1);
-                        V1 = V1.Multiply(Z1);
-                    }
-
-                    bool Z2IsOne = Z2.IsOne;
-                    ECFieldElement U2 = Y1, V2 = X1;
-                    if (!Z2IsOne)
-                    {
-                        U2 = U2.Multiply(Z2);
-                        V2 = V2.Multiply(Z2);
-                    }
-
-                    ECFieldElement U = U1.Add(U2);
-                    ECFieldElement V = V1.Add(V2);
-
-                    if (V.IsZero)
-                    {
-                        if (U.IsZero)
-                        {
-                            return Twice();
-                        }
-
-                        return curve.Infinity;
-                    }
-
-                    ECFieldElement VSq = V.Square();
-                    ECFieldElement VCu = VSq.Multiply(V);
-                    ECFieldElement W = Z1IsOne ? Z2 : Z2IsOne ? Z1 : Z1.Multiply(Z2);
-                    ECFieldElement uv = U.Add(V);
-                    ECFieldElement A = uv.MultiplyPlusProduct(U, VSq, curve.A).Multiply(W).Add(VCu);
-
-                    ECFieldElement X3 = V.Multiply(A);
-                    ECFieldElement VSqZ2 = Z2IsOne ? VSq : VSq.Multiply(Z2);
-                    ECFieldElement Y3 = U.MultiplyPlusProduct(X1, V, Y1).MultiplyPlusProduct(VSqZ2, uv, A);
-                    ECFieldElement Z3 = VCu.Multiply(W);
-
-                    return new F2mPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed);
-                }
-                case ECCurve.COORD_LAMBDA_PROJECTIVE:
-                {
-                    if (X1.IsZero)
-                    {
-                        if (X2.IsZero)
-                            return curve.Infinity;
-
-                        return b.Add(this);
-                    }
-
-                    ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0];
-                    ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0];
-
-                    bool Z1IsOne = Z1.IsOne;
-                    ECFieldElement U2 = X2, S2 = L2;
-                    if (!Z1IsOne)
-                    {
-                        U2 = U2.Multiply(Z1);
-                        S2 = S2.Multiply(Z1);
-                    }
-
-                    bool Z2IsOne = Z2.IsOne;
-                    ECFieldElement U1 = X1, S1 = L1;
-                    if (!Z2IsOne)
-                    {
-                        U1 = U1.Multiply(Z2);
-                        S1 = S1.Multiply(Z2);
-                    }
-
-                    ECFieldElement A = S1.Add(S2);
-                    ECFieldElement B = U1.Add(U2);
-
-                    if (B.IsZero)
-                    {
-                        if (A.IsZero)
-                        {
-                            return Twice();
-                        }
-
-                        return curve.Infinity;
-                    }
-
-                    ECFieldElement X3, L3, Z3;
-                    if (X2.IsZero)
-                    {
-                        // TODO This can probably be optimized quite a bit
-                        ECPoint p = this.Normalize();
-                        X1 = p.RawXCoord;
-                        ECFieldElement Y1 = p.YCoord;
-
-                        ECFieldElement Y2 = L2;
-                        ECFieldElement L = Y1.Add(Y2).Divide(X1);
-
-                        X3 = L.Square().Add(L).Add(X1).Add(curve.A);
-                        if (X3.IsZero)
-                        {
-                            return new F2mPoint(curve, X3, curve.B.Sqrt(), IsCompressed);
-                        }
-
-                        ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1);
-                        L3 = Y3.Divide(X3).Add(X3);
-                        Z3 = curve.FromBigInteger(BigInteger.One);
-                    }
-                    else
-                    {
-                        B = B.Square();
-
-                        ECFieldElement AU1 = A.Multiply(U1);
-                        ECFieldElement AU2 = A.Multiply(U2);
-
-                        X3 = AU1.Multiply(AU2);
-                        if (X3.IsZero)
-                        {
-                            return new F2mPoint(curve, X3, curve.B.Sqrt(), IsCompressed);
-                        }
-
-                        ECFieldElement ABZ2 = A.Multiply(B);
-                        if (!Z2IsOne)
-                        {
-                            ABZ2 = ABZ2.Multiply(Z2);
-                        }
-
-                        L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1));
-
-                        Z3 = ABZ2;
-                        if (!Z1IsOne)
-                        {
-                            Z3 = Z3.Multiply(Z1);
-                        }
-                    }
-
-                    return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed);
-                }
-                default:
-                {
-                    throw new InvalidOperationException("unsupported coordinate system");
-                }
-            }
-        }
-
-        /* (non-Javadoc)
-         * @see Org.BouncyCastle.Math.EC.ECPoint#twice()
-         */
-        public override ECPoint Twice()
-        {
-            if (this.IsInfinity)
-                return this;
-
-            ECCurve curve = this.Curve;
-
-            ECFieldElement X1 = this.RawXCoord;
-            if (X1.IsZero)
-            {
-                // A point with X == 0 is it's own additive inverse
-                return curve.Infinity;
-            }
-
-            int coord = curve.CoordinateSystem;
-
-            switch (coord)
-            {
-                case ECCurve.COORD_AFFINE:
-                {
-                    ECFieldElement Y1 = this.RawYCoord;
-
-                    ECFieldElement L1 = Y1.Divide(X1).Add(X1);
-
-                    ECFieldElement X3 = L1.Square().Add(L1).Add(curve.A);
-                    ECFieldElement Y3 = X1.SquarePlusProduct(X3, L1.AddOne());
-
-                    return new F2mPoint(curve, X3, Y3, IsCompressed);
-                }
-                case ECCurve.COORD_HOMOGENEOUS:
-                {
-                    ECFieldElement Y1 = this.RawYCoord, Z1 = this.RawZCoords[0];
-
-                    bool Z1IsOne = Z1.IsOne;
-                    ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1);
-                    ECFieldElement Y1Z1 = Z1IsOne ? Y1 : Y1.Multiply(Z1);
-
-                    ECFieldElement X1Sq = X1.Square();
-                    ECFieldElement S = X1Sq.Add(Y1Z1);
-                    ECFieldElement V = X1Z1;
-                    ECFieldElement vSquared = V.Square();
-                    ECFieldElement sv = S.Add(V);
-                    ECFieldElement h = sv.MultiplyPlusProduct(S, vSquared, curve.A);
-
-                    ECFieldElement X3 = V.Multiply(h);
-                    ECFieldElement Y3 = X1Sq.Square().MultiplyPlusProduct(V, h, sv);
-                    ECFieldElement Z3 = V.Multiply(vSquared);
-
-                    return new F2mPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed);
-                }
-                case ECCurve.COORD_LAMBDA_PROJECTIVE:
-                {
-                    ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0];
-
-                    bool Z1IsOne = Z1.IsOne;
-                    ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1);
-                    ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square();
-                    ECFieldElement a = curve.A;
-                    ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq);
-                    ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq);
-                    if (T.IsZero)
-                    {
-                        return new F2mPoint(curve, T, curve.B.Sqrt(), IsCompressed);
-                    }
-
-                    ECFieldElement X3 = T.Square();
-                    ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq);
-
-                    ECFieldElement b = curve.B;
-                    ECFieldElement L3;
-                    if (b.BitLength < (curve.FieldSize >> 1))
-                    {
-                        ECFieldElement t1 = L1.Add(X1).Square();
-                        ECFieldElement t2;
-                        if (b.IsOne)
-                        {
-                            t2 = aZ1Sq.Add(Z1Sq).Square();
-                        }
-                        else
-                        {
-                            // TODO Can be calculated with one square if we pre-compute sqrt(b)
-                            t2 = aZ1Sq.SquarePlusProduct(b, Z1Sq.Square());
-                        }
-                        L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(t2).Add(X3);
-                        if (a.IsZero)
-                        {
-                            L3 = L3.Add(Z3);
-                        }
-                        else if (!a.IsOne)
-                        {
-                            L3 = L3.Add(a.AddOne().Multiply(Z3));
-                        }
-                    }
-                    else
-                    {
-                        ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1);
-                        L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3);
-                    }
-
-                    return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed);
-                }
-                default:
-                {
-                    throw new InvalidOperationException("unsupported coordinate system");
-                }
-            }
-        }
-
-        public override ECPoint TwicePlus(ECPoint b)
-        {
-            if (this.IsInfinity)
-                return b;
-            if (b.IsInfinity)
-                return Twice();
-
-            ECCurve curve = this.Curve;
-
-            ECFieldElement X1 = this.RawXCoord;
-            if (X1.IsZero)
-            {
-                // A point with X == 0 is it's own additive inverse
-                return b;
-            }
-
-            int coord = curve.CoordinateSystem;
-
-            switch (coord)
-            {
-                case ECCurve.COORD_LAMBDA_PROJECTIVE:
-                {
-                    // NOTE: twicePlus() only optimized for lambda-affine argument
-                    ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0];
-                    if (X2.IsZero || !Z2.IsOne)
-                    {
-                        return Twice().Add(b);
-                    }
-
-                    ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0];
-                    ECFieldElement L2 = b.RawYCoord;
-
-                    ECFieldElement X1Sq = X1.Square();
-                    ECFieldElement L1Sq = L1.Square();
-                    ECFieldElement Z1Sq = Z1.Square();
-                    ECFieldElement L1Z1 = L1.Multiply(Z1);
-
-                    ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1);
-                    ECFieldElement L2plus1 = L2.AddOne();
-                    ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq);
-                    ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq);
-                    ECFieldElement B = X2Z1Sq.Add(T).Square();
-
-                    if (B.IsZero)
-                    {
-                        if (A.IsZero)
-                        {
-                            return b.Twice();
-                        }
-
-                        return curve.Infinity;
-                    }
-
-                    if (A.IsZero)
-                    {
-                        return new F2mPoint(curve, A, curve.B.Sqrt(), IsCompressed);
-                    }
-
-                    ECFieldElement X3 = A.Square().Multiply(X2Z1Sq);
-                    ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq);
-                    ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3);
-
-                    return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed);
-                }
-                default:
-                {
-                    return Twice().Add(b);
-                }
-            }
-        }
-
-        public override ECPoint Negate()
-        {
-            if (this.IsInfinity)
-                return this;
-
-            ECFieldElement X = this.RawXCoord;
-            if (X.IsZero)
-                return this;
-
-            ECCurve curve = this.Curve;
-            int coord = curve.CoordinateSystem;
-
-            switch (coord)
-            {
-                case ECCurve.COORD_AFFINE:
-                {
-                    ECFieldElement Y = this.RawYCoord;
-                    return new F2mPoint(curve, X, Y.Add(X), IsCompressed);
-                }
-                case ECCurve.COORD_HOMOGENEOUS:
-                {
-                    ECFieldElement Y = this.RawYCoord, Z = this.RawZCoords[0];
-                    return new F2mPoint(curve, X, Y.Add(X), new ECFieldElement[] { Z }, IsCompressed);
-                }
-                case ECCurve.COORD_LAMBDA_AFFINE:
-                {
-                    ECFieldElement L = this.RawYCoord;
-                    return new F2mPoint(curve, X, L.AddOne(), IsCompressed);
-                }
-                case ECCurve.COORD_LAMBDA_PROJECTIVE:
-                {
-                    // L is actually Lambda (X + Y/X) here
-                    ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0];
-                    return new F2mPoint(curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed);
-                }
-                default:
-                {
-                    throw new InvalidOperationException("unsupported coordinate system");
-                }
-            }
-        }
-    }
-}

+ 0 - 9
src/Renci.SshNet/Security/BouncyCastle/math/ec/ECPointMap.cs

@@ -1,9 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC
-{
-    internal interface ECPointMap
-    {
-        ECPoint Map(ECPoint p);
-    }
-}

+ 0 - 2206
src/Renci.SshNet/Security/BouncyCastle/math/ec/LongArray.cs

@@ -1,2206 +0,0 @@
-using System;
-using System.Text;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC
-{
-    internal class LongArray
-    {
-        //private static long DEInterleave_MASK = 0x5555555555555555L;
-
-        /*
-         * This expands 8 bit indices into 16 bit contents (high bit 14), by inserting 0s between bits.
-         * In a binary field, this operation is the same as squaring an 8 bit number.
-         */
-        private static readonly ushort[] INTERLEAVE2_TABLE = new ushort[]
-        {
-            0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015,
-            0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055,
-            0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115,
-            0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155,
-            0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415,
-            0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455,
-            0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515,
-            0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555,
-            0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015,
-            0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055,
-            0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115,
-            0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155,
-            0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415,
-            0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455,
-            0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515,
-            0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555,
-            0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015,
-            0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055,
-            0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115,
-            0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155,
-            0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415,
-            0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455,
-            0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515,
-            0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555,
-            0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015,
-            0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055,
-            0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115,
-            0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155,
-            0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415,
-            0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455,
-            0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515,
-            0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555
-        };
-
-        /*
-         * This expands 7 bit indices into 21 bit contents (high bit 18), by inserting 0s between bits.
-         */
-        private static readonly int[] INTERLEAVE3_TABLE = new  int[]
-        {
-            0x00000, 0x00001, 0x00008, 0x00009, 0x00040, 0x00041, 0x00048, 0x00049,
-            0x00200, 0x00201, 0x00208, 0x00209, 0x00240, 0x00241, 0x00248, 0x00249,
-            0x01000, 0x01001, 0x01008, 0x01009, 0x01040, 0x01041, 0x01048, 0x01049,
-            0x01200, 0x01201, 0x01208, 0x01209, 0x01240, 0x01241, 0x01248, 0x01249,
-            0x08000, 0x08001, 0x08008, 0x08009, 0x08040, 0x08041, 0x08048, 0x08049,
-            0x08200, 0x08201, 0x08208, 0x08209, 0x08240, 0x08241, 0x08248, 0x08249,
-            0x09000, 0x09001, 0x09008, 0x09009, 0x09040, 0x09041, 0x09048, 0x09049,
-            0x09200, 0x09201, 0x09208, 0x09209, 0x09240, 0x09241, 0x09248, 0x09249,
-            0x40000, 0x40001, 0x40008, 0x40009, 0x40040, 0x40041, 0x40048, 0x40049,
-            0x40200, 0x40201, 0x40208, 0x40209, 0x40240, 0x40241, 0x40248, 0x40249,
-            0x41000, 0x41001, 0x41008, 0x41009, 0x41040, 0x41041, 0x41048, 0x41049,
-            0x41200, 0x41201, 0x41208, 0x41209, 0x41240, 0x41241, 0x41248, 0x41249,
-            0x48000, 0x48001, 0x48008, 0x48009, 0x48040, 0x48041, 0x48048, 0x48049,
-            0x48200, 0x48201, 0x48208, 0x48209, 0x48240, 0x48241, 0x48248, 0x48249,
-            0x49000, 0x49001, 0x49008, 0x49009, 0x49040, 0x49041, 0x49048, 0x49049,
-            0x49200, 0x49201, 0x49208, 0x49209, 0x49240, 0x49241, 0x49248, 0x49249
-        };
-
-        /*
-         * This expands 8 bit indices into 32 bit contents (high bit 28), by inserting 0s between bits.
-         */
-        private static readonly int[] INTERLEAVE4_TABLE = new int[]
-        {
-            0x00000000, 0x00000001, 0x00000010, 0x00000011, 0x00000100, 0x00000101, 0x00000110, 0x00000111,
-            0x00001000, 0x00001001, 0x00001010, 0x00001011, 0x00001100, 0x00001101, 0x00001110, 0x00001111,
-            0x00010000, 0x00010001, 0x00010010, 0x00010011, 0x00010100, 0x00010101, 0x00010110, 0x00010111,
-            0x00011000, 0x00011001, 0x00011010, 0x00011011, 0x00011100, 0x00011101, 0x00011110, 0x00011111,
-            0x00100000, 0x00100001, 0x00100010, 0x00100011, 0x00100100, 0x00100101, 0x00100110, 0x00100111,
-            0x00101000, 0x00101001, 0x00101010, 0x00101011, 0x00101100, 0x00101101, 0x00101110, 0x00101111,
-            0x00110000, 0x00110001, 0x00110010, 0x00110011, 0x00110100, 0x00110101, 0x00110110, 0x00110111,
-            0x00111000, 0x00111001, 0x00111010, 0x00111011, 0x00111100, 0x00111101, 0x00111110, 0x00111111,
-            0x01000000, 0x01000001, 0x01000010, 0x01000011, 0x01000100, 0x01000101, 0x01000110, 0x01000111,
-            0x01001000, 0x01001001, 0x01001010, 0x01001011, 0x01001100, 0x01001101, 0x01001110, 0x01001111,
-            0x01010000, 0x01010001, 0x01010010, 0x01010011, 0x01010100, 0x01010101, 0x01010110, 0x01010111,
-            0x01011000, 0x01011001, 0x01011010, 0x01011011, 0x01011100, 0x01011101, 0x01011110, 0x01011111,
-            0x01100000, 0x01100001, 0x01100010, 0x01100011, 0x01100100, 0x01100101, 0x01100110, 0x01100111,
-            0x01101000, 0x01101001, 0x01101010, 0x01101011, 0x01101100, 0x01101101, 0x01101110, 0x01101111,
-            0x01110000, 0x01110001, 0x01110010, 0x01110011, 0x01110100, 0x01110101, 0x01110110, 0x01110111,
-            0x01111000, 0x01111001, 0x01111010, 0x01111011, 0x01111100, 0x01111101, 0x01111110, 0x01111111,
-            0x10000000, 0x10000001, 0x10000010, 0x10000011, 0x10000100, 0x10000101, 0x10000110, 0x10000111,
-            0x10001000, 0x10001001, 0x10001010, 0x10001011, 0x10001100, 0x10001101, 0x10001110, 0x10001111,
-            0x10010000, 0x10010001, 0x10010010, 0x10010011, 0x10010100, 0x10010101, 0x10010110, 0x10010111,
-            0x10011000, 0x10011001, 0x10011010, 0x10011011, 0x10011100, 0x10011101, 0x10011110, 0x10011111,
-            0x10100000, 0x10100001, 0x10100010, 0x10100011, 0x10100100, 0x10100101, 0x10100110, 0x10100111,
-            0x10101000, 0x10101001, 0x10101010, 0x10101011, 0x10101100, 0x10101101, 0x10101110, 0x10101111,
-            0x10110000, 0x10110001, 0x10110010, 0x10110011, 0x10110100, 0x10110101, 0x10110110, 0x10110111,
-            0x10111000, 0x10111001, 0x10111010, 0x10111011, 0x10111100, 0x10111101, 0x10111110, 0x10111111,
-            0x11000000, 0x11000001, 0x11000010, 0x11000011, 0x11000100, 0x11000101, 0x11000110, 0x11000111,
-            0x11001000, 0x11001001, 0x11001010, 0x11001011, 0x11001100, 0x11001101, 0x11001110, 0x11001111,
-            0x11010000, 0x11010001, 0x11010010, 0x11010011, 0x11010100, 0x11010101, 0x11010110, 0x11010111,
-            0x11011000, 0x11011001, 0x11011010, 0x11011011, 0x11011100, 0x11011101, 0x11011110, 0x11011111,
-            0x11100000, 0x11100001, 0x11100010, 0x11100011, 0x11100100, 0x11100101, 0x11100110, 0x11100111,
-            0x11101000, 0x11101001, 0x11101010, 0x11101011, 0x11101100, 0x11101101, 0x11101110, 0x11101111,
-            0x11110000, 0x11110001, 0x11110010, 0x11110011, 0x11110100, 0x11110101, 0x11110110, 0x11110111,
-            0x11111000, 0x11111001, 0x11111010, 0x11111011, 0x11111100, 0x11111101, 0x11111110, 0x11111111
-        };
-
-        /*
-         * This expands 7 bit indices into 35 bit contents (high bit 30), by inserting 0s between bits.
-         */
-        private static readonly int[] INTERLEAVE5_TABLE = new int[] {
-            0x00000000, 0x00000001, 0x00000020, 0x00000021, 0x00000400, 0x00000401, 0x00000420, 0x00000421,
-            0x00008000, 0x00008001, 0x00008020, 0x00008021, 0x00008400, 0x00008401, 0x00008420, 0x00008421,
-            0x00100000, 0x00100001, 0x00100020, 0x00100021, 0x00100400, 0x00100401, 0x00100420, 0x00100421,
-            0x00108000, 0x00108001, 0x00108020, 0x00108021, 0x00108400, 0x00108401, 0x00108420, 0x00108421,
-            0x02000000, 0x02000001, 0x02000020, 0x02000021, 0x02000400, 0x02000401, 0x02000420, 0x02000421,
-            0x02008000, 0x02008001, 0x02008020, 0x02008021, 0x02008400, 0x02008401, 0x02008420, 0x02008421,
-            0x02100000, 0x02100001, 0x02100020, 0x02100021, 0x02100400, 0x02100401, 0x02100420, 0x02100421,
-            0x02108000, 0x02108001, 0x02108020, 0x02108021, 0x02108400, 0x02108401, 0x02108420, 0x02108421,
-            0x40000000, 0x40000001, 0x40000020, 0x40000021, 0x40000400, 0x40000401, 0x40000420, 0x40000421,
-            0x40008000, 0x40008001, 0x40008020, 0x40008021, 0x40008400, 0x40008401, 0x40008420, 0x40008421,
-            0x40100000, 0x40100001, 0x40100020, 0x40100021, 0x40100400, 0x40100401, 0x40100420, 0x40100421,
-            0x40108000, 0x40108001, 0x40108020, 0x40108021, 0x40108400, 0x40108401, 0x40108420, 0x40108421,
-            0x42000000, 0x42000001, 0x42000020, 0x42000021, 0x42000400, 0x42000401, 0x42000420, 0x42000421,
-            0x42008000, 0x42008001, 0x42008020, 0x42008021, 0x42008400, 0x42008401, 0x42008420, 0x42008421,
-            0x42100000, 0x42100001, 0x42100020, 0x42100021, 0x42100400, 0x42100401, 0x42100420, 0x42100421,
-            0x42108000, 0x42108001, 0x42108020, 0x42108021, 0x42108400, 0x42108401, 0x42108420, 0x42108421
-        };
-
-        /*
-         * This expands 9 bit indices into 63 bit (long) contents (high bit 56), by inserting 0s between bits.
-         */
-        private static readonly long[] INTERLEAVE7_TABLE = new long[]
-        {
-            0x0000000000000000L, 0x0000000000000001L, 0x0000000000000080L, 0x0000000000000081L,
-            0x0000000000004000L, 0x0000000000004001L, 0x0000000000004080L, 0x0000000000004081L,
-            0x0000000000200000L, 0x0000000000200001L, 0x0000000000200080L, 0x0000000000200081L,
-            0x0000000000204000L, 0x0000000000204001L, 0x0000000000204080L, 0x0000000000204081L,
-            0x0000000010000000L, 0x0000000010000001L, 0x0000000010000080L, 0x0000000010000081L,
-            0x0000000010004000L, 0x0000000010004001L, 0x0000000010004080L, 0x0000000010004081L,
-            0x0000000010200000L, 0x0000000010200001L, 0x0000000010200080L, 0x0000000010200081L,
-            0x0000000010204000L, 0x0000000010204001L, 0x0000000010204080L, 0x0000000010204081L,
-            0x0000000800000000L, 0x0000000800000001L, 0x0000000800000080L, 0x0000000800000081L,
-            0x0000000800004000L, 0x0000000800004001L, 0x0000000800004080L, 0x0000000800004081L,
-            0x0000000800200000L, 0x0000000800200001L, 0x0000000800200080L, 0x0000000800200081L,
-            0x0000000800204000L, 0x0000000800204001L, 0x0000000800204080L, 0x0000000800204081L,
-            0x0000000810000000L, 0x0000000810000001L, 0x0000000810000080L, 0x0000000810000081L,
-            0x0000000810004000L, 0x0000000810004001L, 0x0000000810004080L, 0x0000000810004081L,
-            0x0000000810200000L, 0x0000000810200001L, 0x0000000810200080L, 0x0000000810200081L,
-            0x0000000810204000L, 0x0000000810204001L, 0x0000000810204080L, 0x0000000810204081L,
-            0x0000040000000000L, 0x0000040000000001L, 0x0000040000000080L, 0x0000040000000081L,
-            0x0000040000004000L, 0x0000040000004001L, 0x0000040000004080L, 0x0000040000004081L,
-            0x0000040000200000L, 0x0000040000200001L, 0x0000040000200080L, 0x0000040000200081L,
-            0x0000040000204000L, 0x0000040000204001L, 0x0000040000204080L, 0x0000040000204081L,
-            0x0000040010000000L, 0x0000040010000001L, 0x0000040010000080L, 0x0000040010000081L,
-            0x0000040010004000L, 0x0000040010004001L, 0x0000040010004080L, 0x0000040010004081L,
-            0x0000040010200000L, 0x0000040010200001L, 0x0000040010200080L, 0x0000040010200081L,
-            0x0000040010204000L, 0x0000040010204001L, 0x0000040010204080L, 0x0000040010204081L,
-            0x0000040800000000L, 0x0000040800000001L, 0x0000040800000080L, 0x0000040800000081L,
-            0x0000040800004000L, 0x0000040800004001L, 0x0000040800004080L, 0x0000040800004081L,
-            0x0000040800200000L, 0x0000040800200001L, 0x0000040800200080L, 0x0000040800200081L,
-            0x0000040800204000L, 0x0000040800204001L, 0x0000040800204080L, 0x0000040800204081L,
-            0x0000040810000000L, 0x0000040810000001L, 0x0000040810000080L, 0x0000040810000081L,
-            0x0000040810004000L, 0x0000040810004001L, 0x0000040810004080L, 0x0000040810004081L,
-            0x0000040810200000L, 0x0000040810200001L, 0x0000040810200080L, 0x0000040810200081L,
-            0x0000040810204000L, 0x0000040810204001L, 0x0000040810204080L, 0x0000040810204081L,
-            0x0002000000000000L, 0x0002000000000001L, 0x0002000000000080L, 0x0002000000000081L,
-            0x0002000000004000L, 0x0002000000004001L, 0x0002000000004080L, 0x0002000000004081L,
-            0x0002000000200000L, 0x0002000000200001L, 0x0002000000200080L, 0x0002000000200081L,
-            0x0002000000204000L, 0x0002000000204001L, 0x0002000000204080L, 0x0002000000204081L,
-            0x0002000010000000L, 0x0002000010000001L, 0x0002000010000080L, 0x0002000010000081L,
-            0x0002000010004000L, 0x0002000010004001L, 0x0002000010004080L, 0x0002000010004081L,
-            0x0002000010200000L, 0x0002000010200001L, 0x0002000010200080L, 0x0002000010200081L,
-            0x0002000010204000L, 0x0002000010204001L, 0x0002000010204080L, 0x0002000010204081L,
-            0x0002000800000000L, 0x0002000800000001L, 0x0002000800000080L, 0x0002000800000081L,
-            0x0002000800004000L, 0x0002000800004001L, 0x0002000800004080L, 0x0002000800004081L,
-            0x0002000800200000L, 0x0002000800200001L, 0x0002000800200080L, 0x0002000800200081L,
-            0x0002000800204000L, 0x0002000800204001L, 0x0002000800204080L, 0x0002000800204081L,
-            0x0002000810000000L, 0x0002000810000001L, 0x0002000810000080L, 0x0002000810000081L,
-            0x0002000810004000L, 0x0002000810004001L, 0x0002000810004080L, 0x0002000810004081L,
-            0x0002000810200000L, 0x0002000810200001L, 0x0002000810200080L, 0x0002000810200081L,
-            0x0002000810204000L, 0x0002000810204001L, 0x0002000810204080L, 0x0002000810204081L,
-            0x0002040000000000L, 0x0002040000000001L, 0x0002040000000080L, 0x0002040000000081L,
-            0x0002040000004000L, 0x0002040000004001L, 0x0002040000004080L, 0x0002040000004081L,
-            0x0002040000200000L, 0x0002040000200001L, 0x0002040000200080L, 0x0002040000200081L,
-            0x0002040000204000L, 0x0002040000204001L, 0x0002040000204080L, 0x0002040000204081L,
-            0x0002040010000000L, 0x0002040010000001L, 0x0002040010000080L, 0x0002040010000081L,
-            0x0002040010004000L, 0x0002040010004001L, 0x0002040010004080L, 0x0002040010004081L,
-            0x0002040010200000L, 0x0002040010200001L, 0x0002040010200080L, 0x0002040010200081L,
-            0x0002040010204000L, 0x0002040010204001L, 0x0002040010204080L, 0x0002040010204081L,
-            0x0002040800000000L, 0x0002040800000001L, 0x0002040800000080L, 0x0002040800000081L,
-            0x0002040800004000L, 0x0002040800004001L, 0x0002040800004080L, 0x0002040800004081L,
-            0x0002040800200000L, 0x0002040800200001L, 0x0002040800200080L, 0x0002040800200081L,
-            0x0002040800204000L, 0x0002040800204001L, 0x0002040800204080L, 0x0002040800204081L,
-            0x0002040810000000L, 0x0002040810000001L, 0x0002040810000080L, 0x0002040810000081L,
-            0x0002040810004000L, 0x0002040810004001L, 0x0002040810004080L, 0x0002040810004081L,
-            0x0002040810200000L, 0x0002040810200001L, 0x0002040810200080L, 0x0002040810200081L,
-            0x0002040810204000L, 0x0002040810204001L, 0x0002040810204080L, 0x0002040810204081L,
-            0x0100000000000000L, 0x0100000000000001L, 0x0100000000000080L, 0x0100000000000081L,
-            0x0100000000004000L, 0x0100000000004001L, 0x0100000000004080L, 0x0100000000004081L,
-            0x0100000000200000L, 0x0100000000200001L, 0x0100000000200080L, 0x0100000000200081L,
-            0x0100000000204000L, 0x0100000000204001L, 0x0100000000204080L, 0x0100000000204081L,
-            0x0100000010000000L, 0x0100000010000001L, 0x0100000010000080L, 0x0100000010000081L,
-            0x0100000010004000L, 0x0100000010004001L, 0x0100000010004080L, 0x0100000010004081L,
-            0x0100000010200000L, 0x0100000010200001L, 0x0100000010200080L, 0x0100000010200081L,
-            0x0100000010204000L, 0x0100000010204001L, 0x0100000010204080L, 0x0100000010204081L,
-            0x0100000800000000L, 0x0100000800000001L, 0x0100000800000080L, 0x0100000800000081L,
-            0x0100000800004000L, 0x0100000800004001L, 0x0100000800004080L, 0x0100000800004081L,
-            0x0100000800200000L, 0x0100000800200001L, 0x0100000800200080L, 0x0100000800200081L,
-            0x0100000800204000L, 0x0100000800204001L, 0x0100000800204080L, 0x0100000800204081L,
-            0x0100000810000000L, 0x0100000810000001L, 0x0100000810000080L, 0x0100000810000081L,
-            0x0100000810004000L, 0x0100000810004001L, 0x0100000810004080L, 0x0100000810004081L,
-            0x0100000810200000L, 0x0100000810200001L, 0x0100000810200080L, 0x0100000810200081L,
-            0x0100000810204000L, 0x0100000810204001L, 0x0100000810204080L, 0x0100000810204081L,
-            0x0100040000000000L, 0x0100040000000001L, 0x0100040000000080L, 0x0100040000000081L,
-            0x0100040000004000L, 0x0100040000004001L, 0x0100040000004080L, 0x0100040000004081L,
-            0x0100040000200000L, 0x0100040000200001L, 0x0100040000200080L, 0x0100040000200081L,
-            0x0100040000204000L, 0x0100040000204001L, 0x0100040000204080L, 0x0100040000204081L,
-            0x0100040010000000L, 0x0100040010000001L, 0x0100040010000080L, 0x0100040010000081L,
-            0x0100040010004000L, 0x0100040010004001L, 0x0100040010004080L, 0x0100040010004081L,
-            0x0100040010200000L, 0x0100040010200001L, 0x0100040010200080L, 0x0100040010200081L,
-            0x0100040010204000L, 0x0100040010204001L, 0x0100040010204080L, 0x0100040010204081L,
-            0x0100040800000000L, 0x0100040800000001L, 0x0100040800000080L, 0x0100040800000081L,
-            0x0100040800004000L, 0x0100040800004001L, 0x0100040800004080L, 0x0100040800004081L,
-            0x0100040800200000L, 0x0100040800200001L, 0x0100040800200080L, 0x0100040800200081L,
-            0x0100040800204000L, 0x0100040800204001L, 0x0100040800204080L, 0x0100040800204081L,
-            0x0100040810000000L, 0x0100040810000001L, 0x0100040810000080L, 0x0100040810000081L,
-            0x0100040810004000L, 0x0100040810004001L, 0x0100040810004080L, 0x0100040810004081L,
-            0x0100040810200000L, 0x0100040810200001L, 0x0100040810200080L, 0x0100040810200081L,
-            0x0100040810204000L, 0x0100040810204001L, 0x0100040810204080L, 0x0100040810204081L,
-            0x0102000000000000L, 0x0102000000000001L, 0x0102000000000080L, 0x0102000000000081L,
-            0x0102000000004000L, 0x0102000000004001L, 0x0102000000004080L, 0x0102000000004081L,
-            0x0102000000200000L, 0x0102000000200001L, 0x0102000000200080L, 0x0102000000200081L,
-            0x0102000000204000L, 0x0102000000204001L, 0x0102000000204080L, 0x0102000000204081L,
-            0x0102000010000000L, 0x0102000010000001L, 0x0102000010000080L, 0x0102000010000081L,
-            0x0102000010004000L, 0x0102000010004001L, 0x0102000010004080L, 0x0102000010004081L,
-            0x0102000010200000L, 0x0102000010200001L, 0x0102000010200080L, 0x0102000010200081L,
-            0x0102000010204000L, 0x0102000010204001L, 0x0102000010204080L, 0x0102000010204081L,
-            0x0102000800000000L, 0x0102000800000001L, 0x0102000800000080L, 0x0102000800000081L,
-            0x0102000800004000L, 0x0102000800004001L, 0x0102000800004080L, 0x0102000800004081L,
-            0x0102000800200000L, 0x0102000800200001L, 0x0102000800200080L, 0x0102000800200081L,
-            0x0102000800204000L, 0x0102000800204001L, 0x0102000800204080L, 0x0102000800204081L,
-            0x0102000810000000L, 0x0102000810000001L, 0x0102000810000080L, 0x0102000810000081L,
-            0x0102000810004000L, 0x0102000810004001L, 0x0102000810004080L, 0x0102000810004081L,
-            0x0102000810200000L, 0x0102000810200001L, 0x0102000810200080L, 0x0102000810200081L,
-            0x0102000810204000L, 0x0102000810204001L, 0x0102000810204080L, 0x0102000810204081L,
-            0x0102040000000000L, 0x0102040000000001L, 0x0102040000000080L, 0x0102040000000081L,
-            0x0102040000004000L, 0x0102040000004001L, 0x0102040000004080L, 0x0102040000004081L,
-            0x0102040000200000L, 0x0102040000200001L, 0x0102040000200080L, 0x0102040000200081L,
-            0x0102040000204000L, 0x0102040000204001L, 0x0102040000204080L, 0x0102040000204081L,
-            0x0102040010000000L, 0x0102040010000001L, 0x0102040010000080L, 0x0102040010000081L,
-            0x0102040010004000L, 0x0102040010004001L, 0x0102040010004080L, 0x0102040010004081L,
-            0x0102040010200000L, 0x0102040010200001L, 0x0102040010200080L, 0x0102040010200081L,
-            0x0102040010204000L, 0x0102040010204001L, 0x0102040010204080L, 0x0102040010204081L,
-            0x0102040800000000L, 0x0102040800000001L, 0x0102040800000080L, 0x0102040800000081L,
-            0x0102040800004000L, 0x0102040800004001L, 0x0102040800004080L, 0x0102040800004081L,
-            0x0102040800200000L, 0x0102040800200001L, 0x0102040800200080L, 0x0102040800200081L,
-            0x0102040800204000L, 0x0102040800204001L, 0x0102040800204080L, 0x0102040800204081L,
-            0x0102040810000000L, 0x0102040810000001L, 0x0102040810000080L, 0x0102040810000081L,
-            0x0102040810004000L, 0x0102040810004001L, 0x0102040810004080L, 0x0102040810004081L,
-            0x0102040810200000L, 0x0102040810200001L, 0x0102040810200080L, 0x0102040810200081L,
-            0x0102040810204000L, 0x0102040810204001L, 0x0102040810204080L, 0x0102040810204081L
-        };
-
-        // For toString(); must have length 64
-        private const string ZEROES = "0000000000000000000000000000000000000000000000000000000000000000";
-
-        internal static readonly byte[] BitLengths =
-        {
-            0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
-        };
-
-        // TODO make m fixed for the LongArray, and hence compute T once and for all
-
-        private long[] m_ints;
-
-        public LongArray(int intLen)
-        {
-            m_ints = new long[intLen];
-        }
-
-        public LongArray(long[] ints)
-        {
-            m_ints = ints;
-        }
-
-        public LongArray(long[] ints, int off, int len)
-        {
-            if (off == 0 && len == ints.Length)
-            {
-                m_ints = ints;
-            }
-            else
-            {
-                m_ints = new long[len];
-                Array.Copy(ints, off, m_ints, 0, len);
-            }
-        }
-
-        public LongArray(BigInteger bigInt)
-        {
-            if (bigInt == null || bigInt.SignValue < 0)
-            {
-                throw new ArgumentException("invalid F2m field value", "bigInt");
-            }
-
-            if (bigInt.SignValue == 0)
-            {
-                m_ints = new long[] { 0L };
-                return;
-            }
-
-            byte[] barr = bigInt.ToByteArray();
-            int barrLen = barr.Length;
-            int barrStart = 0;
-            if (barr[0] == 0)
-            {
-                // First byte is 0 to enforce highest (=sign) bit is zero.
-                // In this case ignore barr[0].
-                barrLen--;
-                barrStart = 1;
-            }
-            int intLen = (barrLen + 7) / 8;
-            m_ints = new long[intLen];
-
-            int iarrJ = intLen - 1;
-            int rem = barrLen % 8 + barrStart;
-            long temp = 0;
-            int barrI = barrStart;
-            if (barrStart < rem)
-            {
-                for (; barrI < rem; barrI++)
-                {
-                    temp <<= 8;
-                    uint barrBarrI = barr[barrI];
-                    temp |= barrBarrI;
-                }
-                m_ints[iarrJ--] = temp;
-            }
-
-            for (; iarrJ >= 0; iarrJ--)
-            {
-                temp = 0;
-                for (int i = 0; i < 8; i++)
-                {
-                    temp <<= 8;
-                    uint barrBarrI = barr[barrI++];
-                    temp |= barrBarrI;
-                }
-                m_ints[iarrJ] = temp;
-            }
-        }
-
-        internal void CopyTo(long[] z, int zOff)
-        {
-            Array.Copy(m_ints, 0, z, zOff, m_ints.Length);
-        }
-
-        public bool IsOne()
-        {
-            long[] a = m_ints;
-            if (a[0] != 1L)
-            {
-                return false;
-            }
-            for (int i = 1; i < a.Length; ++i)
-            {
-                if (a[i] != 0L)
-                {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        public bool IsZero()
-        {
-            long[] a = m_ints;
-            for (int i = 0; i < a.Length; ++i)
-            {
-                if (a[i] != 0L)
-                {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        public int GetUsedLength()
-        {
-            return GetUsedLengthFrom(m_ints.Length);
-        }
-
-        public int GetUsedLengthFrom(int from)
-        {
-            long[] a = m_ints;
-            from = System.Math.Min(from, a.Length);
-
-            if (from < 1)
-            {
-                return 0;
-            }
-
-            // Check if first element will act as sentinel
-            if (a[0] != 0)
-            {
-                while (a[--from] == 0)
-                {
-                }
-                return from + 1;
-            }
-
-            do
-            {
-                if (a[--from] != 0)
-                {
-                    return from + 1;
-                }
-            }
-            while (from > 0);
-
-            return 0;
-        }
-
-        public int Degree()
-        {
-            int i = m_ints.Length;
-            long w;
-            do
-            {
-                if (i == 0)
-                {
-                    return 0;
-                }
-                w = m_ints[--i];
-            }
-            while (w == 0);
-
-            return (i << 6) + BitLength(w);
-        }
-
-        private int DegreeFrom(int limit)
-        {
-            int i = (int)(((uint)limit + 62) >> 6);
-            long w;
-            do
-            {
-                if (i == 0)
-                {
-                    return 0;
-                }
-                w = m_ints[--i];
-            }
-            while (w == 0);
-
-            return (i << 6) + BitLength(w);
-        }
-
-    //    private int lowestCoefficient()
-    //    {
-    //        for (int i = 0; i < m_ints.Length; ++i)
-    //        {
-    //            long mi = m_ints[i];
-    //            if (mi != 0)
-    //            {
-    //                int j = 0;
-    //                while ((mi & 0xFFL) == 0)
-    //                {
-    //                    j += 8;
-    //                    mi >>>= 8;
-    //                }
-    //                while ((mi & 1L) == 0)
-    //                {
-    //                    ++j;
-    //                    mi >>>= 1;
-    //                }
-    //                return (i << 6) + j;
-    //            }
-    //        }
-    //        return -1;
-    //    }
-
-        private static int BitLength(long w)
-        {
-            int u = (int)((ulong)w >> 32), b;
-            if (u == 0)
-            {
-                u = (int)w;
-                b = 0;
-            }
-            else
-            {
-                b = 32;
-            }
-
-            int t = (int)((uint)u >> 16), k;
-            if (t == 0)
-            {
-                t = (int)((uint)u >> 8);
-                k = (t == 0) ? BitLengths[u] : 8 + BitLengths[t];
-            }
-            else
-            {
-                int v = (int)((uint)t >> 8);
-                k = (v == 0) ? 16 + BitLengths[t] : 24 + BitLengths[v];
-            }
-
-            return b + k;
-        }
-
-        private long[] ResizedInts(int newLen)
-        {
-            long[] newInts = new long[newLen];
-            Array.Copy(m_ints, 0, newInts, 0, System.Math.Min(m_ints.Length, newLen));
-            return newInts;
-        }
-
-        public BigInteger ToBigInteger()
-        {
-            int usedLen = GetUsedLength();
-            if (usedLen == 0)
-            {
-                return BigInteger.Zero;
-            }
-
-            long highestInt = m_ints[usedLen - 1];
-            byte[] temp = new byte[8];
-            int barrI = 0;
-            bool trailingZeroBytesDone = false;
-            for (int j = 7; j >= 0; j--)
-            {
-                byte thisByte = (byte)((ulong)highestInt >> (8 * j));
-                if (trailingZeroBytesDone || (thisByte != 0))
-                {
-                    trailingZeroBytesDone = true;
-                    temp[barrI++] = thisByte;
-                }
-            }
-
-            int barrLen = 8 * (usedLen - 1) + barrI;
-            byte[] barr = new byte[barrLen];
-            for (int j = 0; j < barrI; j++)
-            {
-                barr[j] = temp[j];
-            }
-            // Highest value int is done now
-
-            for (int iarrJ = usedLen - 2; iarrJ >= 0; iarrJ--)
-            {
-                long mi = m_ints[iarrJ];
-                for (int j = 7; j >= 0; j--)
-                {
-                    barr[barrI++] = (byte)((ulong)mi >> (8 * j));
-                }
-            }
-            return new BigInteger(1, barr);
-        }
-
-    //    private static long shiftUp(long[] x, int xOff, int count)
-    //    {
-    //        long prev = 0;
-    //        for (int i = 0; i < count; ++i)
-    //        {
-    //            long next = x[xOff + i];
-    //            x[xOff + i] = (next << 1) | prev;
-    //            prev = next >>> 63;
-    //        }
-    //        return prev;
-    //    }
-
-        private static long ShiftUp(long[] x, int xOff, int count, int shift)
-        {
-            int shiftInv = 64 - shift;
-            long prev = 0;
-            for (int i = 0; i < count; ++i)
-            {
-                long next = x[xOff + i];
-                x[xOff + i] = (next << shift) | prev;
-                prev = (long)((ulong)next >> shiftInv);
-            }
-            return prev;
-        }
-
-        private static long ShiftUp(long[] x, int xOff, long[] z, int zOff, int count, int shift)
-        {
-            int shiftInv = 64 - shift;
-            long prev = 0;
-            for (int i = 0; i < count; ++i)
-            {
-                long next = x[xOff + i];
-                z[zOff + i] = (next << shift) | prev;
-                prev = (long)((ulong)next >> shiftInv);
-            }
-            return prev;
-        }
-
-        public LongArray AddOne()
-        {
-            if (m_ints.Length == 0)
-            {
-                return new LongArray(new long[]{ 1L });
-            }
-
-            int resultLen = System.Math.Max(1, GetUsedLength());
-            long[] ints = ResizedInts(resultLen);
-            ints[0] ^= 1L;
-            return new LongArray(ints);
-        }
-
-    //    private void addShiftedByBits(LongArray other, int bits)
-    //    {
-    //        int words = bits >>> 6;
-    //        int shift = bits & 0x3F;
-    //
-    //        if (shift == 0)
-    //        {
-    //            addShiftedByWords(other, words);
-    //            return;
-    //        }
-    //
-    //        int otherUsedLen = other.GetUsedLength();
-    //        if (otherUsedLen == 0)
-    //        {
-    //            return;
-    //        }
-    //
-    //        int minLen = otherUsedLen + words + 1;
-    //        if (minLen > m_ints.Length)
-    //        {
-    //            m_ints = resizedInts(minLen);
-    //        }
-    //
-    //        long carry = addShiftedByBits(m_ints, words, other.m_ints, 0, otherUsedLen, shift);
-    //        m_ints[otherUsedLen + words] ^= carry;
-    //    }
-
-        private void AddShiftedByBitsSafe(LongArray other, int otherDegree, int bits)
-        {
-            int otherLen = (int)((uint)(otherDegree + 63) >> 6);
-
-            int words = (int)((uint)bits >> 6);
-            int shift = bits & 0x3F;
-
-            if (shift == 0)
-            {
-                Add(m_ints, words, other.m_ints, 0, otherLen);
-                return;
-            }
-
-            long carry = AddShiftedUp(m_ints, words, other.m_ints, 0, otherLen, shift);
-            if (carry != 0L)
-            {
-                m_ints[otherLen + words] ^= carry;
-            }
-        }
-
-        private static long AddShiftedUp(long[] x, int xOff, long[] y, int yOff, int count, int shift)
-        {
-            int shiftInv = 64 - shift;
-            long prev = 0;
-            for (int i = 0; i < count; ++i)
-            {
-                long next = y[yOff + i];
-                x[xOff + i] ^= (next << shift) | prev;
-                prev = (long)((ulong)next >> shiftInv);
-            }
-            return prev;
-        }
-
-        private static long AddShiftedDown(long[] x, int xOff, long[] y, int yOff, int count, int shift)
-        {
-            int shiftInv = 64 - shift;
-            long prev = 0;
-            int i = count;
-            while (--i >= 0)
-            {
-                long next = y[yOff + i];
-                x[xOff + i] ^= (long)((ulong)next >> shift) | prev;
-                prev = next << shiftInv;
-            }
-            return prev;
-        }
-
-        public void AddShiftedByWords(LongArray other, int words)
-        {
-            int otherUsedLen = other.GetUsedLength();
-            if (otherUsedLen == 0)
-            {
-                return;
-            }
-
-            int minLen = otherUsedLen + words;
-            if (minLen > m_ints.Length)
-            {
-                m_ints = ResizedInts(minLen);
-            }
-
-            Add(m_ints, words, other.m_ints, 0, otherUsedLen);
-        }
-
-        private static void Add(long[] x, int xOff, long[] y, int yOff, int count)
-        {
-            for (int i = 0; i < count; ++i)
-            {
-                x[xOff + i] ^= y[yOff + i];
-            }
-        }
-
-        private static void Add(long[] x, int xOff, long[] y, int yOff, long[] z, int zOff, int count)
-        {
-            for (int i = 0; i < count; ++i)
-            {
-                z[zOff + i] = x[xOff + i] ^ y[yOff + i];
-            }
-        }
-
-        private static void AddBoth(long[] x, int xOff, long[] y1, int y1Off, long[] y2, int y2Off, int count)
-        {
-            for (int i = 0; i < count; ++i)
-            {
-                x[xOff + i] ^= y1[y1Off + i] ^ y2[y2Off + i];
-            }
-        }
-
-        private static void Distribute(long[] x, int src, int dst1, int dst2, int count)
-        {
-            for (int i = 0; i < count; ++i)
-            {
-                long v = x[src + i];
-                x[dst1 + i] ^= v;
-                x[dst2 + i] ^= v;
-            }
-        }
-
-        public int Length
-        {
-            get { return m_ints.Length; }
-        }
-
-        private static void FlipWord(long[] buf, int off, int bit, long word)
-        {
-            int n = off + (int)((uint)bit >> 6);
-            int shift = bit & 0x3F;
-            if (shift == 0)
-            {
-                buf[n] ^= word;
-            }
-            else
-            {
-                buf[n] ^= word << shift;
-                word = (long)((ulong)word >> (64 - shift));
-                if (word != 0)
-                {
-                    buf[++n] ^= word;
-                }
-            }
-        }
-
-    //    private static long getWord(long[] buf, int off, int len, int bit)
-    //    {
-    //        int n = off + (bit >>> 6);
-    //        int shift = bit & 0x3F;
-    //        if (shift == 0)
-    //        {
-    //            return buf[n];
-    //        }
-    //        long result = buf[n] >>> shift;
-    //        if (++n < len)
-    //        {
-    //            result |= buf[n] << (64 - shift);
-    //        }
-    //        return result;
-    //    }
-
-        public bool TestBitZero()
-        {
-            return m_ints.Length > 0 && (m_ints[0] & 1L) != 0;
-        }
-
-        private static bool TestBit(long[] buf, int off, int n)
-        {
-            // theInt = n / 64
-            int theInt = (int)((uint)n >> 6);
-            // theBit = n % 64
-            int theBit = n & 0x3F;
-            long tester = 1L << theBit;
-            return (buf[off + theInt] & tester) != 0;
-        }
-
-        private static void FlipBit(long[] buf, int off, int n)
-        {
-            // theInt = n / 64
-            int theInt = (int)((uint)n >> 6);
-            // theBit = n % 64
-            int theBit = n & 0x3F;
-            long flipper = 1L << theBit;
-            buf[off + theInt] ^= flipper;
-        }
-
-    //    private static void SetBit(long[] buf, int off, int n)
-    //    {
-    //        // theInt = n / 64
-    //        int theInt = n >>> 6;
-    //        // theBit = n % 64
-    //        int theBit = n & 0x3F;
-    //        long setter = 1L << theBit;
-    //        buf[off + theInt] |= setter;
-    //    }
-    //
-    //    private static void ClearBit(long[] buf, int off, int n)
-    //    {
-    //        // theInt = n / 64
-    //        int theInt = n >>> 6;
-    //        // theBit = n % 64
-    //        int theBit = n & 0x3F;
-    //        long setter = 1L << theBit;
-    //        buf[off + theInt] &= ~setter;
-    //    }
-
-        private static void MultiplyWord(long a, long[] b, int bLen, long[] c, int cOff)
-        {
-            if ((a & 1L) != 0L)
-            {
-                Add(c, cOff, b, 0, bLen);
-            }
-            int k = 1;
-            while ((a = (long)((ulong)a >> 1)) != 0L)
-            {
-                if ((a & 1L) != 0L)
-                {
-                    long carry = AddShiftedUp(c, cOff, b, 0, bLen, k);
-                    if (carry != 0L)
-                    {
-                        c[cOff + bLen] ^= carry;
-                    }
-                }
-                ++k;
-            }
-        }
-
-        public LongArray ModMultiplyLD(LongArray other, int m, int[] ks)
-        {
-            /*
-             * Find out the degree of each argument and handle the zero cases
-             */
-            int aDeg = Degree();
-            if (aDeg == 0)
-            {
-                return this;
-            }
-            int bDeg = other.Degree();
-            if (bDeg == 0)
-            {
-                return other;
-            }
-
-            /*
-             * Swap if necessary so that A is the smaller argument
-             */
-            LongArray A = this, B = other;
-            if (aDeg > bDeg)
-            {
-                A = other; B = this;
-                int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
-            }
-
-            /*
-             * Establish the word lengths of the arguments and result
-             */
-            int aLen = (int)((uint)(aDeg + 63) >> 6);
-            int bLen = (int)((uint)(bDeg + 63) >> 6);
-            int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6);
-
-            if (aLen == 1)
-            {
-                long a0 = A.m_ints[0];
-                if (a0 == 1L)
-                {
-                    return B;
-                }
-
-                /*
-                 * Fast path for small A, with performance dependent only on the number of set bits
-                 */
-                long[] c0 = new long[cLen];
-                MultiplyWord(a0, B.m_ints, bLen, c0, 0);
-
-                /*
-                 * Reduce the raw answer against the reduction coefficients
-                 */
-                return ReduceResult(c0, 0, cLen, m, ks);
-            }
-
-            /*
-             * Determine if B will get bigger during shifting
-             */
-            int bMax = (int)((uint)(bDeg + 7 + 63) >> 6);
-
-            /*
-             * Lookup table for the offset of each B in the tables
-             */
-            int[] ti = new int[16];
-
-            /*
-             * Precompute table of all 4-bit products of B
-             */
-            long[] T0 = new long[bMax << 4];
-            int tOff = bMax;
-            ti[1] = tOff;
-            Array.Copy(B.m_ints, 0, T0, tOff, bLen);
-            for (int i = 2; i < 16; ++i)
-            {
-                ti[i] = (tOff += bMax);
-                if ((i & 1) == 0)
-                {
-                    ShiftUp(T0, (int)((uint)tOff >> 1), T0, tOff, bMax, 1);
-                }
-                else
-                {
-                    Add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax);
-                }
-            }
-
-            /*
-             * Second table with all 4-bit products of B shifted 4 bits
-             */
-            long[] T1 = new long[T0.Length];
-            ShiftUp(T0, 0, T1, 0, T0.Length, 4);
-    //        shiftUp(T0, bMax, T1, bMax, tOff, 4);
-
-            long[] a = A.m_ints;
-            long[] c = new long[cLen];
-
-            int MASK = 0xF;
-
-            /*
-             * Lopez-Dahab algorithm
-             */
-
-            for (int k = 56; k >= 0; k -= 8)
-            {
-                for (int j = 1; j < aLen; j += 2)
-                {
-                    int aVal = (int)((ulong)a[j] >> k);
-                    int u = aVal & MASK;
-                    int v = (int)((uint)aVal >> 4) & MASK;
-                    AddBoth(c, j - 1, T0, ti[u], T1, ti[v], bMax);
-                }
-                ShiftUp(c, 0, cLen, 8);
-            }
-
-            for (int k = 56; k >= 0; k -= 8)
-            {
-                for (int j = 0; j < aLen; j += 2)
-                {
-                    int aVal = (int)((ulong)a[j] >> k);
-                    int u = aVal & MASK;
-                    int v = (int)((uint)aVal >> 4) & MASK;
-                    AddBoth(c, j, T0, ti[u], T1, ti[v], bMax);
-                }
-                if (k > 0)
-                {
-                    ShiftUp(c, 0, cLen, 8);
-                }
-            }
-
-            /*
-             * Finally the raw answer is collected, reduce it against the reduction coefficients
-             */
-            return ReduceResult(c, 0, cLen, m, ks);
-        }
-
-        public LongArray ModMultiply(LongArray other, int m, int[] ks)
-        {
-            /*
-             * Find out the degree of each argument and handle the zero cases
-             */
-            int aDeg = Degree();
-            if (aDeg == 0)
-            {
-                return this;
-            }
-            int bDeg = other.Degree();
-            if (bDeg == 0)
-            {
-                return other;
-            }
-
-            /*
-             * Swap if necessary so that A is the smaller argument
-             */
-            LongArray A = this, B = other;
-            if (aDeg > bDeg)
-            {
-                A = other; B = this;
-                int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
-            }
-
-            /*
-             * Establish the word lengths of the arguments and result
-             */
-            int aLen = (int)((uint)(aDeg + 63) >> 6);
-            int bLen = (int)((uint)(bDeg + 63) >> 6);
-            int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6);
-
-            if (aLen == 1)
-            {
-                long a0 = A.m_ints[0];
-                if (a0 == 1L)
-                {
-                    return B;
-                }
-
-                /*
-                 * Fast path for small A, with performance dependent only on the number of set bits
-                 */
-                long[] c0 = new long[cLen];
-                MultiplyWord(a0, B.m_ints, bLen, c0, 0);
-
-                /*
-                 * Reduce the raw answer against the reduction coefficients
-                 */
-                return ReduceResult(c0, 0, cLen, m, ks);
-            }
-
-            /*
-             * Determine if B will get bigger during shifting
-             */
-            int bMax = (int)((uint)(bDeg + 7 + 63) >> 6);
-
-            /*
-             * Lookup table for the offset of each B in the tables
-             */
-            int[] ti = new int[16];
-
-            /*
-             * Precompute table of all 4-bit products of B
-             */
-            long[] T0 = new long[bMax << 4];
-            int tOff = bMax;
-            ti[1] = tOff;
-            Array.Copy(B.m_ints, 0, T0, tOff, bLen);
-            for (int i = 2; i < 16; ++i)
-            {
-                ti[i] = (tOff += bMax);
-                if ((i & 1) == 0)
-                {
-                    ShiftUp(T0, (int)((uint)tOff >> 1), T0, tOff, bMax, 1);
-                }
-                else
-                {
-                    Add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax);
-                }
-            }
-
-            /*
-             * Second table with all 4-bit products of B shifted 4 bits
-             */
-            long[] T1 = new long[T0.Length];
-            ShiftUp(T0, 0, T1, 0, T0.Length, 4);
-    //        ShiftUp(T0, bMax, T1, bMax, tOff, 4);
-
-            long[] a = A.m_ints;
-            long[] c = new long[cLen << 3];
-
-            int MASK = 0xF;
-
-            /*
-             * Lopez-Dahab (Modified) algorithm
-             */
-
-            for (int aPos = 0; aPos < aLen; ++aPos)
-            {
-                long aVal = a[aPos];
-                int cOff = aPos;
-                for (;;)
-                {
-                    int u = (int)aVal & MASK;
-                    aVal = (long)((ulong)aVal >> 4);
-                    int v = (int)aVal & MASK;
-                    AddBoth(c, cOff, T0, ti[u], T1, ti[v], bMax);
-                    aVal = (long)((ulong)aVal >> 4);
-                    if (aVal == 0L)
-                    {
-                        break;
-                    }
-                    cOff += cLen;
-                }
-            }
-
-            {
-                int cOff = c.Length;
-                while ((cOff -= cLen) != 0)
-                {
-                    AddShiftedUp(c, cOff - cLen, c, cOff, cLen, 8);
-                }
-            }
-
-            /*
-             * Finally the raw answer is collected, reduce it against the reduction coefficients
-             */
-            return ReduceResult(c, 0, cLen, m, ks);
-        }
-
-        public LongArray ModMultiplyAlt(LongArray other, int m, int[] ks)
-        {
-            /*
-             * Find out the degree of each argument and handle the zero cases
-             */
-            int aDeg = Degree();
-            if (aDeg == 0)
-            {
-                return this;
-            }
-            int bDeg = other.Degree();
-            if (bDeg == 0)
-            {
-                return other;
-            }
-
-            /*
-             * Swap if necessary so that A is the smaller argument
-             */
-            LongArray A = this, B = other;
-            if (aDeg > bDeg)
-            {
-                A = other; B = this;
-                int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
-            }
-
-            /*
-             * Establish the word lengths of the arguments and result
-             */
-            int aLen = (int)((uint)(aDeg + 63) >> 6);
-            int bLen = (int)((uint)(bDeg + 63) >> 6);
-            int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6);
-
-            if (aLen == 1)
-            {
-                long a0 = A.m_ints[0];
-                if (a0 == 1L)
-                {
-                    return B;
-                }
-
-                /*
-                 * Fast path for small A, with performance dependent only on the number of set bits
-                 */
-                long[] c0 = new long[cLen];
-                MultiplyWord(a0, B.m_ints, bLen, c0, 0);
-
-                /*
-                 * Reduce the raw answer against the reduction coefficients
-                 */
-                return ReduceResult(c0, 0, cLen, m, ks);
-            }
-
-            // NOTE: This works, but is slower than width 4 processing
-    //        if (aLen == 2)
-    //        {
-    //            /*
-    //             * Use common-multiplicand optimization to save ~1/4 of the adds
-    //             */
-    //            long a1 = A.m_ints[0], a2 = A.m_ints[1];
-    //            long aa = a1 & a2; a1 ^= aa; a2 ^= aa;
-    //
-    //            long[] b = B.m_ints;
-    //            long[] c = new long[cLen];
-    //            multiplyWord(aa, b, bLen, c, 1);
-    //            add(c, 0, c, 1, cLen - 1);
-    //            multiplyWord(a1, b, bLen, c, 0);
-    //            multiplyWord(a2, b, bLen, c, 1);
-    //
-    //            /*
-    //             * Reduce the raw answer against the reduction coefficients
-    //             */
-    //            return ReduceResult(c, 0, cLen, m, ks);
-    //        }
-
-            /*
-             * Determine the parameters of the Interleaved window algorithm: the 'width' in bits to
-             * process together, the number of evaluation 'positions' implied by that width, and the
-             * 'top' position at which the regular window algorithm stops.
-             */
-            int width, positions, top, banks;
-
-            // NOTE: width 4 is the fastest over the entire range of sizes used in current crypto 
-    //        width = 1; positions = 64; top = 64; banks = 4;
-    //        width = 2; positions = 32; top = 64; banks = 4;
-    //        width = 3; positions = 21; top = 63; banks = 3;
-            width = 4; positions = 16; top = 64; banks = 8;
-    //        width = 5; positions = 13; top = 65; banks = 7;
-    //        width = 7; positions = 9; top = 63; banks = 9;
-    //        width = 8; positions = 8; top = 64; banks = 8;
-
-            /*
-             * Determine if B will get bigger during shifting
-             */
-            int shifts = top < 64 ? positions : positions - 1;
-            int bMax = (int)((uint)(bDeg + shifts + 63) >> 6);
-
-            int bTotal = bMax * banks, stride = width * banks;
-
-            /*
-             * Create a single temporary buffer, with an offset table to find the positions of things in it 
-             */
-            int[] ci = new int[1 << width];
-            int cTotal = aLen;
-            {
-                ci[0] = cTotal;
-                cTotal += bTotal;
-                ci[1] = cTotal;
-                for (int i = 2; i < ci.Length; ++i)
-                {
-                    cTotal += cLen;
-                    ci[i] = cTotal;
-                }
-                cTotal += cLen;
-            }
-            // NOTE: Provide a safe dump for "high zeroes" since we are adding 'bMax' and not 'bLen'
-            ++cTotal;
-
-            long[] c = new long[cTotal];
-
-            // Prepare A in Interleaved form, according to the chosen width
-            Interleave(A.m_ints, 0, c, 0, aLen, width);
-
-            // Make a working copy of B, since we will be shifting it
-            {
-                int bOff = aLen;
-                Array.Copy(B.m_ints, 0, c, bOff, bLen);
-                for (int bank = 1; bank < banks; ++bank)
-                {
-                    ShiftUp(c, aLen, c, bOff += bMax, bMax, bank);
-                }
-            }
-
-            /*
-             * The main loop analyzes the Interleaved windows in A, and for each non-zero window
-             * a single word-array XOR is performed to a carefully selected slice of 'c'. The loop is
-             * breadth-first, checking the lowest window in each word, then looping again for the
-             * next higher window position.
-             */
-            int MASK = (1 << width) - 1;
-
-            int k = 0;
-            for (;;)
-            {
-                int aPos = 0;
-                do
-                {
-                    long aVal = (long)((ulong)c[aPos] >> k);
-                    int bank = 0, bOff = aLen;
-                    for (;;)
-                    {
-                        int index = (int)(aVal) & MASK;
-                        if (index != 0)
-                        {
-                            /*
-                             * Add to a 'c' buffer based on the bit-pattern of 'index'. Since A is in
-                             * Interleaved form, the bits represent the current B shifted by 0, 'positions',
-                             * 'positions' * 2, ..., 'positions' * ('width' - 1)
-                             */
-                            Add(c, aPos + ci[index], c, bOff, bMax);
-                        }
-                        if (++bank == banks)
-                        {
-                            break;
-                        }
-                        bOff += bMax;
-                        aVal = (long)((ulong)aVal >> width);
-                    }
-                }
-                while (++aPos < aLen);
-
-                if ((k += stride) >= top)
-                {
-                    if (k >= 64)
-                    {
-                        break;
-                    }
-
-                    /*
-                     * Adjustment for window setups with top == 63, the final bit (if any) is processed
-                     * as the top-bit of a window
-                     */
-                    k = 64 - width;
-                    MASK &= MASK << (top - k);
-                }
-
-                /*
-                 * After each position has been checked for all words of A, B is shifted up 1 place
-                 */
-                ShiftUp(c, aLen, bTotal, banks);
-            }
-
-            int ciPos = ci.Length;
-            while (--ciPos > 1)
-            {
-                if ((ciPos & 1L) == 0L)
-                {
-                    /*
-                     * For even numbers, shift contents and add to the half-position
-                     */
-                    AddShiftedUp(c, ci[(uint)ciPos >> 1], c, ci[ciPos], cLen, positions);
-                }
-                else
-                {
-                    /*
-                     * For odd numbers, 'distribute' contents to the result and the next-lowest position
-                     */
-                    Distribute(c, ci[ciPos], ci[ciPos - 1], ci[1], cLen);
-                }
-            }
-
-            /*
-             * Finally the raw answer is collected, reduce it against the reduction coefficients
-             */
-            return ReduceResult(c, ci[1], cLen, m, ks);
-        }
-
-        public LongArray ModReduce(int m, int[] ks)
-        {
-            long[] buf = Arrays.Clone(m_ints);
-            int rLen = ReduceInPlace(buf, 0, buf.Length, m, ks);
-            return new LongArray(buf, 0, rLen);
-        }
-
-        public LongArray Multiply(LongArray other, int m, int[] ks)
-        {
-            /*
-             * Find out the degree of each argument and handle the zero cases
-             */
-            int aDeg = Degree();
-            if (aDeg == 0)
-            {
-                return this;
-            }
-            int bDeg = other.Degree();
-            if (bDeg == 0)
-            {
-                return other;
-            }
-
-            /*
-             * Swap if necessary so that A is the smaller argument
-             */
-            LongArray A = this, B = other;
-            if (aDeg > bDeg)
-            {
-                A = other; B = this;
-                int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
-            }
-
-            /*
-             * Establish the word lengths of the arguments and result
-             */
-            int aLen = (int)((uint)(aDeg + 63) >> 6);
-            int bLen = (int)((uint)(bDeg + 63) >> 6);
-            int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6);
-
-            if (aLen == 1)
-            {
-                long a0 = A.m_ints[0];
-                if (a0 == 1L)
-                {
-                    return B;
-                }
-
-                /*
-                 * Fast path for small A, with performance dependent only on the number of set bits
-                 */
-                long[] c0 = new long[cLen];
-                MultiplyWord(a0, B.m_ints, bLen, c0, 0);
-
-                /*
-                 * Reduce the raw answer against the reduction coefficients
-                 */
-                //return ReduceResult(c0, 0, cLen, m, ks);
-                return new LongArray(c0, 0, cLen);
-            }
-
-            /*
-             * Determine if B will get bigger during shifting
-             */
-            int bMax = (int)((uint)(bDeg + 7 + 63) >> 6);
-
-            /*
-             * Lookup table for the offset of each B in the tables
-             */
-            int[] ti = new int[16];
-
-            /*
-             * Precompute table of all 4-bit products of B
-             */
-            long[] T0 = new long[bMax << 4];
-            int tOff = bMax;
-            ti[1] = tOff;
-            Array.Copy(B.m_ints, 0, T0, tOff, bLen);
-            for (int i = 2; i < 16; ++i)
-            {
-                ti[i] = (tOff += bMax);
-                if ((i & 1) == 0)
-                {
-                    ShiftUp(T0, (int)((uint)tOff >> 1), T0, tOff, bMax, 1);
-                }
-                else
-                {
-                    Add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax);
-                }
-            }
-
-            /*
-             * Second table with all 4-bit products of B shifted 4 bits
-             */
-            long[] T1 = new long[T0.Length];
-            ShiftUp(T0, 0, T1, 0, T0.Length, 4);
-            //        ShiftUp(T0, bMax, T1, bMax, tOff, 4);
-
-            long[] a = A.m_ints;
-            long[] c = new long[cLen << 3];
-
-            int MASK = 0xF;
-
-            /*
-             * Lopez-Dahab (Modified) algorithm
-             */
-
-            for (int aPos = 0; aPos < aLen; ++aPos)
-            {
-                long aVal = a[aPos];
-                int cOff = aPos;
-                for (; ; )
-                {
-                    int u = (int)aVal & MASK;
-                    aVal = (long)((ulong)aVal >> 4);
-                    int v = (int)aVal & MASK;
-                    AddBoth(c, cOff, T0, ti[u], T1, ti[v], bMax);
-                    aVal = (long)((ulong)aVal >> 4);
-                    if (aVal == 0L)
-                    {
-                        break;
-                    }
-                    cOff += cLen;
-                }
-            }
-
-            {
-                int cOff = c.Length;
-                while ((cOff -= cLen) != 0)
-                {
-                    AddShiftedUp(c, cOff - cLen, c, cOff, cLen, 8);
-                }
-            }
-
-            /*
-             * Finally the raw answer is collected, reduce it against the reduction coefficients
-             */
-            //return ReduceResult(c, 0, cLen, m, ks);
-            return new LongArray(c, 0, cLen);
-        }
-
-        public void Reduce(int m, int[] ks)
-        {
-            long[] buf = m_ints;
-            int rLen = ReduceInPlace(buf, 0, buf.Length, m, ks);
-            if (rLen < buf.Length)
-            {
-                m_ints = new long[rLen];
-                Array.Copy(buf, 0, m_ints, 0, rLen);
-            }
-        }
-
-        private static LongArray ReduceResult(long[] buf, int off, int len, int m, int[] ks)
-        {
-            int rLen = ReduceInPlace(buf, off, len, m, ks);
-            return new LongArray(buf, off, rLen);
-        }
-
-    //    private static void deInterleave(long[] x, int xOff, long[] z, int zOff, int count, int rounds)
-    //    {
-    //        for (int i = 0; i < count; ++i)
-    //        {
-    //            z[zOff + i] = deInterleave(x[zOff + i], rounds);
-    //        }
-    //    }
-    //
-    //    private static long deInterleave(long x, int rounds)
-    //    {
-    //        while (--rounds >= 0)
-    //        {
-    //            x = deInterleave32(x & DEInterleave_MASK) | (deInterleave32((x >>> 1) & DEInterleave_MASK) << 32);
-    //        }
-    //        return x;
-    //    }
-    //
-    //    private static long deInterleave32(long x)
-    //    {
-    //        x = (x | (x >>> 1)) & 0x3333333333333333L;
-    //        x = (x | (x >>> 2)) & 0x0F0F0F0F0F0F0F0FL;
-    //        x = (x | (x >>> 4)) & 0x00FF00FF00FF00FFL;
-    //        x = (x | (x >>> 8)) & 0x0000FFFF0000FFFFL;
-    //        x = (x | (x >>> 16)) & 0x00000000FFFFFFFFL;
-    //        return x;
-    //    }
-
-        private static int ReduceInPlace(long[] buf, int off, int len, int m, int[] ks)
-        {
-            int mLen = (m + 63) >> 6;
-            if (len < mLen)
-            {
-                return len;
-            }
-
-            int numBits = System.Math.Min(len << 6, (m << 1) - 1); // TODO use actual degree?
-            int excessBits = (len << 6) - numBits;
-            while (excessBits >= 64)
-            {
-                --len;
-                excessBits -= 64;
-            }
-
-            int kLen = ks.Length, kMax = ks[kLen - 1], kNext = kLen > 1 ? ks[kLen - 2] : 0;
-            int wordWiseLimit = System.Math.Max(m, kMax + 64);
-            int vectorableWords = (excessBits + System.Math.Min(numBits - wordWiseLimit, m - kNext)) >> 6;
-            if (vectorableWords > 1)
-            {
-                int vectorWiseWords = len - vectorableWords;
-                ReduceVectorWise(buf, off, len, vectorWiseWords, m, ks);
-                while (len > vectorWiseWords)
-                {
-                    buf[off + --len] = 0L;
-                }
-                numBits = vectorWiseWords << 6;
-            }
-
-            if (numBits > wordWiseLimit)
-            {
-                ReduceWordWise(buf, off, len, wordWiseLimit, m, ks);
-                numBits = wordWiseLimit;
-            }
-
-            if (numBits > m)
-            {
-                ReduceBitWise(buf, off, numBits, m, ks);
-            }
-
-            return mLen;
-        }
-
-        private static void ReduceBitWise(long[] buf, int off, int BitLength, int m, int[] ks)
-        {
-            while (--BitLength >= m)
-            {
-                if (TestBit(buf, off, BitLength))
-                {
-                    ReduceBit(buf, off, BitLength, m, ks);
-                }
-            }
-        }
-
-        private static void ReduceBit(long[] buf, int off, int bit, int m, int[] ks)
-        {
-            FlipBit(buf, off, bit);
-            int n = bit - m;
-            int j = ks.Length;
-            while (--j >= 0)
-            {
-                FlipBit(buf, off, ks[j] + n);
-            }
-            FlipBit(buf, off, n);
-        }
-
-        private static void ReduceWordWise(long[] buf, int off, int len, int toBit, int m, int[] ks)
-        {
-            int toPos = (int)((uint)toBit >> 6);
-
-            while (--len > toPos)
-            {
-                long word = buf[off + len];
-                if (word != 0)
-                {
-                    buf[off + len] = 0;
-                    ReduceWord(buf, off, (len << 6), word, m, ks);
-                }
-            }
-
-            {
-                int partial = toBit & 0x3F;
-                long word = (long)((ulong)buf[off + toPos] >> partial);
-                if (word != 0)
-                {
-                    buf[off + toPos] ^= word << partial;
-                    ReduceWord(buf, off, toBit, word, m, ks);
-                }
-            }
-        }
-
-        private static void ReduceWord(long[] buf, int off, int bit, long word, int m, int[] ks)
-        {
-            int offset = bit - m;
-            int j = ks.Length;
-            while (--j >= 0)
-            {
-                FlipWord(buf, off, offset + ks[j], word);
-            }
-            FlipWord(buf, off, offset, word);
-        }
-
-        private static void ReduceVectorWise(long[] buf, int off, int len, int words, int m, int[] ks)
-        {
-            /*
-             * NOTE: It's important we go from highest coefficient to lowest, because for the highest
-             * one (only) we allow the ranges to partially overlap, and therefore any changes must take
-             * effect for the subsequent lower coefficients.
-             */
-            int baseBit = (words << 6) - m;
-            int j = ks.Length;
-            while (--j >= 0)
-            {
-                FlipVector(buf, off, buf, off + words, len - words, baseBit + ks[j]);
-            }
-            FlipVector(buf, off, buf, off + words, len - words, baseBit);
-        }
-
-        private static void FlipVector(long[] x, int xOff, long[] y, int yOff, int yLen, int bits)
-        {
-            xOff += (int)((uint)bits >> 6);
-            bits &= 0x3F;
-
-            if (bits == 0)
-            {
-                Add(x, xOff, y, yOff, yLen);
-            }
-            else
-            {
-                long carry = AddShiftedDown(x, xOff + 1, y, yOff, yLen, 64 - bits);
-                x[xOff] ^= carry;
-            }
-        }
-
-        public LongArray ModSquare(int m, int[] ks)
-        {
-            int len = GetUsedLength();
-            if (len == 0)
-            {
-                return this;
-            }
-
-            int _2len = len << 1;
-            long[] r = new long[_2len];
-
-            int pos = 0;
-            while (pos < _2len)
-            {
-                long mi = m_ints[(uint)pos >> 1];
-                r[pos++] = Interleave2_32to64((int)mi);
-                r[pos++] = Interleave2_32to64((int)((ulong)mi >> 32));
-            }
-
-            return new LongArray(r, 0, ReduceInPlace(r, 0, r.Length, m, ks));
-        }
-
-        public LongArray ModSquareN(int n, int m, int[] ks)
-        {
-            int len = GetUsedLength();
-            if (len == 0)
-            {
-                return this;
-            }
-    
-            int mLen = (m + 63) >> 6;
-            long[] r = new long[mLen << 1];
-            Array.Copy(m_ints, 0, r, 0, len);
-    
-            while (--n >= 0)
-            {
-                SquareInPlace(r, len, m, ks);
-                len = ReduceInPlace(r, 0, r.Length, m, ks);
-            }
-    
-            return new LongArray(r, 0, len);
-        }
-
-        public LongArray Square(int m, int[] ks)
-        {
-            int len = GetUsedLength();
-            if (len == 0)
-            {
-                return this;
-            }
-
-            int _2len = len << 1;
-            long[] r = new long[_2len];
-
-            int pos = 0;
-            while (pos < _2len)
-            {
-                long mi = m_ints[(uint)pos >> 1];
-                r[pos++] = Interleave2_32to64((int)mi);
-                r[pos++] = Interleave2_32to64((int)((ulong)mi >> 32));
-            }
-
-            return new LongArray(r, 0, r.Length);
-        }
-
-        private static void SquareInPlace(long[] x, int xLen, int m, int[] ks)
-        {
-            int pos = xLen << 1;
-            while (--xLen >= 0)
-            {
-                long xVal = x[xLen];
-                x[--pos] = Interleave2_32to64((int)((ulong)xVal >> 32));
-                x[--pos] = Interleave2_32to64((int)xVal);
-            }
-        }
-
-        private static void Interleave(long[] x, int xOff, long[] z, int zOff, int count, int width)
-        {
-            switch (width)
-            {
-            case 3:
-                Interleave3(x, xOff, z, zOff, count);
-                break;
-            case 5:
-                Interleave5(x, xOff, z, zOff, count);
-                break;
-            case 7:
-                Interleave7(x, xOff, z, zOff, count);
-                break;
-            default:
-                Interleave2_n(x, xOff, z, zOff, count, BitLengths[width] - 1);
-                break;
-            }
-        }
-
-        private static void Interleave3(long[] x, int xOff, long[] z, int zOff, int count)
-        {
-            for (int i = 0; i < count; ++i)
-            {
-                z[zOff + i] = Interleave3(x[xOff + i]);
-            }
-        }
-
-        private static long Interleave3(long x)
-        {
-            long z = x & (1L << 63);
-            return z
-                | Interleave3_21to63((int)x & 0x1FFFFF)
-                | Interleave3_21to63((int)((ulong)x >> 21) & 0x1FFFFF) << 1
-                | Interleave3_21to63((int)((ulong)x >> 42) & 0x1FFFFF) << 2;
-
-    //        int zPos = 0, wPos = 0, xPos = 0;
-    //        for (;;)
-    //        {
-    //            z |= ((x >>> xPos) & 1L) << zPos;
-    //            if (++zPos == 63)
-    //            {
-    //                String sz2 = Long.toBinaryString(z);
-    //                return z;
-    //            }
-    //            if ((xPos += 21) >= 63)
-    //            {
-    //                xPos = ++wPos;
-    //            }
-    //        }
-        }
-
-        private static long Interleave3_21to63(int x)
-        {
-            int r00 = INTERLEAVE3_TABLE[x & 0x7F];
-            int r21 = INTERLEAVE3_TABLE[((uint)x >> 7) & 0x7F];
-            int r42 = INTERLEAVE3_TABLE[(uint)x >> 14];
-            return (r42 & 0xFFFFFFFFL) << 42 | (r21 & 0xFFFFFFFFL) << 21 | (r00 & 0xFFFFFFFFL);
-        }
-
-        private static void Interleave5(long[] x, int xOff, long[] z, int zOff, int count)
-        {
-            for (int i = 0; i < count; ++i)
-            {
-                z[zOff + i] = Interleave5(x[xOff + i]);
-            }
-        }
-
-        private static long Interleave5(long x)
-        {
-            return Interleave3_13to65((int)x & 0x1FFF)
-                | Interleave3_13to65((int)((ulong)x >> 13) & 0x1FFF) << 1
-                | Interleave3_13to65((int)((ulong)x >> 26) & 0x1FFF) << 2
-                | Interleave3_13to65((int)((ulong)x >> 39) & 0x1FFF) << 3
-                | Interleave3_13to65((int)((ulong)x >> 52) & 0x1FFF) << 4;
-
-    //        long z = 0;
-    //        int zPos = 0, wPos = 0, xPos = 0;
-    //        for (;;)
-    //        {
-    //            z |= ((x >>> xPos) & 1L) << zPos;
-    //            if (++zPos == 64)
-    //            {
-    //                return z;
-    //            }
-    //            if ((xPos += 13) >= 64)
-    //            {
-    //                xPos = ++wPos;
-    //            }
-    //        }
-        }
-
-        private static long Interleave3_13to65(int x)
-        {
-            int r00 = INTERLEAVE5_TABLE[x & 0x7F];
-            int r35 = INTERLEAVE5_TABLE[(uint)x >> 7];
-            return (r35 & 0xFFFFFFFFL) << 35 | (r00 & 0xFFFFFFFFL);
-        }
-
-        private static void Interleave7(long[] x, int xOff, long[] z, int zOff, int count)
-        {
-            for (int i = 0; i < count; ++i)
-            {
-                z[zOff + i] = Interleave7(x[xOff + i]);
-            }
-        }
-
-        private static long Interleave7(long x)
-        {
-            long z = x & (1L << 63);
-            return z
-                | INTERLEAVE7_TABLE[(int)x & 0x1FF]
-                | INTERLEAVE7_TABLE[(int)((ulong)x >> 9) & 0x1FF] << 1
-                | INTERLEAVE7_TABLE[(int)((ulong)x >> 18) & 0x1FF] << 2
-                | INTERLEAVE7_TABLE[(int)((ulong)x >> 27) & 0x1FF] << 3
-                | INTERLEAVE7_TABLE[(int)((ulong)x >> 36) & 0x1FF] << 4
-                | INTERLEAVE7_TABLE[(int)((ulong)x >> 45) & 0x1FF] << 5
-                | INTERLEAVE7_TABLE[(int)((ulong)x >> 54) & 0x1FF] << 6;
-
-    //        int zPos = 0, wPos = 0, xPos = 0;
-    //        for (;;)
-    //        {
-    //            z |= ((x >>> xPos) & 1L) << zPos;
-    //            if (++zPos == 63)
-    //            {
-    //                return z;
-    //            }
-    //            if ((xPos += 9) >= 63)
-    //            {
-    //                xPos = ++wPos;
-    //            }
-    //        }
-        }
-
-        private static void Interleave2_n(long[] x, int xOff, long[] z, int zOff, int count, int rounds)
-        {
-            for (int i = 0; i < count; ++i)
-            {
-                z[zOff + i] = Interleave2_n(x[xOff + i], rounds);
-            }
-        }
-
-        private static long Interleave2_n(long x, int rounds)
-        {
-            while (rounds > 1)
-            {
-                rounds -= 2;
-                x = Interleave4_16to64((int)x & 0xFFFF)
-                    | Interleave4_16to64((int)((ulong)x >> 16) & 0xFFFF) << 1
-                    | Interleave4_16to64((int)((ulong)x >> 32) & 0xFFFF) << 2
-                    | Interleave4_16to64((int)((ulong)x >> 48) & 0xFFFF) << 3;
-            }
-            if (rounds > 0)
-            {
-                x = Interleave2_32to64((int)x) | Interleave2_32to64((int)((ulong)x >> 32)) << 1;
-            }
-            return x;
-        }
-
-        private static long Interleave4_16to64(int x)
-        {
-            int r00 = INTERLEAVE4_TABLE[x & 0xFF];
-            int r32 = INTERLEAVE4_TABLE[(uint)x >> 8];
-            return (r32 & 0xFFFFFFFFL) << 32 | (r00 & 0xFFFFFFFFL);
-        }
-
-        private static long Interleave2_32to64(int x)
-        {
-            int r00 = INTERLEAVE2_TABLE[x & 0xFF] | INTERLEAVE2_TABLE[((uint)x >> 8) & 0xFF] << 16;
-            int r32 = INTERLEAVE2_TABLE[((uint)x >> 16) & 0xFF] | INTERLEAVE2_TABLE[(uint)x >> 24] << 16;
-            return (r32 & 0xFFFFFFFFL) << 32 | (r00 & 0xFFFFFFFFL);
-        }
-
-    //    private static LongArray ExpItohTsujii2(LongArray B, int n, int m, int[] ks)
-    //    {
-    //        LongArray t1 = B, t3 = new LongArray(new long[]{ 1L });
-    //        int scale = 1;
-    //
-    //        int numTerms = n;
-    //        while (numTerms > 1)
-    //        {
-    //            if ((numTerms & 1) != 0)
-    //            {
-    //                t3 = t3.ModMultiply(t1, m, ks);
-    //                t1 = t1.modSquareN(scale, m, ks);
-    //            }
-    //
-    //            LongArray t2 = t1.modSquareN(scale, m, ks);
-    //            t1 = t1.ModMultiply(t2, m, ks);
-    //            numTerms >>>= 1; scale <<= 1;
-    //        }
-    //
-    //        return t3.ModMultiply(t1, m, ks);
-    //    }
-    //
-    //    private static LongArray ExpItohTsujii23(LongArray B, int n, int m, int[] ks)
-    //    {
-    //        LongArray t1 = B, t3 = new LongArray(new long[]{ 1L });
-    //        int scale = 1;
-    //
-    //        int numTerms = n;
-    //        while (numTerms > 1)
-    //        {
-    //            bool m03 = numTerms % 3 == 0;
-    //            bool m14 = !m03 && (numTerms & 1) != 0;
-    //
-    //            if (m14)
-    //            {
-    //                t3 = t3.ModMultiply(t1, m, ks);
-    //                t1 = t1.modSquareN(scale, m, ks);
-    //            }
-    //
-    //            LongArray t2 = t1.modSquareN(scale, m, ks);
-    //            t1 = t1.ModMultiply(t2, m, ks);
-    //
-    //            if (m03)
-    //            {
-    //                t2 = t2.modSquareN(scale, m, ks);
-    //                t1 = t1.ModMultiply(t2, m, ks);
-    //                numTerms /= 3; scale *= 3;
-    //            }
-    //            else
-    //            {
-    //                numTerms >>>= 1; scale <<= 1;
-    //            }
-    //        }
-    //
-    //        return t3.ModMultiply(t1, m, ks);
-    //    }
-    //
-    //    private static LongArray ExpItohTsujii235(LongArray B, int n, int m, int[] ks)
-    //    {
-    //        LongArray t1 = B, t4 = new LongArray(new long[]{ 1L });
-    //        int scale = 1;
-    //
-    //        int numTerms = n;
-    //        while (numTerms > 1)
-    //        {
-    //            if (numTerms % 5 == 0)
-    //            {
-    ////                t1 = ExpItohTsujii23(t1, 5, m, ks);
-    //
-    //                LongArray t3 = t1;
-    //                t1 = t1.modSquareN(scale, m, ks);
-    //
-    //                LongArray t2 = t1.modSquareN(scale, m, ks);
-    //                t1 = t1.ModMultiply(t2, m, ks);
-    //                t2 = t1.modSquareN(scale << 1, m, ks);
-    //                t1 = t1.ModMultiply(t2, m, ks);
-    //
-    //                t1 = t1.ModMultiply(t3, m, ks);
-    //
-    //                numTerms /= 5; scale *= 5;
-    //                continue;
-    //            }
-    //
-    //            bool m03 = numTerms % 3 == 0;
-    //            bool m14 = !m03 && (numTerms & 1) != 0;
-    //
-    //            if (m14)
-    //            {
-    //                t4 = t4.ModMultiply(t1, m, ks);
-    //                t1 = t1.modSquareN(scale, m, ks);
-    //            }
-    //
-    //            LongArray t2 = t1.modSquareN(scale, m, ks);
-    //            t1 = t1.ModMultiply(t2, m, ks);
-    //
-    //            if (m03)
-    //            {
-    //                t2 = t2.modSquareN(scale, m, ks);
-    //                t1 = t1.ModMultiply(t2, m, ks);
-    //                numTerms /= 3; scale *= 3;
-    //            }
-    //            else
-    //            {
-    //                numTerms >>>= 1; scale <<= 1;
-    //            }
-    //        }
-    //
-    //        return t4.ModMultiply(t1, m, ks);
-    //    }
-
-        public LongArray ModInverse(int m, int[] ks)
-        {
-            /*
-             * Fermat's Little Theorem
-             */
-    //        LongArray A = this;
-    //        LongArray B = A.modSquare(m, ks);
-    //        LongArray R0 = B, R1 = B;
-    //        for (int i = 2; i < m; ++i)
-    //        {
-    //            R1 = R1.modSquare(m, ks);
-    //            R0 = R0.ModMultiply(R1, m, ks);
-    //        }
-    //
-    //        return R0;
-
-            /*
-             * Itoh-Tsujii
-             */
-    //        LongArray B = modSquare(m, ks);
-    //        switch (m)
-    //        {
-    //        case 409:
-    //            return ExpItohTsujii23(B, m - 1, m, ks);
-    //        case 571:
-    //            return ExpItohTsujii235(B, m - 1, m, ks);
-    //        case 163:
-    //        case 233:
-    //        case 283:
-    //        default:
-    //            return ExpItohTsujii2(B, m - 1, m, ks);
-    //        }
-
-            /*
-             * Inversion in F2m using the extended Euclidean algorithm
-             * 
-             * Input: A nonzero polynomial a(z) of degree at most m-1
-             * Output: a(z)^(-1) mod f(z)
-             */
-            int uzDegree = Degree();
-            if (uzDegree == 0)
-            {
-                throw new InvalidOperationException();
-            }
-            if (uzDegree == 1)
-            {
-                return this;
-            }
-
-            // u(z) := a(z)
-            LongArray uz = (LongArray)Copy();
-
-            int t = (m + 63) >> 6;
-
-            // v(z) := f(z)
-            LongArray vz = new LongArray(t);
-            ReduceBit(vz.m_ints, 0, m, m, ks);
-
-            // g1(z) := 1, g2(z) := 0
-            LongArray g1z = new LongArray(t);
-            g1z.m_ints[0] = 1L;
-            LongArray g2z = new LongArray(t);
-
-            int[] uvDeg = new int[]{ uzDegree, m + 1 };
-            LongArray[] uv = new LongArray[]{ uz, vz };
-
-            int[] ggDeg = new int[]{ 1, 0 };
-            LongArray[] gg = new LongArray[]{ g1z, g2z };
-
-            int b = 1;
-            int duv1 = uvDeg[b];
-            int dgg1 = ggDeg[b];
-            int j = duv1 - uvDeg[1 - b];
-
-            for (;;)
-            {
-                if (j < 0)
-                {
-                    j = -j;
-                    uvDeg[b] = duv1;
-                    ggDeg[b] = dgg1;
-                    b = 1 - b;
-                    duv1 = uvDeg[b];
-                    dgg1 = ggDeg[b];
-                }
-
-                uv[b].AddShiftedByBitsSafe(uv[1 - b], uvDeg[1 - b], j);
-
-                int duv2 = uv[b].DegreeFrom(duv1);
-                if (duv2 == 0)
-                {
-                    return gg[1 - b];
-                }
-
-                {
-                    int dgg2 = ggDeg[1 - b];
-                    gg[b].AddShiftedByBitsSafe(gg[1 - b], dgg2, j);
-                    dgg2 += j;
-
-                    if (dgg2 > dgg1)
-                    {
-                        dgg1 = dgg2;
-                    }
-                    else if (dgg2 == dgg1)
-                    {
-                        dgg1 = gg[b].DegreeFrom(dgg1);
-                    }
-                }
-
-                j += (duv2 - duv1);
-                duv1 = duv2;
-            }
-        }
-
-        public override bool Equals(object obj)
-        {
-            return Equals(obj as LongArray);
-        }
-
-        public virtual bool Equals(LongArray other)
-        {
-            if (this == other)
-                return true;
-            if (null == other)
-                return false;
-            int usedLen = GetUsedLength();
-            if (other.GetUsedLength() != usedLen)
-            {
-                return false;
-            }
-            for (int i = 0; i < usedLen; i++)
-            {
-                if (m_ints[i] != other.m_ints[i])
-                {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        public override int GetHashCode()
-        {
-            int usedLen = GetUsedLength();
-            int hash = 1;
-            for (int i = 0; i < usedLen; i++)
-            {
-                long mi = m_ints[i];
-                hash *= 31;
-                hash ^= (int)mi;
-                hash *= 31;
-                hash ^= (int)((ulong)mi >> 32);
-            }
-            return hash;
-        }
-
-        public LongArray Copy()
-        {
-            return new LongArray(Arrays.Clone(m_ints));
-        }
-
-        public override string ToString()
-        {
-            int i = GetUsedLength();
-            if (i == 0)
-            {
-                return "0";
-            }
-
-            StringBuilder sb = new StringBuilder(Convert.ToString(m_ints[--i], 2));
-            while (--i >= 0)
-            {
-                string s = Convert.ToString(m_ints[i], 2);
-
-                // Add leading zeroes, except for highest significant word
-                int len = s.Length;
-                if (len < 64)
-                {
-                    sb.Append(ZEROES.Substring(len));
-                }
-
-                sb.Append(s);
-            }
-            return sb.ToString();
-        }
-    }
-}

+ 0 - 241
src/Renci.SshNet/Security/BouncyCastle/math/ec/abc/SimpleBigDecimal.cs

@@ -1,241 +0,0 @@
-using System;
-using System.Text;
-
-namespace Renci.SshNet.Security.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;
-		}
-
-	}
-}

+ 0 - 845
src/Renci.SshNet/Security/BouncyCastle/math/ec/abc/Tnaf.cs

@@ -1,845 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.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;
-        }
-    }
-}

+ 0 - 36
src/Renci.SshNet/Security/BouncyCastle/math/ec/abc/ZTauElement.cs

@@ -1,36 +0,0 @@
-namespace Renci.SshNet.Security.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;
-		}
-	}
-}

+ 0 - 11
src/Renci.SshNet/Security/BouncyCastle/math/ec/endo/ECEndomorphism.cs

@@ -1,11 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Endo
-{
-    internal interface ECEndomorphism
-    {
-        ECPointMap PointMap { get; }
-
-        bool HasEfficientPointMap { get; }
-    }
-}

+ 0 - 10
src/Renci.SshNet/Security/BouncyCastle/math/ec/endo/GlvEndomorphism.cs

@@ -1,10 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Endo
-{
-    internal interface GlvEndomorphism
-        : ECEndomorphism
-    {
-        BigInteger[] DecomposeScalar(BigInteger k);
-    }
-}

+ 0 - 29
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/AbstractECMultiplier.cs

@@ -1,29 +0,0 @@
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-    internal abstract class AbstractECMultiplier
-        : ECMultiplier
-    {
-        public virtual ECPoint Multiply(ECPoint p, BigInteger k)
-        {
-            int sign = k.SignValue;
-            if (sign == 0 || p.IsInfinity)
-                return p.Curve.Infinity;
-
-            ECPoint positive = MultiplyPositive(p, k.Abs());
-            ECPoint result = sign > 0 ? positive : positive.Negate();
-
-            /*
-             * Although the various multipliers ought not to produce invalid output under normal
-             * circumstances, a final check here is advised to guard against fault attacks.
-             */
-            return CheckResult(result);
-        }
-
-        protected abstract ECPoint MultiplyPositive(ECPoint p, BigInteger k);
-
-        protected virtual ECPoint CheckResult(ECPoint p)
-        {
-            return ECAlgorithms.ImplCheckResult(p);
-        }
-    }
-}

+ 0 - 18
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/ECMultiplier.cs

@@ -1,18 +0,0 @@
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-    /**
-    * Interface for classes encapsulating a point multiplication algorithm
-    * for <code>ECPoint</code>s.
-    */
-    internal interface ECMultiplier
-    {
-        /**
-         * Multiplies the <code>ECPoint p</code> by <code>k</code>, i.e.
-         * <code>p</code> is added <code>k</code> times to itself.
-         * @param p The <code>ECPoint</code> to be multiplied.
-         * @param k The factor by which <code>p</code> is multiplied.
-         * @return <code>p</code> multiplied by <code>k</code>.
-         */
-        ECPoint Multiply(ECPoint p, BigInteger k);
-    }
-}

+ 0 - 58
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/FixedPointCombMultiplier.cs

@@ -1,58 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math.Raw;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-    internal class FixedPointCombMultiplier
-        : AbstractECMultiplier
-    {
-        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
-        {
-            ECCurve c = p.Curve;
-            int size = FixedPointUtilities.GetCombSize(c);
-
-            if (k.BitLength > size)
-            {
-                /*
-                 * 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 info = FixedPointUtilities.Precompute(p);
-            ECLookupTable lookupTable = info.LookupTable;
-            int width = info.Width;
-
-            int d = (size + width - 1) / width;
-
-            ECPoint R = c.Infinity;
-
-            int fullComb = d * width;
-            uint[] K = Nat.FromBigInteger(fullComb, k);
-
-            int top = fullComb - 1;
-            for (int i = 0; i < d; ++i)
-            {
-                uint secretIndex = 0;
-
-                for (int j = top - i; j >= 0; j -= d)
-                {
-                    uint secretBit = K[j >> 5] >> (j & 0x1F);
-                    secretIndex ^= secretBit >> 1;
-                    secretIndex <<= 1;
-                    secretIndex ^= secretBit;
-                }
-
-                ECPoint add = lookupTable.Lookup((int)secretIndex);
-
-                R = R.TwicePlus(add);
-            }
-
-            return R.Add(info.Offset);
-        }
-    }
-}

+ 0 - 43
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/FixedPointPreCompInfo.cs

@@ -1,43 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-    /**
-     * Class holding precomputation data for fixed-point multiplications.
-     */
-    internal class FixedPointPreCompInfo
-        : PreCompInfo
-    {
-        protected ECPoint m_offset = null;
-
-        /**
-         * Lookup table for the precomputed <code>ECPoint</code>s used for a fixed point multiplication.
-         */
-        protected ECLookupTable m_lookupTable = null;
-
-        /**
-         * The width used for the precomputation. If a larger width precomputation
-         * is already available this may be larger than was requested, so calling
-         * code should refer to the actual width.
-         */
-        protected int m_width = -1;
-
-        public virtual ECLookupTable LookupTable
-        {
-            get { return m_lookupTable; }
-            set { this.m_lookupTable = value; }
-        }
-
-        public virtual ECPoint Offset
-        {
-			get { return m_offset; }
-			set { this.m_offset = value; }
-		}
-
-        public virtual int Width
-        {
-            get { return m_width; }
-            set { this.m_width = value; }
-        }
-    }
-}

+ 0 - 95
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/FixedPointUtilities.cs

@@ -1,95 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-    internal class FixedPointUtilities
-    {
-        public static readonly string PRECOMP_NAME = "bc_fixed_point";
-
-        public static int GetCombSize(ECCurve c)
-        {
-            BigInteger order = c.Order;
-            return order == null ? c.FieldSize + 1 : order.BitLength;
-        }
-
-        public static FixedPointPreCompInfo GetFixedPointPreCompInfo(PreCompInfo preCompInfo)
-        {
-            return preCompInfo as FixedPointPreCompInfo;
-        }
-
-        public static FixedPointPreCompInfo Precompute(ECPoint p)
-        {
-            return (FixedPointPreCompInfo)p.Curve.Precompute(p, PRECOMP_NAME, new FixedPointCallback(p));
-        }
-
-        private class FixedPointCallback
-            : IPreCompCallback
-        {
-            private readonly ECPoint m_p;
-
-            internal FixedPointCallback(ECPoint p)
-            {
-                this.m_p = p;
-            }
-
-            public PreCompInfo Precompute(PreCompInfo existing)
-            {
-                FixedPointPreCompInfo existingFP = (existing is FixedPointPreCompInfo) ? (FixedPointPreCompInfo)existing : null;
-
-                ECCurve c = m_p.Curve;
-                int bits = FixedPointUtilities.GetCombSize(c);
-                int minWidth = bits > 250 ? 6 : 5;
-                int n = 1 << minWidth;
-
-                if (CheckExisting(existingFP, n))
-                    return existingFP;
-
-                int d = (bits + minWidth - 1) / minWidth;
-
-                ECPoint[] pow2Table = new ECPoint[minWidth + 1];
-                pow2Table[0] = m_p;
-                for (int i = 1; i < minWidth; ++i)
-                {
-                    pow2Table[i] = pow2Table[i - 1].TimesPow2(d);
-                }
-
-                // This will be the 'offset' value 
-                pow2Table[minWidth] = pow2Table[0].Subtract(pow2Table[1]);
-
-                c.NormalizeAll(pow2Table);
-
-                ECPoint[] lookupTable = new ECPoint[n];
-                lookupTable[0] = pow2Table[0];
-
-                for (int bit = minWidth - 1; bit >= 0; --bit)
-                {
-                    ECPoint pow2 = pow2Table[bit];
-
-                    int step = 1 << bit;
-                    for (int i = step; i < n; i += (step << 1))
-                    {
-                        lookupTable[i] = lookupTable[i - step].Add(pow2);
-                    }
-                }
-
-                c.NormalizeAll(lookupTable);
-
-                FixedPointPreCompInfo result = new FixedPointPreCompInfo();
-                result.LookupTable = c.CreateCacheSafeLookupTable(lookupTable, 0, lookupTable.Length);
-                result.Offset = pow2Table[minWidth];
-                result.Width = minWidth;
-                return result;
-            }
-
-            private bool CheckExisting(FixedPointPreCompInfo existingFP, int n)
-            {
-                return existingFP != null && CheckTable(existingFP.LookupTable, n);
-            }
-
-            private bool CheckTable(ECLookupTable table, int n)
-            {
-                return table != null && table.Size >= n;
-            }
-        }
-    }
-}

+ 0 - 40
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/GlvMultiplier.cs

@@ -1,40 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Endo;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-    internal class GlvMultiplier
-        :   AbstractECMultiplier
-    {
-        protected readonly ECCurve curve;
-        protected readonly GlvEndomorphism glvEndomorphism;
-
-        public GlvMultiplier(ECCurve curve, GlvEndomorphism glvEndomorphism)
-        {
-            if (curve == null || curve.Order == null)
-                throw new ArgumentException("Need curve with known group order", "curve");
-
-            this.curve = curve;
-            this.glvEndomorphism = glvEndomorphism;
-        }
-
-        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
-        {
-            if (!curve.Equals(p.Curve))
-                throw new InvalidOperationException();
-
-            BigInteger n = p.Curve.Order;
-            BigInteger[] ab = glvEndomorphism.DecomposeScalar(k.Mod(n));
-            BigInteger a = ab[0], b = ab[1];
-
-            ECPointMap pointMap = glvEndomorphism.PointMap;
-            if (glvEndomorphism.HasEfficientPointMap)
-            {
-                return ECAlgorithms.ImplShamirsTrickWNaf(p, a, pointMap, b);
-            }
-
-            return ECAlgorithms.ImplShamirsTrickWNaf(p, a, pointMap.Map(p), b);
-        }
-    }
-}

+ 0 - 9
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/IPreCompCallback.cs

@@ -1,9 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-    internal interface IPreCompCallback
-    {
-        PreCompInfo Precompute(PreCompInfo existing);
-    }
-}

+ 0 - 11
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/PreCompInfo.cs

@@ -1,11 +0,0 @@
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-	/**
-	* Interface for classes storing precomputation data for multiplication
-	* algorithms. Used as a Memento (see GOF patterns) for
-	* <code>WNafMultiplier</code>.
-	*/
-	internal interface PreCompInfo
-	{
-	}
-}

+ 0 - 44
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/ValidityPreCompInfo.cs

@@ -1,44 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-    internal class ValidityPreCompInfo
-        : PreCompInfo
-    {
-        internal static readonly string PRECOMP_NAME = "bc_validity";
-
-        private bool failed = false;
-        private bool curveEquationPassed = false;
-        private bool orderPassed = false;
-
-        internal bool HasFailed()
-        {
-            return failed;
-        }
-
-        internal void ReportFailed()
-        {
-            failed = true;
-        }
-
-        internal bool HasCurveEquationPassed()
-        {
-            return curveEquationPassed;
-        }
-
-        internal void ReportCurveEquationPassed()
-        {
-            curveEquationPassed = true;
-        }
-
-        internal bool HasOrderPassed()
-        {
-            return orderPassed;
-        }
-
-        internal void ReportOrderPassed()
-        {
-            orderPassed = true;
-        }
-    }
-}

+ 0 - 98
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/WNafL2RMultiplier.cs

@@ -1,98 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-    /**
-    * Class implementing the WNAF (Window Non-Adjacent Form) multiplication
-    * algorithm.
-    */
-    internal class WNafL2RMultiplier
-        : AbstractECMultiplier
-    {
-        /**
-         * Multiplies <code>this</code> by an integer <code>k</code> using the
-         * Window NAF method.
-         * @param k The integer by which <code>this</code> is multiplied.
-         * @return A new <code>ECPoint</code> which equals <code>this</code>
-         * multiplied by <code>k</code>.
-         */
-        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
-        {
-            // Clamp the window width in the range [2, 16]
-            int width = System.Math.Max(2, System.Math.Min(16, GetWindowSize(k.BitLength)));
-
-            WNafPreCompInfo wnafPreCompInfo = WNafUtilities.Precompute(p, width, true);
-            ECPoint[] preComp = wnafPreCompInfo.PreComp;
-            ECPoint[] preCompNeg = wnafPreCompInfo.PreCompNeg;
-
-            int[] wnaf = WNafUtilities.GenerateCompactWindowNaf(width, k);
-
-            ECPoint R = p.Curve.Infinity;
-
-            int i = wnaf.Length;
-
-            /*
-             * NOTE: We try to optimize the first window using the precomputed points to substitute an
-             * addition for 2 or more doublings.
-             */
-            if (i > 1)
-            {
-                int wi = wnaf[--i];
-                int digit = wi >> 16, zeroes = wi & 0xFFFF;
-
-                int n = System.Math.Abs(digit);
-                ECPoint[] table = digit < 0 ? preCompNeg : preComp;
-
-                // Optimization can only be used for values in the lower half of the table
-                if ((n << 2) < (1 << width))
-                {
-                    int highest = LongArray.BitLengths[n];
-
-                    // TODO Get addition/doubling cost ratio from curve and compare to 'scale' to see if worth substituting?
-                    int scale = width - highest;
-                    int lowBits = n ^ (1 << (highest - 1));
-
-                    int i1 = ((1 << (width - 1)) - 1);
-                    int i2 = (lowBits << scale) + 1;
-                    R = table[i1 >> 1].Add(table[i2 >> 1]);
-
-                    zeroes -= scale;
-
-                    //Console.WriteLine("Optimized: 2^" + scale + " * " + n + " = " + i1 + " + " + i2);
-                }
-                else
-                {
-                    R = table[n >> 1];
-                }
-
-                R = R.TimesPow2(zeroes);
-            }
-
-            while (i > 0)
-            {
-                int wi = wnaf[--i];
-                int digit = wi >> 16, zeroes = wi & 0xFFFF;
-
-                int n = System.Math.Abs(digit);
-                ECPoint[] table = digit < 0 ? preCompNeg : preComp;
-                ECPoint r = table[n >> 1];
-
-                R = R.TwicePlus(r);
-                R = R.TimesPow2(zeroes);
-            }
-
-            return R;
-        }
-
-        /**
-         * Determine window width to use for a scalar multiplication of the given size.
-         * 
-         * @param bits the bit-length of the scalar to multiply by
-         * @return the window size to use
-         */
-        protected virtual int GetWindowSize(int bits)
-        {
-            return WNafUtilities.GetWindowSize(bits);
-        }
-    }
-}

+ 0 - 46
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/WNafPreCompInfo.cs

@@ -1,46 +0,0 @@
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-    /**
-    * Class holding precomputation data for the WNAF (Window Non-Adjacent Form)
-    * algorithm.
-    */
-    internal class WNafPreCompInfo
-        : PreCompInfo 
-    {
-        /**
-         * Array holding the precomputed <code>ECPoint</code>s used for a Window
-         * NAF multiplication.
-         */
-        protected ECPoint[] m_preComp = null;
-
-        /**
-         * Array holding the negations of the precomputed <code>ECPoint</code>s used
-         * for a Window NAF multiplication.
-         */
-        protected ECPoint[] m_preCompNeg = null;
-
-        /**
-         * Holds an <code>ECPoint</code> representing Twice(this). Used for the
-         * Window NAF multiplication to create or extend the precomputed values.
-         */
-        protected ECPoint m_twice = null;
-
-        public virtual ECPoint[] PreComp
-        {
-            get { return m_preComp; }
-            set { this.m_preComp = value; }
-        }
-
-        public virtual ECPoint[] PreCompNeg
-        {
-            get { return m_preCompNeg; }
-            set { this.m_preCompNeg = value; }
-        }
-
-        public virtual ECPoint Twice
-        {
-            get { return m_twice; }
-            set { this.m_twice = value; }
-        }
-    }
-}

+ 0 - 579
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/WNafUtilities.cs

@@ -1,579 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-    internal abstract class WNafUtilities
-    {
-        public static readonly string PRECOMP_NAME = "bc_wnaf";
-
-        private static readonly int[] DEFAULT_WINDOW_SIZE_CUTOFFS = new int[]{ 13, 41, 121, 337, 897, 2305 };
-
-        private static readonly ECPoint[] EMPTY_POINTS = new ECPoint[0];
-
-        public static int[] GenerateCompactNaf(BigInteger k)
-        {
-            if ((k.BitLength >> 16) != 0)
-                throw new ArgumentException("must have bitlength < 2^16", "k");
-            if (k.SignValue == 0)
-                return Arrays.EmptyInts;
-
-            BigInteger _3k = k.ShiftLeft(1).Add(k);
-
-            int bits = _3k.BitLength;
-            int[] naf = new int[bits >> 1];
-
-            BigInteger diff = _3k.Xor(k);
-
-            int highBit = bits - 1, length = 0, zeroes = 0;
-            for (int i = 1; i < highBit; ++i)
-            {
-                if (!diff.TestBit(i))
-                {
-                    ++zeroes;
-                    continue;
-                }
-
-                int digit = k.TestBit(i) ? -1 : 1;
-                naf[length++] = (digit << 16) | zeroes;
-                zeroes = 1;
-                ++i;
-            }
-
-            naf[length++] = (1 << 16) | zeroes;
-
-            if (naf.Length > length)
-            {
-                naf = Trim(naf, length);
-            }
-
-            return naf;
-        }
-
-        public static int[] GenerateCompactWindowNaf(int width, BigInteger k)
-        {
-            if (width == 2)
-            {
-                return GenerateCompactNaf(k);
-            }
-
-            if (width < 2 || width > 16)
-                throw new ArgumentException("must be in the range [2, 16]", "width");
-            if ((k.BitLength >> 16) != 0)
-                throw new ArgumentException("must have bitlength < 2^16", "k");
-            if (k.SignValue == 0)
-                return Arrays.EmptyInts;
-
-            int[] wnaf = new int[k.BitLength / width + 1];
-
-            // 2^width and a mask and sign bit set accordingly
-            int pow2 = 1 << width;
-            int mask = pow2 - 1;
-            int sign = pow2 >> 1;
-
-            bool carry = false;
-            int length = 0, pos = 0;
-
-            while (pos <= k.BitLength)
-            {
-                if (k.TestBit(pos) == carry)
-                {
-                    ++pos;
-                    continue;
-                }
-
-                k = k.ShiftRight(pos);
-
-                int digit = k.IntValue & mask;
-                if (carry)
-                {
-                    ++digit;
-                }
-
-                carry = (digit & sign) != 0;
-                if (carry)
-                {
-                    digit -= pow2;
-                }
-
-                int zeroes = length > 0 ? pos - 1 : pos;
-                wnaf[length++] = (digit << 16) | zeroes;
-                pos = width;
-            }
-
-            // Reduce the WNAF array to its actual length
-            if (wnaf.Length > length)
-            {
-                wnaf = Trim(wnaf, length);
-            }
-
-            return wnaf;
-        }
-
-        public static byte[] GenerateJsf(BigInteger g, BigInteger h)
-        {
-            int digits = System.Math.Max(g.BitLength, h.BitLength) + 1;
-            byte[] jsf = new byte[digits];
-
-            BigInteger k0 = g, k1 = h;
-            int j = 0, d0 = 0, d1 = 0;
-
-            int offset = 0;
-            while ((d0 | d1) != 0 || k0.BitLength > offset || k1.BitLength > offset)
-            {
-                int n0 = ((int)((uint)k0.IntValue >> offset) + d0) & 7;
-                int n1 = ((int)((uint)k1.IntValue >> offset) + d1) & 7;
-
-                int u0 = n0 & 1;
-                if (u0 != 0)
-                {
-                    u0 -= (n0 & 2);
-                    if ((n0 + u0) == 4 && (n1 & 3) == 2)
-                    {
-                        u0 = -u0;
-                    }
-                }
-
-                int u1 = n1 & 1;
-                if (u1 != 0)
-                {
-                    u1 -= (n1 & 2);
-                    if ((n1 + u1) == 4 && (n0 & 3) == 2)
-                    {
-                        u1 = -u1;
-                    }
-                }
-
-                if ((d0 << 1) == 1 + u0)
-                {
-                    d0 ^= 1;
-                }
-                if ((d1 << 1) == 1 + u1)
-                {
-                    d1 ^= 1;
-                }
-
-                if (++offset == 30)
-                {
-                    offset = 0;
-                    k0 = k0.ShiftRight(30);
-                    k1 = k1.ShiftRight(30);
-                }
-
-                jsf[j++] = (byte)((u0 << 4) | (u1 & 0xF));
-            }
-
-            // Reduce the JSF array to its actual length
-            if (jsf.Length > j)
-            {
-                jsf = Trim(jsf, j);
-            }
-
-            return jsf;
-        }
-
-        public static byte[] GenerateNaf(BigInteger k)
-        {
-            if (k.SignValue == 0)
-                return Arrays.EmptyBytes;
-
-            BigInteger _3k = k.ShiftLeft(1).Add(k);
-
-            int digits = _3k.BitLength - 1;
-            byte[] naf = new byte[digits];
-
-            BigInteger diff = _3k.Xor(k);
-
-            for (int i = 1; i < digits; ++i)
-            {
-                if (diff.TestBit(i))
-                {
-                    naf[i - 1] = (byte)(k.TestBit(i) ? -1 : 1);
-                    ++i;
-                }
-            }
-
-            naf[digits - 1] = 1;
-
-            return naf;
-        }
-
-        /**
-         * Computes the Window NAF (non-adjacent Form) of an integer.
-         * @param width The width <code>w</code> of the Window NAF. The width is
-         * defined as the minimal number <code>w</code>, such that for any
-         * <code>w</code> consecutive digits in the resulting representation, at
-         * most one is non-zero.
-         * @param k The integer of which the Window NAF is computed.
-         * @return The Window NAF of the given width, such that the following holds:
-         * <code>k = &amp;sum;<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup>
-         * </code>, where the <code>k<sub>i</sub></code> denote the elements of the
-         * returned <code>byte[]</code>.
-         */
-        public static byte[] GenerateWindowNaf(int width, BigInteger k)
-        {
-            if (width == 2)
-            {
-                return GenerateNaf(k);
-            }
-
-            if (width < 2 || width > 8)
-                throw new ArgumentException("must be in the range [2, 8]", "width");
-            if (k.SignValue == 0)
-                return Arrays.EmptyBytes;
-
-            byte[] wnaf = new byte[k.BitLength + 1];
-
-            // 2^width and a mask and sign bit set accordingly
-            int pow2 = 1 << width;
-            int mask = pow2 - 1;
-            int sign = pow2 >> 1;
-
-            bool carry = false;
-            int length = 0, pos = 0;
-
-            while (pos <= k.BitLength)
-            {
-                if (k.TestBit(pos) == carry)
-                {
-                    ++pos;
-                    continue;
-                }
-
-                k = k.ShiftRight(pos);
-
-                int digit = k.IntValue & mask;
-                if (carry)
-                {
-                    ++digit;
-                }
-
-                carry = (digit & sign) != 0;
-                if (carry)
-                {
-                    digit -= pow2;
-                }
-
-                length += (length > 0) ? pos - 1 : pos;
-                wnaf[length++] = (byte)digit;
-                pos = width;
-            }
-
-            // Reduce the WNAF array to its actual length
-            if (wnaf.Length > length)
-            {
-                wnaf = Trim(wnaf, length);
-            }
-        
-            return wnaf;
-        }
-
-        public static int GetNafWeight(BigInteger k)
-        {
-            if (k.SignValue == 0)
-                return 0;
-
-            BigInteger _3k = k.ShiftLeft(1).Add(k);
-            BigInteger diff = _3k.Xor(k);
-
-            return diff.BitCount;
-        }
-
-        public static WNafPreCompInfo GetWNafPreCompInfo(ECPoint p)
-        {
-            return GetWNafPreCompInfo(p.Curve.GetPreCompInfo(p, PRECOMP_NAME));
-        }
-
-        public static WNafPreCompInfo GetWNafPreCompInfo(PreCompInfo preCompInfo)
-        {
-            return preCompInfo as WNafPreCompInfo;
-        }
-
-        /**
-         * Determine window width to use for a scalar multiplication of the given size.
-         * 
-         * @param bits the bit-length of the scalar to multiply by
-         * @return the window size to use
-         */
-        public static int GetWindowSize(int bits)
-        {
-            return GetWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS);
-        }
-
-        /**
-         * Determine window width to use for a scalar multiplication of the given size.
-         * 
-         * @param bits the bit-length of the scalar to multiply by
-         * @param windowSizeCutoffs a monotonically increasing list of bit sizes at which to increment the window width
-         * @return the window size to use
-         */
-        public static int GetWindowSize(int bits, int[] windowSizeCutoffs)
-        {
-            int w = 0;
-            for (; w < windowSizeCutoffs.Length; ++w)
-            {
-                if (bits < windowSizeCutoffs[w])
-                {
-                    break;
-                }
-            }
-            return w + 2;
-        }
-
-        public static ECPoint MapPointWithPrecomp(ECPoint p, int width, bool includeNegated,
-            ECPointMap pointMap)
-        {
-            ECCurve c = p.Curve;
-            WNafPreCompInfo wnafPreCompP = Precompute(p, width, includeNegated);
-
-            ECPoint q = pointMap.Map(p);
-            c.Precompute(q, PRECOMP_NAME, new MapPointCallback(wnafPreCompP, includeNegated, pointMap));
-            return q;
-        }
-
-        public static WNafPreCompInfo Precompute(ECPoint p, int width, bool includeNegated)
-        {
-            return (WNafPreCompInfo)p.Curve.Precompute(p, PRECOMP_NAME, new WNafCallback(p, width, includeNegated));
-        }
-
-        private static byte[] Trim(byte[] a, int length)
-        {
-            byte[] result = new byte[length];
-            Array.Copy(a, 0, result, 0, result.Length);
-            return result;
-        }
-
-        private static int[] Trim(int[] a, int length)
-        {
-            int[] result = new int[length];
-            Array.Copy(a, 0, result, 0, result.Length);
-            return result;
-        }
-
-        private static ECPoint[] ResizeTable(ECPoint[] a, int length)
-        {
-            ECPoint[] result = new ECPoint[length];
-            Array.Copy(a, 0, result, 0, a.Length);
-            return result;
-        }
-
-        private class MapPointCallback
-            : IPreCompCallback
-        {
-            private readonly WNafPreCompInfo m_wnafPreCompP;
-            private readonly bool m_includeNegated;
-            private readonly ECPointMap m_pointMap;
-
-            internal MapPointCallback(WNafPreCompInfo wnafPreCompP, bool includeNegated, ECPointMap pointMap)
-            {
-                this.m_wnafPreCompP = wnafPreCompP;
-                this.m_includeNegated = includeNegated;
-                this.m_pointMap = pointMap;
-            }
-
-            public PreCompInfo Precompute(PreCompInfo existing)
-            {
-                WNafPreCompInfo result = new WNafPreCompInfo();
-
-                ECPoint twiceP = m_wnafPreCompP.Twice;
-                if (twiceP != null)
-                {
-                    ECPoint twiceQ = m_pointMap.Map(twiceP);
-                    result.Twice = twiceQ;
-                }
-
-                ECPoint[] preCompP = m_wnafPreCompP.PreComp;
-                ECPoint[] preCompQ = new ECPoint[preCompP.Length];
-                for (int i = 0; i < preCompP.Length; ++i)
-                {
-                    preCompQ[i] = m_pointMap.Map(preCompP[i]);
-                }
-                result.PreComp = preCompQ;
-
-                if (m_includeNegated)
-                {
-                    ECPoint[] preCompNegQ = new ECPoint[preCompQ.Length];
-                    for (int i = 0; i < preCompNegQ.Length; ++i)
-                    {
-                        preCompNegQ[i] = preCompQ[i].Negate();
-                    }
-                    result.PreCompNeg = preCompNegQ;
-                }
-
-                return result;
-            }
-        }
-
-        private class WNafCallback
-            : IPreCompCallback
-        {
-            private readonly ECPoint m_p;
-            private readonly int m_width;
-            private readonly bool m_includeNegated;
-
-            internal WNafCallback(ECPoint p, int width, bool includeNegated)
-            {
-                this.m_p = p;
-                this.m_width = width;
-                this.m_includeNegated = includeNegated;
-            }
-
-            public PreCompInfo Precompute(PreCompInfo existing)
-            {
-                WNafPreCompInfo existingWNaf = existing as WNafPreCompInfo;
-
-                int reqPreCompLen = 1 << System.Math.Max(0, m_width - 2);
-
-                if (CheckExisting(existingWNaf, reqPreCompLen, m_includeNegated))
-                    return existingWNaf;
-
-                ECCurve c = m_p.Curve;
-                ECPoint[] preComp = null, preCompNeg = null;
-                ECPoint twiceP = null;
-
-                if (existingWNaf != null)
-                {
-                    preComp = existingWNaf.PreComp;
-                    preCompNeg = existingWNaf.PreCompNeg;
-                    twiceP = existingWNaf.Twice;
-                }
-
-                int iniPreCompLen = 0;
-                if (preComp == null)
-                {
-                    preComp = EMPTY_POINTS;
-                }
-                else
-                {
-                    iniPreCompLen = preComp.Length;
-                }
-
-                if (iniPreCompLen < reqPreCompLen)
-                {
-                    preComp = WNafUtilities.ResizeTable(preComp, reqPreCompLen);
-
-                    if (reqPreCompLen == 1)
-                    {
-                        preComp[0] = m_p.Normalize();
-                    }
-                    else
-                    {
-                        int curPreCompLen = iniPreCompLen;
-                        if (curPreCompLen == 0)
-                        {
-                            preComp[0] = m_p;
-                            curPreCompLen = 1;
-                        }
-
-                        ECFieldElement iso = null;
-
-                        if (reqPreCompLen == 2)
-                        {
-                            preComp[1] = m_p.ThreeTimes();
-                        }
-                        else
-                        {
-                            ECPoint isoTwiceP = twiceP, last = preComp[curPreCompLen - 1];
-                            if (isoTwiceP == null)
-                            {
-                                isoTwiceP = preComp[0].Twice();
-                                twiceP = isoTwiceP;
-
-                                /*
-                                 * For Fp curves with Jacobian projective coordinates, use a (quasi-)isomorphism
-                                 * where 'twiceP' is "affine", so that the subsequent additions are cheaper. This
-                                 * also requires scaling the initial point's X, Y coordinates, and reversing the
-                                 * isomorphism as part of the subsequent normalization.
-                                 * 
-                                 *  NOTE: The correctness of this optimization depends on:
-                                 *      1) additions do not use the curve's A, B coefficients.
-                                 *      2) no special cases (i.e. Q +/- Q) when calculating 1P, 3P, 5P, ...
-                                 */
-                                if (!twiceP.IsInfinity && ECAlgorithms.IsFpCurve(c) && c.FieldSize >= 64)
-                                {
-                                    switch (c.CoordinateSystem)
-                                    {
-                                    case ECCurve.COORD_JACOBIAN:
-                                    case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
-                                    case ECCurve.COORD_JACOBIAN_MODIFIED:
-                                    {
-                                        iso = twiceP.GetZCoord(0);
-                                        isoTwiceP = c.CreatePoint(twiceP.XCoord.ToBigInteger(),
-                                            twiceP.YCoord.ToBigInteger());
-
-                                        ECFieldElement iso2 = iso.Square(), iso3 = iso2.Multiply(iso);
-                                        last = last.ScaleX(iso2).ScaleY(iso3);
-
-                                        if (iniPreCompLen == 0)
-                                        {
-                                            preComp[0] = last;
-                                        }
-                                        break;
-                                    }
-                                    }
-                                }
-                            }
-
-                            while (curPreCompLen < reqPreCompLen)
-                            {
-                                /*
-                                 * Compute the new ECPoints for the precomputation array. The values 1, 3,
-                                 * 5, ..., 2^(width-1)-1 times p are computed
-                                 */
-                                preComp[curPreCompLen++] = last = last.Add(isoTwiceP);
-                            }
-                        }
-
-                        /*
-                         * Having oft-used operands in affine form makes operations faster.
-                         */
-                        c.NormalizeAll(preComp, iniPreCompLen, reqPreCompLen - iniPreCompLen, iso);
-                    }
-                }
-
-                if (m_includeNegated)
-                {
-                    int pos;
-                    if (preCompNeg == null)
-                    {
-                        pos = 0;
-                        preCompNeg = new ECPoint[reqPreCompLen]; 
-                    }
-                    else
-                    {
-                        pos = preCompNeg.Length;
-                        if (pos < reqPreCompLen)
-                        {
-                            preCompNeg = WNafUtilities.ResizeTable(preCompNeg, reqPreCompLen);
-                        }
-                    }
-
-                    while (pos < reqPreCompLen)
-                    {
-                        preCompNeg[pos] = preComp[pos].Negate();
-                        ++pos;
-                    }
-                }
-
-                WNafPreCompInfo result = new WNafPreCompInfo();
-                result.PreComp = preComp;
-                result.PreCompNeg = preCompNeg;
-                result.Twice = twiceP;
-                return result;
-            }
-
-            private bool CheckExisting(WNafPreCompInfo existingWNaf, int reqPreCompLen, bool includeNegated)
-            {
-                return existingWNaf != null
-                    && CheckTable(existingWNaf.PreComp, reqPreCompLen)
-                    && (!includeNegated || CheckTable(existingWNaf.PreCompNeg, reqPreCompLen));
-            }
-
-            private bool CheckTable(ECPoint[] table, int reqLen)
-            {
-                return table != null && table.Length >= reqLen;
-            }
-        }
-    }
-}

+ 0 - 138
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/WTauNafMultiplier.cs

@@ -1,138 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Abc;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-    /**
-    * Class implementing the WTNAF (Window
-    * <code>&#964;</code>-adic Non-Adjacent Form) algorithm.
-    */
-    internal class WTauNafMultiplier
-        : AbstractECMultiplier
-    {
-        // TODO Create WTauNafUtilities class and move various functionality into it
-        internal static readonly string PRECOMP_NAME = "bc_wtnaf";
-
-        /**
-        * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint}
-        * by <code>k</code> using the reduced <code>&#964;</code>-adic NAF (RTNAF)
-        * method.
-        * @param p The AbstractF2mPoint to multiply.
-        * @param k The integer by which to multiply <code>k</code>.
-        * @return <code>p</code> multiplied by <code>k</code>.
-        */
-        protected override ECPoint MultiplyPositive(ECPoint point, BigInteger k)
-        {
-            if (!(point is AbstractF2mPoint))
-                throw new ArgumentException("Only AbstractF2mPoint can be used in WTauNafMultiplier");
-
-            AbstractF2mPoint p = (AbstractF2mPoint)point;
-            AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve;
-            int m = curve.FieldSize;
-            sbyte a = (sbyte)curve.A.ToBigInteger().IntValue;
-            sbyte mu = Tnaf.GetMu(a);
-            BigInteger[] s = curve.GetSi();
-
-            ZTauElement rho = Tnaf.PartModReduction(k, m, a, s, mu, (sbyte)10);
-
-            return MultiplyWTnaf(p, rho, a, mu);
-        }
-
-        /**
-        * 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> of which to compute the
-        * <code>[&#964;]</code>-adic NAF.
-        * @return <code>p</code> multiplied by <code>&#955;</code>.
-        */
-        private AbstractF2mPoint MultiplyWTnaf(AbstractF2mPoint p, ZTauElement lambda,
-            sbyte a, sbyte mu)
-        {
-            ZTauElement[] alpha = (a == 0) ? Tnaf.Alpha0 : Tnaf.Alpha1;
-
-            BigInteger tw = Tnaf.GetTw(mu, Tnaf.Width);
-
-            sbyte[]u = Tnaf.TauAdicWNaf(mu, lambda, Tnaf.Width,
-                BigInteger.ValueOf(Tnaf.Pow2Width), tw, alpha);
-
-            return MultiplyFromWTnaf(p, u);
-        }
-        
-        /**
-        * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint}
-        * by an element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>
-        * using the window <code>&#964;</code>-adic NAF (TNAF) method, given the
-        * WTNAF of <code>&#955;</code>.
-        * @param p The AbstractF2mPoint to multiply.
-        * @param u The the WTNAF of <code>&#955;</code>..
-        * @return <code>&#955; * p</code>
-        */
-        private static AbstractF2mPoint MultiplyFromWTnaf(AbstractF2mPoint p, sbyte[] u)
-        {
-            AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve;
-            sbyte a = (sbyte)curve.A.ToBigInteger().IntValue;
-
-            WTauNafCallback callback = new WTauNafCallback(p, a);
-            WTauNafPreCompInfo preCompInfo = (WTauNafPreCompInfo)curve.Precompute(p, PRECOMP_NAME, callback);
-            AbstractF2mPoint[] pu = preCompInfo.PreComp;
-
-            // TODO Include negations in precomp (optionally) and use from here
-            AbstractF2mPoint[] puNeg = new AbstractF2mPoint[pu.Length];
-            for (int i = 0; i < pu.Length; ++i)
-            {
-                puNeg[i] = (AbstractF2mPoint)pu[i].Negate();
-            }
-
-            
-            // q = infinity
-            AbstractF2mPoint q = (AbstractF2mPoint) p.Curve.Infinity;
-
-            int tauCount = 0;
-            for (int i = u.Length - 1; i >= 0; i--)
-            {
-                ++tauCount;
-                int ui = u[i];
-                if (ui != 0)
-                {
-                    q = q.TauPow(tauCount);
-                    tauCount = 0;
-
-                    ECPoint x = ui > 0 ? pu[ui >> 1] : puNeg[(-ui) >> 1];
-                    q = (AbstractF2mPoint)q.Add(x);
-                }
-            }
-            if (tauCount > 0)
-            {
-                q = q.TauPow(tauCount);
-            }
-            return q;
-        }
-
-        private class WTauNafCallback
-            : IPreCompCallback
-        {
-            private readonly AbstractF2mPoint m_p;
-            private readonly sbyte m_a;
-
-            internal WTauNafCallback(AbstractF2mPoint p, sbyte a)
-            {
-                this.m_p = p;
-                this.m_a = a;
-            }
-
-            public PreCompInfo Precompute(PreCompInfo existing)
-            {
-                if (existing is WTauNafPreCompInfo)
-                    return existing;
-
-                WTauNafPreCompInfo result = new WTauNafPreCompInfo();
-                result.PreComp = Tnaf.GetPreComp(m_p, m_a);
-                return result;
-            }
-        }
-    }
-}

+ 0 - 24
src/Renci.SshNet/Security/BouncyCastle/math/ec/multiplier/WTauNafPreCompInfo.cs

@@ -1,24 +0,0 @@
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
-{
-    /**
-     * Class holding precomputation data for the WTNAF (Window
-     * <code>&#964;</code>-adic Non-Adjacent Form) algorithm.
-     */
-    internal class WTauNafPreCompInfo
-        : PreCompInfo
-    {
-        /**
-         * Array holding the precomputed <code>AbstractF2mPoint</code>s used for the
-         * WTNAF multiplication in <code>
-         * {@link org.bouncycastle.math.ec.multiplier.WTauNafMultiplier.multiply()
-         * WTauNafMultiplier.multiply()}</code>.
-         */
-        protected AbstractF2mPoint[] m_preComp;
-
-        public virtual AbstractF2mPoint[] PreComp
-        {
-            get { return m_preComp; }
-            set { this.m_preComp = value; }
-        }
-    }
-}

+ 0 - 54
src/Renci.SshNet/Security/BouncyCastle/math/field/FiniteFields.cs

@@ -1,54 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Field
-{
-    internal abstract class FiniteFields
-    {
-        internal static readonly IFiniteField GF_2 = new PrimeField(BigInteger.ValueOf(2));
-        internal static readonly IFiniteField GF_3 = new PrimeField(BigInteger.ValueOf(3));
-
-        public static IPolynomialExtensionField GetBinaryExtensionField(int[] exponents)
-        {
-            if (exponents[0] != 0)
-            {
-                throw new ArgumentException("Irreducible polynomials in GF(2) must have constant term", "exponents");
-            }
-            for (int i = 1; i < exponents.Length; ++i)
-            {
-                if (exponents[i] <= exponents[i - 1])
-                {
-                    throw new ArgumentException("Polynomial exponents must be montonically increasing", "exponents");
-                }
-            }
-
-            return new GenericPolynomialExtensionField(GF_2, new GF2Polynomial(exponents));
-        }
-
-    //    public static IPolynomialExtensionField GetTernaryExtensionField(Term[] terms)
-    //    {
-    //        return new GenericPolynomialExtensionField(GF_3, new GF3Polynomial(terms));
-    //    }
-
-        public static IFiniteField GetPrimeField(BigInteger characteristic)
-        {
-            int bitLength = characteristic.BitLength;
-            if (characteristic.SignValue <= 0 || bitLength < 2)
-            {
-                throw new ArgumentException("Must be >= 2", "characteristic");
-            }
-
-            if (bitLength < 3)
-            {
-                switch (characteristic.IntValue)
-                {
-                case 2:
-                    return GF_2;
-                case 3:
-                    return GF_3;
-                }
-            }
-
-            return new PrimeField(characteristic);
-        }
-    }
-}

+ 0 - 46
src/Renci.SshNet/Security/BouncyCastle/math/field/GF2Polynomial.cs

@@ -1,46 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Field
-{
-    internal class GF2Polynomial
-        : IPolynomial
-    {
-        protected readonly int[] exponents;
-
-        internal GF2Polynomial(int[] exponents)
-        {
-            this.exponents = Arrays.Clone(exponents);
-        }
-
-        public virtual int Degree
-        {
-            get { return exponents[exponents.Length - 1]; }
-        }
-
-        public virtual int[] GetExponentsPresent()
-        {
-            return Arrays.Clone(exponents);
-        }
-
-        public override bool Equals(object obj)
-        {
-            if (this == obj)
-            {
-                return true;
-            }
-            GF2Polynomial other = obj as GF2Polynomial;
-            if (null == other)
-            {
-                return false;
-            }
-            return Arrays.AreEqual(exponents, other.exponents);
-        }
-
-        public override int GetHashCode()
-        {
-            return Arrays.GetHashCode(exponents);
-        }
-    }
-}

+ 0 - 63
src/Renci.SshNet/Security/BouncyCastle/math/field/GenericPolynomialExtensionField.cs

@@ -1,63 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Field
-{
-    internal class GenericPolynomialExtensionField
-        : IPolynomialExtensionField
-    {
-        protected readonly IFiniteField subfield;
-        protected readonly IPolynomial minimalPolynomial;
-
-        internal GenericPolynomialExtensionField(IFiniteField subfield, IPolynomial polynomial)
-        {
-            this.subfield = subfield;
-            this.minimalPolynomial = polynomial;
-        }
-
-        public virtual BigInteger Characteristic
-        {
-            get { return subfield.Characteristic; }
-        }
-
-        public virtual int Dimension
-        {
-            get { return subfield.Dimension * minimalPolynomial.Degree; }
-        }
-
-        public virtual IFiniteField Subfield
-        {
-            get { return subfield; }
-        }
-
-        public virtual int Degree
-        {
-            get { return minimalPolynomial.Degree; }
-        }
-
-        public virtual IPolynomial MinimalPolynomial
-        {
-            get { return minimalPolynomial; }
-        }
-
-        public override bool Equals(object obj)
-        {
-            if (this == obj)
-            {
-                return true;
-            }
-            GenericPolynomialExtensionField other = obj as GenericPolynomialExtensionField;
-            if (null == other)
-            {
-                return false;
-            }
-            return subfield.Equals(other.subfield) && minimalPolynomial.Equals(other.minimalPolynomial);
-        }
-
-        public override int GetHashCode()
-        {
-            return subfield.GetHashCode() ^ Integers.RotateLeft(minimalPolynomial.GetHashCode(), 16);
-        }
-    }
-}

+ 0 - 12
src/Renci.SshNet/Security/BouncyCastle/math/field/IExtensionField.cs

@@ -1,12 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Field
-{
-    internal interface IExtensionField
-        : IFiniteField
-    {
-        IFiniteField Subfield { get; }
-
-        int Degree { get; }
-    }
-}

+ 0 - 11
src/Renci.SshNet/Security/BouncyCastle/math/field/IFiniteField.cs

@@ -1,11 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Field
-{
-    internal interface IFiniteField
-    {
-        BigInteger Characteristic { get; }
-
-        int Dimension { get; }
-    }
-}

+ 0 - 13
src/Renci.SshNet/Security/BouncyCastle/math/field/IPolynomial.cs

@@ -1,13 +0,0 @@
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Field
-{
-    internal interface IPolynomial
-    {
-        int Degree { get; }
-
-        //BigInteger[] GetCoefficients();
-
-        int[] GetExponentsPresent();
-
-        //Term[] GetNonZeroTerms();
-    }
-}

+ 0 - 8
src/Renci.SshNet/Security/BouncyCastle/math/field/IPolynomialExtensionField.cs

@@ -1,8 +0,0 @@
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Field
-{
-    internal interface IPolynomialExtensionField
-        : IExtensionField
-    {
-        IPolynomial MinimalPolynomial { get; }
-    }
-}

+ 0 - 42
src/Renci.SshNet/Security/BouncyCastle/math/field/PrimeField.cs

@@ -1,42 +0,0 @@
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Field
-{
-    internal class PrimeField
-        : IFiniteField
-    {
-        protected readonly BigInteger characteristic;
-
-        internal PrimeField(BigInteger characteristic)
-        {
-            this.characteristic = characteristic;
-        }
-
-        public virtual BigInteger Characteristic
-        {
-            get { return characteristic; }
-        }
-
-        public virtual int Dimension
-        {
-            get { return 1; }
-        }
-
-        public override bool Equals(object obj)
-        {
-            if (this == obj)
-            {
-                return true;
-            }
-            PrimeField other = obj as PrimeField;
-            if (null == other)
-            {
-                return false;
-            }
-            return characteristic.Equals(other.characteristic);
-        }
-
-        public override int GetHashCode()
-        {
-            return characteristic.GetHashCode();
-        }
-    }
-}

+ 0 - 185
src/Renci.SshNet/Security/BouncyCastle/math/raw/Mod.cs

@@ -1,185 +0,0 @@
-using System;
-using System.Diagnostics;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Utilities;
-using Renci.SshNet.Security.Org.BouncyCastle.Security;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Raw
-{
-    internal abstract class Mod
-    {
-        private static readonly SecureRandom RandomSource = new SecureRandom();
-
-        public static void Invert(uint[] p, uint[] x, uint[] z)
-        {
-            int len = p.Length;
-            if (Nat.IsZero(len, x))
-                throw new ArgumentException("cannot be 0", "x");
-            if (Nat.IsOne(len, x))
-            {
-                Array.Copy(x, 0, z, 0, len);
-                return;
-            }
-
-            uint[] u = Nat.Copy(len, x);
-            uint[] a = Nat.Create(len);
-            a[0] = 1;
-            int ac = 0;
-
-            if ((u[0] & 1) == 0)
-            {
-                InversionStep(p, u, len, a, ref ac);
-            }
-            if (Nat.IsOne(len, u))
-            {
-                InversionResult(p, ac, a, z);
-                return;
-            }
-
-            uint[] v = Nat.Copy(len, p);
-            uint[] b = Nat.Create(len);
-            int bc = 0;
-
-            int uvLen = len;
-
-            for (;;)
-            {
-                while (u[uvLen - 1] == 0 && v[uvLen - 1] == 0)
-                {
-                    --uvLen;
-                }
-
-                if (Nat.Gte(len, u, v))
-                {
-                    Nat.SubFrom(len, v, u);
-                    Debug.Assert((u[0] & 1) == 0);
-                    ac += Nat.SubFrom(len, b, a) - bc;
-                    InversionStep(p, u, uvLen, a, ref ac);
-                    if (Nat.IsOne(len, u))
-                    {
-                        InversionResult(p, ac, a, z);
-                        return;
-                    }
-                }
-                else
-                {
-                    Nat.SubFrom(len, u, v);
-                    Debug.Assert((v[0] & 1) == 0);
-                    bc += Nat.SubFrom(len, a, b) - ac;
-                    InversionStep(p, v, uvLen, b, ref bc);
-                    if (Nat.IsOne(len, v))
-                    {
-                        InversionResult(p, bc, b, z);
-                        return;
-                    }
-                }
-            }
-        }
-
-        public static uint[] Random(uint[] p)
-        {
-            int len = p.Length;
-            uint[] s = Nat.Create(len);
-
-            uint m = p[len - 1];
-            m |= m >> 1;
-            m |= m >> 2;
-            m |= m >> 4;
-            m |= m >> 8;
-            m |= m >> 16;
-
-            do
-            {
-                byte[] bytes = new byte[len << 2];
-                RandomSource.NextBytes(bytes);
-                Pack.BE_To_UInt32(bytes, 0, s);
-                s[len - 1] &= m;
-            }
-            while (Nat.Gte(len, s, p));
-
-            return s;
-        }
-
-        public static void Add(uint[] p, uint[] x, uint[] y, uint[] z)
-        {
-            int len = p.Length;
-            uint c = Nat.Add(len, x, y, z);
-            if (c != 0)
-            {
-                Nat.SubFrom(len, p, z);
-            }
-        }
-
-        public static void Subtract(uint[] p, uint[] x, uint[] y, uint[] z)
-        {
-            int len = p.Length;
-            int c = Nat.Sub(len, x, y, z);
-            if (c != 0)
-            {
-                Nat.AddTo(len, p, z);
-            }
-        }
-
-        private static void InversionResult(uint[] p, int ac, uint[] a, uint[] z)
-        {
-            if (ac < 0)
-            {
-                Nat.Add(p.Length, a, p, z);
-            }
-            else
-            {
-                Array.Copy(a, 0, z, 0, p.Length);
-            }
-        }
-
-        private static void InversionStep(uint[] p, uint[] u, int uLen, uint[] x, ref int xc)
-        {
-            int len = p.Length;
-            int count = 0;
-            while (u[0] == 0)
-            {
-                Nat.ShiftDownWord(uLen, u, 0);
-                count += 32;
-            }
-
-            {
-                int zeroes = GetTrailingZeroes(u[0]);
-                if (zeroes > 0)
-                {
-                    Nat.ShiftDownBits(uLen, u, zeroes, 0);
-                    count += zeroes;
-                }
-            }
-
-            for (int i = 0; i < count; ++i)
-            {
-                if ((x[0] & 1) != 0)
-                {
-                    if (xc < 0)
-                    {
-                        xc += (int)Nat.AddTo(len, p, x);
-                    }
-                    else
-                    {
-                        xc += Nat.SubFrom(len, p, x);
-                    }
-                }
-
-                Debug.Assert(xc == 0 || xc == -1);
-                Nat.ShiftDownBit(len, x, (uint)xc);
-            }
-        }
-
-        private static int GetTrailingZeroes(uint x)
-        {
-            Debug.Assert(x != 0);
-            int count = 0;
-            while ((x & 1) == 0)
-            {
-                x >>= 1;
-                ++count;
-            }
-            return count;
-        }
-    }
-}

+ 0 - 1153
src/Renci.SshNet/Security/BouncyCastle/math/raw/Nat.cs

@@ -1,1153 +0,0 @@
-using System;
-using System.Diagnostics;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Raw
-{
-    internal abstract class Nat
-    {
-        private const ulong M = 0xFFFFFFFFUL;
-
-        public static uint Add(int len, uint[] x, uint[] y, uint[] z)
-        {
-            ulong c = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                c += (ulong)x[i] + y[i];
-                z[i] = (uint)c;
-                c >>= 32;
-            }
-            return (uint)c;
-        }
-
-        public static uint Add33At(int len, uint x, uint[] z, int zPos)
-        {
-            Debug.Assert(zPos <= (len - 2));
-            ulong c = (ulong)z[zPos + 0] + x;
-            z[zPos + 0] = (uint)c;
-            c >>= 32;
-            c += (ulong)z[zPos + 1] + 1;
-            z[zPos + 1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : IncAt(len, z, zPos + 2);
-        }
-
-        public static uint Add33At(int len, uint x, uint[] z, int zOff, int zPos)
-        {
-            Debug.Assert(zPos <= (len - 2));
-            ulong c = (ulong)z[zOff + zPos] + x;
-            z[zOff + zPos] = (uint)c;
-            c >>= 32;
-            c += (ulong)z[zOff + zPos + 1] + 1;
-            z[zOff + zPos + 1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 2);
-        }
-
-        public static uint Add33To(int len, uint x, uint[] z)
-        {
-            ulong c = (ulong)z[0] + x;
-            z[0] = (uint)c;
-            c >>= 32;
-            c += (ulong)z[1] + 1;
-            z[1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : IncAt(len, z, 2);
-        }
-
-        public static uint Add33To(int len, uint x, uint[] z, int zOff)
-        {
-            ulong c = (ulong)z[zOff + 0] + x;
-            z[zOff + 0] = (uint)c;
-            c >>= 32;
-            c += (ulong)z[zOff + 1] + 1;
-            z[zOff + 1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : IncAt(len, z, zOff, 2);
-        }
-
-        public static uint AddBothTo(int len, uint[] x, uint[] y, uint[] z)
-        {
-            ulong c = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                c += (ulong)x[i] + y[i] + z[i];
-                z[i] = (uint)c;
-                c >>= 32;
-            }
-            return (uint)c;
-        }
-
-        public static uint AddBothTo(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff)
-        {
-            ulong c = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                c += (ulong)x[xOff + i] + y[yOff + i] + z[zOff + i];
-                z[zOff + i] = (uint)c;
-                c >>= 32;
-            }
-            return (uint)c;
-        }
-
-        public static uint AddDWordAt(int len, ulong x, uint[] z, int zPos)
-        {
-            Debug.Assert(zPos <= (len - 2));
-            ulong c = (ulong)z[zPos + 0] + (x & M);
-            z[zPos + 0] = (uint)c;
-            c >>= 32;
-            c += (ulong)z[zPos + 1] + (x >> 32);
-            z[zPos + 1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : IncAt(len, z, zPos + 2);
-        }
-
-        public static uint AddDWordAt(int len, ulong x, uint[] z, int zOff, int zPos)
-        {
-            Debug.Assert(zPos <= (len - 2));
-            ulong c = (ulong)z[zOff + zPos] + (x & M);
-            z[zOff + zPos] = (uint)c;
-            c >>= 32;
-            c += (ulong)z[zOff + zPos + 1] + (x >> 32);
-            z[zOff + zPos + 1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 2);
-        }
-
-        public static uint AddDWordTo(int len, ulong x, uint[] z)
-        {
-            ulong c = (ulong)z[0] + (x & M);
-            z[0] = (uint)c;
-            c >>= 32;
-            c += (ulong)z[1] + (x >> 32);
-            z[1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : IncAt(len, z, 2);
-        }
-
-        public static uint AddDWordTo(int len, ulong x, uint[] z, int zOff)
-        {
-            ulong c = (ulong)z[zOff + 0] + (x & M);
-            z[zOff + 0] = (uint)c;
-            c >>= 32;
-            c += (ulong)z[zOff + 1] + (x >> 32);
-            z[zOff + 1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : IncAt(len, z, zOff, 2);
-        }
-
-        public static uint AddTo(int len, uint[] x, uint[] z)
-        {
-            ulong c = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                c += (ulong)x[i] + z[i];
-                z[i] = (uint)c;
-                c >>= 32;
-            }
-            return (uint)c;
-        }
-
-        public static uint AddTo(int len, uint[] x, int xOff, uint[] z, int zOff)
-        {
-            ulong c = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                c += (ulong)x[xOff + i] + z[zOff + i];
-                z[zOff + i] = (uint)c;
-                c >>= 32;
-            }
-            return (uint)c;
-        }
-
-        public static uint AddWordAt(int len, uint x, uint[] z, int zPos)
-        {
-            Debug.Assert(zPos <= (len - 1));
-            ulong c = (ulong)x + z[zPos];
-            z[zPos] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : IncAt(len, z, zPos + 1);
-        }
-
-        public static uint AddWordAt(int len, uint x, uint[] z, int zOff, int zPos)
-        {
-            Debug.Assert(zPos <= (len - 1));
-            ulong c = (ulong)x + z[zOff + zPos];
-            z[zOff + zPos] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 1);
-        }
-
-        public static uint AddWordTo(int len, uint x, uint[] z)
-        {
-            ulong c = (ulong)x + z[0];
-            z[0] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : IncAt(len, z, 1);
-        }
-
-        public static uint AddWordTo(int len, uint x, uint[] z, int zOff)
-        {
-            ulong c = (ulong)x + z[zOff];
-            z[zOff] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : IncAt(len, z, zOff, 1);
-        }
-
-        public static uint CAdd(int len, int mask, uint[] x, uint[] y, uint[] z)
-        {
-            uint MASK = (uint)-(mask & 1);
-
-            ulong c = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                c += (ulong)x[i] + (y[i] & MASK);
-                z[i] = (uint)c;
-                c >>= 32;
-            }
-            return (uint)c;
-        }
-
-        public static void CMov(int len, int mask, uint[] x, int xOff, uint[] z, int zOff)
-        {
-            uint MASK = (uint)-(mask & 1);
-
-            for (int i = 0; i < len; ++i)
-            {
-                uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i];
-                z_i ^= (diff & MASK);
-                z[zOff + i] = z_i;
-            }
-
-            //uint half = 0x55555555U, rest = half << (-(int)MASK);
-
-            //for (int i = 0; i < len; ++i)
-            //{
-            //    uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i];
-            //    z_i ^= (diff & half);
-            //    z_i ^= (diff & rest);
-            //    z[zOff + i] = z_i;
-            //}
-        }
-
-        public static void CMov(int len, int mask, int[] x, int xOff, int[] z, int zOff)
-        {
-            mask = -(mask & 1);
-
-            for (int i = 0; i < len; ++i)
-            {
-                int z_i = z[zOff + i], diff = z_i ^ x[xOff + i];
-                z_i ^= (diff & mask);
-                z[zOff + i] = z_i;
-            }
-
-            //int half = 0x55555555, rest = half << (-mask);
-
-            //for (int i = 0; i < len; ++i)
-            //{
-            //    int z_i = z[zOff + i], diff = z_i ^ x[xOff + i];
-            //    z_i ^= (diff & half);
-            //    z_i ^= (diff & rest);
-            //    z[zOff + i] = z_i;
-            //}
-        }
-
-        public static void Copy(int len, uint[] x, uint[] z)
-        {
-            Array.Copy(x, 0, z, 0, len);
-        }
-
-        public static uint[] Copy(int len, uint[] x)
-        {
-            uint[] z = new uint[len];
-            Array.Copy(x, 0, z, 0, len);
-            return z;
-        }
-
-        public static void Copy(int len, uint[] x, int xOff, uint[] z, int zOff)
-        {
-            Array.Copy(x, xOff, z, zOff, len);
-        }
-
-        public static uint[] Create(int len)
-        {
-            return new uint[len];
-        }
-
-        public static ulong[] Create64(int len)
-        {
-            return new ulong[len];
-        }
-
-        public static int Dec(int len, uint[] z)
-        {
-            for (int i = 0; i < len; ++i)
-            {
-                if (--z[i] != uint.MaxValue)
-                {
-                    return 0;
-                }
-            }
-            return -1;
-        }
-
-        public static int Dec(int len, uint[] x, uint[] z)
-        {
-            int i = 0;
-            while (i < len)
-            {
-                uint c = x[i] - 1;
-                z[i] = c;
-                ++i;
-                if (c != uint.MaxValue)
-                {
-                    while (i < len)
-                    {
-                        z[i] = x[i];
-                        ++i;
-                    }
-                    return 0;
-                }
-            }
-            return -1;
-        }
-
-        public static int DecAt(int len, uint[] z, int zPos)
-        {
-            Debug.Assert(zPos <= len);
-            for (int i = zPos; i < len; ++i)
-            {
-                if (--z[i] != uint.MaxValue)
-                {
-                    return 0;
-                }
-            }
-            return -1;
-        }
-
-        public static int DecAt(int len, uint[] z, int zOff, int zPos)
-        {
-            Debug.Assert(zPos <= len);
-            for (int i = zPos; i < len; ++i)
-            {
-                if (--z[zOff + i] != uint.MaxValue)
-                {
-                    return 0;
-                }
-            }
-            return -1;
-        }
-
-        public static bool Eq(int len, uint[] x, uint[] y)
-        {
-            for (int i = len - 1; i >= 0; --i)
-            {
-                if (x[i] != y[i])
-                {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        public static uint[] FromBigInteger(int bits, BigInteger x)
-        {
-            if (x.SignValue < 0 || x.BitLength > bits)
-                throw new ArgumentException();
-
-            int len = (bits + 31) >> 5;
-            uint[] z = Create(len);
-            int i = 0;
-            while (x.SignValue != 0)
-            {
-                z[i++] = (uint)x.IntValue;
-                x = x.ShiftRight(32);
-            }
-            return z;
-        }
-
-        public static uint GetBit(uint[] x, int bit)
-        {
-            if (bit == 0)
-            {
-                return x[0] & 1;
-            }
-            int w = bit >> 5;
-            if (w < 0 || w >= x.Length)
-            {
-                return 0;
-            }
-            int b = bit & 31;
-            return (x[w] >> b) & 1;
-        }
-
-        public static bool Gte(int len, uint[] x, uint[] y)
-        {
-            for (int i = len - 1; i >= 0; --i)
-            {
-                uint x_i = x[i], y_i = y[i];
-                if (x_i < y_i)
-                    return false;
-                if (x_i > y_i)
-                    return true;
-            }
-            return true;
-        }
-
-        public static uint Inc(int len, uint[] z)
-        {
-            for (int i = 0; i < len; ++i)
-            {
-                if (++z[i] != uint.MinValue)
-                {
-                    return 0;
-                }
-            }
-            return 1;
-        }
-
-        public static uint Inc(int len, uint[] x, uint[] z)
-        {
-            int i = 0;
-            while (i < len)
-            {
-                uint c = x[i] + 1;
-                z[i] = c;
-                ++i;
-                if (c != 0)
-                {
-                    while (i < len)
-                    {
-                        z[i] = x[i];
-                        ++i;
-                    }
-                    return 0;
-                }
-            }
-            return 1;
-        }
-
-        public static uint IncAt(int len, uint[] z, int zPos)
-        {
-            Debug.Assert(zPos <= len);
-            for (int i = zPos; i < len; ++i)
-            {
-                if (++z[i] != uint.MinValue)
-                {
-                    return 0;
-                }
-            }
-            return 1;
-        }
-
-        public static uint IncAt(int len, uint[] z, int zOff, int zPos)
-        {
-            Debug.Assert(zPos <= len);
-            for (int i = zPos; i < len; ++i)
-            {
-                if (++z[zOff + i] != uint.MinValue)
-                {
-                    return 0;
-                }
-            }
-            return 1;
-        }
-
-        public static bool IsOne(int len, uint[] x)
-        {
-            if (x[0] != 1)
-            {
-                return false;
-            }
-            for (int i = 1; i < len; ++i)
-            {
-                if (x[i] != 0)
-                {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        public static bool IsZero(int len, uint[] x)
-        {
-            if (x[0] != 0)
-            {
-                return false;
-            }
-            for (int i = 1; i < len; ++i)
-            {
-                if (x[i] != 0)
-                {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        public static void Mul(int len, uint[] x, uint[] y, uint[] zz)
-        {
-            zz[len] = MulWord(len, x[0], y, zz);
-
-            for (int i = 1; i < len; ++i)
-            {
-                zz[i + len] = MulWordAddTo(len, x[i], y, 0, zz, i);
-            }
-        }
-
-        public static void Mul(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff)
-        {
-            zz[zzOff + len] = MulWord(len, x[xOff], y, yOff, zz, zzOff);
-
-            for (int i = 1; i < len; ++i)
-            {
-                zz[zzOff + i + len] = MulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff + i);
-            }
-        }
-
-        public static void Mul(uint[] x, int xOff, int xLen, uint[] y, int yOff, int yLen, uint[] zz, int zzOff)
-        {
-            zz[zzOff + yLen] = MulWord(yLen, x[xOff], y, yOff, zz, zzOff);
-
-            for (int i = 1; i < xLen; ++i)
-            {
-                zz[zzOff + i + yLen] = MulWordAddTo(yLen, x[xOff + i], y, yOff, zz, zzOff + i);
-            }
-        }
-
-        public static uint MulAddTo(int len, uint[] x, uint[] y, uint[] zz)
-        {
-            ulong zc = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                ulong c = MulWordAddTo(len, x[i], y, 0, zz, i) & M;
-                c += zc + (zz[i + len] & M);
-                zz[i + len] = (uint)c;
-                zc = c >> 32;
-            }
-            return (uint)zc;
-        }
-
-        public static uint MulAddTo(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff)
-        {
-            ulong zc = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                ulong c = MulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff) & M;
-                c += zc + (zz[zzOff + len] & M);
-                zz[zzOff + len] = (uint)c;
-                zc = c >> 32;
-                ++zzOff;
-            }
-            return (uint)zc;
-        }
-
-        public static uint Mul31BothAdd(int len, uint a, uint[] x, uint b, uint[] y, uint[] z, int zOff)
-        {
-            ulong c = 0, aVal = (ulong)a, bVal = (ulong)b;
-            int i = 0;
-            do
-            {
-                c += aVal * x[i] + bVal * y[i] + z[zOff + i];
-                z[zOff + i] = (uint)c;
-                c >>= 32;
-            }
-            while (++i < len);
-            return (uint)c;
-        }
-
-        public static uint MulWord(int len, uint x, uint[] y, uint[] z)
-        {
-            ulong c = 0, xVal = (ulong)x;
-            int i = 0;
-            do
-            {
-                c += xVal * y[i];
-                z[i] = (uint)c;
-                c >>= 32;
-            }
-            while (++i < len);
-            return (uint)c;
-        }
-
-        public static uint MulWord(int len, uint x, uint[] y, int yOff, uint[] z, int zOff)
-        {
-            ulong c = 0, xVal = (ulong)x;
-            int i = 0;
-            do
-            {
-                c += xVal * y[yOff + i];
-                z[zOff + i] = (uint)c;
-                c >>= 32;
-            }
-            while (++i < len);
-            return (uint)c;
-        }
-
-        public static uint MulWordAddTo(int len, uint x, uint[] y, int yOff, uint[] z, int zOff)
-        {
-            ulong c = 0, xVal = (ulong)x;
-            int i = 0;
-            do
-            {
-                c += xVal * y[yOff + i] + z[zOff + i];
-                z[zOff + i] = (uint)c;
-                c >>= 32;
-            }
-            while (++i < len);
-            return (uint)c;
-        }
-
-        public static uint MulWordDwordAddAt(int len, uint x, ulong y, uint[] z, int zPos)
-        {
-            Debug.Assert(zPos <= (len - 3));
-            ulong c = 0, xVal = (ulong)x;
-            c += xVal * (uint)y + z[zPos + 0];
-            z[zPos + 0] = (uint)c;
-            c >>= 32;
-            c += xVal * (y >> 32) + z[zPos + 1];
-            z[zPos + 1] = (uint)c;
-            c >>= 32;
-            c += (ulong)z[zPos + 2];
-            z[zPos + 2] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : IncAt(len, z, zPos + 3);
-        }
-
-        public static uint ShiftDownBit(int len, uint[] z, uint c)
-        {
-            int i = len;
-            while (--i >= 0)
-            {
-                uint next = z[i];
-                z[i] = (next >> 1) | (c << 31);
-                c = next;
-            }
-            return c << 31;
-        }
-
-        public static uint ShiftDownBit(int len, uint[] z, int zOff, uint c)
-        {
-            int i = len;
-            while (--i >= 0)
-            {
-                uint next = z[zOff + i];
-                z[zOff + i] = (next >> 1) | (c << 31);
-                c = next;
-            }
-            return c << 31;
-        }
-
-        public static uint ShiftDownBit(int len, uint[] x, uint c, uint[] z)
-        {
-            int i = len;
-            while (--i >= 0)
-            {
-                uint next = x[i];
-                z[i] = (next >> 1) | (c << 31);
-                c = next;
-            }
-            return c << 31;
-        }
-
-        public static uint ShiftDownBit(int len, uint[] x, int xOff, uint c, uint[] z, int zOff)
-        {
-            int i = len;
-            while (--i >= 0)
-            {
-                uint next = x[xOff + i];
-                z[zOff + i] = (next >> 1) | (c << 31);
-                c = next;
-            }
-            return c << 31;
-        }
-
-        public static uint ShiftDownBits(int len, uint[] z, int bits, uint c)
-        {
-            Debug.Assert(bits > 0 && bits < 32);
-            int i = len;
-            while (--i >= 0)
-            {
-                uint next = z[i];
-                z[i] = (next >> bits) | (c << -bits);
-                c = next;
-            }
-            return c << -bits;
-        }
-
-        public static uint ShiftDownBits(int len, uint[] z, int zOff, int bits, uint c)
-        {
-            Debug.Assert(bits > 0 && bits < 32);
-            int i = len;
-            while (--i >= 0)
-            {
-                uint next = z[zOff + i];
-                z[zOff + i] = (next >> bits) | (c << -bits);
-                c = next;
-            }
-            return c << -bits;
-        }
-
-        public static uint ShiftDownBits(int len, uint[] x, int bits, uint c, uint[] z)
-        {
-            Debug.Assert(bits > 0 && bits < 32);
-            int i = len;
-            while (--i >= 0)
-            {
-                uint next = x[i];
-                z[i] = (next >> bits) | (c << -bits);
-                c = next;
-            }
-            return c << -bits;
-        }
-
-        public static uint ShiftDownBits(int len, uint[] x, int xOff, int bits, uint c, uint[] z, int zOff)
-        {
-            Debug.Assert(bits > 0 && bits < 32);
-            int i = len;
-            while (--i >= 0)
-            {
-                uint next = x[xOff + i];
-                z[zOff + i] = (next >> bits) | (c << -bits);
-                c = next;
-            }
-            return c << -bits;
-        }
-
-        public static uint ShiftDownWord(int len, uint[] z, uint c)
-        {
-            int i = len;
-            while (--i >= 0)
-            {
-                uint next = z[i];
-                z[i] = c;
-                c = next;
-            }
-            return c;
-        }
-
-        public static uint ShiftUpBit(int len, uint[] z, uint c)
-        {
-            for (int i = 0; i < len; ++i)
-            {
-                uint next = z[i];
-                z[i] = (next << 1) | (c >> 31);
-                c = next;
-            }
-            return c >> 31;
-        }
-
-        public static uint ShiftUpBit(int len, uint[] z, int zOff, uint c)
-        {
-            for (int i = 0; i < len; ++i)
-            {
-                uint next = z[zOff + i];
-                z[zOff + i] = (next << 1) | (c >> 31);
-                c = next;
-            }
-            return c >> 31;
-        }
-
-        public static uint ShiftUpBit(int len, uint[] x, uint c, uint[] z)
-        {
-            for (int i = 0; i < len; ++i)
-            {
-                uint next = x[i];
-                z[i] = (next << 1) | (c >> 31);
-                c = next;
-            }
-            return c >> 31;
-        }
-
-        public static uint ShiftUpBit(int len, uint[] x, int xOff, uint c, uint[] z, int zOff)
-        {
-            for (int i = 0; i < len; ++i)
-            {
-                uint next = x[xOff + i];
-                z[zOff + i] = (next << 1) | (c >> 31);
-                c = next;
-            }
-            return c >> 31;
-        }
-
-        public static ulong ShiftUpBit64(int len, ulong[] x, int xOff, ulong c, ulong[] z, int zOff)
-        {
-            for (int i = 0; i < len; ++i)
-            {
-                ulong next = x[xOff + i];
-                z[zOff + i] = (next << 1) | (c >> 63);
-                c = next;
-            }
-            return c >> 63;
-        }
-
-        public static uint ShiftUpBits(int len, uint[] z, int bits, uint c)
-        {
-            Debug.Assert(bits > 0 && bits < 32);
-            for (int i = 0; i < len; ++i)
-            {
-                uint next = z[i];
-                z[i] = (next << bits) | (c >> -bits);
-                c = next;
-            }
-            return c >> -bits;
-        }
-
-        public static uint ShiftUpBits(int len, uint[] z, int zOff, int bits, uint c)
-        {
-            Debug.Assert(bits > 0 && bits < 32);
-            for (int i = 0; i < len; ++i)
-            {
-                uint next = z[zOff + i];
-                z[zOff + i] = (next << bits) | (c >> -bits);
-                c = next;
-            }
-            return c >> -bits;
-        }
-
-        public static ulong ShiftUpBits64(int len, ulong[] z, int zOff, int bits, ulong c)
-        {
-            Debug.Assert(bits > 0 && bits < 64);
-            for (int i = 0; i < len; ++i)
-            {
-                ulong next = z[zOff + i];
-                z[zOff + i] = (next << bits) | (c >> -bits);
-                c = next;
-            }
-            return c >> -bits;
-        }
-
-        public static uint ShiftUpBits(int len, uint[] x, int bits, uint c, uint[] z)
-        {
-            Debug.Assert(bits > 0 && bits < 32);
-            for (int i = 0; i < len; ++i)
-            {
-                uint next = x[i];
-                z[i] = (next << bits) | (c >> -bits);
-                c = next;
-            }
-            return c >> -bits;
-        }
-
-        public static uint ShiftUpBits(int len, uint[] x, int xOff, int bits, uint c, uint[] z, int zOff)
-        {
-            Debug.Assert(bits > 0 && bits < 32);
-            for (int i = 0; i < len; ++i)
-            {
-                uint next = x[xOff + i];
-                z[zOff + i] = (next << bits) | (c >> -bits);
-                c = next;
-            }
-            return c >> -bits;
-        }
-
-        public static ulong ShiftUpBits64(int len, ulong[] x, int xOff, int bits, ulong c, ulong[] z, int zOff)
-        {
-            Debug.Assert(bits > 0 && bits < 64);
-            for (int i = 0; i < len; ++i)
-            {
-                ulong next = x[xOff + i];
-                z[zOff + i] = (next << bits) | (c >> -bits);
-                c = next;
-            }
-            return c >> -bits;
-        }
-
-        public static void Square(int len, uint[] x, uint[] zz)
-        {
-            int extLen = len << 1;
-            uint c = 0;
-            int j = len, k = extLen;
-            do
-            {
-                ulong xVal = (ulong)x[--j];
-                ulong p = xVal * xVal;
-                zz[--k] = (c << 31) | (uint)(p >> 33);
-                zz[--k] = (uint)(p >> 1);
-                c = (uint)p;
-            }
-            while (j > 0);
-
-            for (int i = 1; i < len; ++i)
-            {
-                c = SquareWordAdd(x, i, zz);
-                AddWordAt(extLen, c, zz, i << 1);
-            }
-
-            ShiftUpBit(extLen, zz, x[0] << 31);
-        }
-
-        public static void Square(int len, uint[] x, int xOff, uint[] zz, int zzOff)
-        {
-            int extLen = len << 1;
-            uint c = 0;
-            int j = len, k = extLen;
-            do
-            {
-                ulong xVal = (ulong)x[xOff + --j];
-                ulong p = xVal * xVal;
-                zz[zzOff + --k] = (c << 31) | (uint)(p >> 33);
-                zz[zzOff + --k] = (uint)(p >> 1);
-                c = (uint)p;
-            }
-            while (j > 0);
-
-            for (int i = 1; i < len; ++i)
-            {
-                c = SquareWordAdd(x, xOff, i, zz, zzOff);
-                AddWordAt(extLen, c, zz, zzOff, i << 1);
-            }
-
-            ShiftUpBit(extLen, zz, zzOff, x[xOff] << 31);
-        }
-
-        public static uint SquareWordAdd(uint[] x, int xPos, uint[] z)
-        {
-            ulong c = 0, xVal = (ulong)x[xPos];
-            int i = 0;
-            do
-            {
-                c += xVal * x[i] + z[xPos + i];
-                z[xPos + i] = (uint)c;
-                c >>= 32;
-            }
-            while (++i < xPos);
-            return (uint)c;
-        }
-
-        public static uint SquareWordAdd(uint[] x, int xOff, int xPos, uint[] z, int zOff)
-        {
-            ulong c = 0, xVal = (ulong)x[xOff + xPos];
-            int i = 0;
-            do
-            {
-                c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M);
-                z[xPos + zOff] = (uint)c;
-                c >>= 32;
-                ++zOff;
-            }
-            while (++i < xPos);
-            return (uint)c;
-        }
-
-        public static int Sub(int len, uint[] x, uint[] y, uint[] z)
-        {
-            long c = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                c += (long)x[i] - y[i];
-                z[i] = (uint)c;
-                c >>= 32;
-            }
-            return (int)c;
-        }
-
-        public static int Sub(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff)
-        {
-            long c = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                c += (long)x[xOff + i] - y[yOff + i];
-                z[zOff + i] = (uint)c;
-                c >>= 32;
-            }
-            return (int)c;
-        }
-        public static int Sub33At(int len, uint x, uint[] z, int zPos)
-        {
-            Debug.Assert(zPos <= (len - 2));
-            long c = (long)z[zPos + 0] - x;
-            z[zPos + 0] = (uint)c;
-            c >>= 32;
-            c += (long)z[zPos + 1] - 1;
-            z[zPos + 1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : DecAt(len, z, zPos + 2);
-        }
-
-        public static int Sub33At(int len, uint x, uint[] z, int zOff, int zPos)
-        {
-            Debug.Assert(zPos <= (len - 2));
-            long c = (long)z[zOff + zPos] - x;
-            z[zOff + zPos] = (uint)c;
-            c >>= 32;
-            c += (long)z[zOff + zPos + 1] - 1;
-            z[zOff + zPos + 1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 2);
-        }
-
-        public static int Sub33From(int len, uint x, uint[] z)
-        {
-            long c = (long)z[0] - x;
-            z[0] = (uint)c;
-            c >>= 32;
-            c += (long)z[1] - 1;
-            z[1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : DecAt(len, z, 2);
-        }
-
-        public static int Sub33From(int len, uint x, uint[] z, int zOff)
-        {
-            long c = (long)z[zOff + 0] - x;
-            z[zOff + 0] = (uint)c;
-            c >>= 32;
-            c += (long)z[zOff + 1] - 1;
-            z[zOff + 1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : DecAt(len, z, zOff, 2);
-        }
-
-        public static int SubBothFrom(int len, uint[] x, uint[] y, uint[] z)
-        {
-            long c = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                c += (long)z[i] - x[i] - y[i];
-                z[i] = (uint)c;
-                c >>= 32;
-            }
-            return (int)c;
-        }
-
-        public static int SubBothFrom(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff)
-        {
-            long c = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                c += (long)z[zOff + i] - x[xOff + i] - y[yOff + i];
-                z[zOff + i] = (uint)c;
-                c >>= 32;
-            }
-            return (int)c;
-        }
-
-        public static int SubDWordAt(int len, ulong x, uint[] z, int zPos)
-        {
-            Debug.Assert(zPos <= (len - 2));
-            long c = (long)z[zPos + 0] - (long)(x & M);
-            z[zPos + 0] = (uint)c;
-            c >>= 32;
-            c += (long)z[zPos + 1] - (long)(x >> 32);
-            z[zPos + 1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : DecAt(len, z, zPos + 2);
-        }
-
-        public static int SubDWordAt(int len, ulong x, uint[] z, int zOff, int zPos)
-        {
-            Debug.Assert(zPos <= (len - 2));
-            long c = (long)z[zOff + zPos] - (long)(x & M);
-            z[zOff + zPos] = (uint)c;
-            c >>= 32;
-            c += (long)z[zOff + zPos + 1] - (long)(x >> 32);
-            z[zOff + zPos + 1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : DecAt(len, z,  zOff, zPos + 2);
-        }
-
-        public static int SubDWordFrom(int len, ulong x, uint[] z)
-        {
-            long c = (long)z[0] - (long)(x & M);
-            z[0] = (uint)c;
-            c >>= 32;
-            c += (long)z[1] - (long)(x >> 32);
-            z[1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : DecAt(len, z, 2);
-        }
-
-        public static int SubDWordFrom(int len, ulong x, uint[] z, int zOff)
-        {
-            long c = (long)z[zOff + 0] - (long)(x & M);
-            z[zOff + 0] = (uint)c;
-            c >>= 32;
-            c += (long)z[zOff + 1] - (long)(x >> 32);
-            z[zOff + 1] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : DecAt(len, z, zOff, 2);
-        }
-
-        public static int SubFrom(int len, uint[] x, uint[] z)
-        {
-            long c = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                c += (long)z[i] - x[i];
-                z[i] = (uint)c;
-                c >>= 32;
-            }
-            return (int)c;
-        }
-
-        public static int SubFrom(int len, uint[] x, int xOff, uint[] z, int zOff)
-        {
-            long c = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                c += (long)z[zOff + i] - x[xOff + i];
-                z[zOff + i] = (uint)c;
-                c >>= 32;
-            }
-            return (int)c;
-        }
-
-        public static int SubWordAt(int len, uint x, uint[] z, int zPos)
-        {
-            Debug.Assert(zPos <= (len - 1));
-            long c = (long)z[zPos] - x;
-            z[zPos] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : DecAt(len, z, zPos + 1);
-        }
-
-        public static int SubWordAt(int len, uint x, uint[] z, int zOff, int zPos)
-        {
-            Debug.Assert(zPos <= (len - 1));
-            long c = (long)z[zOff + zPos] - x;
-            z[zOff + zPos] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 1);
-        }
-
-        public static int SubWordFrom(int len, uint x, uint[] z)
-        {
-            long c = (long)z[0] - x;
-            z[0] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : DecAt(len, z, 1);
-        }
-
-        public static int SubWordFrom(int len, uint x, uint[] z, int zOff)
-        {
-            long c = (long)z[zOff + 0] - x;
-            z[zOff + 0] = (uint)c;
-            c >>= 32;
-            return c == 0 ? 0 : DecAt(len, z, zOff, 1);
-        }
-
-        public static BigInteger ToBigInteger(int len, uint[] x)
-        {
-            byte[] bs = new byte[len << 2];
-            for (int i = 0; i < len; ++i)
-            {
-                uint x_i = x[i];
-                if (x_i != 0)
-                {
-                    Pack.UInt32_To_BE(x_i, bs, (len - 1 - i) << 2);
-                }
-            }
-            return new BigInteger(1, bs);
-        }
-
-        public static void Zero(int len, uint[] z)
-        {
-            for (int i = 0; i < len; ++i)
-            {
-                z[i] = 0;
-            }
-        }
-    }
-}

+ 0 - 34
src/Renci.SshNet/Security/BouncyCastle/security/DigestUtilities.cs

@@ -1,34 +0,0 @@
-using Renci.SshNet.Security.Org.BouncyCastle.Crypto;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Security
-{
-    /// <remarks>
-    ///  Utility class for creating IDigest objects from their names/Oids
-    /// </remarks>
-    internal sealed class DigestUtilities
-    {
-        private enum DigestAlgorithm {
-            SHA_256
-        };
-
-        private DigestUtilities()
-        {
-        }
-
-        public static byte[] DoFinal(
-            IDigest digest)
-        {
-            byte[] b = new byte[digest.GetDigestSize()];
-            digest.DoFinal(b, 0);
-            return b;
-        }
-
-        public static byte[] DoFinal(
-            IDigest	digest,
-            byte[]	input)
-        {
-            digest.BlockUpdate(input, 0, input.Length);
-            return DoFinal(digest);
-        }
-    }
-}

+ 0 - 179
src/Renci.SshNet/Security/BouncyCastle/security/SecureRandom.cs

@@ -1,179 +0,0 @@
-using System;
-using System.Threading;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Crypto;
-using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Digests;
-using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Prng;
-using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Security
-{
-    internal class SecureRandom
-        : Random
-    {
-        private static long counter = Times.NanoTime();
-
-       private static long NextCounterValue()
-        {
-            return Interlocked.Increment(ref counter);
-        }
-
-        private static readonly SecureRandom master = new SecureRandom(new CryptoApiRandomGenerator());
-        private static SecureRandom Master
-        {
-            get { return master; }
-        }
-
-        private static DigestRandomGenerator CreatePrng(IDigest digest, bool autoSeed)
-        {
-            DigestRandomGenerator prng = new DigestRandomGenerator(digest);
-            if (autoSeed)
-            {
-                prng.AddSeedMaterial(NextCounterValue());
-                prng.AddSeedMaterial(GetNextBytes(Master, digest.GetDigestSize()));
-            }
-            return prng;
-        }
-
-        public static byte[] GetNextBytes(SecureRandom secureRandom, int length)
-        {
-            byte[] result = new byte[length];
-            secureRandom.NextBytes(result);
-            return result;
-        }
-
-        protected readonly IRandomGenerator generator;
-
-        public SecureRandom()
-            : this(CreatePrng(new Sha256Digest(), true))
-        {
-        }
-
-        /// <summary>Use the specified instance of IRandomGenerator as random source.</summary>
-        /// <remarks>
-        /// This constructor performs no seeding of either the <c>IRandomGenerator</c> or the
-        /// constructed <c>SecureRandom</c>. It is the responsibility of the client to provide
-        /// proper seed material as necessary/appropriate for the given <c>IRandomGenerator</c>
-        /// implementation.
-        /// </remarks>
-        /// <param name="generator">The source to generate all random bytes from.</param>
-        public SecureRandom(IRandomGenerator generator)
-#pragma warning disable CA5394 // Do not use insecure randomness
-            : base(0)
-#pragma warning restore CA5394 // Do not use insecure randomness
-        {
-            this.generator = generator;
-        }
-
-        public virtual byte[] GenerateSeed(int length)
-        {
-            return GetNextBytes(Master, length);
-        }
-
-        public virtual void SetSeed(byte[] seed)
-        {
-            generator.AddSeedMaterial(seed);
-        }
-
-        public virtual void SetSeed(long seed)
-        {
-            generator.AddSeedMaterial(seed);
-        }
-
-        public override int Next()
-        {
-            return NextInt() & int.MaxValue;
-        }
-
-        public override int Next(int maxValue)
-        {
-
-            if (maxValue < 2)
-            {
-                if (maxValue < 0)
-                    throw new ArgumentOutOfRangeException("maxValue", "cannot be negative");
-
-                return 0;
-            }
-
-            int bits;
-
-            // Test whether maxValue is a power of 2
-            if ((maxValue & (maxValue - 1)) == 0)
-            {
-                bits = NextInt() & int.MaxValue;
-                return (int)(((long)bits * maxValue) >> 31);
-            }
-
-            int result;
-            do
-            {
-                bits = NextInt() & int.MaxValue;
-                result = bits % maxValue;
-            }
-            while (bits - result + (maxValue - 1) < 0); // Ignore results near overflow
-
-            return result;
-        }
-
-        public override int Next(int minValue, int maxValue)
-        {
-            if (maxValue <= minValue)
-            {
-                if (maxValue == minValue)
-                    return minValue;
-
-                throw new ArgumentException("maxValue cannot be less than minValue");
-            }
-
-            int diff = maxValue - minValue;
-            if (diff > 0)
-                return minValue + Next(diff);
-
-            for (;;)
-            {
-                int i = NextInt();
-
-                if (i >= minValue && i < maxValue)
-                    return i;
-            }
-        }
-
-        public override void NextBytes(byte[] buf)
-        {
-            generator.NextBytes(buf);
-        }
-
-        public virtual void NextBytes(byte[] buf, int off, int len)
-        {
-            generator.NextBytes(buf, off, len);
-        }
-
-        private static readonly double DoubleScale = System.Math.Pow(2.0, 64.0);
-
-        public override double NextDouble()
-        {
-            return Convert.ToDouble((ulong) NextLong()) / DoubleScale;
-        }
-
-        public virtual int NextInt()
-        {
-            byte[] bytes = new byte[4];
-            NextBytes(bytes);
-
-            uint result = bytes[0];
-            result <<= 8;
-            result |= bytes[1];
-            result <<= 8;
-            result |= bytes[2];
-            result <<= 8;
-            result |= bytes[3];
-            return (int)result;
-        }
-
-        public virtual long NextLong()
-        {
-            return ((long)(uint) NextInt() << 32) | (long)(uint) NextInt();
-        }
-    }
-}

+ 0 - 36
src/Renci.SshNet/Security/BouncyCastle/security/SecurityUtilityException.cs

@@ -1,36 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Security
-{
-#if NETFRAMEWORK
-    [Serializable]
-#endif
-    internal class SecurityUtilityException
-		: Exception
-    {
-        /**
-        * base constructor.
-        */
-        public SecurityUtilityException()
-        {
-        }
-
-		/**
-         * create a SecurityUtilityException with the given message.
-         *
-         * @param message the message to be carried with the exception.
-         */
-        public SecurityUtilityException(
-            string message)
-			: base(message)
-        {
-        }
-
-		public SecurityUtilityException(
-            string		message,
-            Exception	exception)
-			: base(message, exception)
-        {
-        }
-    }
-}

+ 0 - 718
src/Renci.SshNet/Security/BouncyCastle/util/Arrays.cs

@@ -1,718 +0,0 @@
-using System;
-using System.Text;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Utilities
-{
-    /// <summary> General array utilities.</summary>
-    internal abstract class Arrays
-    {
-        public static readonly byte[] EmptyBytes = new byte[0];
-        public static readonly int[] EmptyInts = new int[0];
-
-        public static bool AreAllZeroes(byte[] buf, int off, int len)
-        {
-            uint bits = 0;
-            for (int i = 0; i < len; ++i)
-            {
-                bits |= buf[off + i];
-            }
-            return bits == 0;
-        }
-
-        public static bool AreEqual(
-            bool[]  a,
-            bool[]  b)
-        {
-            if (a == b)
-                return true;
-
-            if (a == null || b == null)
-                return false;
-
-            return HaveSameContents(a, b);
-        }
-
-        public static bool AreEqual(
-            char[] a,
-            char[] b)
-        {
-            if (a == b)
-                return true;
-
-            if (a == null || b == null)
-                return false;
-
-            return HaveSameContents(a, b);
-        }
-
-        /// <summary>
-        /// Are two arrays equal.
-        /// </summary>
-        /// <param name="a">Left side.</param>
-        /// <param name="b">Right side.</param>
-        /// <returns>True if equal.</returns>
-        public static bool AreEqual(
-            byte[]	a,
-            byte[]	b)
-        {
-            if (a == b)
-                return true;
-
-            if (a == null || b == null)
-                return false;
-
-            return HaveSameContents(a, b);
-        }
-
-        [Obsolete("Use 'AreEqual' method instead")]
-        public static bool AreSame(
-            byte[]	a,
-            byte[]	b)
-        {
-            return AreEqual(a, b);
-        }
-
-        /// <summary>
-        /// A constant time equals comparison - does not terminate early if
-        /// test will fail.
-        /// </summary>
-        /// <param name="a">first array</param>
-        /// <param name="b">second array</param>
-        /// <returns>true if arrays equal, false otherwise.</returns>
-        public static bool ConstantTimeAreEqual(
-            byte[]	a,
-            byte[]	b)
-        {
-            int i = a.Length;
-            if (i != b.Length)
-                return false;
-            int cmp = 0;
-            while (i != 0)
-            {
-                --i;
-                cmp |= (a[i] ^ b[i]);
-            }
-            return cmp == 0;
-        }
-
-        public static bool AreEqual(
-            int[]	a,
-            int[]	b)
-        {
-            if (a == b)
-                return true;
-
-            if (a == null || b == null)
-                return false;
-
-            return HaveSameContents(a, b);
-        }
-
-        public static bool AreEqual(uint[] a, uint[] b)
-        {
-            if (a == b)
-                return true;
-
-            if (a == null || b == null)
-                return false;
-
-            return HaveSameContents(a, b);
-        }
-
-        private static bool HaveSameContents(
-            bool[] a,
-            bool[] b)
-        {
-            int i = a.Length;
-            if (i != b.Length)
-                return false;
-            while (i != 0)
-            {
-                --i;
-                if (a[i] != b[i])
-                    return false;
-            }
-            return true;
-        }
-
-        private static bool HaveSameContents(
-            char[] a,
-            char[] b)
-        {
-            int i = a.Length;
-            if (i != b.Length)
-                return false;
-            while (i != 0)
-            {
-                --i;
-                if (a[i] != b[i])
-                    return false;
-            }
-            return true;
-        }
-
-        private static bool HaveSameContents(
-            byte[]	a,
-            byte[]	b)
-        {
-            int i = a.Length;
-            if (i != b.Length)
-                return false;
-            while (i != 0)
-            {
-                --i;
-                if (a[i] != b[i])
-                    return false;
-            }
-            return true;
-        }
-
-        private static bool HaveSameContents(
-            int[]	a,
-            int[]	b)
-        {
-            int i = a.Length;
-            if (i != b.Length)
-                return false;
-            while (i != 0)
-            {
-                --i;
-                if (a[i] != b[i])
-                    return false;
-            }
-            return true;
-        }
-
-        private static bool HaveSameContents(uint[] a, uint[] b)
-        {
-            int i = a.Length;
-            if (i != b.Length)
-                return false;
-            while (i != 0)
-            {
-                --i;
-                if (a[i] != b[i])
-                    return false;
-            }
-            return true;
-        }
-
-        public static string ToString(
-            object[] a)
-        {
-            StringBuilder sb = new StringBuilder('[');
-            if (a.Length > 0)
-            {
-                sb.Append(a[0]);
-                for (int index = 1; index < a.Length; ++index)
-                {
-                    sb.Append(", ").Append(a[index]);
-                }
-            }
-            sb.Append(']');
-            return sb.ToString();
-        }
-
-        public static int GetHashCode(byte[] data)
-        {
-            if (data == null)
-            {
-                return 0;
-            }
-
-            int i = data.Length;
-            int hc = i + 1;
-
-            while (--i >= 0)
-            {
-                hc *= 257;
-                hc ^= data[i];
-            }
-
-            return hc;
-        }
-
-        public static int GetHashCode(byte[] data, int off, int len)
-        {
-            if (data == null)
-            {
-                return 0;
-            }
-
-            int i = len;
-            int hc = i + 1;
-
-            while (--i >= 0)
-            {
-                hc *= 257;
-                hc ^= data[off + i];
-            }
-
-            return hc;
-        }
-
-        public static int GetHashCode(int[] data)
-        {
-            if (data == null)
-                return 0;
-
-            int i = data.Length;
-            int hc = i + 1;
-
-            while (--i >= 0)
-            {
-                hc *= 257;
-                hc ^= data[i];
-            }
-
-            return hc;
-        }
-
-        public static int GetHashCode(int[] data, int off, int len)
-        {
-            if (data == null)
-                return 0;
-
-            int i = len;
-            int hc = i + 1;
-
-            while (--i >= 0)
-            {
-                hc *= 257;
-                hc ^= data[off + i];
-            }
-
-            return hc;
-        }
-
-        public static int GetHashCode(uint[] data)
-        {
-            if (data == null)
-                return 0;
-
-            int i = data.Length;
-            int hc = i + 1;
-
-            while (--i >= 0)
-            {
-                hc *= 257;
-                hc ^= (int)data[i];
-            }
-
-            return hc;
-        }
-
-        public static int GetHashCode(uint[] data, int off, int len)
-        {
-            if (data == null)
-                return 0;
-
-            int i = len;
-            int hc = i + 1;
-
-            while (--i >= 0)
-            {
-                hc *= 257;
-                hc ^= (int)data[off + i];
-            }
-
-            return hc;
-        }
-
-        public static int GetHashCode(ulong[] data)
-        {
-            if (data == null)
-                return 0;
-
-            int i = data.Length;
-            int hc = i + 1;
-
-            while (--i >= 0)
-            {
-                ulong di = data[i];
-                hc *= 257;
-                hc ^= (int)di;
-                hc *= 257;
-                hc ^= (int)(di >> 32);
-            }
-
-            return hc;
-        }
-
-        public static int GetHashCode(ulong[] data, int off, int len)
-        {
-            if (data == null)
-                return 0;
-
-            int i = len;
-            int hc = i + 1;
-
-            while (--i >= 0)
-            {
-                ulong di = data[off + i];
-                hc *= 257;
-                hc ^= (int)di;
-                hc *= 257;
-                hc ^= (int)(di >> 32);
-            }
-
-            return hc;
-        }
-
-        public static byte[] Clone(
-            byte[] data)
-        {
-            return data == null ? null : (byte[])data.Clone();
-        }
-
-        public static byte[] Clone(
-            byte[] data, 
-            byte[] existing)
-        {
-            if (data == null)
-            {
-                return null;
-            }
-            if ((existing == null) || (existing.Length != data.Length))
-            {
-                return Clone(data);
-            }
-            Array.Copy(data, 0, existing, 0, existing.Length);
-            return existing;
-        }
-
-        public static int[] Clone(
-            int[] data)
-        {
-            return data == null ? null : (int[])data.Clone();
-        }
-
-        internal static uint[] Clone(uint[] data)
-        {
-            return data == null ? null : (uint[])data.Clone();
-        }
-
-        public static long[] Clone(long[] data)
-        {
-            return data == null ? null : (long[])data.Clone();
-        }
-
-        public static ulong[] Clone(
-            ulong[] data)
-        {
-            return data == null ? null : (ulong[]) data.Clone();
-        }
-
-        public static ulong[] Clone(
-            ulong[] data, 
-            ulong[] existing)
-        {
-            if (data == null)
-            {
-                return null;
-            }
-            if ((existing == null) || (existing.Length != data.Length))
-            {
-                return Clone(data);
-            }
-            Array.Copy(data, 0, existing, 0, existing.Length);
-            return existing;
-        }
-
-        public static bool Contains(byte[] a, byte n)
-        {
-            for (int i = 0; i < a.Length; ++i)
-            {
-                if (a[i] == n)
-                    return true;
-            }
-            return false;
-        }
-
-        public static bool Contains(short[] a, short n)
-        {
-            for (int i = 0; i < a.Length; ++i)
-            {
-                if (a[i] == n)
-                    return true;
-            }
-            return false;
-        }
-
-        public static bool Contains(int[] a, int n)
-        {
-            for (int i = 0; i < a.Length; ++i)
-            {
-                if (a[i] == n)
-                    return true;
-            }
-            return false;
-        }
-
-        public static void Fill(
-            byte[]	buf,
-            byte	b)
-        {
-            int i = buf.Length;
-            while (i > 0)
-            {
-                buf[--i] = b;
-            }
-        }
-
-        public static void Fill(byte[] buf, int from, int to, byte b)
-        {
-            for (int i = from; i < to; ++i)
-            {
-                buf[i] = b;
-            }
-        }
-
-        public static byte[] CopyOf(byte[] data, int newLength)
-        {
-            byte[] tmp = new byte[newLength];
-            Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length));
-            return tmp;
-        }
-
-        public static char[] CopyOf(char[] data, int newLength)
-        {
-            char[] tmp = new char[newLength];
-            Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length));
-            return tmp;
-        }
-
-        public static int[] CopyOf(int[] data, int newLength)
-        {
-            int[] tmp = new int[newLength];
-            Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length));
-            return tmp;
-        }
-
-        public static long[] CopyOf(long[] data, int newLength)
-        {
-            long[] tmp = new long[newLength];
-            Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length));
-            return tmp;
-        }
-
-        public static BigInteger[] CopyOf(BigInteger[] data, int newLength)
-        {
-            BigInteger[] tmp = new BigInteger[newLength];
-            Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length));
-            return tmp;
-        }
-
-        /**
-         * Make a copy of a range of bytes from the passed in data array. The range can
-         * extend beyond the end of the input array, in which case the return array will
-         * be padded with zeroes.
-         *
-         * @param data the array from which the data is to be copied.
-         * @param from the start index at which the copying should take place.
-         * @param to the final index of the range (exclusive).
-         *
-         * @return a new byte array containing the range given.
-         */
-        public static byte[] CopyOfRange(byte[] data, int from, int to)
-        {
-            int newLength = GetLength(from, to);
-            byte[] tmp = new byte[newLength];
-            Array.Copy(data, from, tmp, 0, System.Math.Min(newLength, data.Length - from));
-            return tmp;
-        }
-
-        public static int[] CopyOfRange(int[] data, int from, int to)
-        {
-            int newLength = GetLength(from, to);
-            int[] tmp = new int[newLength];
-            Array.Copy(data, from, tmp, 0, System.Math.Min(newLength, data.Length - from));
-            return tmp;
-        }
-
-        public static long[] CopyOfRange(long[] data, int from, int to)
-        {
-            int newLength = GetLength(from, to);
-            long[] tmp = new long[newLength];
-            Array.Copy(data, from, tmp, 0, System.Math.Min(newLength, data.Length - from));
-            return tmp;
-        }
-
-        public static BigInteger[] CopyOfRange(BigInteger[] data, int from, int to)
-        {
-            int newLength = GetLength(from, to);
-            BigInteger[] tmp = new BigInteger[newLength];
-            Array.Copy(data, from, tmp, 0, System.Math.Min(newLength, data.Length - from));
-            return tmp;
-        }
-
-        private static int GetLength(int from, int to)
-        {
-            int newLength = to - from;
-            if (newLength < 0)
-                throw new ArgumentException(from + " > " + to);
-            return newLength;
-        }
-
-        public static byte[] Append(byte[] a, byte b)
-        {
-            if (a == null)
-                return new byte[] { b };
-
-            int length = a.Length;
-            byte[] result = new byte[length + 1];
-            Array.Copy(a, 0, result, 0, length);
-            result[length] = b;
-            return result;
-        }
-
-        public static short[] Append(short[] a, short b)
-        {
-            if (a == null)
-                return new short[] { b };
-
-            int length = a.Length;
-            short[] result = new short[length + 1];
-            Array.Copy(a, 0, result, 0, length);
-            result[length] = b;
-            return result;
-        }
-
-        public static int[] Append(int[] a, int b)
-        {
-            if (a == null)
-                return new int[] { b };
-
-            int length = a.Length;
-            int[] result = new int[length + 1];
-            Array.Copy(a, 0, result, 0, length);
-            result[length] = b;
-            return result;
-        }
-
-        public static byte[] Concatenate(byte[] a, byte[] b)
-        {
-            if (a == null)
-                return Clone(b);
-            if (b == null)
-                return Clone(a);
-
-            byte[] rv = new byte[a.Length + b.Length];
-            Array.Copy(a, 0, rv, 0, a.Length);
-            Array.Copy(b, 0, rv, a.Length, b.Length);
-            return rv;
-        }
-
-        public static byte[] ConcatenateAll(params byte[][] vs)
-        {
-            byte[][] nonNull = new byte[vs.Length][];
-            int count = 0;
-            int totalLength = 0;
-
-            for (int i = 0; i < vs.Length; ++i)
-            {
-                byte[] v = vs[i];
-                if (v != null)
-                {
-                    nonNull[count++] = v;
-                    totalLength += v.Length;
-                }
-            }
-
-            byte[] result = new byte[totalLength];
-            int pos = 0;
-
-            for (int j = 0; j < count; ++j)
-            {
-                byte[] v = nonNull[j];
-                Array.Copy(v, 0, result, pos, v.Length);
-                pos += v.Length;
-            }
-
-            return result;
-        }
-
-        public static int[] Concatenate(int[] a, int[] b)
-        {
-            if (a == null)
-                return Clone(b);
-            if (b == null)
-                return Clone(a);
-
-            int[] rv = new int[a.Length + b.Length];
-            Array.Copy(a, 0, rv, 0, a.Length);
-            Array.Copy(b, 0, rv, a.Length, b.Length);
-            return rv;
-        }
-
-        public static byte[] Prepend(byte[] a, byte b)
-        {
-            if (a == null)
-                return new byte[] { b };
-
-            int length = a.Length;
-            byte[] result = new byte[length + 1];
-            Array.Copy(a, 0, result, 1, length);
-            result[0] = b;
-            return result;
-        }
-
-        public static short[] Prepend(short[] a, short b)
-        {
-            if (a == null)
-                return new short[] { b };
-
-            int length = a.Length;
-            short[] result = new short[length + 1];
-            Array.Copy(a, 0, result, 1, length);
-            result[0] = b;
-            return result;
-        }
-
-        public static int[] Prepend(int[] a, int b)
-        {
-            if (a == null)
-                return new int[] { b };
-
-            int length = a.Length;
-            int[] result = new int[length + 1];
-            Array.Copy(a, 0, result, 1, length);
-            result[0] = b;
-            return result;
-        }
-
-        public static byte[] Reverse(byte[] a)
-        {
-            if (a == null)
-                return null;
-
-            int p1 = 0, p2 = a.Length;
-            byte[] result = new byte[p2];
-
-            while (--p2 >= 0)
-            {
-                result[p2] = a[p1++];
-            }
-
-            return result;
-        }
-
-        public static int[] Reverse(int[] a)
-        {
-            if (a == null)
-                return null;
-
-            int p1 = 0, p2 = a.Length;
-            int[] result = new int[p2];
-
-            while (--p2 >= 0)
-            {
-                result[p2] = a[p1++];
-            }
-
-            return result;
-        }
-    }
-}

+ 0 - 95
src/Renci.SshNet/Security/BouncyCastle/util/BigIntegers.cs

@@ -1,95 +0,0 @@
-using System;
-
-using Renci.SshNet.Security.Org.BouncyCastle.Math;
-using Renci.SshNet.Security.Org.BouncyCastle.Security;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Utilities
-{
-    /**
-     * BigInteger utilities.
-     */
-    internal abstract class BigIntegers
-    {
-        private const int MaxIterations = 1000;
-
-        /**
-        * Return the passed in value as an unsigned byte array.
-        *
-        * @param value value to be converted.
-        * @return a byte array without a leading zero byte if present in the signed encoding.
-        */
-        public static byte[] AsUnsignedByteArray(
-            BigInteger n)
-        {
-            return n.ToByteArrayUnsigned();
-        }
-
-        /**
-         * Return the passed in value as an unsigned byte array of specified length, zero-extended as necessary.
-         *
-         * @param length desired length of result array.
-         * @param n value to be converted.
-         * @return a byte array of specified length, with leading zeroes as necessary given the size of n.
-         */
-        public static byte[] AsUnsignedByteArray(int length, BigInteger n)
-        {
-            byte[] bytes = n.ToByteArrayUnsigned();
-
-            if (bytes.Length > length)
-                throw new ArgumentException("standard length exceeded", "n");
-
-            if (bytes.Length == length)
-                return bytes;
-
-            byte[] tmp = new byte[length];
-            Array.Copy(bytes, 0, tmp, tmp.Length - bytes.Length, bytes.Length);
-            return tmp;
-        }
-
-        /**
-        * Return a random BigInteger not less than 'min' and not greater than 'max'
-        * 
-        * @param min the least value that may be generated
-        * @param max the greatest value that may be generated
-        * @param random the source of randomness
-        * @return a random BigInteger value in the range [min,max]
-        */
-        public static BigInteger CreateRandomInRange(
-            BigInteger		min,
-            BigInteger		max,
-            // TODO Should have been just Random class
-            SecureRandom	random)
-        {
-            int cmp = min.CompareTo(max);
-            if (cmp >= 0)
-            {
-                if (cmp > 0)
-                    throw new ArgumentException("'min' may not be greater than 'max'");
-
-                return min;
-            }
-
-            if (min.BitLength > max.BitLength / 2)
-            {
-                return CreateRandomInRange(BigInteger.Zero, max.Subtract(min), random).Add(min);
-            }
-
-            for (int i = 0; i < MaxIterations; ++i)
-            {
-                BigInteger x = new BigInteger(max.BitLength, random);
-                if (x.CompareTo(min) >= 0 && x.CompareTo(max) <= 0)
-                {
-                    return x;
-                }
-            }
-
-            // fall back to a faster (restricted) method
-            return new BigInteger(max.Subtract(min).BitLength - 1, random).Add(min);
-        }
-
-        public static int GetUnsignedByteLength(BigInteger n)
-        {
-            return (n.BitLength + 7) / 8;
-        }
-    }
-}

+ 0 - 29
src/Renci.SshNet/Security/BouncyCastle/util/IMemoable.cs

@@ -1,29 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Utilities
-{
-	internal interface IMemoable
-	{
-		/// <summary>
-		/// Produce a copy of this object with its configuration and in its current state.
-		/// </summary>
-		/// <remarks>
-		/// The returned object may be used simply to store the state, or may be used as a similar object
-		/// starting from the copied state.
-		/// </remarks>
-		IMemoable Copy();
-
-		/// <summary>
-		/// Restore a copied object state into this object.
-		/// </summary>
-		/// <remarks>
-		/// Implementations of this method <em>should</em> try to avoid or minimise memory allocation to perform the reset.
-		/// </remarks>
-		/// <param name="other">an object originally {@link #copy() copied} from an object of the same type as this instance.</param>
-		/// <exception cref="InvalidCastException">if the provided object is not of the correct type.</exception>
-		/// <exception cref="MemoableResetException">if the <b>other</b> parameter is in some other way invalid.</exception>
-		void Reset(IMemoable other);
-	}
-
-}
-

+ 0 - 27
src/Renci.SshNet/Security/BouncyCastle/util/Integers.cs

@@ -1,27 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Utilities
-{
-    internal abstract class Integers
-    {
-        public static int RotateLeft(int i, int distance)
-        {
-            return (i << distance) ^ (int)((uint)i >> -distance);
-        }
-
-        public static uint RotateLeft(uint i, int distance)
-        {
-            return (i << distance) ^ (i >> -distance);
-        }
-
-        public static int RotateRight(int i, int distance)
-        {
-            return (int)((uint)i >> distance) ^ (i << -distance);
-        }
-
-        public static uint RotateRight(uint i, int distance)
-        {
-            return (i >> distance) ^ (i << -distance);
-        }
-    }
-}

+ 0 - 27
src/Renci.SshNet/Security/BouncyCastle/util/MemoableResetException.cs

@@ -1,27 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Utilities
-{
-    /**
-     * Exception to be thrown on a failure to reset an object implementing Memoable.
-     * <p>
-     * The exception extends InvalidCastException to enable users to have a single handling case,
-     * only introducing specific handling of this one if required.
-     * </p>
-     */
-    internal class MemoableResetException
-        : InvalidCastException
-    {
-        /**
-         * Basic Constructor.
-         *
-         * @param msg message to be associated with this exception.
-         */
-        public MemoableResetException(string msg)
-            : base(msg)
-        {
-        }
-    }
-
-}
-

+ 0 - 14
src/Renci.SshNet/Security/BouncyCastle/util/Times.cs

@@ -1,14 +0,0 @@
-using System;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Utilities
-{
-    internal sealed class Times
-    {
-        private static long NanosecondsPerTick = 100L;
-
-        public static long NanoTime()
-        {
-            return DateTime.UtcNow.Ticks * NanosecondsPerTick;
-        }
-    }
-}

+ 0 - 129
src/Renci.SshNet/Security/BouncyCastle/util/encoders/Hex.cs

@@ -1,129 +0,0 @@
-using System.IO;
-using System.Text;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Utilities.Encoders
-{
-    /// <summary>
-    /// Class to decode and encode Hex.
-    /// </summary>
-    internal sealed class Hex
-    {
-        private static readonly HexEncoder encoder = new HexEncoder();
-
-        private Hex()
-        {
-        }
-
-        public static string ToHexString(
-            byte[] data)
-        {
-            return ToHexString(data, 0, data.Length);
-        }
-
-        public static string ToHexString(
-            byte[]	data,
-            int		off,
-            int		length)
-        {
-            byte[] hex = Encode(data, off, length);
-            return Encoding.UTF8.GetString(hex, 0, hex.Length);
-        }
-
-        /**
-         * encode the input data producing a Hex encoded byte array.
-         *
-         * @return a byte array containing the Hex encoded data.
-         */
-        public static byte[] Encode(
-            byte[] data)
-        {
-            return Encode(data, 0, data.Length);
-        }
-
-        /**
-         * encode the input data producing a Hex encoded byte array.
-         *
-         * @return a byte array containing the Hex encoded data.
-         */
-        public static byte[] Encode(
-            byte[]	data,
-            int		off,
-            int		length)
-        {
-            MemoryStream bOut = new MemoryStream(length * 2);
-
-            encoder.Encode(data, off, length, bOut);
-
-            return bOut.ToArray();
-        }
-
-        /**
-         * Hex encode the byte data writing it to the given output stream.
-         *
-         * @return the number of bytes produced.
-         */
-        public static int Encode(
-            byte[]	data,
-            Stream	outStream)
-        {
-            return encoder.Encode(data, 0, data.Length, outStream);
-        }
-
-        /**
-         * Hex encode the byte data writing it to the given output stream.
-         *
-         * @return the number of bytes produced.
-         */
-        public static int Encode(
-            byte[]	data,
-            int		off,
-            int		length,
-            Stream	outStream)
-        {
-            return encoder.Encode(data, off, length, outStream);
-        }
-
-        /**
-         * decode the Hex encoded input data. It is assumed the input data is valid.
-         *
-         * @return a byte array representing the decoded data.
-         */
-        public static byte[] Decode(
-            byte[] data)
-        {
-            MemoryStream bOut = new MemoryStream((data.Length + 1) / 2);
-
-            encoder.Decode(data, 0, data.Length, bOut);
-
-            return bOut.ToArray();
-        }
-
-        /**
-         * decode the Hex encoded string data - whitespace will be ignored.
-         *
-         * @return a byte array representing the decoded data.
-         */
-        public static byte[] Decode(
-            string data)
-        {
-            MemoryStream bOut = new MemoryStream((data.Length + 1) / 2);
-
-            encoder.DecodeString(data, bOut);
-
-            return bOut.ToArray();
-        }
-
-        /**
-         * decode the Hex encoded string data writing it to the given output stream,
-         * whitespace characters will be ignored.
-         *
-         * @return the number of bytes produced.
-         */
-        public static int Decode(
-            string	data,
-            Stream	outStream)
-        {
-            return encoder.DecodeString(data, outStream);
-        }
-    }
-}

+ 0 - 174
src/Renci.SshNet/Security/BouncyCastle/util/encoders/HexEncoder.cs

@@ -1,174 +0,0 @@
-using System.IO;
-
-namespace Renci.SshNet.Security.Org.BouncyCastle.Utilities.Encoders
-{
-    internal class HexEncoder
-    {
-        protected readonly byte[] encodingTable =
-        {
-            (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7',
-            (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'
-        };
-
-        /*
-         * set up the decoding table.
-         */
-        protected readonly byte[] decodingTable = new byte[128];
-
-        protected void InitialiseDecodingTable()
-        {
-            Arrays.Fill(decodingTable, (byte)0xff);
-
-            for (int i = 0; i < encodingTable.Length; i++)
-            {
-                decodingTable[encodingTable[i]] = (byte)i;
-            }
-
-            decodingTable['A'] = decodingTable['a'];
-            decodingTable['B'] = decodingTable['b'];
-            decodingTable['C'] = decodingTable['c'];
-            decodingTable['D'] = decodingTable['d'];
-            decodingTable['E'] = decodingTable['e'];
-            decodingTable['F'] = decodingTable['f'];
-        }
-
-        public HexEncoder()
-        {
-            InitialiseDecodingTable();
-        }
-
-        /**
-        * encode the input data producing a Hex output stream.
-        *
-        * @return the number of bytes produced.
-        */
-        public int Encode(
-            byte[]	data,
-            int		off,
-            int		length,
-            Stream	outStream)
-        {
-            for (int i = off; i < (off + length); i++)
-            {
-                int v = data[i];
-
-                outStream.WriteByte(encodingTable[v >> 4]);
-                outStream.WriteByte(encodingTable[v & 0xf]);
-            }
-
-            return length * 2;
-        }
-
-        private static bool Ignore(char c)
-        {
-            return c == '\n' || c =='\r' || c == '\t' || c == ' ';
-        }
-
-        /**
-        * decode the Hex encoded byte data writing it to the given output stream,
-        * whitespace characters will be ignored.
-        *
-        * @return the number of bytes produced.
-        */
-        public int Decode(
-            byte[]	data,
-            int		off,
-            int		length,
-            Stream	outStream)
-        {
-            byte b1, b2;
-            int outLen = 0;
-            int end = off + length;
-
-            while (end > off)
-            {
-                if (!Ignore((char)data[end - 1]))
-                {
-                    break;
-                }
-
-                end--;
-            }
-
-            int i = off;
-            while (i < end)
-            {
-                while (i < end && Ignore((char)data[i]))
-                {
-                    i++;
-                }
-
-                b1 = decodingTable[data[i++]];
-
-                while (i < end && Ignore((char)data[i]))
-                {
-                    i++;
-                }
-
-                b2 = decodingTable[data[i++]];
-
-                if ((b1 | b2) >= 0x80)
-                    throw new IOException("invalid characters encountered in Hex data");
-
-                outStream.WriteByte((byte)((b1 << 4) | b2));
-
-                outLen++;
-            }
-
-            return outLen;
-        }
-
-        /**
-        * decode the Hex encoded string data writing it to the given output stream,
-        * whitespace characters will be ignored.
-        *
-        * @return the number of bytes produced.
-        */
-        public int DecodeString(
-            string	data,
-            Stream	outStream)
-        {
-            byte    b1, b2;
-            int     length = 0;
-
-            int     end = data.Length;
-
-            while (end > 0)
-            {
-                if (!Ignore(data[end - 1]))
-                {
-                    break;
-                }
-
-                end--;
-            }
-
-            int i = 0;
-            while (i < end)
-            {
-                while (i < end && Ignore(data[i]))
-                {
-                    i++;
-                }
-
-                b1 = decodingTable[data[i++]];
-
-                while (i < end && Ignore(data[i]))
-                {
-                    i++;
-                }
-
-                b2 = decodingTable[data[i++]];
-
-                if ((b1 | b2) >= 0x80)
-                    throw new IOException("invalid characters encountered in Hex data");
-
-                outStream.WriteByte((byte)((b1 << 4) | b2));
-
-                length++;
-            }
-
-            return length;
-        }
-    }
-}

+ 7 - 7
src/Renci.SshNet/Security/KeyExchangeECDH.cs

@@ -1,15 +1,15 @@
 using System;
 
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Crypto.Agreement;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math.EC;
+using Org.BouncyCastle.Security;
+
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages.Transport;
 
-using Renci.SshNet.Security.Org.BouncyCastle.Asn1.X9;
-using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Agreement;
-using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Generators;
-using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Parameters;
-using Renci.SshNet.Security.Org.BouncyCastle.Math.EC;
-using Renci.SshNet.Security.Org.BouncyCastle.Security;
-
 namespace Renci.SshNet.Security
 {
     internal abstract class KeyExchangeECDH : KeyExchangeEC

+ 5 - 4
src/Renci.SshNet/Security/KeyExchangeECDH256.cs

@@ -1,6 +1,7 @@
-using Renci.SshNet.Abstractions;
-using Renci.SshNet.Security.Org.BouncyCastle.Asn1.Sec;
-using Renci.SshNet.Security.Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Asn1.Sec;
+using Org.BouncyCastle.Asn1.X9;
+
+using Renci.SshNet.Abstractions;
 
 namespace Renci.SshNet.Security
 {
@@ -21,7 +22,7 @@ namespace Renci.SshNet.Security
         {
             get
             {
-                return SecNamedCurves.GetByName("P-256");
+                return SecNamedCurves.GetByName("secp256r1");
             }
         }
 

+ 5 - 4
src/Renci.SshNet/Security/KeyExchangeECDH384.cs

@@ -1,6 +1,7 @@
-using Renci.SshNet.Abstractions;
-using Renci.SshNet.Security.Org.BouncyCastle.Asn1.Sec;
-using Renci.SshNet.Security.Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Asn1.Sec;
+using Org.BouncyCastle.Asn1.X9;
+
+using Renci.SshNet.Abstractions;
 
 namespace Renci.SshNet.Security
 {
@@ -21,7 +22,7 @@ namespace Renci.SshNet.Security
         {
             get
             {
-                return SecNamedCurves.GetByName("P-384");
+                return SecNamedCurves.GetByName("secp384r1");
             }
         }
 

+ 5 - 4
src/Renci.SshNet/Security/KeyExchangeECDH521.cs

@@ -1,6 +1,7 @@
-using Renci.SshNet.Abstractions;
-using Renci.SshNet.Security.Org.BouncyCastle.Asn1.Sec;
-using Renci.SshNet.Security.Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Asn1.Sec;
+using Org.BouncyCastle.Asn1.X9;
+
+using Renci.SshNet.Abstractions;
 
 namespace Renci.SshNet.Security
 {
@@ -21,7 +22,7 @@ namespace Renci.SshNet.Security
         {
             get
             {
-                return SecNamedCurves.GetByName("P-521");
+                return SecNamedCurves.GetByName("secp521r1");
             }
         }