using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; namespace Chop.Game.Encryption { public class DiffieHellman { #region Static vars public readonly int BIT_LENGTH = 30; #endregion #region Variables public BigInteger Prime { get; private set; } public BigInteger Generator { get; private set; } public BigInteger PrivateKey { get; private set; } public BigInteger PublicKey { get; private set; } public BigInteger PublicClientKey { get; private set; } public BigInteger SharedKey { get; private set; } #endregion #region Constructor public DiffieHellman() { this.InitDH(); } public DiffieHellman(int b) { this.BIT_LENGTH = b; this.InitDH(); } private void InitDH() { this.PublicKey = 0; while (this.PublicKey == 0) { this.Prime = BigInteger.genPseudoPrime(BIT_LENGTH, 10, new Random()); this.Generator = BigInteger.genPseudoPrime(BIT_LENGTH, 10, new Random()); this.PrivateKey = new BigInteger(GenerateRandomHexString(BIT_LENGTH), 16); if (this.Generator > this.Prime) { BigInteger temp = this.Prime; this.Prime = this.Generator; this.Generator = temp; } this.PublicKey = this.Generator.modPow(this.PrivateKey, this.Prime); } } public DiffieHellman(BigInteger prime, BigInteger generator) { this.Prime = prime; this.Generator = generator; this.PrivateKey = new BigInteger(GenerateRandomHexString(BIT_LENGTH), 16); if (this.Generator > this.Prime) { BigInteger temp = this.Prime; this.Prime = this.Generator; this.Generator = temp; } this.PublicKey = this.Generator.modPow(this.PrivateKey, this.Prime); } #endregion #region SharedKey public void GenerateSharedKey(string ckey) { this.PublicClientKey = new BigInteger(ckey, 10); this.SharedKey = this.PublicClientKey.modPow(this.PrivateKey, this.Prime); } #endregion #region RandomHexString public static string GenerateRandomHexString(int len) { var rng = new RNGCryptoServiceProvider(); byte[] bytes = new byte[len / 2]; rng.GetBytes(bytes); BigInteger result = new BigInteger(bytes); if (result < 0) { result *= -1; } return result.ToString(16); } #endregion } }