Skip to content

Commit 1b881f5

Browse files
committed
Change how clientExchangeValue is calculated (#130)
1 parent f50b9f1 commit 1b881f5

File tree

2 files changed

+88
-9
lines changed

2 files changed

+88
-9
lines changed

src/Renci.SshNet.Tests/Classes/Common/BigIntegerTest.cs

+61
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.Threading;
1717
using Microsoft.VisualStudio.TestTools.UnitTesting;
1818
using Renci.SshNet.Common;
19+
using System.Text.RegularExpressions;
1920
#if FEATURE_NUMERICS_BIGINTEGER
2021
using BigInteger = System.Numerics.BigInteger;
2122
#else
@@ -1650,6 +1651,66 @@ public void Zero()
16501651
Assert.AreEqual(0, zero.Sign);
16511652
}
16521653

1654+
[TestMethod]
1655+
public void TestClientExhcangeGenerationItem130()
1656+
{
1657+
var test = "1090748135619415929450294929359784500348155124953172211774101106966150168922785639028532473848836817769712164169076432969224698752674677662739994265785437233596157045970922338040698100507861033047312331823982435279475700199860971612732540528796554502867919746776983759391475987142521315878719577519148811830879919426939958487087540965716419167467499326156226529675209172277001377591248147563782880558861083327174154014975134893125116015776318890295960698011614157721282527539468816519319333337503114777192360412281721018955834377615480468479252748867320362385355596601795122806756217713579819870634321561907813255153703950795271232652404894983869492174481652303803498881366210508647263668376514131031102336837488999775744046733651827239395353540348414872854639719294694323450186884189822544540647226987292160693184734654941906936646576130260972193280317171696418971553954161446191759093719524951116705577362073481319296041201283516154269044389257727700289684119460283480452306204130024913879981135908026983868205969318167819680850998649694416907952712904962404937775789698917207356355227455066183815847669135530549755439819480321732925869069136146085326382334628745456398071603058051634209386708703306545903199608523824513729625136659128221100967735450519952404248198262813831097374261650380017277916975324134846574681307337017380830353680623216336949471306191686438249305686413380231046096450953594089375540285037292470929395114028305547452584962074309438151825437902976012891749355198678420603722034900311364893046495761404333938686140037848030916292543273684533640032637639100774502371542479302473698388692892420946478947733800387782741417786484770190108867879778991633218628640533982619322466154883011452291890252336487236086654396093853898628805813177559162076363154436494477507871294119841637867701722166609831201845484078070518041336869808398454625586921201308185638888082699408686536045192649569198110353659943111802300636106509865023943661829436426563007917282050894429388841748885398290707743052973605359277515749619730823773215894755121761467887865327707115573804264519206349215850195195364813387526811742474131549802130246506341207020335797706780705406945275438806265978516209706795702579244075380490231741030862614968783306207869687868108423639971983209077624758080499988275591392787267627182442892809646874228263172435642368588260139161962836121481966092745325488641054238839295138992979335446110090325230955276870524611359124918392740353154294858383359";
1658+
BigInteger prime;
1659+
BigInteger.TryParse(test, NumberStyles.Number, NumberFormatInfo.CurrentInfo, out prime);
1660+
1661+
BigInteger group = 2;
1662+
var bitLength = prime.BitLength;
1663+
1664+
BigInteger clientExchangeValue;
1665+
do
1666+
{
1667+
var randomValue = BigInteger.Random(bitLength);
1668+
1669+
//clientExchangeValue = BigInteger.ModPow(group, randomValue, prime);
1670+
clientExchangeValue = (group ^ randomValue) % prime;
1671+
} while (clientExchangeValue < 1 || clientExchangeValue > (prime - 1));
1672+
}
1673+
1674+
[TestMethod]
1675+
public void TestClientExhcangeGenerationGroup1()
1676+
{
1677+
var test = "00FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF";
1678+
BigInteger prime;
1679+
BigInteger.TryParse(test, NumberStyles.AllowHexSpecifier, NumberFormatInfo.CurrentInfo, out prime);
1680+
1681+
BigInteger group = 2;
1682+
var bitLength = prime.BitLength;
1683+
1684+
BigInteger clientExchangeValue;
1685+
do
1686+
{
1687+
var randomValue = BigInteger.Random(bitLength);
1688+
1689+
//clientExchangeValue = BigInteger.ModPow(group, randomValue, prime);
1690+
clientExchangeValue = (group ^ randomValue) % prime;
1691+
} while (clientExchangeValue < 1 || clientExchangeValue > (prime - 1));
1692+
}
1693+
1694+
[TestMethod]
1695+
public void TestClientExhcangeGenerationGroup14()
1696+
{
1697+
var test = "00FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF";
1698+
BigInteger prime;
1699+
BigInteger.TryParse(test, NumberStyles.AllowHexSpecifier, NumberFormatInfo.CurrentInfo, out prime);
1700+
1701+
BigInteger group = 2;
1702+
var bitLength = prime.BitLength;
1703+
1704+
BigInteger clientExchangeValue;
1705+
do
1706+
{
1707+
var randomValue = BigInteger.Random(bitLength);
1708+
1709+
//clientExchangeValue = BigInteger.ModPow(group, randomValue, prime);
1710+
clientExchangeValue = (group ^ randomValue) % prime;
1711+
} while (clientExchangeValue < 1 || clientExchangeValue > (prime - 1));
1712+
}
1713+
16531714
private static void AssertEqual(byte[] a, byte[] b)
16541715
{
16551716
Assert.IsTrue(a.IsEqualTo(b));

src/Renci.SshNet/Common/BigInteger.cs

+27-9
Original file line numberDiff line numberDiff line change
@@ -165,18 +165,36 @@ public static BigInteger PositiveMod(BigInteger dividend, BigInteger divisor)
165165
}
166166

167167
/// <summary>
168-
/// Generates random <see cref="BigInteger"/> number.
168+
/// Generates a new, random <see cref="BigInteger"/> of the specified length.
169169
/// </summary>
170-
/// <param name="bitLength">Length of random number in bits.</param>
171-
/// <returns>
172-
/// A random number.
173-
/// </returns>
170+
/// <param name="bitLength">The number of bits for the new number.</param>
171+
/// <returns>A random number of the specified length.</returns>
174172
public static BigInteger Random(int bitLength)
175173
{
176-
var bytesArray = new byte[bitLength / 8 + (((bitLength % 8) > 0) ? 1 : 0)];
177-
CryptoAbstraction.GenerateRandom(bytesArray);
178-
bytesArray[bytesArray.Length - 1] = (byte)(bytesArray[bytesArray.Length - 1] & 0x7F); // Ensure not a negative value
179-
return new BigInteger(bytesArray);
174+
int dwords = bitLength >> 5;
175+
int remBits = bitLength & 0x1F;
176+
177+
if (remBits != 0)
178+
dwords++;
179+
180+
BigInteger ret = new BigInteger(1, new uint[(uint)dwords + 1]);
181+
byte[] random = new byte[dwords << 2];
182+
183+
CryptoAbstraction.GenerateRandom(random);
184+
Buffer.BlockCopy(random, 0, ret._data, 0, (int)dwords << 2);
185+
186+
if (remBits != 0)
187+
{
188+
uint mask = (uint)(0x01 << (remBits - 1));
189+
ret._data[dwords - 1] |= mask;
190+
191+
mask = (uint)(0xFFFFFFFF >> (32 - remBits));
192+
ret._data[dwords - 1] &= mask;
193+
}
194+
else
195+
ret._data[dwords - 1] |= 0x80000000;
196+
197+
return ret;
180198
}
181199

182200
#endregion SSH.NET additions

0 commit comments

Comments
 (0)