Merge pull request #496 from darinkes/elliptic

Elliptic Curves
This commit is contained in:
Gert Driesen
2020-01-11 21:16:33 +01:00
committed by GitHub
177 changed files with 30557 additions and 54 deletions
+52 -4
View File
@@ -18,22 +18,70 @@ This project was inspired by **Sharp.SSH** library which was ported from java an
* Remote, dynamic and local port forwarding
* Shell/Terminal implementation
* Specify key file pass phrase
* Use multiple key files to authenticate
* Supports 3des-cbc, aes128-cbc, aes192-cbc, aes256-cbc, aes128-ctr, aes192-ctr, aes256-ctr, blowfish-cbc, cast128-cbc, arcfour and twofish encryptions
* Use multiple key files to authenticate
* Supports publickey, password and keyboard-interactive authentication methods
* Supports RSA and DSA private key
* Supports DES-EDE3-CBC, DES-EDE3-CFB, DES-CBC, AES-128-CBC, AES-192-CBC and AES-256-CBC algorithms for private key encryption
* Supports two-factor or higher authentication
* Supports SOCKS4, SOCKS5 and HTTP Proxy
## Encryption Method
**SSH.NET** supports the following encryption methods:
* aes256-ctr
* 3des-cbc
* aes128-cbc
* aes192-cbc
* aes256-cbc
* blowfish-cbc
* twofish-cbc
* twofish192-cbc
* twofish128-cbc
* twofish256-cbc
* arcfour
* arcfour128
* arcfour256
* cast128-cbc
* aes128-ctr
* aes192-ctr
## Key Exchange Method
**SSH.NET** supports the following key exchange methods:
* curve25519-sha256
* curve25519-sha256@libssh.org
* ecdh-sha2-nistp256
* ecdh-sha2-nistp384
* ecdh-sha2-nistp521
* diffie-hellman-group-exchange-sha256
* diffie-hellman-group-exchange-sha1
* diffie-hellman-group14-sha1
* diffie-hellman-group1-sha1
## Public Key Authenntication
**SSH.NET** supports the following private key formats:
* RSA in OpenSSL PEM and ssh.com format
* DSA in OpenSSL PEM and ssh.com format
* ECDSA 256/384/521 in OpenSSL PEM format
* ED25519 in OpenSSH key format
Private keys can be encrypted using one of the following cipher methods:
* DES-EDE3-CBC
* DES-EDE3-CFB
* DES-CBC
* AES-128-CBC
* AES-192-CBC
* AES-256-CBC
## Host Key Algorithms
**SSH.NET** supports the following host key algorithms:
* ssh-ed25519
* ecdsa-sha2-nistp256
* ecdsa-sha2-nistp384
* ecdsa-sha2-nistp521
* ssh-rsa
* ssh-dss
## Message Authentication Code
**SSH.NET** supports the following MAC algorithms:
+73
View File
@@ -0,0 +1,73 @@
SSH.NET uses third-party libraries or other resources that may be
distributed under licenses different than the SSH.NET software.
License notice for BouncyCastle
-------------------------------
http://bouncycastle.org/csharp
Copyright (c) 2000 - 2018 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
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, sublicense, 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:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
License notice for Chaos.NaCl
-------------------------------
https://github.com/CodesInChaos/Chaos.NaCl
Public domain
C# port + code by Christian Winnerlein (CodesInChaos)
Poly1305 in c
written by Andrew M. (floodyberry)
original license: MIT or PUBLIC DOMAIN
https://github.com/floodyberry/poly1305-donna/blob/master/poly1305-donna-unrolled.c
Curve25519 and Ed25519 in c
written by Dan Bernstein (djb)
public domain
from Ref10 in SUPERCOP http://bench.cr.yp.to/supercop.html
(H)Salsa20 in c
written by Dan Bernstein (djb)
public domain
from SUPERCOP http://bench.cr.yp.to/supercop.html
SHA512
written by Christian Winnerlein (CodesInChaos)
public domain
directly from the specification
License notice for BCrypt
-------------------------
Copyright (c) 2006 Damien Miller <djm@mindrot.org>
Copyright (c) 2010 Ryan D. Emerle
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -18,7 +18,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
<DefineConstants>TRACE;DEBUG;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII;FEATURE_ECDSA</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
@@ -29,7 +29,7 @@
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
<DefineConstants>TRACE;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII;FEATURE_ECDSA</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Renci.SshNet.xml</DocumentationFile>
@@ -602,12 +602,414 @@
<Compile Include="..\Renci.SshNet\Security\Algorithm.cs">
<Link>Security\Algorithm.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\sec\SECNamedCurves.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\sec\SECNamedCurves.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9Curve.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9Curve.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9ECParameters.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9ECParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9ECParametersHolder.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9ECParametersHolder.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9ECPoint.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9ECPoint.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\agreement\ECDHCBasicAgreement.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\agreement\ECDHCBasicAgreement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\AsymmetricCipherKeyPair.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\AsymmetricCipherKeyPair.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\AsymmetricKeyParameter.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\AsymmetricKeyParameter.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\digests\GeneralDigest.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\digests\GeneralDigest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\digests\Sha256Digest.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\digests\Sha256Digest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\generators\ECKeyPairGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\generators\ECKeyPairGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\IAsymmetricCipherKeyPairGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\IAsymmetricCipherKeyPairGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\IDigest.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\IDigest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\KeyGenerationParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\KeyGenerationParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECDomainParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECDomainParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECKeyGenerationParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECKeyGenerationParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECKeyParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECKeyParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECPrivateKeyParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECPrivateKeyParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECPublicKeyParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECPublicKeyParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\prng\CryptoApiRandomGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\prng\CryptoApiRandomGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\prng\DigestRandomGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\prng\DigestRandomGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\prng\IRandomGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\prng\IRandomGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\util\Pack.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\util\Pack.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\BigInteger.cs">
<Link>Security\Cryptography\BouncyCastle\math\BigInteger.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\abc\SimpleBigDecimal.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\abc\SimpleBigDecimal.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\abc\Tnaf.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\abc\Tnaf.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\abc\ZTauElement.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\abc\ZTauElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECAlgorithms.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECAlgorithms.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECCurve.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECCurve.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECFieldElement.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECFieldElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECLookupTable.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECLookupTable.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECPoint.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECPoint.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECPointMap.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECPointMap.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\endo\ECEndomorphism.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\endo\ECEndomorphism.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\endo\GlvEndomorphism.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\endo\GlvEndomorphism.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\LongArray.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\LongArray.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\AbstractECMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\AbstractECMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\ECMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\ECMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\FixedPointCombMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\FixedPointCombMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\FixedPointPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\FixedPointPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\FixedPointUtilities.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\FixedPointUtilities.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\GlvMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\GlvMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\IPreCompCallback.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\IPreCompCallback.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\PreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\PreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\ValidityPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\ValidityPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafL2RMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WNafL2RMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WNafPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafUtilities.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WNafUtilities.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WTauNafMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WTauNafMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WTauNafPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WTauNafPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\FiniteFields.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\FiniteFields.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\GenericPolynomialExtensionField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\GenericPolynomialExtensionField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\GF2Polynomial.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\GF2Polynomial.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IExtensionField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IExtensionField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IFiniteField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IFiniteField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IPolynomial.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IPolynomial.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IPolynomialExtensionField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IPolynomialExtensionField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\PrimeField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\PrimeField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\raw\Mod.cs">
<Link>Security\Cryptography\BouncyCastle\math\raw\Mod.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\raw\Nat.cs">
<Link>Security\Cryptography\BouncyCastle\math\raw\Nat.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\security\DigestUtilities.cs">
<Link>Security\Cryptography\BouncyCastle\security\DigestUtilities.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\security\SecureRandom.cs">
<Link>Security\Cryptography\BouncyCastle\security\SecureRandom.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\security\SecurityUtilityException.cs">
<Link>Security\Cryptography\BouncyCastle\security\SecurityUtilityException.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Arrays.cs">
<Link>Security\Cryptography\BouncyCastle\util\Arrays.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\BigIntegers.cs">
<Link>Security\Cryptography\BouncyCastle\util\BigIntegers.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\encoders\Hex.cs">
<Link>Security\Cryptography\BouncyCastle\util\encoders\Hex.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\encoders\HexEncoder.cs">
<Link>Security\Cryptography\BouncyCastle\util\encoders\HexEncoder.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Enums.cs">
<Link>Security\Cryptography\BouncyCastle\util\Enums.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\IMemoable.cs">
<Link>Security\Cryptography\BouncyCastle\util\IMemoable.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Integers.cs">
<Link>Security\Cryptography\BouncyCastle\util\Integers.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\MemoableResetException.cs">
<Link>Security\Cryptography\BouncyCastle\util\MemoableResetException.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Times.cs">
<Link>Security\Cryptography\BouncyCastle\util\Times.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\CertificateHostAlgorithm.cs">
<Link>Security\CertificateHostAlgorithm.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\CryptoBytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\CryptoBytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Ed25519.cs">
<Link>Security\Cryptography\Chaos.NaCl\Ed25519.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Array16.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Array16.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Array8.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Array8.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\ByteIntegerConverter.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\ByteIntegerConverter.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\base.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\base.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\base2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\base2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\d.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\d.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\d2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\d2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_1.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_1.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_add.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_add.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_cmov.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_cmov.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_cswap.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_cswap.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_frombytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_frombytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_invert.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_invert.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnegative.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnegative.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnonzero.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnonzero.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul121666.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul121666.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_neg.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_neg.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_pow22523.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_pow22523.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sub.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_sub.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_tobytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_tobytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\FieldElement.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\FieldElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_add.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_add.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_double_scalarmult.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_double_scalarmult.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_frombytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_frombytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_madd.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_madd.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_msub.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_msub.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p3.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p3.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_dbl.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_dbl.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_dbl.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_dbl.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_tobytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_tobytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_cached.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_cached.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_p2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_p2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_precomp_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_precomp_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_scalarmult_base.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_scalarmult_base.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_sub.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_sub.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_tobytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_tobytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\GroupElement.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\GroupElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\keypair.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\keypair.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\open.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\open.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\scalarmult.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\scalarmult.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_clamp.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sc_clamp.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_mul_add.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sc_mul_add.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_reduce.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sc_reduce.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sign.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sign.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sqrtm1.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sqrtm1.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\InternalAssert.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\InternalAssert.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Poly1305Donna.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Poly1305Donna.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Salsa\Salsa20.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Salsa\Salsa20.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Salsa\SalsaCore.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Salsa\SalsaCore.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Sha512Internal.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Sha512Internal.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\MontgomeryCurve25519.cs">
<Link>Security\Cryptography\Chaos.NaCl\MontgomeryCurve25519.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Sha512.cs">
<Link>Security\Cryptography\Chaos.NaCl\Sha512.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\AsymmetricCipher.cs">
<Link>Security\Cryptography\AsymmetricCipher.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\Bcrypt.cs">
<Link>Security\Cryptography\Bcrypt.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\BlockCipher.cs">
<Link>Security\Cryptography\BlockCipher.cs</Link>
</Compile>
@@ -677,6 +1079,12 @@
<Compile Include="..\Renci.SshNet\Security\Cryptography\DsaKey.cs">
<Link>Security\Cryptography\DsaKey.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\ED25519DigitalSignature.cs">
<Link>Security\Cryptography\ED25519DigitalSignature.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\ED25519Key.cs">
<Link>Security\Cryptography\ED25519Key.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\HMACMD5.cs">
<Link>Security\Cryptography\HMACMD5.cs</Link>
</Compile>
@@ -695,6 +1103,12 @@
<Compile Include="..\Renci.SshNet\Security\Cryptography\Key.cs">
<Link>Security\Cryptography\Key.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\EcdsaDigitalSignature.cs">
<Link>Security\Cryptography\EcdsaDigitalSignature.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\EcdsaKey.cs">
<Link>Security\Cryptography\EcdsaKey.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\RsaDigitalSignature.cs">
<Link>Security\Cryptography\RsaDigitalSignature.cs</Link>
</Compile>
@@ -740,6 +1154,24 @@
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupSha1.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupSha1.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeEC.cs">
<Link>Security\KeyExchangeEC.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECCurve25519.cs">
<Link>Security\KeyExchangeECCurve25519.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH.cs">
<Link>Security\KeyExchangeECDH.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH256.cs">
<Link>Security\KeyExchangeECDH256.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH384.cs">
<Link>Security\KeyExchangeECDH384.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH521.cs">
<Link>Security\KeyExchangeECDH521.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyHostAlgorithm.cs">
<Link>Security\KeyHostAlgorithm.cs</Link>
</Compile>
@@ -981,4 +1413,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
@@ -27,11 +27,12 @@
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="SshNet.Security.Cryptography" Version="[1.3.0]" />
<PackageReference Include="System.Security.Cryptography.Cng" Version="4.4.0" />
</ItemGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
<DefineConstants>FEATURE_ENCODING_ASCII;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_DIRECTORYINFO_ENUMERATEFILES;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_RNG_CREATE;FEATURE_SOCKET_TAP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_SOCKET_DISPOSE;FEATURE_DNS_TAP;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_WAITHANDLE_DISPOSE;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<DefineConstants>FEATURE_ENCODING_ASCII;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_DIRECTORYINFO_ENUMERATEFILES;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_RNG_CREATE;FEATURE_SOCKET_TAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_SOCKET_DISPOSE;FEATURE_DNS_SYNC;FEATURE_DNS_APM;FEATURE_DNS_TAP;FEATURE_STREAM_APM;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_WAITHANDLE_DISPOSE;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512</DefineConstants>
<DefineConstants>FEATURE_ENCODING_ASCII;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_DIRECTORYINFO_ENUMERATEFILES;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_RNG_CREATE;FEATURE_SOCKET_TAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_SOCKET_DISPOSE;FEATURE_DNS_SYNC;FEATURE_DNS_APM;FEATURE_DNS_TAP;FEATURE_STREAM_APM;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_WAITHANDLE_DISPOSE;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_ECDSA</DefineConstants>
</PropertyGroup>
</Project>
</Project>
@@ -602,12 +602,414 @@
<Compile Include="..\Renci.SshNet\Security\Algorithm.cs">
<Link>Security\Algorithm.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\sec\SECNamedCurves.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\sec\SECNamedCurves.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9Curve.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9Curve.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9ECParameters.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9ECParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9ECParametersHolder.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9ECParametersHolder.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9ECPoint.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9ECPoint.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\agreement\ECDHCBasicAgreement.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\agreement\ECDHCBasicAgreement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\AsymmetricCipherKeyPair.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\AsymmetricCipherKeyPair.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\AsymmetricKeyParameter.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\AsymmetricKeyParameter.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\digests\GeneralDigest.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\digests\GeneralDigest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\digests\Sha256Digest.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\digests\Sha256Digest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\generators\ECKeyPairGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\generators\ECKeyPairGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\IAsymmetricCipherKeyPairGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\IAsymmetricCipherKeyPairGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\IDigest.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\IDigest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\KeyGenerationParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\KeyGenerationParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECDomainParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECDomainParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECKeyGenerationParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECKeyGenerationParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECKeyParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECKeyParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECPrivateKeyParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECPrivateKeyParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECPublicKeyParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECPublicKeyParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\prng\CryptoApiRandomGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\prng\CryptoApiRandomGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\prng\DigestRandomGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\prng\DigestRandomGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\prng\IRandomGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\prng\IRandomGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\util\Pack.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\util\Pack.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\BigInteger.cs">
<Link>Security\Cryptography\BouncyCastle\math\BigInteger.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\abc\SimpleBigDecimal.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\abc\SimpleBigDecimal.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\abc\Tnaf.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\abc\Tnaf.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\abc\ZTauElement.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\abc\ZTauElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECAlgorithms.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECAlgorithms.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECCurve.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECCurve.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECFieldElement.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECFieldElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECLookupTable.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECLookupTable.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECPoint.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECPoint.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECPointMap.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECPointMap.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\endo\ECEndomorphism.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\endo\ECEndomorphism.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\endo\GlvEndomorphism.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\endo\GlvEndomorphism.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\LongArray.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\LongArray.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\AbstractECMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\AbstractECMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\ECMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\ECMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\FixedPointCombMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\FixedPointCombMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\FixedPointPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\FixedPointPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\FixedPointUtilities.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\FixedPointUtilities.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\GlvMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\GlvMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\IPreCompCallback.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\IPreCompCallback.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\PreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\PreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\ValidityPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\ValidityPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafL2RMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WNafL2RMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WNafPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafUtilities.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WNafUtilities.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WTauNafMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WTauNafMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WTauNafPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WTauNafPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\FiniteFields.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\FiniteFields.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\GenericPolynomialExtensionField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\GenericPolynomialExtensionField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\GF2Polynomial.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\GF2Polynomial.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IExtensionField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IExtensionField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IFiniteField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IFiniteField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IPolynomial.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IPolynomial.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IPolynomialExtensionField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IPolynomialExtensionField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\PrimeField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\PrimeField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\raw\Mod.cs">
<Link>Security\Cryptography\BouncyCastle\math\raw\Mod.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\raw\Nat.cs">
<Link>Security\Cryptography\BouncyCastle\math\raw\Nat.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\security\DigestUtilities.cs">
<Link>Security\Cryptography\BouncyCastle\security\DigestUtilities.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\security\SecureRandom.cs">
<Link>Security\Cryptography\BouncyCastle\security\SecureRandom.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\security\SecurityUtilityException.cs">
<Link>Security\Cryptography\BouncyCastle\security\SecurityUtilityException.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Arrays.cs">
<Link>Security\Cryptography\BouncyCastle\util\Arrays.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\BigIntegers.cs">
<Link>Security\Cryptography\BouncyCastle\util\BigIntegers.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\encoders\Hex.cs">
<Link>Security\Cryptography\BouncyCastle\util\encoders\Hex.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\encoders\HexEncoder.cs">
<Link>Security\Cryptography\BouncyCastle\util\encoders\HexEncoder.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Enums.cs">
<Link>Security\Cryptography\BouncyCastle\util\Enums.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\IMemoable.cs">
<Link>Security\Cryptography\BouncyCastle\util\IMemoable.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Integers.cs">
<Link>Security\Cryptography\BouncyCastle\util\Integers.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\MemoableResetException.cs">
<Link>Security\Cryptography\BouncyCastle\util\MemoableResetException.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Times.cs">
<Link>Security\Cryptography\BouncyCastle\util\Times.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\CertificateHostAlgorithm.cs">
<Link>Security\CertificateHostAlgorithm.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\CryptoBytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\CryptoBytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Ed25519.cs">
<Link>Security\Cryptography\Chaos.NaCl\Ed25519.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Array16.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Array16.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Array8.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Array8.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\ByteIntegerConverter.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\ByteIntegerConverter.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\base.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\base.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\base2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\base2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\d.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\d.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\d2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\d2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_1.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_1.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_add.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_add.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_cmov.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_cmov.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_cswap.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_cswap.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_frombytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_frombytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_invert.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_invert.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnegative.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnegative.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnonzero.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnonzero.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul121666.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul121666.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_neg.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_neg.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_pow22523.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_pow22523.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sub.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_sub.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_tobytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_tobytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\FieldElement.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\FieldElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_add.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_add.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_double_scalarmult.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_double_scalarmult.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_frombytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_frombytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_madd.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_madd.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_msub.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_msub.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p3.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p3.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_dbl.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_dbl.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_dbl.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_dbl.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_tobytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_tobytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_cached.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_cached.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_p2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_p2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_precomp_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_precomp_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_scalarmult_base.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_scalarmult_base.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_sub.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_sub.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_tobytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_tobytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\GroupElement.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\GroupElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\keypair.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\keypair.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\open.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\open.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\scalarmult.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\scalarmult.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_clamp.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sc_clamp.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_mul_add.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sc_mul_add.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_reduce.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sc_reduce.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sign.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sign.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sqrtm1.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sqrtm1.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\InternalAssert.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\InternalAssert.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Poly1305Donna.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Poly1305Donna.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Salsa\Salsa20.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Salsa\Salsa20.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Salsa\SalsaCore.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Salsa\SalsaCore.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Sha512Internal.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Sha512Internal.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\MontgomeryCurve25519.cs">
<Link>Security\Cryptography\Chaos.NaCl\MontgomeryCurve25519.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Sha512.cs">
<Link>Security\Cryptography\Chaos.NaCl\Sha512.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\AsymmetricCipher.cs">
<Link>Security\Cryptography\AsymmetricCipher.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\Bcrypt.cs">
<Link>Security\Cryptography\Bcrypt.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\BlockCipher.cs">
<Link>Security\Cryptography\BlockCipher.cs</Link>
</Compile>
@@ -677,6 +1079,12 @@
<Compile Include="..\Renci.SshNet\Security\Cryptography\DsaKey.cs">
<Link>Security\Cryptography\DsaKey.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\ED25519DigitalSignature.cs">
<Link>Security\Cryptography\ED25519DigitalSignature.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\ED25519Key.cs">
<Link>Security\Cryptography\ED25519Key.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\HMACMD5.cs">
<Link>Security\Cryptography\HMACMD5.cs</Link>
</Compile>
@@ -740,6 +1148,24 @@
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupSha1.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupSha1.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeEC.cs">
<Link>Security\KeyExchangeEC.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECCurve25519.cs">
<Link>Security\KeyExchangeECCurve25519.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH.cs">
<Link>Security\KeyExchangeECDH.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH256.cs">
<Link>Security\KeyExchangeECDH256.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH384.cs">
<Link>Security\KeyExchangeECDH384.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH521.cs">
<Link>Security\KeyExchangeECDH521.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyHostAlgorithm.cs">
<Link>Security\KeyHostAlgorithm.cs</Link>
</Compile>
@@ -980,4 +1406,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
@@ -351,6 +351,12 @@
<Compile Include="..\Renci.SshNet.Tests\Classes\Common\ExtensionsTest_Take_OffsetAndCount.cs">
<Link>Classes\Common\ExtensionsTest_Take_OffsetAndCount.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\Common\ExtensionsTest_ToBigInteger2.cs">
<Link>Classes\Common\ExtensionsTest_ToBigInteger2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\Common\ExtensionsTest_Pad.cs">
<Link>Classes\Common\ExtensionsTest_Pad.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\Common\ExtensionsTest_TrimLeadingZeros.cs">
<Link>Classes\Common\ExtensionsTest_TrimLeadingZeros.cs</Link>
</Compile>
@@ -1737,6 +1743,32 @@
<Link>Data\Key.SSH2.RSA.txt</Link>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.ECDSA.txt">
<Link>Data\Key.ECDSA.txt</Link>
</EmbeddedResource>
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.ECDSA384.txt">
<Link>Data\Key.ECDSA384.txt</Link>
</EmbeddedResource>
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.ECDSA521.txt">
<Link>Data\Key.ECDSA521.txt</Link>
</EmbeddedResource>
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.ECDSA.Encrypted.txt">
<Link>Data\Key.ECDSA.Encrypted.txt</Link>
</EmbeddedResource>
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.ECDSA384.Encrypted.txt">
<Link>Data\Key.ECDSA384.Encrypted.txt</Link>
</EmbeddedResource>
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.ECDSA521.Encrypted.txt">
<Link>Data\Key.ECDSA521.Encrypted.txt</Link>
</EmbeddedResource>
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.OPENSSH.ED25519.Encrypted.txt">
<Link>Data\Key.OPENSSH.ED25519.Encrypted.txt</Link>
</EmbeddedResource>
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.OPENSSH.ED25519.txt">
<Link>Data\Key.OPENSSH.ED25519.txt</Link>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
@@ -1750,4 +1782,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
@@ -0,0 +1,32 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Renci.SshNet.Common;
namespace Renci.SshNet.Tests.Classes.Common
{
[TestClass]
[SuppressMessage("ReSharper", "InvokeAsExtensionMethod")]
public class ExtensionsTest_Pad
{
[TestMethod]
public void ShouldReturnNotPadded()
{
byte[] value = {0x0a, 0x0d};
byte[] padded = value.Pad(2);
Assert.AreEqual(value, padded);
Assert.AreEqual(value.Length, padded.Length);
}
[TestMethod]
public void ShouldReturnPadded()
{
byte[] value = { 0x0a, 0x0d };
byte[] padded = value.Pad(3);
Assert.AreEqual(value.Length + 1, padded.Length);
Assert.AreEqual(0x00, padded[0]);
Assert.AreEqual(0x0a, padded[1]);
Assert.AreEqual(0x0d, padded[2]);
}
}
}
@@ -0,0 +1,40 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Renci.SshNet.Common;
namespace Renci.SshNet.Tests.Classes.Common
{
[TestClass]
[SuppressMessage("ReSharper", "InvokeAsExtensionMethod")]
public class ExtensionsTest_ToBigInteger2
{
[TestMethod]
public void ShouldNotAppendZero()
{
byte[] value = { 0x0a, 0x0d };
var actual = value.ToBigInteger2().ToByteArray().Reverse();
Assert.IsNotNull(actual);
Assert.AreEqual(2, actual.Length);
Assert.AreEqual(0x0a, actual[0]);
Assert.AreEqual(0x0d, actual[1]);
}
[TestMethod]
public void ShouldAppendZero()
{
byte[] value = { 0xff, 0x0a, 0x0d };
var actual = value.ToBigInteger2().ToByteArray().Reverse();
Assert.IsNotNull(actual);
Assert.AreEqual(4, actual.Length);
Assert.AreEqual(0x00, actual[0]);
Assert.AreEqual(0xff, actual[1]);
Assert.AreEqual(0x0a, actual[2]);
Assert.AreEqual(0x0d, actual[3]);
}
}
}
@@ -319,6 +319,72 @@ namespace Renci.SshNet.Tests.Classes
}
}
[TestMethod]
[Owner("darinkes")]
[TestCategory("PrivateKey")]
public void Test_PrivateKey_ECDSA()
{
using (var stream = GetData("Key.ECDSA.txt"))
{
new PrivateKeyFile(stream);
}
}
[TestMethod]
[Owner("darinkes")]
[TestCategory("PrivateKey")]
public void Test_PrivateKey_ECDSA384()
{
using (var stream = GetData("Key.ECDSA384.txt"))
{
new PrivateKeyFile(stream);
}
}
[TestMethod]
[Owner("darinkes")]
[TestCategory("PrivateKey")]
public void Test_PrivateKey_ECDSA521()
{
using (var stream = GetData("Key.ECDSA521.txt"))
{
new PrivateKeyFile(stream);
}
}
[TestMethod]
[Owner("darinkes")]
[TestCategory("PrivateKey")]
public void Test_PrivateKey_ECDSA_Encrypted()
{
using (var stream = GetData("Key.ECDSA.Encrypted.txt"))
{
new PrivateKeyFile(stream, "12345");
}
}
[TestMethod]
[Owner("darinkes")]
[TestCategory("PrivateKey")]
public void Test_PrivateKey_ECDSA384_Encrypted()
{
using (var stream = GetData("Key.ECDSA384.Encrypted.txt"))
{
new PrivateKeyFile(stream, "12345");
}
}
[TestMethod]
[Owner("darinkes")]
[TestCategory("PrivateKey")]
public void Test_PrivateKey_ECDSA521_Encrypted()
{
using (var stream = GetData("Key.ECDSA521.Encrypted.txt"))
{
new PrivateKeyFile(stream, "12345");
}
}
/// <summary>
///A test for Dispose
///</summary>
@@ -479,6 +545,34 @@ namespace Renci.SshNet.Tests.Classes
}
}
/// <summary>
/// A test for opening an openssh v1 keyfile where there is no passphrase.
///</summary>
[TestMethod()]
[Owner("bhalbright")]
[TestCategory("PrivateKey")]
public void TestOpenSshV1KeyFileNoPassphrase()
{
using (var stream = GetData("Key.OPENSSH.ED25519.txt"))
{
new PrivateKeyFile(stream);
}
}
/// <summary>
/// A test for opening an openssh v1 keyfile where there is a passphrase.
///</summary>
[TestMethod()]
[Owner("bhalbright")]
[TestCategory("PrivateKey")]
public void TestOpenSshV1KeyFileWithPassphrase()
{
using (var stream = GetData("Key.OPENSSH.ED25519.Encrypted.txt"))
{
new PrivateKeyFile(stream, "password");
}
}
private void SaveStreamToFile(Stream stream, string fileName)
{
var buffer = new byte[4000];
@@ -501,4 +595,4 @@ namespace Renci.SshNet.Tests.Classes
return tempFile;
}
}
}
}
@@ -0,0 +1,8 @@
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,54D46F498C989115AAE14FEA21E3AF11
IQdFnndcbzz10d7YQIgEE1TzuzJrm7uYJr4Hvdfz/FshVxMRqxqaqtEgo2vAHHik
BOcPkm+84ERlTNPslcJqLSkKzCdxb7Rz5hfwHuN3Y6Lf01qGakDlzAUEjEyDor+4
zQtAne+f+gRUJnBvLLoVhH4xdeQFC55GECNUFQpEmos=
-----END EC PRIVATE KEY-----
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIEdqaFKgJBIibVjyUh1v7Y35LwIQJrocdTaYFLwl7iB0oAoGCCqGSM49
AwEHoUQDQgAEQD5MO/n9yqSDTszwzVpApLx5SQFecE5ZfDkgxqVdHQecm1BAPozZ
4eKGNhKn72hT79mLlp9HXX+oNEcuVT83Hw==
-----END EC PRIVATE KEY-----
@@ -0,0 +1,9 @@
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,1D64653C5E18C2AACB0B17E3FE43C219
lCtRmcvKSeIACwqTtsf/ei1brtCZ386rsk/j7bSXdkZBpvzcmzbeo6w6CYm206Km
hV9TMl2dIO/I1/ov5/2VIR3ZkaElyDOJD/+Be0e3aus4EZj1H1YM/Dv+4QJId+is
Cw4ycWjfudYPPejGdiyjzt5qjaIJwrrEvGtMg7sWVAqDpjcAjS9KuaCu5nOgdItL
s7oHuz+DTGdJQNfUHAlUnz1JaMRWzpP0MwtxdcaRY+w=
-----END EC PRIVATE KEY-----
@@ -0,0 +1,6 @@
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDCQawHdHLR7NvKa2vPV0sVkbzOE8c0enp95iEysGcGV66RXE1EH//nh
gu5UzeTR4KigBwYFK4EEACKhZANiAAQUk4rVvoOPI1hQzWpNx09Uo6qG+srGcbvB
q15eFK0GnK/T0UBKxdbZ2+//KAYI6SeDHM9t3ORF1aX5EpjTEBI4d7ZY/lV9jX6M
nJ4XuGteJselM2iMmy+p9ZYw83BYB1Y=
-----END EC PRIVATE KEY-----
@@ -0,0 +1,10 @@
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,F995028237EBD79C928530CC6C3E957F
wT+iajbte4MnpCipVy/7W9t2I8OgwbMjNBw9PB5xmXR1NQX+yWa81DXMTgjHi8++
6tp+Vlftkr7mY1yvZCVo1Sy4VgcvZeMhtpVKtvYdMCmHJC6gaDOTYX3yee8DJ4FL
fG+IQz0wFyZZ26NFrHiwbufW9z6pXhGNCQZK0KLbFxI9iKwVA0llc7uzTEcmBBpn
0/Snp0CVvX+i6AP9Xj0bBdrFCsvcoT+ZHzS8YWJUfu3m6cpAJksCAy0PXR3ifvus
edTfDpkMxd4/b+DtPB6SMekIAjnQyzbyaTwJCujm8iU=
-----END EC PRIVATE KEY-----
@@ -0,0 +1,7 @@
-----BEGIN EC PRIVATE KEY-----
MIHcAgEBBEIBn2DAme7AU8sCA+/sd6s3c2FNW26IiPvulGd3FC8k5q+fjBZ5LUWR
iJMGrsf2rJLO8hXMGJYoF9tjZEGaabQ8KVagBwYFK4EEACOhgYkDgYYABABrpVjs
ANqcvqMUo1wo0I1uVCXQ6xrauy4iU86FiOwFmkYRrle4w3oYdRJwniC3TwGMuBuM
PMIoCTXr0UtUzn1vkQESNR/J/jAxVseLlVe+KDfZHKvsvk2+O4XaSa1qMfLwN3sp
wlj08+ylKjlO6V3g0hbz4ZaSVwuiRS7Xsv8W2MV6rg==
-----END EC PRIVATE KEY-----
@@ -0,0 +1,9 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABBg
HWh+J0IG6OfYxD74SoT9AAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIGFd
yflleGqSPOhgSYZf7ZQFlG0zEL9VDGC69UbtaaByAAAAoDLm8u8wFwlqjzZRfVxj
wzGTYFJFtfkHRqfFBE4xKgknHNRbCT1OQb7rgE7nZbUXIlb1NCTZLbXti9AYNZpz
ycvPD4Dc6lB03b8pNHoFVSkrCwxrWB5bKtIM4OZNcDK1lZDBEWE2aZXf9puRHbu3
ccrK/F5GjRi2pUa8qnfqThN1mNPZwFTx4oSKeRaUMdeHBrNwDtaxq32A6Q4KHoYO
KPM=
-----END OPENSSH PRIVATE KEY-----
@@ -0,0 +1,8 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtz
c2gtZWQyNTUxOQAAACANCWZw0K8UGXDQC32WBuyzwFtTGBBr1VuZ43uzpTBjIgAA
AKBATgCiQE4AogAAAAtzc2gtZWQyNTUxOQAAACANCWZw0K8UGXDQC32WBuyzwFtT
GBBr1VuZ43uzpTBjIgAAAEAAzBF1MPUxrs+ycpJh28zzo/F3m6WcKO+orsSbR5Lw
KQ0JZnDQrxQZcNALfZYG7LPAW1MYEGvVW5nje7OlMGMiAAAAFGVkMjU1MTkta2V5
LTIwMTgxMTI3AQIDBAUGBwgJ
-----END OPENSSH PRIVATE KEY-----
@@ -169,6 +169,8 @@
<Compile Include="Classes\Common\ExtensionsTest_Reverse.cs" />
<Compile Include="Classes\Common\ExtensionsTest_Take_Count.cs" />
<Compile Include="Classes\Common\ExtensionsTest_Take_OffsetAndCount.cs" />
<Compile Include="Classes\Common\ExtensionsTest_ToBigInteger2.cs" />
<Compile Include="Classes\Common\ExtensionsTest_Pad.cs" />
<Compile Include="Classes\Common\ExtensionsTest_TrimLeadingZeros.cs" />
<Compile Include="Classes\Common\PackTest.cs" />
<Compile Include="Classes\Common\PosixPathTest_GetFileName.cs" />
@@ -709,6 +711,18 @@
<Name>Renci.SshNet</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Data\Key.ECDSA.txt" />
<EmbeddedResource Include="Data\Key.ECDSA384.txt" />
<EmbeddedResource Include="Data\Key.ECDSA521.txt" />
<EmbeddedResource Include="Data\Key.ECDSA.Encrypted.txt" />
<EmbeddedResource Include="Data\Key.ECDSA384.Encrypted.txt" />
<EmbeddedResource Include="Data\Key.ECDSA521.Encrypted.txt" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Data\Key.OPENSSH.ED25519.Encrypted.txt" />
<EmbeddedResource Include="Data\Key.OPENSSH.ED25519.txt" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
@@ -717,4 +731,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
@@ -666,12 +666,414 @@
<Compile Include="..\Renci.SshNet\Security\Algorithm.cs">
<Link>Security\Algorithm.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\sec\SECNamedCurves.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\sec\SECNamedCurves.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9Curve.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9Curve.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9ECParameters.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9ECParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9ECParametersHolder.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9ECParametersHolder.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9ECPoint.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9ECPoint.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\agreement\ECDHCBasicAgreement.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\agreement\ECDHCBasicAgreement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\AsymmetricCipherKeyPair.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\AsymmetricCipherKeyPair.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\AsymmetricKeyParameter.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\AsymmetricKeyParameter.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\digests\GeneralDigest.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\digests\GeneralDigest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\digests\Sha256Digest.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\digests\Sha256Digest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\generators\ECKeyPairGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\generators\ECKeyPairGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\IAsymmetricCipherKeyPairGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\IAsymmetricCipherKeyPairGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\IDigest.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\IDigest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\KeyGenerationParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\KeyGenerationParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECDomainParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECDomainParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECKeyGenerationParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECKeyGenerationParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECKeyParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECKeyParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECPrivateKeyParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECPrivateKeyParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECPublicKeyParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECPublicKeyParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\prng\CryptoApiRandomGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\prng\CryptoApiRandomGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\prng\DigestRandomGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\prng\DigestRandomGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\prng\IRandomGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\prng\IRandomGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\util\Pack.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\util\Pack.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\BigInteger.cs">
<Link>Security\Cryptography\BouncyCastle\math\BigInteger.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\abc\SimpleBigDecimal.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\abc\SimpleBigDecimal.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\abc\Tnaf.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\abc\Tnaf.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\abc\ZTauElement.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\abc\ZTauElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECAlgorithms.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECAlgorithms.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECCurve.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECCurve.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECFieldElement.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECFieldElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECLookupTable.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECLookupTable.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECPoint.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECPoint.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECPointMap.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECPointMap.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\endo\ECEndomorphism.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\endo\ECEndomorphism.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\endo\GlvEndomorphism.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\endo\GlvEndomorphism.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\LongArray.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\LongArray.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\AbstractECMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\AbstractECMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\ECMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\ECMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\FixedPointCombMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\FixedPointCombMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\FixedPointPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\FixedPointPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\FixedPointUtilities.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\FixedPointUtilities.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\GlvMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\GlvMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\IPreCompCallback.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\IPreCompCallback.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\PreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\PreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\ValidityPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\ValidityPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafL2RMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WNafL2RMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WNafPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafUtilities.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WNafUtilities.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WTauNafMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WTauNafMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WTauNafPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WTauNafPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\FiniteFields.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\FiniteFields.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\GenericPolynomialExtensionField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\GenericPolynomialExtensionField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\GF2Polynomial.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\GF2Polynomial.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IExtensionField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IExtensionField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IFiniteField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IFiniteField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IPolynomial.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IPolynomial.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IPolynomialExtensionField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IPolynomialExtensionField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\PrimeField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\PrimeField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\raw\Mod.cs">
<Link>Security\Cryptography\BouncyCastle\math\raw\Mod.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\raw\Nat.cs">
<Link>Security\Cryptography\BouncyCastle\math\raw\Nat.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\security\DigestUtilities.cs">
<Link>Security\Cryptography\BouncyCastle\security\DigestUtilities.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\security\SecureRandom.cs">
<Link>Security\Cryptography\BouncyCastle\security\SecureRandom.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\security\SecurityUtilityException.cs">
<Link>Security\Cryptography\BouncyCastle\security\SecurityUtilityException.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Arrays.cs">
<Link>Security\Cryptography\BouncyCastle\util\Arrays.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\BigIntegers.cs">
<Link>Security\Cryptography\BouncyCastle\util\BigIntegers.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\encoders\Hex.cs">
<Link>Security\Cryptography\BouncyCastle\util\encoders\Hex.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\encoders\HexEncoder.cs">
<Link>Security\Cryptography\BouncyCastle\util\encoders\HexEncoder.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Enums.cs">
<Link>Security\Cryptography\BouncyCastle\util\Enums.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\IMemoable.cs">
<Link>Security\Cryptography\BouncyCastle\util\IMemoable.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Integers.cs">
<Link>Security\Cryptography\BouncyCastle\util\Integers.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\MemoableResetException.cs">
<Link>Security\Cryptography\BouncyCastle\util\MemoableResetException.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Times.cs">
<Link>Security\Cryptography\BouncyCastle\util\Times.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\CertificateHostAlgorithm.cs">
<Link>Security\CertificateHostAlgorithm.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\CryptoBytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\CryptoBytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Ed25519.cs">
<Link>Security\Cryptography\Chaos.NaCl\Ed25519.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Array16.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Array16.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Array8.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Array8.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\ByteIntegerConverter.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\ByteIntegerConverter.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\base.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\base.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\base2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\base2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\d.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\d.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\d2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\d2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_1.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_1.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_add.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_add.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_cmov.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_cmov.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_cswap.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_cswap.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_frombytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_frombytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_invert.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_invert.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnegative.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnegative.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnonzero.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnonzero.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul121666.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul121666.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_neg.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_neg.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_pow22523.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_pow22523.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sub.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_sub.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_tobytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_tobytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\FieldElement.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\FieldElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_add.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_add.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_double_scalarmult.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_double_scalarmult.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_frombytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_frombytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_madd.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_madd.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_msub.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_msub.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p3.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p3.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_dbl.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_dbl.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_dbl.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_dbl.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_tobytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_tobytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_cached.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_cached.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_p2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_p2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_precomp_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_precomp_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_scalarmult_base.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_scalarmult_base.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_sub.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_sub.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_tobytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_tobytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\GroupElement.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\GroupElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\keypair.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\keypair.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\open.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\open.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\scalarmult.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\scalarmult.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_clamp.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sc_clamp.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_mul_add.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sc_mul_add.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_reduce.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sc_reduce.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sign.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sign.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sqrtm1.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sqrtm1.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\InternalAssert.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\InternalAssert.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Poly1305Donna.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Poly1305Donna.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Salsa\Salsa20.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Salsa\Salsa20.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Salsa\SalsaCore.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Salsa\SalsaCore.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Sha512Internal.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Sha512Internal.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\MontgomeryCurve25519.cs">
<Link>Security\Cryptography\Chaos.NaCl\MontgomeryCurve25519.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Sha512.cs">
<Link>Security\Cryptography\Chaos.NaCl\Sha512.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\AsymmetricCipher.cs">
<Link>Security\Cryptography\AsymmetricCipher.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\Bcrypt.cs">
<Link>Security\Cryptography\Bcrypt.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\BlockCipher.cs">
<Link>Security\Cryptography\BlockCipher.cs</Link>
</Compile>
@@ -741,6 +1143,12 @@
<Compile Include="..\Renci.SshNet\Security\Cryptography\DsaKey.cs">
<Link>Security\Cryptography\DsaKey.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\ED25519DigitalSignature.cs">
<Link>Security\Cryptography\ED25519DigitalSignature.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\ED25519Key.cs">
<Link>Security\Cryptography\ED25519Key.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\HMACMD5.cs">
<Link>Security\Cryptography\HMACMD5.cs</Link>
</Compile>
@@ -759,6 +1167,12 @@
<Compile Include="..\Renci.SshNet\Security\Cryptography\Key.cs">
<Link>Security\Cryptography\Key.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\EcdsaDigitalSignature.cs">
<Link>Security\Cryptography\EcdsaDigitalSignature.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\EcdsaKey.cs">
<Link>Security\Cryptography\EcdsaKey.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\RsaDigitalSignature.cs">
<Link>Security\Cryptography\RsaDigitalSignature.cs</Link>
</Compile>
@@ -804,6 +1218,24 @@
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupSha1.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupSha1.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeEC.cs">
<Link>Security\KeyExchangeEC.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECCurve25519.cs">
<Link>Security\KeyExchangeECCurve25519.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH.cs">
<Link>Security\KeyExchangeECDH.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH256.cs">
<Link>Security\KeyExchangeECDH256.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH384.cs">
<Link>Security\KeyExchangeECDH384.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH521.cs">
<Link>Security\KeyExchangeECDH521.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyHostAlgorithm.cs">
<Link>Security\KeyHostAlgorithm.cs</Link>
</Compile>
@@ -1034,4 +1466,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
@@ -631,12 +631,414 @@
<Compile Include="..\Renci.SshNet\Security\Algorithm.cs">
<Link>Security\Algorithm.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\sec\SECNamedCurves.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\sec\SECNamedCurves.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9Curve.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9Curve.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9ECParameters.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9ECParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9ECParametersHolder.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9ECParametersHolder.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\asn1\x9\X9ECPoint.cs">
<Link>Security\Cryptography\BouncyCastle\asn1\x9\X9ECPoint.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\agreement\ECDHCBasicAgreement.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\agreement\ECDHCBasicAgreement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\AsymmetricCipherKeyPair.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\AsymmetricCipherKeyPair.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\AsymmetricKeyParameter.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\AsymmetricKeyParameter.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\digests\GeneralDigest.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\digests\GeneralDigest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\digests\Sha256Digest.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\digests\Sha256Digest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\generators\ECKeyPairGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\generators\ECKeyPairGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\IAsymmetricCipherKeyPairGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\IAsymmetricCipherKeyPairGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\IDigest.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\IDigest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\KeyGenerationParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\KeyGenerationParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECDomainParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECDomainParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECKeyGenerationParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECKeyGenerationParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECKeyParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECKeyParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECPrivateKeyParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECPrivateKeyParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\parameters\ECPublicKeyParameters.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\parameters\ECPublicKeyParameters.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\prng\CryptoApiRandomGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\prng\CryptoApiRandomGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\prng\DigestRandomGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\prng\DigestRandomGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\prng\IRandomGenerator.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\prng\IRandomGenerator.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\crypto\util\Pack.cs">
<Link>Security\Cryptography\BouncyCastle\crypto\util\Pack.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\BigInteger.cs">
<Link>Security\Cryptography\BouncyCastle\math\BigInteger.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\abc\SimpleBigDecimal.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\abc\SimpleBigDecimal.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\abc\Tnaf.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\abc\Tnaf.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\abc\ZTauElement.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\abc\ZTauElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECAlgorithms.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECAlgorithms.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECCurve.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECCurve.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECFieldElement.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECFieldElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECLookupTable.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECLookupTable.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECPoint.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECPoint.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\ECPointMap.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\ECPointMap.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\endo\ECEndomorphism.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\endo\ECEndomorphism.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\endo\GlvEndomorphism.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\endo\GlvEndomorphism.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\LongArray.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\LongArray.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\AbstractECMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\AbstractECMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\ECMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\ECMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\FixedPointCombMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\FixedPointCombMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\FixedPointPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\FixedPointPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\FixedPointUtilities.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\FixedPointUtilities.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\GlvMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\GlvMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\IPreCompCallback.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\IPreCompCallback.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\PreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\PreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\ValidityPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\ValidityPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafL2RMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WNafL2RMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WNafPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafUtilities.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WNafUtilities.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WTauNafMultiplier.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WTauNafMultiplier.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WTauNafPreCompInfo.cs">
<Link>Security\Cryptography\BouncyCastle\math\ec\multiplier\WTauNafPreCompInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\FiniteFields.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\FiniteFields.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\GenericPolynomialExtensionField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\GenericPolynomialExtensionField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\GF2Polynomial.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\GF2Polynomial.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IExtensionField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IExtensionField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IFiniteField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IFiniteField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IPolynomial.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IPolynomial.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\IPolynomialExtensionField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\IPolynomialExtensionField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\field\PrimeField.cs">
<Link>Security\Cryptography\BouncyCastle\math\field\PrimeField.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\raw\Mod.cs">
<Link>Security\Cryptography\BouncyCastle\math\raw\Mod.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\math\raw\Nat.cs">
<Link>Security\Cryptography\BouncyCastle\math\raw\Nat.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\security\DigestUtilities.cs">
<Link>Security\Cryptography\BouncyCastle\security\DigestUtilities.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\security\SecureRandom.cs">
<Link>Security\Cryptography\BouncyCastle\security\SecureRandom.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\security\SecurityUtilityException.cs">
<Link>Security\Cryptography\BouncyCastle\security\SecurityUtilityException.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Arrays.cs">
<Link>Security\Cryptography\BouncyCastle\util\Arrays.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\BigIntegers.cs">
<Link>Security\Cryptography\BouncyCastle\util\BigIntegers.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\encoders\Hex.cs">
<Link>Security\Cryptography\BouncyCastle\util\encoders\Hex.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\encoders\HexEncoder.cs">
<Link>Security\Cryptography\BouncyCastle\util\encoders\HexEncoder.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Enums.cs">
<Link>Security\Cryptography\BouncyCastle\util\Enums.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\IMemoable.cs">
<Link>Security\Cryptography\BouncyCastle\util\IMemoable.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Integers.cs">
<Link>Security\Cryptography\BouncyCastle\util\Integers.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\MemoableResetException.cs">
<Link>Security\Cryptography\BouncyCastle\util\MemoableResetException.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\BouncyCastle\util\Times.cs">
<Link>Security\Cryptography\BouncyCastle\util\Times.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\CertificateHostAlgorithm.cs">
<Link>Security\CertificateHostAlgorithm.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\CryptoBytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\CryptoBytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Ed25519.cs">
<Link>Security\Cryptography\Chaos.NaCl\Ed25519.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Array16.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Array16.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Array8.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Array8.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\ByteIntegerConverter.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\ByteIntegerConverter.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\base.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\base.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\base2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\base2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\d.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\d.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\d2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\d2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_1.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_1.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_add.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_add.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_cmov.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_cmov.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_cswap.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_cswap.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_frombytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_frombytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_invert.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_invert.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnegative.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnegative.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnonzero.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnonzero.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul121666.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul121666.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_neg.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_neg.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_pow22523.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_pow22523.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sub.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_sub.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_tobytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\fe_tobytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\FieldElement.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\FieldElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_add.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_add.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_double_scalarmult.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_double_scalarmult.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_frombytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_frombytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_madd.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_madd.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_msub.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_msub.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p3.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p3.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_dbl.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_dbl.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_dbl.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_dbl.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_tobytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_tobytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_cached.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_cached.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_p2.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_p2.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_precomp_0.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_precomp_0.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_scalarmult_base.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_scalarmult_base.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_sub.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_sub.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_tobytes.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\ge_tobytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\GroupElement.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\GroupElement.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\keypair.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\keypair.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\open.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\open.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\scalarmult.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\scalarmult.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_clamp.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sc_clamp.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_mul_add.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sc_mul_add.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_reduce.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sc_reduce.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sign.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sign.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Ed25519Ref10\sqrtm1.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Ed25519Ref10\sqrtm1.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\InternalAssert.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\InternalAssert.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Poly1305Donna.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Poly1305Donna.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Salsa\Salsa20.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Salsa\Salsa20.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Salsa\SalsaCore.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Salsa\SalsaCore.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Internal\Sha512Internal.cs">
<Link>Security\Cryptography\Chaos.NaCl\Internal\Sha512Internal.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\MontgomeryCurve25519.cs">
<Link>Security\Cryptography\Chaos.NaCl\MontgomeryCurve25519.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Chaos.NaCl\Sha512.cs">
<Link>Security\Cryptography\Chaos.NaCl\Sha512.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\AsymmetricCipher.cs">
<Link>Security\Cryptography\AsymmetricCipher.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\Bcrypt.cs">
<Link>Security\Cryptography\Bcrypt.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\BlockCipher.cs">
<Link>Security\Cryptography\BlockCipher.cs</Link>
</Compile>
@@ -703,6 +1105,12 @@
<Compile Include="..\Renci.SshNet\Security\Cryptography\DsaKey.cs">
<Link>Security\Cryptography\DsaKey.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\ED25519DigitalSignature.cs">
<Link>Security\Cryptography\ED25519DigitalSignature.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\ED25519Key.cs">
<Link>Security\Cryptography\ED25519Key.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\HMACMD5.cs">
<Link>Security\Cryptography\HMACMD5.cs</Link>
</Compile>
@@ -721,6 +1129,12 @@
<Compile Include="..\Renci.SshNet\Security\Cryptography\Key.cs">
<Link>Security\Cryptography\Key.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\EcdsaDigitalSignature.cs">
<Link>Security\Cryptography\EcdsaDigitalSignature.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\EcdsaKey.cs">
<Link>Security\Cryptography\EcdsaKey.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Cryptography\RsaDigitalSignature.cs">
<Link>Security\Cryptography\RsaDigitalSignature.cs</Link>
</Compile>
@@ -766,6 +1180,24 @@
<Compile Include="..\Renci.SshNet\Security\KeyExchangeDiffieHellmanGroupSha1.cs">
<Link>Security\KeyExchangeDiffieHellmanGroupSha1.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeEC.cs">
<Link>Security\KeyExchangeEC.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECCurve25519.cs">
<Link>Security\KeyExchangeECCurve25519.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH.cs">
<Link>Security\KeyExchangeECDH.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH256.cs">
<Link>Security\KeyExchangeECDH256.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH384.cs">
<Link>Security\KeyExchangeECDH384.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyExchangeECDH521.cs">
<Link>Security\KeyExchangeECDH521.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\KeyHostAlgorithm.cs">
<Link>Security\KeyHostAlgorithm.cs</Link>
</Compile>
@@ -1007,4 +1439,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
+106 -14
View File
@@ -12,7 +12,7 @@ namespace Renci.SshNet.Common
private const byte Boolean = 0x01;
private const byte Integer = 0x02;
//private const byte BITSTRING = 0x03;
private const byte BITSTRING = 0x03;
private const byte Octetstring = 0x04;
private const byte Null = 0x05;
private const byte Objectidentifier = 0x06;
@@ -70,12 +70,20 @@ namespace Renci.SshNet.Common
/// Initializes a new instance of the <see cref="DerData"/> class.
/// </summary>
/// <param name="data">DER encoded data.</param>
public DerData(byte[] data)
/// <param name="construct">its a construct</param>
public DerData(byte[] data, bool construct = false)
{
_data = new List<byte>(data);
ReadByte(); // skip dataType
var length = ReadLength();
_lastIndex = _readerIndex + length;
if (construct)
{
_lastIndex = _readerIndex + data.Length;
}
else
{
ReadByte(); // skip dataType
var length = ReadLength();
_lastIndex = _readerIndex + length;
}
}
/// <summary>
@@ -101,7 +109,7 @@ namespace Renci.SshNet.Common
{
var type = ReadByte();
if (type != Integer)
throw new InvalidOperationException("Invalid data type, INTEGER(02) is expected.");
throw new InvalidOperationException(string.Format("Invalid data type, INTEGER(02) is expected, but was {0}", type.ToString("X2")));
var length = ReadLength();
@@ -118,7 +126,7 @@ namespace Renci.SshNet.Common
{
var type = ReadByte();
if (type != Integer)
throw new InvalidOperationException("Invalid data type, INTEGER(02) is expected.");
throw new InvalidOperationException(string.Format("Invalid data type, INTEGER(02) is expected, but was {0}", type.ToString("X2")));
var length = ReadLength();
@@ -140,6 +148,51 @@ namespace Renci.SshNet.Common
return result;
}
/// <summary>
/// Reads next octetstring data type from internal buffer.
/// </summary>
/// <returns>data read.</returns>
public byte[] ReadOctetString()
{
var type = ReadByte();
if (type != Octetstring)
throw new InvalidOperationException(string.Format("Invalid data type, OCTETSTRING(04) is expected, but was {0}", type.ToString("X2")));
var length = ReadLength();
var data = ReadBytes(length);
return data;
}
/// <summary>
/// Reads next bitstring data type from internal buffer.
/// </summary>
/// <returns>data read.</returns>
public byte[] ReadBitString()
{
var type = ReadByte();
if (type != BITSTRING)
throw new InvalidOperationException(string.Format("Invalid data type, BITSTRING(03) is expected, but was {0}", type.ToString("X2")));
var length = ReadLength();
var data = ReadBytes(length);
return data;
}
/// <summary>
/// Reads next object data type from internal buffer.
/// </summary>
/// <returns>data read.</returns>
public byte[] ReadObject()
{
var type = ReadByte();
if (type != Objectidentifier)
throw new InvalidOperationException(string.Format("Invalid data type, OBJECT(06) is expected, but was {0}", type.ToString("X2")));
var length = ReadLength();
var data = ReadBytes(length);
return data;
}
/// <summary>
/// Writes BOOLEAN data into internal buffer.
/// </summary>
@@ -189,6 +242,18 @@ namespace Renci.SshNet.Common
WriteBytes(data);
}
/// <summary>
/// Writes BITSTRING data into internal buffer.
/// </summary>
/// <param name="data">The data.</param>
public void WriteBitstring(byte[] data)
{
_data.Add(BITSTRING);
var length = GetLength(data.Length);
WriteBytes(length);
WriteBytes(data);
}
/// <summary>
/// Writes OBJECTIDENTIFIER data into internal buffer.
/// </summary>
@@ -229,6 +294,18 @@ namespace Renci.SshNet.Common
WriteBytes(bytes);
}
/// <summary>
/// Writes OBJECTIDENTIFIER data into internal buffer.
/// </summary>
/// <param name="bytes">The bytes.</param>
public void WriteObjectIdentifier(byte[] bytes)
{
_data.Add(Objectidentifier);
var length = GetLength(bytes.Length);
WriteBytes(length);
WriteBytes(bytes);
}
/// <summary>
/// Writes NULL data into internal buffer.
/// </summary>
@@ -268,10 +345,13 @@ namespace Renci.SshNet.Common
return data;
}
return new[] {(byte) length};
return new[] { (byte)length };
}
private int ReadLength()
/// <summary>
/// Gets Data Length
/// </summary>
/// <returns>length</returns>
public int ReadLength()
{
int length = ReadByte();
@@ -306,12 +386,19 @@ namespace Renci.SshNet.Common
return length;
}
private void WriteBytes(IEnumerable<byte> data)
/// <summary>
/// Write Byte data into internal buffer.
/// </summary>
public void WriteBytes(IEnumerable<byte> data)
{
_data.AddRange(data);
}
private byte ReadByte()
/// <summary>
/// Reads Byte data into internal buffer.
/// </summary>
/// <returns>data read</returns>
public byte ReadByte()
{
if (_readerIndex > _data.Count)
throw new InvalidOperationException("Read out of boundaries.");
@@ -319,7 +406,12 @@ namespace Renci.SshNet.Common
return _data[_readerIndex++];
}
private byte[] ReadBytes(int length)
/// <summary>
/// Reads lengths Bytes data into internal buffer.
/// </summary>
/// <returns>data read</returns>
/// <param name="length">amount of data to read.</param>
public byte[] ReadBytes(int length)
{
if (_readerIndex + length > _data.Count)
throw new InvalidOperationException("Read out of boundaries.");
@@ -330,4 +422,4 @@ namespace Renci.SshNet.Common
return result;
}
}
}
}
+28
View File
@@ -72,6 +72,20 @@ namespace Renci.SshNet.Common
return new BigInteger(reversed.Reverse());
}
/// <summary>
/// Initializes a new instance of the <see cref="BigInteger"/> structure using the SSH BigNum2 Format
/// </summary>
public static BigInteger ToBigInteger2(this byte[] data)
{
if ((data[0] & (1 << 7)) != 0)
{
var buf = new byte[data.Length + 1];
Buffer.BlockCopy(data, 0, buf, 1, data.Length);
data = buf;
}
return data.ToBigInteger();
}
/// <summary>
/// Reverses the sequence of the elements in the entire one-dimensional <see cref="Array"/>.
/// </summary>
@@ -247,6 +261,20 @@ namespace Renci.SshNet.Common
return value;
}
/// <summary>
/// Pads with leading zeros if needd
/// </summary>
/// <param name="data">The data.</param>
/// <param name="length">The length to pad to.</param>
public static byte[] Pad(this byte[] data, int length)
{
if (length <= data.Length)
return data;
var newData = new byte[length];
Buffer.BlockCopy(data, 0, newData, newData.Length - data.Length, data.Length);
return newData;
}
public static byte[] Concat(this byte[] first, byte[] second)
{
if (first == null || first.Length == 0)
+11 -5
View File
@@ -322,14 +322,15 @@ namespace Renci.SshNet
KeyExchangeAlgorithms = new Dictionary<string, Type>
{
{"curve25519-sha256", typeof(KeyExchangeECCurve25519)},
{"curve25519-sha256@libssh.org", typeof(KeyExchangeECCurve25519)},
{"ecdh-sha2-nistp256", typeof(KeyExchangeECDH256)},
{"ecdh-sha2-nistp384", typeof(KeyExchangeECDH384)},
{"ecdh-sha2-nistp521", typeof(KeyExchangeECDH521)},
{"diffie-hellman-group-exchange-sha256", typeof (KeyExchangeDiffieHellmanGroupExchangeSha256)},
{"diffie-hellman-group-exchange-sha1", typeof (KeyExchangeDiffieHellmanGroupExchangeSha1)},
{"diffie-hellman-group14-sha1", typeof (KeyExchangeDiffieHellmanGroup14Sha1)},
{"diffie-hellman-group1-sha1", typeof (KeyExchangeDiffieHellmanGroup1Sha1)},
//{"ecdh-sha2-nistp256", typeof(KeyExchangeEllipticCurveDiffieHellman)},
//{"ecdh-sha2-nistp256", typeof(...)},
//{"ecdh-sha2-nistp384", typeof(...)},
//{"ecdh-sha2-nistp521", typeof(...)},
//"gss-group1-sha1-toWM5Slw5Ew8Mqkay+al2g==" - WinSSHD
//"gss-gex-sha1-toWM5Slw5Ew8Mqkay+al2g==" - WinSSHD
};
@@ -377,9 +378,14 @@ namespace Renci.SshNet
HostKeyAlgorithms = new Dictionary<string, Func<byte[], KeyHostAlgorithm>>
{
{"ssh-ed25519", data => new KeyHostAlgorithm("ssh-ed25519", new ED25519Key(), data)},
#if FEATURE_ECDSA
{"ecdsa-sha2-nistp256", data => new KeyHostAlgorithm("ecdsa-sha2-nistp256", new EcdsaKey(), data)},
{"ecdsa-sha2-nistp384", data => new KeyHostAlgorithm("ecdsa-sha2-nistp384", new EcdsaKey(), data)},
{"ecdsa-sha2-nistp521", data => new KeyHostAlgorithm("ecdsa-sha2-nistp521", new EcdsaKey(), data)},
#endif
{"ssh-rsa", data => new KeyHostAlgorithm("ssh-rsa", new RsaKey(), data)},
{"ssh-dss", data => new KeyHostAlgorithm("ssh-dss", new DsaKey(), data)},
//{"ecdsa-sha2-nistp256 "}
//{"x509v3-sign-rsa", () => { ... },
//{"x509v3-sign-dss", () => { ... },
//{"spki-sign-rsa", () => { ... },
@@ -1,6 +1,4 @@
#if false
using System;
using System;
using Renci.SshNet.Common;
namespace Renci.SshNet.Messages.Transport
@@ -8,7 +6,7 @@ namespace Renci.SshNet.Messages.Transport
/// <summary>
/// Represents SSH_MSG_KEXECDH_INIT message.
/// </summary>
[Message("SSH_MSG_KEXECDH_INIT", 30)]
[Message("SSH_MSG_KEX_ECDH_INIT", 30)]
internal class KeyExchangeEcdhInitMessage : Message, IKeyExchangedAllowed
{
/// <summary>
@@ -33,6 +31,14 @@ namespace Renci.SshNet.Messages.Transport
}
}
/// <summary>
/// Initializes a new instance of the <see cref="KeyExchangeEcdhInitMessage"/> class.
/// </summary>
public KeyExchangeEcdhInitMessage(byte[] q)
{
QC = q;
}
/// <summary>
/// Initializes a new instance of the <see cref="KeyExchangeEcdhInitMessage"/> class.
/// </summary>
@@ -63,7 +69,10 @@ namespace Renci.SshNet.Messages.Transport
{
WriteBinaryString(QC);
}
}
}
#endif // false
internal override void Process(Session session)
{
throw new NotImplementedException();
}
}
}
@@ -1,11 +1,9 @@
#if false
namespace Renci.SshNet.Messages.Transport
namespace Renci.SshNet.Messages.Transport
{
/// <summary>
/// Represents SSH_MSG_KEXECDH_REPLY message.
/// </summary>
[Message("SSH_MSG_KEXECDH_REPLY", 31)]
[Message("SSH_MSG_KEX_ECDH_REPLY", 31)]
public class KeyExchangeEcdhReplyMessage : Message
{
/// <summary>
@@ -65,7 +63,10 @@ namespace Renci.SshNet.Messages.Transport
WriteBinaryString(QS);
WriteBinaryString(Signature);
}
}
}
#endif // false
internal override void Process(Session session)
{
session.OnKeyExchangeEcdhReplyMessageReceived(this);
}
}
}
+169 -1
View File
@@ -11,6 +11,7 @@ using Renci.SshNet.Security.Cryptography.Ciphers;
using Renci.SshNet.Security.Cryptography.Ciphers.Modes;
using Renci.SshNet.Security.Cryptography.Ciphers.Paddings;
using System.Diagnostics.CodeAnalysis;
using Renci.SshNet.Security.Cryptography;
namespace Renci.SshNet
{
@@ -22,7 +23,21 @@ namespace Renci.SshNet
/// </example>
/// <remarks>
/// <para>
/// Supports RSA and DSA private key in both <c>OpenSSH</c> and <c>ssh.com</c> format.
/// The following private keys are supported:
/// <list type="bullet">
/// <item>
/// <description>RSA in OpenSSL PEM and ssh.com format</description>
/// </item>
/// <item>
/// <description>DSA in OpenSSL PEM and ssh.com format</description>
/// </item>
/// <item>
/// <description>ECDSA 256/384/521 in OpenSSL PEM format</description>
/// </item>
/// <item>
/// <description>ED25519 in OpenSSH key format</description>
/// </item>
/// </list>
/// </para>
/// <para>
/// The following encryption algorithms are supported:
@@ -197,6 +212,16 @@ namespace Renci.SshNet
_key = new DsaKey(decryptedData);
HostKey = new KeyHostAlgorithm("ssh-dss", _key);
break;
#if FEATURE_ECDSA
case "EC":
_key = new EcdsaKey(decryptedData);
HostKey = new KeyHostAlgorithm(_key.ToString(), _key);
break;
#endif
case "OPENSSH":
_key = ParseOpenSshV1Key(decryptedData, passPhrase);
HostKey = new KeyHostAlgorithm(_key.ToString(), _key);
break;
case "SSH2 ENCRYPTED":
var reader = new SshDataReader(decryptedData);
var magicNumber = reader.ReadUInt32();
@@ -341,6 +366,144 @@ namespace Renci.SshNet
return cipher.Decrypt(cipherData);
}
/// <summary>
/// Parses an OpenSSH V1 key file (i.e. ED25519 key) according to the the key spec:
/// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key.
/// </summary>
/// <param name="keyFileData">the key file data (i.e. base64 encoded data between the header/footer)</param>
/// <param name="passPhrase">passphrase or null if there isn't one</param>
/// <returns></returns>
private ED25519Key ParseOpenSshV1Key(byte [] keyFileData, string passPhrase)
{
var keyReader = new SshDataReader(keyFileData);
//check magic header
var authMagic = Encoding.UTF8.GetBytes("openssh-key-v1\0");
var keyHeaderBytes = keyReader.ReadBytes(authMagic.Length);
if (!authMagic.IsEqualTo(keyHeaderBytes))
{
throw new SshException("This openssh key does not contain the 'openssh-key-v1' format magic header");
}
//cipher will be "aes256-cbc" if using a passphrase, "none" otherwise
var cipherName = keyReader.ReadString(Encoding.UTF8);
//key derivation function (kdf): bcrypt or nothing
var kdfName = keyReader.ReadString(Encoding.UTF8);
//kdf options length: 24 if passphrase, 0 if no passphrase
var kdfOptionsLen = (int)keyReader.ReadUInt32();
byte[] salt = null;
int rounds = 0;
if (kdfOptionsLen > 0)
{
var saltLength = (int)keyReader.ReadUInt32();
salt = keyReader.ReadBytes(saltLength);
rounds = (int)keyReader.ReadUInt32();
}
//number of public keys, only supporting 1 for now
var numberOfPublicKeys = (int)keyReader.ReadUInt32();
if (numberOfPublicKeys != 1)
{
throw new SshException("At this time only one public key in the openssh key is supported.");
}
//length of first public key section
keyReader.ReadUInt32();
var keyType = keyReader.ReadString(Encoding.UTF8);
if(keyType != "ssh-ed25519")
{
throw new SshException("openssh key type: " + keyType + " is not supported");
}
//read public key
var publicKeyLength = (int)keyReader.ReadUInt32(); //32
var publicKey = keyReader.ReadBytes(publicKeyLength);
//possibly encrypted private key
var privateKeyLength = (int)keyReader.ReadUInt32();
var privateKeyBytes = keyReader.ReadBytes(privateKeyLength);
//decrypt private key if necessary
if (cipherName == "aes256-cbc")
{
if (string.IsNullOrEmpty(passPhrase))
{
throw new SshPassPhraseNullOrEmptyException("Private key is encrypted but passphrase is empty.");
}
if (string.IsNullOrEmpty(kdfName) || kdfName != "bcrypt")
{
throw new SshException("kdf " + kdfName + " is not supported for openssh key file");
}
//inspired by the SSHj library (https://github.com/hierynomus/sshj)
//apply the kdf to derive a key and iv from the passphrase
var passPhraseBytes = Encoding.UTF8.GetBytes(passPhrase);
byte[] keyiv = new byte[48];
new BCrypt().Pbkdf(passPhraseBytes, salt, rounds, keyiv);
byte[] key = new byte[32];
Array.Copy(keyiv, 0, key, 0, 32);
byte[] iv = new byte[16];
Array.Copy(keyiv, 32, iv, 0, 16);
//now that we have the key/iv, use a cipher to decrypt the bytes
var cipher = new AesCipher(key, new CbcCipherMode(iv), new PKCS7Padding());
privateKeyBytes = cipher.Decrypt(privateKeyBytes);
}
else if (cipherName != "none")
{
throw new SshException("cipher name " + cipherName + " for openssh key file is not supported");
}
//validate private key length
privateKeyLength = privateKeyBytes.Length;
if (privateKeyLength % 8 != 0)
{
throw new SshException("The private key section must be a multiple of the block size (8)");
}
//now parse the data we called the private key, it actually contains the public key again
//so we need to parse through it to get the private key bytes, plus there's some
//validation we need to do.
var privateKeyReader = new SshDataReader(privateKeyBytes);
//check ints should match, they wouldn't match for example if the wrong passphrase was supplied
int checkInt1 = (int)privateKeyReader.ReadUInt32();
int checkInt2 = (int)privateKeyReader.ReadUInt32();
if (checkInt1 != checkInt2)
{
throw new SshException("The checkints differed, the openssh key was not correctly decoded.");
}
//key type, we already know it is ssh-ed25519
privateKeyReader.ReadString(Encoding.UTF8);
//public key length/bytes (again)
var publicKeyLength2 = (int)privateKeyReader.ReadUInt32();
privateKeyReader.ReadBytes(publicKeyLength2);
//length of private and public key (64)
privateKeyReader.ReadUInt32();
var unencryptedPrivateKey = privateKeyReader.ReadBytes(32);
//public key (again)
privateKeyReader.ReadBytes(32);
//comment, we don't need this but we could log it, not sure if necessary
var comment = privateKeyReader.ReadString(Encoding.UTF8);
//The list of privatekey/comment pairs is padded with the bytes 1, 2, 3, ...
//until the total length is a multiple of the cipher block size.
var padding = privateKeyReader.ReadBytes();
for (int i = 0; i < padding.Length; i++)
{
if ((int)padding[i] != i + 1)
{
throw new SshException("Padding of openssh key format contained wrong byte at position: " + i);
}
}
return new ED25519Key(publicKey.Reverse(), unencryptedPrivateKey);
}
#region IDisposable Members
private bool _isDisposed;
@@ -409,6 +572,11 @@ namespace Renci.SshNet
return base.ReadBytes(length);
}
public new byte[] ReadBytes()
{
return base.ReadBytes();
}
/// <summary>
/// Reads next mpint data type from internal buffer where length specified in bits.
/// </summary>
+148 -2
View File
@@ -18,7 +18,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_SOCKET_DISPOSE;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_WAITHANDLE_DISPOSE;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
<DefineConstants>TRACE;DEBUG;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_SOCKET_DISPOSE;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_WAITHANDLE_DISPOSE;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII;FEATURE_ECDSA</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Debug\Renci.SshNet.xml</DocumentationFile>
@@ -29,7 +29,7 @@
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_SOCKET_DISPOSE;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_WAITHANDLE_DISPOSE;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
<DefineConstants>FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_SOCKET_DISPOSE;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_WAITHANDLE_DISPOSE;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII;FEATURE_ECDSA</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Renci.SshNet.xml</DocumentationFile>
@@ -168,6 +168,144 @@
<Compile Include="RemotePathNoneTransformation.cs" />
<Compile Include="RemotePathShellQuoteTransformation.cs" />
<Compile Include="RemotePathTransformation.cs" />
<Compile Include="Security\BouncyCastle\asn1\sec\SECNamedCurves.cs" />
<Compile Include="Security\BouncyCastle\asn1\x9\X9Curve.cs" />
<Compile Include="Security\BouncyCastle\asn1\x9\X9ECParameters.cs" />
<Compile Include="Security\BouncyCastle\asn1\x9\X9ECParametersHolder.cs" />
<Compile Include="Security\BouncyCastle\asn1\x9\X9ECPoint.cs" />
<Compile Include="Security\BouncyCastle\crypto\agreement\ECDHCBasicAgreement.cs" />
<Compile Include="Security\BouncyCastle\crypto\AsymmetricCipherKeyPair.cs" />
<Compile Include="Security\BouncyCastle\crypto\AsymmetricKeyParameter.cs" />
<Compile Include="Security\BouncyCastle\crypto\digests\GeneralDigest.cs" />
<Compile Include="Security\BouncyCastle\crypto\digests\Sha256Digest.cs" />
<Compile Include="Security\BouncyCastle\crypto\generators\ECKeyPairGenerator.cs" />
<Compile Include="Security\BouncyCastle\crypto\IAsymmetricCipherKeyPairGenerator.cs" />
<Compile Include="Security\BouncyCastle\crypto\IDigest.cs" />
<Compile Include="Security\BouncyCastle\crypto\KeyGenerationParameters.cs" />
<Compile Include="Security\BouncyCastle\crypto\parameters\ECDomainParameters.cs" />
<Compile Include="Security\BouncyCastle\crypto\parameters\ECKeyGenerationParameters.cs" />
<Compile Include="Security\BouncyCastle\crypto\parameters\ECKeyParameters.cs" />
<Compile Include="Security\BouncyCastle\crypto\parameters\ECPrivateKeyParameters.cs" />
<Compile Include="Security\BouncyCastle\crypto\parameters\ECPublicKeyParameters.cs" />
<Compile Include="Security\BouncyCastle\crypto\prng\CryptoApiRandomGenerator.cs" />
<Compile Include="Security\BouncyCastle\crypto\prng\DigestRandomGenerator.cs" />
<Compile Include="Security\BouncyCastle\crypto\prng\IRandomGenerator.cs" />
<Compile Include="Security\BouncyCastle\crypto\util\Pack.cs" />
<Compile Include="Security\BouncyCastle\math\BigInteger.cs" />
<Compile Include="Security\BouncyCastle\math\ec\abc\SimpleBigDecimal.cs" />
<Compile Include="Security\BouncyCastle\math\ec\abc\Tnaf.cs" />
<Compile Include="Security\BouncyCastle\math\ec\abc\ZTauElement.cs" />
<Compile Include="Security\BouncyCastle\math\ec\ECAlgorithms.cs" />
<Compile Include="Security\BouncyCastle\math\ec\ECCurve.cs" />
<Compile Include="Security\BouncyCastle\math\ec\ECFieldElement.cs" />
<Compile Include="Security\BouncyCastle\math\ec\ECLookupTable.cs" />
<Compile Include="Security\BouncyCastle\math\ec\ECPoint.cs" />
<Compile Include="Security\BouncyCastle\math\ec\ECPointMap.cs" />
<Compile Include="Security\BouncyCastle\math\ec\endo\ECEndomorphism.cs" />
<Compile Include="Security\BouncyCastle\math\ec\endo\GlvEndomorphism.cs" />
<Compile Include="Security\BouncyCastle\math\ec\LongArray.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\AbstractECMultiplier.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\ECMultiplier.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\FixedPointCombMultiplier.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\FixedPointPreCompInfo.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\FixedPointUtilities.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\GlvMultiplier.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\IPreCompCallback.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\PreCompInfo.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\ValidityPreCompInfo.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\WNafL2RMultiplier.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\WNafPreCompInfo.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\WNafUtilities.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\WTauNafMultiplier.cs" />
<Compile Include="Security\BouncyCastle\math\ec\multiplier\WTauNafPreCompInfo.cs" />
<Compile Include="Security\BouncyCastle\math\field\FiniteFields.cs" />
<Compile Include="Security\BouncyCastle\math\field\GenericPolynomialExtensionField.cs" />
<Compile Include="Security\BouncyCastle\math\field\GF2Polynomial.cs" />
<Compile Include="Security\BouncyCastle\math\field\IExtensionField.cs" />
<Compile Include="Security\BouncyCastle\math\field\IFiniteField.cs" />
<Compile Include="Security\BouncyCastle\math\field\IPolynomial.cs" />
<Compile Include="Security\BouncyCastle\math\field\IPolynomialExtensionField.cs" />
<Compile Include="Security\BouncyCastle\math\field\PrimeField.cs" />
<Compile Include="Security\BouncyCastle\math\raw\Mod.cs" />
<Compile Include="Security\BouncyCastle\math\raw\Nat.cs" />
<Compile Include="Security\BouncyCastle\security\DigestUtilities.cs" />
<Compile Include="Security\BouncyCastle\security\SecureRandom.cs" />
<Compile Include="Security\BouncyCastle\security\SecurityUtilityException.cs" />
<Compile Include="Security\BouncyCastle\util\Arrays.cs" />
<Compile Include="Security\BouncyCastle\util\BigIntegers.cs" />
<Compile Include="Security\BouncyCastle\util\encoders\Hex.cs" />
<Compile Include="Security\BouncyCastle\util\encoders\HexEncoder.cs" />
<Compile Include="Security\BouncyCastle\util\Enums.cs" />
<Compile Include="Security\BouncyCastle\util\IMemoable.cs" />
<Compile Include="Security\BouncyCastle\util\Integers.cs" />
<Compile Include="Security\BouncyCastle\util\MemoableResetException.cs" />
<Compile Include="Security\BouncyCastle\util\Times.cs" />
<Compile Include="Security\Chaos.NaCl\CryptoBytes.cs" />
<Compile Include="Security\Chaos.NaCl\Ed25519.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Array16.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Array8.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\ByteIntegerConverter.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\base.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\base2.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\d.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\d2.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_0.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_1.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_add.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_cmov.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_cswap.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_frombytes.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_invert.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnegative.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_isnonzero.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_mul121666.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_neg.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_pow22523.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sq2.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_sub.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\fe_tobytes.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\FieldElement.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_add.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_double_scalarmult.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_frombytes.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_madd.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_msub.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p2.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p1p1_to_p3.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_0.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p2_dbl.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_0.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_dbl.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_tobytes.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_cached.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_p3_to_p2.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_precomp_0.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_scalarmult_base.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_sub.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\ge_tobytes.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\GroupElement.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\keypair.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\open.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\scalarmult.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_clamp.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_mul_add.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\sc_reduce.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\sign.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Ed25519Ref10\sqrtm1.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\InternalAssert.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Poly1305Donna.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Salsa\Salsa20.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Salsa\SalsaCore.cs" />
<Compile Include="Security\Chaos.NaCl\Internal\Sha512Internal.cs" />
<Compile Include="Security\Chaos.NaCl\MontgomeryCurve25519.cs" />
<Compile Include="Security\Chaos.NaCl\Sha512.cs" />
<Compile Include="Security\Cryptography\ED25519DigitalSignature.cs" />
<Compile Include="Security\Cryptography\EcdsaDigitalSignature.cs" />
<Compile Include="Security\Cryptography\EcdsaKey.cs" />
<Compile Include="Security\Cryptography\ED25519Key.cs" />
<Compile Include="Security\Cryptography\Bcrypt.cs" />
<Compile Include="Security\Cryptography\HMACMD5.cs" />
<Compile Include="Security\Cryptography\HMACSHA1.cs" />
<Compile Include="Security\Cryptography\HMACSHA256.cs" />
@@ -176,6 +314,12 @@
<Compile Include="Security\GroupExchangeHashData.cs" />
<Compile Include="Security\IKeyExchange.cs" />
<Compile Include="Security\KeyExchangeDiffieHellmanGroupExchangeShaBase.cs" />
<Compile Include="Security\KeyExchangeEC.cs" />
<Compile Include="Security\KeyExchangeECCurve25519.cs" />
<Compile Include="Security\KeyExchangeECDH.cs" />
<Compile Include="Security\KeyExchangeECDH521.cs" />
<Compile Include="Security\KeyExchangeECDH384.cs" />
<Compile Include="Security\KeyExchangeECDH256.cs" />
<Compile Include="ServiceFactory.cs" />
<Compile Include="ServiceFactory.NET.cs" />
<Compile Include="Sftp\ISftpFileReader.cs" />
@@ -468,6 +612,8 @@
</ItemGroup>
<ItemGroup>
<Content Include="Documentation\SshNet.shfbproj" />
<Content Include="Security\Chaos.NaCl\Internal\Salsa\replace regex.txt" />
<Content Include="Security\Chaos.NaCl\License.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -0,0 +1,121 @@
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,0 +1,40 @@
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,0 +1,93 @@
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,0 +1,25 @@
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,0 +1,57 @@
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,0 +1,33 @@
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,0 +1,42 @@
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,0 +1,9 @@
namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto
{
internal interface IAsymmetricCipherKeyPairGenerator
{
void Init(KeyGenerationParameters parameters);
AsymmetricCipherKeyPair GenerateKeyPair();
}
}
@@ -0,0 +1,61 @@
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,0 +1,56 @@
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,0 +1,39 @@
<!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,0 +1,46 @@
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,0 +1,129 @@
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,0 +1,280 @@
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,0 +1,91 @@
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,0 +1,91 @@
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,0 +1,23 @@
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,0 +1,79 @@
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,0 +1,61 @@
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,0 +1,60 @@
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,0 +1,69 @@
using System;
using System.Security.Cryptography;
namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Prng
{
internal class CryptoApiRandomGenerator
: IRandomGenerator
{
private readonly RandomNumberGenerator rndProv;
public CryptoApiRandomGenerator()
#if FEATURE_RNG_CREATE || FEATURE_RNG_CSP
: this(Abstractions.CryptoAbstraction.CreateRandomNumberGenerator())
#endif
{
}
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)
{
#if FEATURE_RNG_CREATE || FEATURE_RNG_CSP
rndProv.GetBytes(bytes);
#else
if (bytes == null)
throw new ArgumentNullException("bytes");
var buffer = Windows.Security.Cryptography.CryptographicBuffer.GenerateRandom((uint)bytes.Length);
System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.CopyTo(buffer, bytes);
#endif
}
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,0 +1,117 @@
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,0 +1,26 @@
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,0 +1,345 @@
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;
}
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,496 @@
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;
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,972 @@
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,0 +1,10 @@
using System;
namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC
{
internal interface ECLookupTable
{
int Size { get; }
ECPoint Lookup(int index);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,9 @@
using System;
namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC
{
internal interface ECPointMap
{
ECPoint Map(ECPoint p);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,241 @@
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,0 +1,845 @@
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,0 +1,36 @@
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,0 +1,11 @@
using System;
namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Endo
{
internal interface ECEndomorphism
{
ECPointMap PointMap { get; }
bool HasEfficientPointMap { get; }
}
}
@@ -0,0 +1,10 @@
using System;
namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Endo
{
internal interface GlvEndomorphism
: ECEndomorphism
{
BigInteger[] DecomposeScalar(BigInteger k);
}
}
@@ -0,0 +1,29 @@
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,0 +1,18 @@
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,0 +1,58 @@
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,0 +1,43 @@
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,0 +1,95 @@
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,0 +1,40 @@
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,0 +1,9 @@
using System;
namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier
{
internal interface IPreCompCallback
{
PreCompInfo Precompute(PreCompInfo existing);
}
}
@@ -0,0 +1,11 @@
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,0 +1,44 @@
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,0 +1,98 @@
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,0 +1,46 @@
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,0 +1,579 @@
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,0 +1,138 @@
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,0 +1,24 @@
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,0 +1,54 @@
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,0 +1,46 @@
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,0 +1,63 @@
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,0 +1,12 @@
using System;
namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Field
{
internal interface IExtensionField
: IFiniteField
{
IFiniteField Subfield { get; }
int Degree { get; }
}
}
@@ -0,0 +1,11 @@
using System;
namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Field
{
internal interface IFiniteField
{
BigInteger Characteristic { get; }
int Dimension { get; }
}
}
@@ -0,0 +1,13 @@
namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Field
{
internal interface IPolynomial
{
int Degree { get; }
//BigInteger[] GetCoefficients();
int[] GetExponentsPresent();
//Term[] GetNonZeroTerms();
}
}
@@ -0,0 +1,8 @@
namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Field
{
internal interface IPolynomialExtensionField
: IExtensionField
{
IPolynomial MinimalPolynomial { get; }
}
}
@@ -0,0 +1,42 @@
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,0 +1,185 @@
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;
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,92 @@
using System;
using System.Collections;
using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Digests;
using Renci.SshNet.Security.Org.BouncyCastle.Crypto;
using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
using System.Collections.Generic;
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()
{
}
private static readonly IDictionary algorithms = new Dictionary<object, object>();
private static readonly IDictionary oids = new Dictionary<object, object>();
static DigestUtilities()
{
// Signal to obfuscation tools not to change enum constants
((DigestAlgorithm)Enums.GetArbitraryValue(typeof(DigestAlgorithm))).ToString();
algorithms["SHA256"] = "SHA-256";
algorithms["2.16.840.1.101.3.4.2.1"] = "SHA-256";
}
public static ICollection Algorithms
{
get { return oids.Keys; }
}
public static IDigest GetDigest(
string algorithm)
{
string upper = algorithm.ToUpper();
string mechanism = (string) algorithms[upper];
if (mechanism == null)
{
mechanism = upper;
}
try
{
DigestAlgorithm digestAlgorithm = (DigestAlgorithm)Enums.GetEnumValue(
typeof(DigestAlgorithm), mechanism);
switch (digestAlgorithm)
{
case DigestAlgorithm.SHA_256: return new Sha256Digest();
}
}
catch (ArgumentException)
{
}
throw new SecurityUtilityException("Digest " + mechanism + " not recognised.");
}
public static byte[] CalculateDigest(string algorithm, byte[] input)
{
IDigest digest = GetDigest(algorithm);
digest.BlockUpdate(input, 0, input.Length);
return DoFinal(digest);
}
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,0 +1,210 @@
using System;
using System.Threading;
using Renci.SshNet.Security.Org.BouncyCastle.Crypto;
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(string digestName, bool autoSeed)
{
IDigest digest = DigestUtilities.GetDigest(digestName);
if (digest == null)
return null;
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;
}
/// <summary>
/// Create and auto-seed an instance based on the given algorithm.
/// </summary>
/// <remarks>Equivalent to GetInstance(algorithm, true)</remarks>
/// <param name="algorithm">e.g. "SHA256PRNG"</param>
public static SecureRandom GetInstance(string algorithm)
{
return GetInstance(algorithm, true);
}
/// <summary>
/// Create an instance based on the given algorithm, with optional auto-seeding
/// </summary>
/// <param name="algorithm">e.g. "SHA256PRNG"</param>
/// <param name="autoSeed">If true, the instance will be auto-seeded.</param>
public static SecureRandom GetInstance(string algorithm, bool autoSeed)
{
string upper = algorithm.ToUpper();
if (upper.EndsWith("PRNG"))
{
string digestName = upper.Substring(0, upper.Length - "PRNG".Length);
DigestRandomGenerator prng = CreatePrng(digestName, autoSeed);
if (prng != null)
{
return new SecureRandom(prng);
}
}
throw new ArgumentException("Unrecognised PRNG algorithm: " + algorithm, "algorithm");
}
protected readonly IRandomGenerator generator;
public SecureRandom()
: this(CreatePrng("SHA256", 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)
: base(0)
{
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,0 +1,36 @@
using System;
namespace Renci.SshNet.Security.Org.BouncyCastle.Security
{
#if FEATURE_BINARY_SERIALIZATION
[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,0 +1,725 @@
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);
}
[CLSCompliantAttribute(false)]
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;
}
[CLSCompliantAttribute(false)]
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;
}
[CLSCompliantAttribute(false)]
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;
}
[CLSCompliantAttribute(false)]
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;
}
[CLSCompliantAttribute(false)]
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();
}
[CLSCompliantAttribute(false)]
public static ulong[] Clone(
ulong[] data)
{
return data == null ? null : (ulong[]) data.Clone();
}
[CLSCompliantAttribute(false)]
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,0 +1,95 @@
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,0 +1,32 @@
using System;
namespace Renci.SshNet.Security.Org.BouncyCastle.Utilities
{
internal abstract class Enums
{
internal static Enum GetEnumValue(System.Type enumType, string s)
{
// We only want to parse single named constants
if (s.Length > 0 && char.IsLetter(s[0]) && s.IndexOf(',') < 0)
{
s = s.Replace('-', '_');
s = s.Replace('/', '_');
return (Enum)Enum.Parse(enumType, s, false);
}
throw new ArgumentException();
}
internal static Array GetEnumValues(System.Type enumType)
{
return Enum.GetValues(enumType);
}
internal static Enum GetArbitraryValue(System.Type enumType)
{
Array values = GetEnumValues(enumType);
int pos = (int)(int.MaxValue) % values.Length;
return (Enum)values.GetValue(pos);
}
}
}
@@ -0,0 +1,29 @@
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,0 +1,29 @@
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);
}
[CLSCompliantAttribute(false)]
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);
}
[CLSCompliantAttribute(false)]
public static uint RotateRight(uint i, int distance)
{
return (i >> distance) ^ (i << -distance);
}
}
}
@@ -0,0 +1,27 @@
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,0 +1,14 @@
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,0 +1,129 @@
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,0 +1,174 @@
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;
}
}
}

Some files were not shown because too many files have changed in this diff Show More