Skip to content

Instantly share code, notes, and snippets.

@nathan130200
Last active July 12, 2021 14:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nathan130200/6a091a2a9abf4dfe013e4ee09e97c4ec to your computer and use it in GitHub Desktop.
Save nathan130200/6a091a2a9abf4dfe013e4ee09e97c4ec to your computer and use it in GitHub Desktop.
Diffie Hellman - Prototype Test of DH Key Exchange Generator
Test #1 : K=c9de2dd7cd18e827cb6ffd1c6477952ec7df244c274682f7dc36e61e529fd426 (size=32)
Test #2 : K=8d1bc01e471bd1d5372d6db3b3ff618ab359733d9d167583d204ef717d98c914 (size=32)
Test #3 : K=6e331952ee6337a27cc41abd928f7fb888d8fa569bc08ca4dc2c63be26e7f10f (size=32)
Test #4 : K=18a0e3236fa77dd3b7fa0e6715f64a67bce9e3eda97b04230370180fd2cc7a29 (size=32)
Test #5 : K=0124b3721868ecad0af3b867b551312bc3fef6cc37dc48a994fef69dd12f0f42 (size=32)
Test #6 : K=344c3acbf3676e9d0024a0b789c79004c0165b4ea8f8970d86d0b744b65c072e (size=32)
Test #7 : K=20c5b769797710c4c3ccacce9c99e6cbede817bd830d8f5652f3c0a41fdf8458 (size=32)
Test #8 : K=4015e33df9ea5226b37eabe4fd7aec425f969a87379b4d384b0b79069e62ee5f (size=32)
Test #9 : K=e15431d44131f0a10a148a956958bbff6b02741d51fa5ce1d3f4a60d16647e14 (size=32)
Test #10 : K=1ec616c502c7771d2e425f33d2d0c9efeea50bdc22e2341cf5b60cacd5488060 (size=32)
----------------------------------------------------------------------------------------------------
Tests Executed : 10
Tests Passed : 10
Tests Failed : 0
Tests Errored : 0
Elapsed Time: 23ms
using System;
using System.Diagnostics;
using System.IO;
using System.Numerics;
using System.Security.Cryptography;
using System.Threading;
namespace Dh
{
class Program
{
static void Main(string[] args)
{
var defaultNumTests = 100;
var numTests = args.Length > 1 ? (int.TryParse(args[0], out var temp) ? temp : defaultNumTests) : defaultNumTests;
if (numTests <= 0)
numTests = 10;
Console.WriteLine();
Console.WriteLine();
var errored = 0;
var passed = 0;
var executed = 0;
var watch = Stopwatch.StartNew();
for (int i = 0; i < numTests; i++)
{
executed++;
try
{
if (TestDH(i))
passed++;
}
catch
{
errored++;
}
}
Console.WriteLine(new string('-', 100));
Console.WriteLine("Tests Executed : " + numTests);
Console.WriteLine("Tests Passed : " + passed);
Console.WriteLine("Tests Failed : " + (numTests - passed));
Console.WriteLine("Tests Errored : " + errored);
Console.WriteLine();
Console.WriteLine("Elapsed Time: " + watch.ElapsedMilliseconds + "ms");
Console.WriteLine();
Console.WriteLine();
}
static bool TestDH(int testNum)
{
var server = new ServerKey();
var client = new ClientKey(server);
client.CalculateKey(server.A);
server.GetKey(client.B);
var result = server.K == client.K;
if (result)
{
var k = client.K.ToByteArray();
if (k.Length != 32)
return false;
Console.WriteLine("Test #{0}: K={1} (size={2})", (testNum + 1).ToString().PadRight(6), k.Hex(), k.Length);
}
return result;
}
}
public class ServerKey
{
public BigInteger b, e, p, y, A, K;
public ServerKey()
{
b = Util.RandomNumber();
p = Util.RandomPrime();
e = BigInteger.Divide(p, 1);
y = BigInteger.ModPow(Util.g, e, p);
A = BigInteger.ModPow(y, b, p);
}
public byte[] GetPacket()
{
using var ms = new MemoryStream();
ms.Write(Util.g.ToByteArray().Xor());
ms.Write(p.ToByteArray().Xor());
ms.Write(A.ToByteArray().Xor());
ms.Write(BitConverter.GetBytes(1L));
return ms.ToArray();
}
bool isValid;
public byte[] GetKey(BigInteger B)
{
if (!isValid)
{
K = BigInteger.ModPow(B, A, p);
isValid = true;
}
return K.ToByteArray();
}
}
public class ClientKey
{
public BigInteger b, B, K;
public ClientKey(ServerKey sk)
{
b = Util.RandomNumber(32);
B = BigInteger.ModPow(Util.g, sk.e, sk.p);
sk.GetKey(B);
K = BigInteger.ModPow(B, sk.A, sk.p);
}
bool isValid;
public byte[] CalculateKey(BigInteger A)
{
if (!isValid)
{
isValid = true;
}
return K.ToByteArray();
}
public byte[] GetPacket()
=> B.ToByteArray().Xor();
}
static class Util
{
public static readonly BigInteger g = 2;
static readonly RandomNumberGenerator RNG
= RandomNumberGenerator.Create();
public static BigInteger RandomNumber(uint size = 32)
{
BigInteger result;
var buffer = new byte[size];
while (true)
{
RNG.GetBytes(buffer);
result = new BigInteger(buffer);
if (result >= 1)
break;
}
return result;
}
public static byte[] Xor(this byte[] b, byte key = 0x26)
{
var temp = new byte[b.Length];
for (uint i = 0; i < temp.Length; i++)
temp[i] = (byte)(b[i] ^ key);
return temp;
}
public static string Hex(this byte[] buff)
=> BitConverter.ToString(buff).Replace("-", string.Empty).ToLowerInvariant();
internal static BigInteger RandomPrime()
{
BigInteger result;
while (true)
{
result = RandomNumber();
if (CheckIfPrime(result))
break;
result = default;
Thread.Sleep(1);
}
return result;
}
static bool CheckIfPrime(BigInteger n) //to check if the random number generated is prime
{
return n >= 1 && !n.IsEven;
}
}
}
Reference to use: https://www.unknowncheats.me/forum/warface/143270-hacked-warface-game-protocol-4.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment