You've already forked lidgren-network-gen3
mirror of
https://github.com/lidgren/lidgren-network-gen3.git
synced 2026-05-17 23:56:30 +09:00
More SRP work (still not working 100%)
This commit is contained in:
@@ -38,6 +38,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="NetBigInteger.cs" />
|
<Compile Include="NetBigInteger.cs" />
|
||||||
|
<Compile Include="NetBigIntegerBC.cs" />
|
||||||
<Compile Include="NetBitVector.cs" />
|
<Compile Include="NetBitVector.cs" />
|
||||||
<Compile Include="NetConnectionStatistics.cs" />
|
<Compile Include="NetConnectionStatistics.cs" />
|
||||||
<Compile Include="NetBitWriter.cs" />
|
<Compile Include="NetBitWriter.cs" />
|
||||||
|
|||||||
@@ -34,13 +34,25 @@
|
|||||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
//using Mono.Math.Prime.Generator;
|
||||||
|
//using Mono.Math.Prime;
|
||||||
|
|
||||||
namespace Lidgren.Network
|
namespace Lidgren.Network
|
||||||
{
|
{
|
||||||
public sealed class BigInteger
|
|
||||||
|
#if INSIDE_CORLIB
|
||||||
|
internal
|
||||||
|
#else
|
||||||
|
public
|
||||||
|
#endif
|
||||||
|
class BigInteger
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#region Data Storage
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Length of this BigInteger
|
/// The Length of this BigInteger
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -51,6 +63,10 @@ namespace Lidgren.Network
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
uint[] data;
|
uint[] data;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constants
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default length of a BigInteger in bytes
|
/// Default length of a BigInteger in bytes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -146,7 +162,13 @@ namespace Lidgren.Network
|
|||||||
Positive = 1
|
Positive = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#region Exception Messages
|
||||||
const string WouldReturnNegVal = "Operation would return a negative value";
|
const string WouldReturnNegVal = "Operation would return a negative value";
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
public BigInteger()
|
public BigInteger()
|
||||||
{
|
{
|
||||||
@@ -154,7 +176,9 @@ namespace Lidgren.Network
|
|||||||
this.length = DEFAULT_LEN;
|
this.length = DEFAULT_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public BigInteger(Sign sign, uint len)
|
public BigInteger(Sign sign, uint len)
|
||||||
{
|
{
|
||||||
this.data = new uint[len];
|
this.data = new uint[len];
|
||||||
@@ -167,7 +191,9 @@ namespace Lidgren.Network
|
|||||||
this.length = bi.length;
|
this.length = bi.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public BigInteger(BigInteger bi, uint len)
|
public BigInteger(BigInteger bi, uint len)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -179,6 +205,10 @@ namespace Lidgren.Network
|
|||||||
this.length = bi.length;
|
this.length = bi.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Conversions
|
||||||
|
|
||||||
public BigInteger(byte[] inData)
|
public BigInteger(byte[] inData)
|
||||||
{
|
{
|
||||||
length = (uint)inData.Length >> 2;
|
length = (uint)inData.Length >> 2;
|
||||||
@@ -209,7 +239,9 @@ namespace Lidgren.Network
|
|||||||
this.Normalize();
|
this.Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public BigInteger(uint[] inData)
|
public BigInteger(uint[] inData)
|
||||||
{
|
{
|
||||||
length = (uint)inData.Length;
|
length = (uint)inData.Length;
|
||||||
@@ -222,13 +254,17 @@ namespace Lidgren.Network
|
|||||||
this.Normalize();
|
this.Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public BigInteger(uint ui)
|
public BigInteger(uint ui)
|
||||||
{
|
{
|
||||||
data = new uint[] { ui };
|
data = new uint[] { ui };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public BigInteger(ulong ul)
|
public BigInteger(ulong ul)
|
||||||
{
|
{
|
||||||
data = new uint[2] { (uint)ul, (uint)(ul >> 32) };
|
data = new uint[2] { (uint)ul, (uint)(ul >> 32) };
|
||||||
@@ -237,7 +273,9 @@ namespace Lidgren.Network
|
|||||||
this.Normalize();
|
this.Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public static implicit operator BigInteger(uint value)
|
public static implicit operator BigInteger(uint value)
|
||||||
{
|
{
|
||||||
return (new BigInteger(value));
|
return (new BigInteger(value));
|
||||||
@@ -249,7 +287,9 @@ namespace Lidgren.Network
|
|||||||
return (new BigInteger((uint)value));
|
return (new BigInteger((uint)value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public static implicit operator BigInteger(ulong value)
|
public static implicit operator BigInteger(ulong value)
|
||||||
{
|
{
|
||||||
return (new BigInteger(value));
|
return (new BigInteger(value));
|
||||||
@@ -308,6 +348,10 @@ namespace Lidgren.Network
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Operators
|
||||||
|
|
||||||
public static BigInteger operator +(BigInteger bi1, BigInteger bi2)
|
public static BigInteger operator +(BigInteger bi1, BigInteger bi2)
|
||||||
{
|
{
|
||||||
if (bi1 == 0)
|
if (bi1 == 0)
|
||||||
@@ -413,6 +457,10 @@ namespace Lidgren.Network
|
|||||||
return Kernel.RightShift(bi1, shiftVal);
|
return Kernel.RightShift(bi1, shiftVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Friendly names for operators
|
||||||
|
|
||||||
// with names suggested by FxCop 1.30
|
// with names suggested by FxCop 1.30
|
||||||
|
|
||||||
public static BigInteger Add(BigInteger bi1, BigInteger bi2)
|
public static BigInteger Add(BigInteger bi1, BigInteger bi2)
|
||||||
@@ -425,6 +473,16 @@ namespace Lidgren.Network
|
|||||||
return (bi1 - bi2);
|
return (bi1 - bi2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BigInteger Modulus(BigInteger mod)
|
||||||
|
{
|
||||||
|
return BigInteger.Modulus(this, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigInteger Multiply(BigInteger mult)
|
||||||
|
{
|
||||||
|
return BigInteger.Multiply(this, mult);
|
||||||
|
}
|
||||||
|
|
||||||
public static int Modulus(BigInteger bi, int i)
|
public static int Modulus(BigInteger bi, int i)
|
||||||
{
|
{
|
||||||
return (bi % i);
|
return (bi % i);
|
||||||
@@ -462,7 +520,114 @@ namespace Lidgren.Network
|
|||||||
{
|
{
|
||||||
return (bi * i);
|
return (bi * i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Random
|
||||||
|
private static RandomNumberGenerator rng;
|
||||||
|
private static RandomNumberGenerator Rng
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (rng == null)
|
||||||
|
rng = RandomNumberGenerator.Create();
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a new, random BigInteger of the specified length.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bits">The number of bits for the new number.</param>
|
||||||
|
/// <param name="rng">A random number generator to use to obtain the bits.</param>
|
||||||
|
/// <returns>A random number of the specified length.</returns>
|
||||||
|
public static BigInteger GenerateRandom(int bits, RandomNumberGenerator rng)
|
||||||
|
{
|
||||||
|
int dwords = bits >> 5;
|
||||||
|
int remBits = bits & 0x1F;
|
||||||
|
|
||||||
|
if (remBits != 0)
|
||||||
|
dwords++;
|
||||||
|
|
||||||
|
BigInteger ret = new BigInteger(Sign.Positive, (uint)dwords + 1);
|
||||||
|
byte[] random = new byte[dwords << 2];
|
||||||
|
|
||||||
|
rng.GetBytes(random);
|
||||||
|
Buffer.BlockCopy(random, 0, ret.data, 0, (int)dwords << 2);
|
||||||
|
|
||||||
|
if (remBits != 0)
|
||||||
|
{
|
||||||
|
uint mask = (uint)(0x01 << (remBits - 1));
|
||||||
|
ret.data[dwords - 1] |= mask;
|
||||||
|
|
||||||
|
mask = (uint)(0xFFFFFFFF >> (32 - remBits));
|
||||||
|
ret.data[dwords - 1] &= mask;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret.data[dwords - 1] |= 0x80000000;
|
||||||
|
|
||||||
|
ret.Normalize();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a new, random BigInteger of the specified length using the default RNG crypto service provider.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bits">The number of bits for the new number.</param>
|
||||||
|
/// <returns>A random number of the specified length.</returns>
|
||||||
|
public static BigInteger GenerateRandom(int bits)
|
||||||
|
{
|
||||||
|
return GenerateRandom(bits, Rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Randomizes the bits in "this" from the specified RNG.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rng">A RNG.</param>
|
||||||
|
public void Randomize(RandomNumberGenerator rng)
|
||||||
|
{
|
||||||
|
if (this == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int bits = this.BitCount();
|
||||||
|
int dwords = bits >> 5;
|
||||||
|
int remBits = bits & 0x1F;
|
||||||
|
|
||||||
|
if (remBits != 0)
|
||||||
|
dwords++;
|
||||||
|
|
||||||
|
byte[] random = new byte[dwords << 2];
|
||||||
|
|
||||||
|
rng.GetBytes(random);
|
||||||
|
Buffer.BlockCopy(random, 0, data, 0, (int)dwords << 2);
|
||||||
|
|
||||||
|
if (remBits != 0)
|
||||||
|
{
|
||||||
|
uint mask = (uint)(0x01 << (remBits - 1));
|
||||||
|
data[dwords - 1] |= mask;
|
||||||
|
|
||||||
|
mask = (uint)(0xFFFFFFFF >> (32 - remBits));
|
||||||
|
data[dwords - 1] &= mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
data[dwords - 1] |= 0x80000000;
|
||||||
|
|
||||||
|
Normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Randomizes the bits in "this" from the default RNG.
|
||||||
|
/// </summary>
|
||||||
|
public void Randomize()
|
||||||
|
{
|
||||||
|
Randomize(Rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Bitwise
|
||||||
|
|
||||||
public int BitCount()
|
public int BitCount()
|
||||||
{
|
{
|
||||||
this.Normalize();
|
this.Normalize();
|
||||||
@@ -486,7 +651,9 @@ namespace Lidgren.Network
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bitNum">The bit to test. The least significant bit is 0.</param>
|
/// <param name="bitNum">The bit to test. The least significant bit is 0.</param>
|
||||||
/// <returns>True if bitNum is set to 1, else false.</returns>
|
/// <returns>True if bitNum is set to 1, else false.</returns>
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public bool TestBit(uint bitNum)
|
public bool TestBit(uint bitNum)
|
||||||
{
|
{
|
||||||
uint bytePos = bitNum >> 5; // divide by 32
|
uint bytePos = bitNum >> 5; // divide by 32
|
||||||
@@ -507,19 +674,25 @@ namespace Lidgren.Network
|
|||||||
return ((this.data[bytePos] | mask) == this.data[bytePos]);
|
return ((this.data[bytePos] | mask) == this.data[bytePos]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public void SetBit(uint bitNum)
|
public void SetBit(uint bitNum)
|
||||||
{
|
{
|
||||||
SetBit(bitNum, true);
|
SetBit(bitNum, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public void ClearBit(uint bitNum)
|
public void ClearBit(uint bitNum)
|
||||||
{
|
{
|
||||||
SetBit(bitNum, false);
|
SetBit(bitNum, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public void SetBit(uint bitNum, bool value)
|
public void SetBit(uint bitNum, bool value)
|
||||||
{
|
{
|
||||||
uint bytePos = bitNum >> 5; // divide by 32
|
uint bytePos = bitNum >> 5; // divide by 32
|
||||||
@@ -571,14 +744,22 @@ namespace Lidgren.Network
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Compare
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public static bool operator ==(BigInteger bi1, uint ui)
|
public static bool operator ==(BigInteger bi1, uint ui)
|
||||||
{
|
{
|
||||||
if (bi1.length != 1) bi1.Normalize();
|
if (bi1.length != 1) bi1.Normalize();
|
||||||
return bi1.length == 1 && bi1.data[0] == ui;
|
return bi1.length == 1 && bi1.data[0] == ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public static bool operator !=(BigInteger bi1, uint ui)
|
public static bool operator !=(BigInteger bi1, uint ui)
|
||||||
{
|
{
|
||||||
if (bi1.length != 1) bi1.Normalize();
|
if (bi1.length != 1) bi1.Normalize();
|
||||||
@@ -630,13 +811,21 @@ namespace Lidgren.Network
|
|||||||
return Kernel.Compare(this, bi);
|
return Kernel.Compare(this, bi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Formatting
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public string ToString(uint radix)
|
public string ToString(uint radix)
|
||||||
{
|
{
|
||||||
return ToString(radix, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
return ToString(radix, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public string ToString(uint radix, string characterSet)
|
public string ToString(uint radix, string characterSet)
|
||||||
{
|
{
|
||||||
if (characterSet.Length < radix)
|
if (characterSet.Length < radix)
|
||||||
@@ -660,6 +849,10 @@ namespace Lidgren.Network
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Misc
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Normalizes this by setting the length to the actual number of
|
/// Normalizes this by setting the length to the actual number of
|
||||||
/// uints used in data and by setting the sign to Sign.Zero if the
|
/// uints used in data and by setting the sign to Sign.Zero if the
|
||||||
@@ -681,6 +874,10 @@ namespace Lidgren.Network
|
|||||||
data[i] = 0x00;
|
data[i] = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Object Impl
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
uint val = 0;
|
uint val = 0;
|
||||||
@@ -704,6 +901,10 @@ namespace Lidgren.Network
|
|||||||
return Kernel.Compare(this, (BigInteger)o) == 0;
|
return Kernel.Compare(this, (BigInteger)o) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Number Theory
|
||||||
|
|
||||||
public BigInteger GCD(BigInteger bi)
|
public BigInteger GCD(BigInteger bi)
|
||||||
{
|
{
|
||||||
return Kernel.gcd(this, bi);
|
return Kernel.gcd(this, bi);
|
||||||
@@ -720,8 +921,17 @@ namespace Lidgren.Network
|
|||||||
return mr.Pow(this, exp);
|
return mr.Pow(this, exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ModulusRing
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#if INSIDE_CORLIB
|
||||||
|
internal
|
||||||
|
#else
|
||||||
|
public
|
||||||
|
#endif
|
||||||
|
sealed class ModulusRing
|
||||||
{
|
{
|
||||||
|
|
||||||
BigInteger mod, constant;
|
BigInteger mod, constant;
|
||||||
|
|
||||||
public ModulusRing(BigInteger modulus)
|
public ModulusRing(BigInteger modulus)
|
||||||
@@ -922,10 +1132,13 @@ namespace Lidgren.Network
|
|||||||
return resultNum;
|
return resultNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Pow Small Base
|
||||||
|
|
||||||
// TODO: Make tests for this, not really needed b/c prime stuff
|
// TODO: Make tests for this, not really needed b/c prime stuff
|
||||||
// checks it, but still would be nice
|
// checks it, but still would be nice
|
||||||
|
#if !INSIDE_CORLIB
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
|
#endif
|
||||||
public BigInteger Pow(uint b, BigInteger exp)
|
public BigInteger Pow(uint b, BigInteger exp)
|
||||||
{
|
{
|
||||||
// if (b != 2) {
|
// if (b != 2) {
|
||||||
@@ -1180,6 +1393,142 @@ namespace Lidgren.Network
|
|||||||
|
|
||||||
return resultNum;
|
return resultNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* known to be buggy in some cases
|
||||||
|
private unsafe BigInteger EvenModTwoPow (BigInteger exp)
|
||||||
|
{
|
||||||
|
exp.Normalize ();
|
||||||
|
uint [] wkspace = new uint [mod.length << 1 + 1];
|
||||||
|
|
||||||
|
BigInteger resultNum = new BigInteger (2, mod.length << 1 +1);
|
||||||
|
|
||||||
|
uint value = exp.data [exp.length - 1];
|
||||||
|
uint mask = 0x80000000;
|
||||||
|
|
||||||
|
// Find the first bit of the exponent
|
||||||
|
while ((value & mask) == 0)
|
||||||
|
mask >>= 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// We know that the first itr will make the val 2,
|
||||||
|
// so eat one bit of the exponent
|
||||||
|
//
|
||||||
|
mask >>= 1;
|
||||||
|
|
||||||
|
uint wPos = exp.length - 1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
value = exp.data [wPos];
|
||||||
|
do {
|
||||||
|
Kernel.SquarePositive (resultNum, ref wkspace);
|
||||||
|
if (resultNum.length >= mod.length)
|
||||||
|
BarrettReduction (resultNum);
|
||||||
|
|
||||||
|
if ((value & mask) != 0) {
|
||||||
|
//
|
||||||
|
// resultNum = (resultNum * 2) % mod
|
||||||
|
//
|
||||||
|
|
||||||
|
fixed (uint* u = resultNum.data) {
|
||||||
|
//
|
||||||
|
// Double
|
||||||
|
//
|
||||||
|
uint* uu = u;
|
||||||
|
uint* uuE = u + resultNum.length;
|
||||||
|
uint x, carry = 0;
|
||||||
|
while (uu < uuE) {
|
||||||
|
x = *uu;
|
||||||
|
*uu = (x << 1) | carry;
|
||||||
|
carry = x >> (32 - 1);
|
||||||
|
uu++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// subtraction inlined because we know it is square
|
||||||
|
if (carry != 0 || resultNum >= mod) {
|
||||||
|
uu = u;
|
||||||
|
uint c = 0;
|
||||||
|
uint [] s = mod.data;
|
||||||
|
uint i = 0;
|
||||||
|
do {
|
||||||
|
uint a = s [i];
|
||||||
|
if (((a += c) < c) | ((* (uu++) -= a) > ~a))
|
||||||
|
c = 1;
|
||||||
|
else
|
||||||
|
c = 0;
|
||||||
|
i++;
|
||||||
|
} while (uu < uuE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while ((mask >>= 1) > 0);
|
||||||
|
mask = 0x80000000;
|
||||||
|
} while (wPos-- > 0);
|
||||||
|
|
||||||
|
return resultNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
private unsafe BigInteger OddModTwoPow (BigInteger exp)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint [] wkspace = new uint [mod.length << 1 + 1];
|
||||||
|
|
||||||
|
BigInteger resultNum = Montgomery.ToMont ((BigInteger)2, this.mod);
|
||||||
|
resultNum = new BigInteger (resultNum, mod.length << 1 +1);
|
||||||
|
|
||||||
|
uint mPrime = Montgomery.Inverse (mod.data [0]);
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: eat small bits, the ones we can do with no modular reduction
|
||||||
|
//
|
||||||
|
uint pos = (uint)exp.BitCount () - 2;
|
||||||
|
|
||||||
|
do {
|
||||||
|
Kernel.SquarePositive (resultNum, ref wkspace);
|
||||||
|
resultNum = Montgomery.Reduce (resultNum, mod, mPrime);
|
||||||
|
|
||||||
|
if (exp.TestBit (pos)) {
|
||||||
|
//
|
||||||
|
// resultNum = (resultNum * 2) % mod
|
||||||
|
//
|
||||||
|
|
||||||
|
fixed (uint* u = resultNum.data) {
|
||||||
|
//
|
||||||
|
// Double
|
||||||
|
//
|
||||||
|
uint* uu = u;
|
||||||
|
uint* uuE = u + resultNum.length;
|
||||||
|
uint x, carry = 0;
|
||||||
|
while (uu < uuE) {
|
||||||
|
x = *uu;
|
||||||
|
*uu = (x << 1) | carry;
|
||||||
|
carry = x >> (32 - 1);
|
||||||
|
uu++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// subtraction inlined because we know it is square
|
||||||
|
if (carry != 0 || resultNum >= mod) {
|
||||||
|
fixed (uint* s = mod.data) {
|
||||||
|
uu = u;
|
||||||
|
uint c = 0;
|
||||||
|
uint* ss = s;
|
||||||
|
do {
|
||||||
|
uint a = *ss++;
|
||||||
|
if (((a += c) < c) | ((* (uu++) -= a) > ~a))
|
||||||
|
c = 1;
|
||||||
|
else
|
||||||
|
c = 0;
|
||||||
|
} while (uu < uuE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (pos-- > 0);
|
||||||
|
|
||||||
|
resultNum = Montgomery.Reduce (resultNum, mod, mPrime);
|
||||||
|
return resultNum;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class Montgomery
|
internal sealed class Montgomery
|
||||||
@@ -1266,13 +1615,22 @@ namespace Lidgren.Network
|
|||||||
|
|
||||||
return A;
|
return A;
|
||||||
}
|
}
|
||||||
|
#if _NOT_USED_
|
||||||
|
public static BigInteger Reduce (BigInteger n, BigInteger m)
|
||||||
|
{
|
||||||
|
return Reduce (n, m, Inverse (m.data [0]));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Low level functions for the BigInteger
|
/// Low level functions for the BigInteger
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static class Kernel
|
private sealed class Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#region Addition/Subtraction
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds two numbers with the same sign.
|
/// Adds two numbers with the same sign.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1488,6 +1846,10 @@ namespace Lidgren.Network
|
|||||||
bi1.Normalize();
|
bi1.Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Compare
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Compares two BigInteger
|
/// Compares two BigInteger
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1527,6 +1889,12 @@ namespace Lidgren.Network
|
|||||||
return Sign.Zero;
|
return Sign.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Division
|
||||||
|
|
||||||
|
#region Dword
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs n / d and n % d in one operation.
|
/// Performs n / d and n % d in one operation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1605,6 +1973,10 @@ namespace Lidgren.Network
|
|||||||
return new BigInteger[] { ret, rem };
|
return new BigInteger[] { ret, rem };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region BigNum
|
||||||
|
|
||||||
public static BigInteger[] multiByteDivide(BigInteger bi1, BigInteger bi2)
|
public static BigInteger[] multiByteDivide(BigInteger bi1, BigInteger bi2)
|
||||||
{
|
{
|
||||||
if (Kernel.Compare(bi1, bi2) == Sign.Negative)
|
if (Kernel.Compare(bi1, bi2) == Sign.Negative)
|
||||||
@@ -1720,6 +2092,11 @@ namespace Lidgren.Network
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Shift
|
||||||
public static BigInteger LeftShift(BigInteger bi, int n)
|
public static BigInteger LeftShift(BigInteger bi, int n)
|
||||||
{
|
{
|
||||||
if (n == 0) return new BigInteger(bi, bi.length + 1);
|
if (n == 0) return new BigInteger(bi, bi.length + 1);
|
||||||
@@ -1787,6 +2164,10 @@ namespace Lidgren.Network
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Multiply
|
||||||
|
|
||||||
public static BigInteger MultiplyByDword(BigInteger n, uint f)
|
public static BigInteger MultiplyByDword(BigInteger n, uint f)
|
||||||
{
|
{
|
||||||
BigInteger ret = new BigInteger(Sign.Positive, n.length + 1);
|
BigInteger ret = new BigInteger(Sign.Positive, n.length + 1);
|
||||||
@@ -1992,6 +2373,10 @@ namespace Lidgren.Network
|
|||||||
return carry != 0;
|
return carry != 0;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Number Theory
|
||||||
|
|
||||||
public static BigInteger gcd(BigInteger a, BigInteger b)
|
public static BigInteger gcd(BigInteger a, BigInteger b)
|
||||||
{
|
{
|
||||||
BigInteger x = a;
|
BigInteger x = a;
|
||||||
@@ -2100,7 +2485,9 @@ namespace Lidgren.Network
|
|||||||
throw (new ArithmeticException("No inverse!"));
|
throw (new ArithmeticException("No inverse!"));
|
||||||
|
|
||||||
return mr.Difference(p[0], p[1] * q[0]);
|
return mr.Difference(p[0], p[1] * q[0]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
3158
Lidgren.Network/NetBigIntegerBC.cs
Normal file
3158
Lidgren.Network/NetBigIntegerBC.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -166,13 +166,14 @@ namespace Lidgren.Network
|
|||||||
string one = NetUtility.ToHexString(N.GetBytes());
|
string one = NetUtility.ToHexString(N.GetBytes());
|
||||||
string two = NetUtility.ToHexString(g.GetBytes());
|
string two = NetUtility.ToHexString(g.GetBytes());
|
||||||
byte[] cc = NetUtility.ToByteArray(one + two.PadLeft(one.Length, '0'));
|
byte[] cc = NetUtility.ToByteArray(one + two.PadLeft(one.Length, '0'));
|
||||||
return BigInteger.Modulus(new BigInteger(NetSha.Hash(cc)), N);
|
BigInteger retval = BigInteger.Modulus(new BigInteger(NetSha.Hash(cc)), N);
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a verifier that the server can use to authenticate users later on (v)
|
/// Creates a verifier that the server can use to authenticate users later on (v)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static byte[] ComputePasswordVerifier(string username, string password, byte[] salt, out byte[] x)
|
public static void ComputePasswordVerifier(string username, string password, byte[] salt, out byte[] serverVerifier, out byte[] clientVerifier)
|
||||||
{
|
{
|
||||||
byte[] tmp = Encoding.ASCII.GetBytes(username + ":" + password);
|
byte[] tmp = Encoding.ASCII.GetBytes(username + ":" + password);
|
||||||
byte[] innerHash = NetSha.Hash(tmp);
|
byte[] innerHash = NetSha.Hash(tmp);
|
||||||
@@ -181,38 +182,59 @@ namespace Lidgren.Network
|
|||||||
Buffer.BlockCopy(salt, 0, total, 0, salt.Length);
|
Buffer.BlockCopy(salt, 0, total, 0, salt.Length);
|
||||||
Buffer.BlockCopy(innerHash, 0, total, salt.Length, innerHash.Length);
|
Buffer.BlockCopy(innerHash, 0, total, salt.Length, innerHash.Length);
|
||||||
|
|
||||||
x = NetSha.Hash(total);
|
clientVerifier = NetSha.Hash(total);
|
||||||
|
|
||||||
// Verifier (v) = g^x (mod N)
|
// Verifier (v) = g^x (mod N)
|
||||||
BigInteger xx = new BigInteger(x);
|
BigInteger xx = new BigInteger(clientVerifier);
|
||||||
return g.ModPow(xx, N).GetBytes();
|
serverVerifier = g.ModPow(xx, N).GetBytes();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get 256 random bits
|
/// Get 256 random bits
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static byte[] CreateRandomChallenge()
|
public static byte[] CreateRandomKey()
|
||||||
{
|
{
|
||||||
byte[] retval = new byte[32];
|
byte[] retval = new byte[32];
|
||||||
NetRandom.Instance.NextBytes(retval);
|
NetRandom.Instance.NextBytes(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets 80 random bits
|
||||||
|
/// </summary>
|
||||||
|
public static byte[] CreateRandomSalt()
|
||||||
|
{
|
||||||
|
byte[] retval = new byte[10];
|
||||||
|
NetRandom.Instance.NextBytes(retval);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Compute client challenge (A)
|
/// Compute client challenge (A)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static byte[] ComputeClientChallenge(byte[] clientSalt) // a
|
public static byte[] ComputeClientPublicKey(byte[] clientPrivateKey) // a
|
||||||
{
|
{
|
||||||
BigInteger salt = new BigInteger(clientSalt);
|
BigInteger salt = new BigInteger(clientPrivateKey);
|
||||||
return g.ModPow(salt, N).GetBytes();
|
|
||||||
|
BigInteger retval = g.ModPow(salt, N);
|
||||||
|
|
||||||
|
string gs = NetUtility.ToHexString(g.GetBytes());
|
||||||
|
|
||||||
|
|
||||||
|
Console.WriteLine("SALT: " + NetUtility.ToHexString(salt.GetBytes()));
|
||||||
|
Console.WriteLine("A: " + NetUtility.ToHexString(retval.GetBytes()));
|
||||||
|
|
||||||
|
return retval.GetBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Compute server challenge (B)
|
/// Compute server challenge (B)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static byte[] ComputeServerChallenge(byte[] serverSalt, byte[] verifier) // b
|
public static byte[] ComputeServerPublicKey(byte[] serverPrivateKey, byte[] verifier) // b
|
||||||
{
|
{
|
||||||
BigInteger salt = new BigInteger(serverSalt);
|
BigInteger salt = new BigInteger(serverPrivateKey);
|
||||||
|
|
||||||
var bb = g.ModPow(salt, N);
|
var bb = g.ModPow(salt, N);
|
||||||
var B = BigInteger.Modulus((bb + (new BigInteger(verifier) * k)), N);
|
var B = BigInteger.Modulus((bb + (new BigInteger(verifier) * k)), N);
|
||||||
@@ -220,10 +242,10 @@ namespace Lidgren.Network
|
|||||||
return B.GetBytes();
|
return B.GetBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] ComputeU(byte[] clientChallenge, byte[] serverChallenge)
|
public static byte[] ComputeU(byte[] clientPublicKey, byte[] serverPublicKey) // u
|
||||||
{
|
{
|
||||||
byte[] A = clientChallenge;
|
byte[] A = clientPublicKey;
|
||||||
byte[] B = serverChallenge;
|
byte[] B = serverPublicKey;
|
||||||
|
|
||||||
string one = NetUtility.ToHexString(A);
|
string one = NetUtility.ToHexString(A);
|
||||||
string two = NetUtility.ToHexString(B);
|
string two = NetUtility.ToHexString(B);
|
||||||
@@ -232,141 +254,75 @@ namespace Lidgren.Network
|
|||||||
byte[] cc = NetUtility.ToByteArray(compound);
|
byte[] cc = NetUtility.ToByteArray(compound);
|
||||||
|
|
||||||
return NetSha.Hash(cc);
|
return NetSha.Hash(cc);
|
||||||
|
|
||||||
//byte[] res = NetSha.Hash(cc);
|
|
||||||
//var resbig = new BigInteger(res);
|
|
||||||
//return BigInteger.Modulus(resbig, N).GetBytes();
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* SRP-3: u = first 32 bits (MSB) of SHA-1(B)
|
|
||||||
* SRP-6(a): u = SHA-1(A || B)
|
|
||||||
function srp_compute_u(Nv, av, bv) {
|
|
||||||
var ahex;
|
|
||||||
var bhex = String(bigInt2radix(bv, 16));
|
|
||||||
var hashin = "";
|
|
||||||
var utmp;
|
|
||||||
var nlen;
|
|
||||||
if(proto != "3") {
|
|
||||||
ahex = String(bigInt2radix(av, 16));
|
|
||||||
if(proto == "6") {
|
|
||||||
if((ahex.length & 1) == 0) {
|
|
||||||
hashin += ahex;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
hashin += "0" + ahex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { // 6a requires left-padding
|
|
||||||
nlen = 2 * ((Nv.bitLength() + 7) >> 3);
|
|
||||||
hashin += nzero(nlen - ahex.length) + ahex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(proto == "3" || proto == "6") {
|
|
||||||
if((bhex.length & 1) == 0) {
|
|
||||||
hashin += bhex;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
hashin += "0" + bhex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { // 6a requires left-padding; nlen already set above
|
|
||||||
hashin += nzero(nlen - bhex.length) + bhex;
|
|
||||||
}
|
|
||||||
if(proto == "3") {
|
|
||||||
utmp = parseBigInt(calcSHA1Hex(hashin).substr(0, 8), 16);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
utmp = parseBigInt(calcSHA1Hex(hashin), 16);
|
|
||||||
}
|
|
||||||
if(utmp.compareTo(Nv) < 0) {
|
|
||||||
return utmp;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return utmp.mod(Nv.subtract(one));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
public static byte[] ComputeServerSessionKey(byte[] clientPublicKey, byte[] verifier, byte[] u, byte[] serverPrivateKey) // Ss
|
||||||
public static byte[] ComputeClientToken(byte[] serverChallenge, byte[] x, byte[] u)
|
|
||||||
{
|
|
||||||
|
|
||||||
// S = (B - kg^x) ^ (a + ux) (mod N)
|
|
||||||
function srp_compute_client_S(BB, xx, uu, aa, kk) {
|
|
||||||
var bx = g.modPow(xx, N);
|
|
||||||
var btmp = BB.add(N.multiply(kk)).subtract(bx.multiply(kk)).mod(N);
|
|
||||||
return btmp.modPow(xx.multiply(uu).add(aa), N);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static byte[] ComputeServerToken(byte[] clientChallenge, byte[] verifier, byte[] u, byte[] serverChallengeSalt)
|
|
||||||
{
|
|
||||||
// S = (Av^u) ^ b (mod N)
|
|
||||||
// function srp_compute_server_S(AA, vv, uu, bb) {
|
|
||||||
|
|
||||||
BigInteger vv = new BigInteger(verifier);
|
|
||||||
|
|
||||||
BigInteger c1 = vv.ModPow(new BigInteger(u), N);
|
|
||||||
BigInteger c2 = new BigInteger(clientChallenge);
|
|
||||||
|
|
||||||
BigInteger r1 = c1 * c2;
|
|
||||||
|
|
||||||
BigInteger r2 = BigInteger.Modulus(r1, N);
|
|
||||||
|
|
||||||
return r2.ModPow(new BigInteger(serverChallengeSalt), N).GetBytes();
|
|
||||||
//return vv.modPow(uu, N).multiply(A).mod(N).modPow(bb, N);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] ComputeServerCompareValue(byte[] A, byte[] verifier, byte[] u, byte[] b)
|
|
||||||
{
|
{
|
||||||
// S = (Av^u) ^ b (mod N)
|
// S = (Av^u) ^ b (mod N)
|
||||||
|
// return vv.modPow(uu, N).multiply(A).mod(N).modPow(bb, N);
|
||||||
|
|
||||||
BigInteger verBi = new BigInteger(verifier);
|
BigInteger verBi = new BigInteger(verifier);
|
||||||
BigInteger uBi = new BigInteger(u);
|
BigInteger uBi = new BigInteger(u);
|
||||||
BigInteger ABi = new BigInteger(A);
|
BigInteger ABi = new BigInteger(clientPublicKey); // A
|
||||||
BigInteger bBi = new BigInteger(b);
|
BigInteger bBi = new BigInteger(serverPrivateKey); // b
|
||||||
|
|
||||||
BigInteger res1 = verBi.ModPow(uBi, N);
|
Console.WriteLine("Ss input v: " + NetUtility.ToHexString(verifier));
|
||||||
BigInteger res2 = BigInteger.Multiply(res1, ABi);
|
Console.WriteLine("Ss input u: " + NetUtility.ToHexString(u));
|
||||||
BigInteger res3 = BigInteger.Modulus(res2, N);
|
Console.WriteLine("Ss input A: " + NetUtility.ToHexString(clientPublicKey));
|
||||||
BigInteger res4 = res3.ModPow(bBi, N);
|
Console.WriteLine("Ss input A: " + ABi.ToString(16));
|
||||||
|
Console.WriteLine("Ss input b: " + NetUtility.ToHexString(serverPrivateKey));
|
||||||
|
|
||||||
return res4.GetBytes();
|
BigInteger retval = verBi.ModPow(uBi, N).Multiply(ABi).Modulus(N).ModPow(bBi, N).Modulus(N);
|
||||||
}
|
Console.WriteLine("Ss (trad): " + NetUtility.ToHexString(retval.GetBytes()));
|
||||||
|
BigInteger f1 = verBi.ModPow(uBi, N);
|
||||||
|
Console.WriteLine("f1 (trad): " + NetUtility.ToHexString(f1.GetBytes()));
|
||||||
|
|
||||||
public static byte[] ComputeClientCompareValue(byte[] B, byte[] x, byte[] u, byte[] A)
|
//return retval.GetBytes();
|
||||||
{
|
|
||||||
// S = (B - kg^x) ^ (a + ux) (mod N)
|
|
||||||
BigInteger xBi = new BigInteger(x);
|
|
||||||
BigInteger BBi = new BigInteger(B);
|
|
||||||
BigInteger uBi = new BigInteger(u);
|
|
||||||
BigInteger ABi = new BigInteger(A);
|
|
||||||
|
|
||||||
|
|
||||||
//var btmp = BB.add(N.multiply(kk)).subtract(bx.multiply(kk)).mod(N);
|
// own
|
||||||
|
// BigInteger tmp1 = verBi.ModPow(uBi, N).ModPow(bBi, N).Modulus(N);
|
||||||
|
BigInteger tmp1 = (ABi * verBi.ModPow(uBi, N)).ModPow(bBi, N);
|
||||||
|
Console.WriteLine("Ss (own): " + NetUtility.ToHexString(tmp1.GetBytes()));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// bc
|
||||||
|
BigIntegerBC verBi2 = new BigIntegerBC(verifier);
|
||||||
|
BigIntegerBC ABi2 = new BigIntegerBC(clientPublicKey); // A
|
||||||
|
BigIntegerBC uBi2 = new BigIntegerBC(u);
|
||||||
|
BigIntegerBC bBi2 = new BigIntegerBC(serverPrivateKey);
|
||||||
|
BigIntegerBC N2 = new BigIntegerBC(N.GetBytes());
|
||||||
|
|
||||||
|
BigIntegerBC retval2 = verBi2.ModPow(uBi2, N2).Multiply(ABi2).Modulus(N2).ModPow(bBi2, N2).Modulus(N2);
|
||||||
|
Console.WriteLine("Ss (bc): " + NetUtility.ToHexString(retval2.ToByteArray()));
|
||||||
|
BigIntegerBC f12 = verBi2.ModPow(uBi2, N2);
|
||||||
|
Console.WriteLine("f1 (bc): " + NetUtility.ToHexString(f12.ToByteArray()));
|
||||||
|
|
||||||
//return btmp.modPow(xx.multiply(uu).add(aa), N);
|
|
||||||
|
// own bc
|
||||||
|
BigIntegerBC tmp2 = verBi2.ModPow(uBi2, N2).ModPow(bBi2, N2).Modulus(N2);
|
||||||
|
Console.WriteLine("Ss (ownBC): " + NetUtility.ToHexString(tmp2.ToByteArray()));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BigInteger bx = g.ModPow(xBi, N);
|
return retval.GetBytes();
|
||||||
|
|
||||||
BigInteger res1 = BigInteger.Multiply(N, k);
|
//return NetSha.Hash(retval.GetBytes());
|
||||||
BigInteger btmp1 = BigInteger.Add(BBi, res1);
|
|
||||||
|
|
||||||
BigInteger res2 = BigInteger.Multiply(bx, k);
|
|
||||||
BigInteger res3 = BigInteger.Subtract(btmp1, res2);
|
|
||||||
BigInteger btmp = BigInteger.Modulus(res3, N);
|
|
||||||
|
|
||||||
BigInteger res5 = BigInteger.Multiply(xBi, uBi);
|
|
||||||
BigInteger res6 = BigInteger.Add(res5, ABi);
|
|
||||||
|
|
||||||
return btmp.ModPow(res6, N).GetBytes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] ComputeClientSessionKey(byte[] serverPublicKey, byte[] x, byte[] u, byte[] clientPrivateKey) // Sc
|
||||||
|
{
|
||||||
|
BigInteger xBi = new BigInteger(x);
|
||||||
|
BigInteger BBi = new BigInteger(serverPublicKey); // B
|
||||||
|
BigInteger uBi = new BigInteger(u);
|
||||||
|
BigInteger aBi = new BigInteger(clientPrivateKey); // a
|
||||||
|
|
||||||
|
BigInteger retval = (BBi + (N - ((k * g.ModPow(xBi, N)) % N))).ModPow(aBi + uBi * xBi, N);
|
||||||
|
|
||||||
|
return retval.GetBytes();
|
||||||
|
|
||||||
|
//return NetSha.Hash(retval.GetBytes());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ namespace Lidgren.Network
|
|||||||
|
|
||||||
m_listenPort = boundEp.Port;
|
m_listenPort = boundEp.Port;
|
||||||
|
|
||||||
long first = (pa == null ? (long)0 : (long)pa.GetHashCode());
|
long first = (pa == null ? (long)this.GetHashCode() : (long)pa.GetHashCode());
|
||||||
long second = (long)((long)boundEp.GetHashCode() << 32);
|
long second = (long)((long)boundEp.GetHashCode() << 32);
|
||||||
m_uniqueIdentifier = first ^ second;
|
m_uniqueIdentifier = first ^ second;
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Lidgren.Network
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Thread safe (blocking) queue with TryDequeue() and EnqueueFirst()
|
/// Thread safe (blocking) queue with TryDequeue() and EnqueueFirst()
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerDisplay("Count={m_size}")]
|
[DebuggerDisplay("Count={Count} Capacity={Capacity}")]
|
||||||
public sealed class NetQueue<T>
|
public sealed class NetQueue<T>
|
||||||
{
|
{
|
||||||
// Example:
|
// Example:
|
||||||
@@ -49,6 +49,8 @@ namespace Lidgren.Network
|
|||||||
|
|
||||||
public int Count { get { return m_size; } }
|
public int Count { get { return m_size; } }
|
||||||
|
|
||||||
|
public int Capacity { get { return m_items.Length; } }
|
||||||
|
|
||||||
public NetQueue(int initialCapacity)
|
public NetQueue(int initialCapacity)
|
||||||
{
|
{
|
||||||
m_lock = new object();
|
m_lock = new object();
|
||||||
|
|||||||
@@ -58,20 +58,22 @@ namespace UnitTests
|
|||||||
|
|
||||||
Console.WriteLine("Message encryption OK");
|
Console.WriteLine("Message encryption OK");
|
||||||
|
|
||||||
byte[] salt = NetUtility.ToByteArray("47d980ce4c2333b6ce5b"); // s
|
/*
|
||||||
byte[] x;
|
Console.WriteLine("x = " + NetUtility.ToHexString(x));
|
||||||
byte[] verifier = NetSRP.ComputePasswordVerifier("user", "password", salt, out x);
|
|
||||||
|
|
||||||
Console.WriteLine("v = " + NetUtility.ToHexString(verifier));
|
Console.WriteLine("v = " + NetUtility.ToHexString(verifier));
|
||||||
|
Console.WriteLine("");
|
||||||
|
|
||||||
byte[] a = NetUtility.ToByteArray("94f5a7f6875df8b569840a917b918c84aa002b145e24e77dabdd3941de82e6f5");
|
byte[] a = NetUtility.ToByteArray("d378cc3b09d12cfca5130e22df3f2f3bcf8ecfaddeae6af7f8b3e9f8b4fc9749"); // random
|
||||||
|
Console.WriteLine("a = " + NetUtility.ToHexString(a));
|
||||||
byte[] A = NetSRP.ComputeClientChallenge(a);
|
byte[] A = NetSRP.ComputeClientChallenge(a);
|
||||||
Console.WriteLine("A = " + NetUtility.ToHexString(A));
|
Console.WriteLine("A = " + NetUtility.ToHexString(A));
|
||||||
|
Console.WriteLine("");
|
||||||
|
|
||||||
byte[] b = NetUtility.ToByteArray("a4ae167ba24c498a52d9a6963c285bb999246d3ce4c5e1028be5206809611358");
|
byte[] b = NetUtility.ToByteArray("8394bdaebe1709124f4c1221707053440b30e270d457ece02818da63b53c2482"); // random
|
||||||
Console.WriteLine("b = " + NetUtility.ToHexString(b));
|
Console.WriteLine("b = " + NetUtility.ToHexString(b));
|
||||||
byte[] B = NetSRP.ComputeServerChallenge(b, verifier);
|
byte[] B = NetSRP.ComputeServerChallenge(b, verifier);
|
||||||
Console.WriteLine("B = " + NetUtility.ToHexString(B));
|
Console.WriteLine("B = " + NetUtility.ToHexString(B));
|
||||||
|
Console.WriteLine("");
|
||||||
|
|
||||||
byte[] u = NetSRP.ComputeU(A, B);
|
byte[] u = NetSRP.ComputeU(A, B);
|
||||||
Console.WriteLine("u = " + NetUtility.ToHexString(u));
|
Console.WriteLine("u = " + NetUtility.ToHexString(u));
|
||||||
@@ -81,8 +83,63 @@ namespace UnitTests
|
|||||||
Console.WriteLine("Ss = " + NetUtility.ToHexString(serverCompareValue));
|
Console.WriteLine("Ss = " + NetUtility.ToHexString(serverCompareValue));
|
||||||
|
|
||||||
byte[] clientCompareValue; // Ss
|
byte[] clientCompareValue; // Ss
|
||||||
clientCompareValue = NetSRP.ComputeClientCompareValue(B, x, u, A);
|
clientCompareValue = NetSRP.ComputeClientCompareValue(B, x, u, a);
|
||||||
Console.WriteLine("Sc = " + NetUtility.ToHexString(clientCompareValue));
|
Console.WriteLine("Sc = " + NetUtility.ToHexString(clientCompareValue));
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Pre-step:
|
||||||
|
//
|
||||||
|
// Server must store { Username, salt, verifier }
|
||||||
|
//byte[] salt = NetSRP.CreateRandomSalt();
|
||||||
|
byte[] salt = NetUtility.ToByteArray("D016E5A43F0E2A1C8FF8");
|
||||||
|
Console.WriteLine("s = " + NetUtility.ToHexString(salt));
|
||||||
|
byte[] serverVerifier;
|
||||||
|
byte[] clientVerifier;
|
||||||
|
NetSRP.ComputePasswordVerifier("user", "password", salt, out serverVerifier, out clientVerifier);
|
||||||
|
//
|
||||||
|
Console.WriteLine("x = " + NetUtility.ToHexString(clientVerifier));
|
||||||
|
Console.WriteLine("v = " + NetUtility.ToHexString(serverVerifier));
|
||||||
|
|
||||||
|
// CLIENT:
|
||||||
|
// Step 1: Client creates session private/public key pair
|
||||||
|
//byte[] clientPrivateKey = NetSRP.CreateRandomKey();
|
||||||
|
byte[] clientPrivateKey = NetUtility.ToByteArray("EFDBE24D15173DC1FBA22A8D51077AE932841CB2DBA8B09B2CFC5543983B2C7A");
|
||||||
|
Console.WriteLine("a = " + NetUtility.ToHexString(clientPrivateKey));
|
||||||
|
byte[] clientPublicKey = NetSRP.ComputeClientPublicKey(clientPrivateKey);
|
||||||
|
// Step 2: Client sends username and client public key to server
|
||||||
|
|
||||||
|
// SERVER:
|
||||||
|
// Step 3: Server creates session private/public key pair
|
||||||
|
//byte[] serverPrivateKey = NetSRP.CreateRandomKey();
|
||||||
|
byte[] serverPrivateKey = NetUtility.ToByteArray("FB1D472CD89EAF323DB0F7DE80A01CC51DD5A0D1AFC8B79F3CF5A2FC88529ADC");
|
||||||
|
Console.WriteLine("b = " + NetUtility.ToHexString(serverPrivateKey));
|
||||||
|
byte[] serverPublicKey = NetSRP.ComputeServerPublicKey(serverPrivateKey, serverVerifier);
|
||||||
|
// Step 4: Server sends salt and server public key to client
|
||||||
|
|
||||||
|
// CLIENT:
|
||||||
|
// Step 5: Client computes u and compare value
|
||||||
|
byte[] u = NetSRP.ComputeU(clientPublicKey, serverPublicKey);
|
||||||
|
Console.WriteLine("u = " + NetUtility.ToHexString(u));
|
||||||
|
byte[] clientSessionKey = NetSRP.ComputeClientSessionKey(serverPublicKey, clientVerifier, u, clientPrivateKey); // this is where client proves it has x (and thus the password)
|
||||||
|
Console.WriteLine("Sc = " + NetUtility.ToHexString(clientSessionKey));
|
||||||
|
|
||||||
|
// SERVER:
|
||||||
|
// Step 6: Server computes u and compare value
|
||||||
|
// byte[] u = NetSRP.ComputeU(clientPublicKey, serverPublicKey);
|
||||||
|
byte[] serverSessionKey = NetSRP.ComputeServerSessionKey(clientPublicKey, serverVerifier, u, serverPrivateKey);
|
||||||
|
Console.WriteLine("Ss = " + NetUtility.ToHexString(serverSessionKey));
|
||||||
|
|
||||||
|
if (!NetUtility.CompareElements(clientSessionKey, serverSessionKey))
|
||||||
|
Console.WriteLine("BAD!!!!!!!");
|
||||||
|
|
||||||
|
// Console.WriteLine("SRP test OK");
|
||||||
|
/*
|
||||||
|
C ==> S C, A
|
||||||
|
C <== S s, B
|
||||||
|
C ==> S M[1]
|
||||||
|
C <== S M[2]
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user