Додаток 6
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Numerics;
namespace DH
{
class Program
{
static void Main(string[] args)
{
//Both
BigInteger p = 10;
BigInteger g = 10;
while (!ferma(g))
{
while (!ferma(p) && !ferma(p - 1 / 2))
p = new Random().Next(int.MaxValue / 4000, int.MaxValue / 2000);
g = GetPRoot(p);
}
//Alice
int a = new Random().Next(int.MaxValue / 2, int.MaxValue);
//Bob
int b = new Random().Next(int.MaxValue / 2, int.MaxValue);
//Alice
BigInteger A = pows(g, a, p);
//Bob
BigInteger B = pows(g, b, p);
//Both
BigInteger K = pows(B, a, p); /* = pows(A, b, p);*/
BigInteger K_v2 = pows(A, b, p);
//keys equals
Console.WriteLine("p=" + p);
Console.WriteLine("g=" + g);
Console.WriteLine("a=" + a);
Console.WriteLine("b=" + b);
Console.WriteLine("A=" + A);
Console.WriteLine("B=" + B);
Console.WriteLine("K=K");
Console.WriteLine(K + "=" + K_v2);
Console.ReadKey();
}
static bool ferma(BigInteger x)
{
if (x == 2)
return true;
for (int i = 0; i < 100; i++)
{
BigInteger a = (new Random().Next() % (x - 2)) + 2;
if (gcd(a, x) != 1)
return false;
if (pows(a, x - 1, x) != 1)
return false;
}
return true;
}
static BigInteger gcd(BigInteger a, BigInteger b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
static BigInteger mul(BigInteger a, BigInteger b, BigInteger m)
{
if (b == 1)
return a;
if (b % 2 == 0)
{
BigInteger t = mul(a, b / 2, m);
return (2 * t) % m;
}
return (mul(a, b - 1, m) + a) % m;
}
static BigInteger pows(BigInteger a, BigInteger b, BigInteger m)
{
if (b == 0)
return 1;
if (b % 2 == 0)
{
BigInteger t = pows(a, b / 2, m);
return mul(t, t, m) % m;
}
return (mul(pows(a, b - 1, m), a, m)) % m;
}
static BigInteger GetPRoot(BigInteger p)
{
for (BigInteger i = 0; i < p; i++)
if (IsPRoot(p, i))
return i;
return 0;
}
static bool IsPRoot(BigInteger p, BigInteger a)
{
if (a == 0 || a == 1)
return false;
BigInteger last = 1;
HashSet<BigInteger> set = new HashSet<BigInteger>();
for (BigInteger i = 0; i < p - 1; i++)
{
last = (last * a) % p;
if (set.Contains(last)) // Если повтор
return false;
set.Add(last);
}
return true;
}
}
}
