# Diffie Hellman c# implementation

Information Security Asked by Roger Far on January 2, 2022

For a test project I have tried to implement the (famous) Diffie Hellman algorithm for safe key exchange.

Now I have written this in C#:

using System;
using System.Collections;
using System.Collections.Generic;

namespace DiffieHellman.Cryptology
{
public static class CentralAuthority
{
private static readonly List<Int32> _primes = new List<Int32>();

public static void CreatePrimeTable()
{
const Int32 topNumber = Int32.MaxValue / 2;
BitArray numbers = new BitArray(topNumber, true);

for (Int32 i = 2; i < topNumber; i++)
{
if (!numbers[i])
continue;

for (Int32 j = i * 2; j < topNumber; j += i)
numbers[j] = false;
}

for (Int32 i = 1; i < topNumber; i++)
{
if (numbers[i])
}
}

/// <summary>
/// Generate a random Prime Number.
/// </summary>
public static Int32 GeneratePrime()
{
Int32 p = Randomizer.GetRandom(1, _primes.Count);
return _primes[p];
}

/// <summary>
/// Generate a random base integer (g) less than the prime
/// </summary>
public static Int32 GenerateBase(
Int32 prime)
{
return Randomizer.GetRandom(1, prime - 1);
}
}
}

using System;

namespace DiffieHellman.Cryptology
{
{
public Int64 Key { get; private set; }
public Int32 Prime { get; private set; }
public Int32 Generator { get; private set; }
public Int64 ExponentiationY { get; private set; }
private Int32 _privateX;

public void GenerateParameters(
Int32 prime = 0,
Int32 generator = 0)
{
if (prime < 1 && generator < 1)
{
prime = CentralAuthority.GeneratePrime();
generator = CentralAuthority.GenerateBase(prime);
}

if (prime <= generator - 1)
return;

Prime = prime;
Generator = generator;
_privateX = Randomizer.GetRandom(1, Prime - 1);

Int64 xor = Generator ^ _privateX;
while (xor > Prime - 1
|| xor == _privateX)
{
_privateX = Randomizer.GetRandom(1, Prime - 1);
xor = Generator ^ _privateX;
}

ExponentiationY = (xor) % Prime;
}

public void GenerateKey(
Int64 exponentiationYOther)
{
Key = (exponentiationYOther ^ _privateX) % Prime;
}
}
}

using System;
using System.Security.Cryptography;

namespace DiffieHellman.Cryptology
{
public static class Randomizer
{
/// <summary>
/// Real random generator
/// Slower then Random().Next()!
/// </summary>
public static Int32 GetRandom(
Int32 max)
{
return GetRandom(0, max);
}

/// <summary>
/// Real random generator
/// Slower than Random().Next()!
/// </summary>
public static Int32 GetRandom(
Int32 min,
Int32 max)
{
// Start a slower but more acurate randomizer service
RNGCryptoServiceProvider rngCryptoServiceProvider = new RNGCryptoServiceProvider();
Byte[] randomBytes = new Byte[4];
rngCryptoServiceProvider.GetBytes(randomBytes);
Int32 seed = BitConverter.ToInt32(randomBytes, 0);

return new Random(seed).Next(min, max);
}
}
}

using System;
using System.Diagnostics;
using DiffieHellman.Cryptology;

namespace DiffieHellman
{
public class Program
{

static void Main()
{
Stopwatch stopwatch = Stopwatch.StartNew();
CentralAuthority.CreatePrimeTable();
stopwatch.Stop();
Console.WriteLine("Create Prime Table: {0}ms", stopwatch.ElapsedMilliseconds);

stopwatch = Stopwatch.StartNew();
for (Int32 i = 0; i < Int32.MaxValue; i++)
{
// Generate random prime and generator at server

// Send prime and generator to client

// Calculate the key

// Calculate the key

Console.WriteLine("Error ({0}): wrong key", i);

if (_caDiffieHellmanServer.Key == 0 || _caDiffieHellmanClient.Key == 0)
Console.WriteLine("Error ({0}): key 0", i);

if (i % 10000 == 0)
Console.WriteLine("Progress: {0}, {1}ms, {2}", i, stopwatch.ElapsedMilliseconds, _caDiffieHellmanServer.Key);
}
stopwatch.Stop();
Console.WriteLine("Loop: {0}ms", stopwatch.ElapsedMilliseconds);

}
}
}


Now my main concern is that I did not use the standard formula: g pow(a) mod p = A, but g XOR a mod p. The pow(a) does not work if it goes outside the int64 value.

Is this a safety concern?

This implementation has only 1 bug: when both parties generate the same privateX, it will fail, but with the large amount of base numbers generated this only happens once in about 50 million times.

I would like to discuss the strength of this method and potential pitfalls!

Thanks!

What you implemented is not Diffie-Hellman, and has no strength at all. You are being confused with the use of the '^' character.

In C-like programming languages, '^' is the operator for a bitwise exclusive-or (a "XOR").

When writing mathematics in ASCII, it is customary to denotes exponentiation with the '^' character -- and it is not a XOR at all ! This notation comes from LaTeX, a typesetting system which is the de facto standard among mathematicians. In this message, I can use HTML tags and write 'ga' to say "g to the power a", but if I were to write in plain ASCII (e.g. on Usenet), I would have to write: 'g^a'.

Moreover, Diffie-Hellman uses modular exponentation on big integers -- typical size being 1024 bits or more. 32-bit or 64-bit integers will not be enough to achieve any kind of security, and, in any case, modular exponentiation is not what pow() implements (in algebraic terms, you want to work over a finite field, not plain integers or real numbers). In C# (.NET 4.0), you would want to use the System.Numerics.BigInteger class, and in particular its ModPow() method. But first, if you ever want to do that, you first have to understand the underlying mathematics. You can begin by reading the first three chapters of the Handbook of Applied Cryptography (no relation whatsoever with Schneier's "Applied Cryptography", and, in my view, the "Handbook" is a far more useful book). It may seem a bit harsh, but you cannot hope to implement Diffie-Hellman properly unless you master the mathematics described in those first three chapters.

(And, of course, implementing cryptographic algorithms has other pitfalls, related to side-channel leaks, so even if you do understand what happens mathematically, making your own implementation is not necessarily a good idea.)

Answered by Thomas Pornin on January 2, 2022

Diffie-Hellman is based on modular exponentiation, so by using a different function in this code you haven't implemented Diffie-Hellman at all but something else.

Also the 63/64-bit numbers you're using are too small in any case.

You should read a basic text on cryptography, e.g. Schneier's Applied Cryptography.

Answered by frankodwyer on January 2, 2022

## Related Questions

### Does a TLS interception proxy present the user’s browser with the end server’s certificate?

4  Asked on January 20, 2021 by sentinel

### Help in Suricata rule bitmask syntax problem

1  Asked on January 18, 2021 by khalid

### Protecting personal documents in cloud

3  Asked on January 18, 2021 by zud

### Is it possible to circumvent the 2FA protection on Gmail using a stolen photo id?

0  Asked on January 17, 2021 by gloomyfit

### Challenge-Response authentication and SSL

1  Asked on January 16, 2021 by thunderbolt

### Network intrusion security warning in router logs

2  Asked on January 15, 2021 by helpme123

### Is this nginx config suitable to enforce proper authorization?

0  Asked on January 14, 2021 by mechmk1

### Creating port-specific SSH authentication for the same user

3  Asked on January 14, 2021 by brill

### Can a website steal passwords saved in my browser?

5  Asked on January 13, 2021 by sfrj

### Securing Android Application API access

1  Asked on January 13, 2021 by a-android-ucg

### Step by step protocol for complete system wipe (suspecting persistent backdoor)

1  Asked on January 13, 2021 by joshnow

### Is XSS possible when using htmlspecialchars and https prefix check in href?

1  Asked on January 12, 2021 by awaaaaarghhh

### Can an empty, but used, usb flash drive that has NO firmware within it be infected with malware?

2  Asked on January 10, 2021 by 888-999

### XKCD #936: Short complex password, or long dictionary passphrase?

22  Asked on January 9, 2021

### Sqlmap and multipart/form-data forms

2  Asked on January 8, 2021 by brigante

### Shared Text Content – XSS Safe

1  Asked on January 8, 2021 by newb-4-you-bb

### Deciding the kind of key required for implementation of monitoring software

0  Asked on January 6, 2021 by olle-hudga

### Wrapped Key Encryption – Hide AES secret key in Javascript & Java

0  Asked on January 6, 2021 by jian25

### What is the impact of an exposed secret key for a JWT token implementation?

3  Asked on January 4, 2021 by darren19824

### How do sites detect credential sniffing, and what is the purpose of this attack?

1  Asked on January 4, 2021

### Ask a Question

Get help from others!