
Додаток 4
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Numerics;
using System.Security.Cryptography;
namespace ЕGSА
{
class Program
{
static void Main(string[] args)
{
BigInteger P;
BigInteger Y;
BigInteger G;
BigInteger a;
int X = new Random().Next(1, int.MaxValue);
Console.WriteLine("Enter number:");
long M = Convert.ToInt64(Console.ReadLine());
//Без преобразования в хеш, т.к. долго идут расчеты, и не всегда позволяет стек
//byte[] hash = new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(M));
BigInteger m = new BigInteger(M);
for (P = BigInteger.Pow(2, 16/*1024*/); P < BigInteger.Pow(2, 1025); P++)
if (ferma(P))
break;
for (G = BigInteger.Pow(2, 8/*512*/); G < BigInteger.Pow(2, 513); G++)
if (ferma(G))
break;
Y = BigInteger.ModPow(G, X, P);
int K = new Random().Next(1, int.MaxValue);
a = BigInteger.ModPow(G, K, P);
BigInteger b = Euclid(X,a,K,P,m);
Console.WriteLine("P=" + P);
Console.WriteLine("G=" + G);
Console.WriteLine("Y=" + Y);
Console.WriteLine("a=" + a);
Console.WriteLine("b=" + b);
BigInteger S1 = (BigInteger.Pow(Y, (int)a)) * (BigInteger.Pow(a, (int)b)) % P;
BigInteger S2 = BigInteger.ModPow(G, m, P);
Console.WriteLine("S1 = S2");
Console.WriteLine(S1 + "=" + S2);
Console.ReadKey();
}
static BigInteger Euclid(int X, BigInteger a, int K, BigInteger P, BigInteger m)
{
for (BigInteger b = 1;; b++ )
if (m == BigInteger.ModPow((X * a + K * b), 1, (P - 1)))
return b;
}
static BigInteger Random()
{
var rng = new RNGCryptoServiceProvider();
byte[] bytes = new byte[3];
rng.GetBytes(bytes);
BigInteger h = new BigInteger(bytes);
return h;
}
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;
}
}
}