Добавил:
донатики - https://qiwi.com/n/1ZOMBIE1 Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КР / КР_БунинаАВ_18062023.docx
Скачиваний:
19
Добавлен:
01.10.2023
Размер:
704.47 Кб
Скачать

Приложение а

Исходный код программы

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Numerics;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

namespace CW_Bunina_14062023_cryptography

{

public partial class Form1 : Form

{

BigInteger U, H, n, f_n, Z, k, g, S, znamenatel, lv_4, step, step2, pr_4;

public static BigInteger betta { get; set; }

public static BigInteger alpha { get; set; }

public static BigInteger r { get; set; }

public static BigInteger q { get; set; }

public static BigInteger gamma { get; set; }

public Form1()

{

InitializeComponent();

}

private void button1_Click(object sender, EventArgs e)

{

if (string.IsNullOrWhiteSpace(textBoxR.Text) || string.IsNullOrWhiteSpace(textBoxQ.Text) || string.IsNullOrWhiteSpace(textBoxU.Text) || string.IsNullOrWhiteSpace(textBoxH.Text) || textBoxQ.Text == textBoxR.Text)

{

// textbox пустой

MessageBox.Show("Пожалуйста, заполните доступные поля или введите r и q не равные друг другу.", "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Information);

}

else

{

r = BigInteger.Parse(textBoxR.Text);

q = BigInteger.Parse(textBoxQ.Text);

if (r < 50 || q < 50)

{

MessageBox.Show("Введите r и q больше 50", "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Information);

return;

}

if (!CheckPrime(r))

{

MessageBox.Show("r - не является простым числом.", "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Information);

return;

}

if (!CheckPrime(q))

{

MessageBox.Show("q - не является простым числом.", "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Information);

return;

}

U = BigInteger.Parse(textBoxU.Text);

H = BigInteger.Parse(textBoxH.Text);

n = r * q;

textBoxN.Text = n.ToString();

f_n = (r - 1) * (q - 1);

textBoxF.Text = f_n.ToString();

var y1 = FindingPrimeDivisors(r - 1);

foreach (var x in y1)

{

textBoxY1.Text = y1.Max().ToString();

}

var y2 = FindingPrimeDivisors(q - 1);

foreach (var x in y2)

{

textBoxY2.Text = y2.Max().ToString();

}

gamma = y1.Max() * y2.Max();

textBoxY.Text = gamma.ToString();

for (int betta = 2; betta < n; betta++)

{

alpha = BigInteger.ModPow(betta, f_n / gamma, n);

BigInteger[] numbers = { alpha - 1, n }; // пример массива чисел

// вычисляем НОД всех чисел в массиве

BigInteger gcd = numbers[0];

for (int j = 1; j < numbers.Length; j++)

{

gcd = BigInteger.GreatestCommonDivisor(gcd, numbers[j]);

}

// проверяем, равняется ли НОД 1

if (gcd == 1)

{

textBoxB.Text = betta.ToString();

textBoxA.Text = alpha.ToString();

Console.WriteLine($"a = {betta} ^ {f_n} / {gamma} mod {n} = {betta ^ (f_n / gamma)} mod {n} = {alpha}");

break;

}

}

Z = BigInteger.ModPow(alpha, U, n);

textBoxZ.Text = Z.ToString();

znamenatel = H + Z + 1;

BigInteger multElement = MultiplicativeElement(znamenatel, gamma);

k = (multElement * U * (H + Z)) % gamma;

textBoxK.Text = k.ToString();

g = (multElement * U) % gamma;

textBoxG.Text = g.ToString();

S = BigInteger.ModPow(alpha, g, n);

textBoxS.Text = S.ToString();

step = H + ((S*BigInteger.Pow(alpha, (int)(k)))%n);

//проверка

lv_4 = BigInteger.ModPow(S, step, n);

textBoxLv_4.Text = lv_4.ToString();

pr_4 = BigInteger.ModPow(alpha, k, n);

textBoxPr_4.Text = pr_4.ToString();

}

}

static bool CheckPrime(BigInteger number)//простое или нет

{

if (number <= 1)

{

return false;

}

if (number == 2 || number == 3)

{

return true;

}

if (number % 2 == 0 || number % 3 == 0)

{

return false;

}

for (BigInteger i = 5; i * i <= number; i += 6)

{

if (number % i == 0 || number % (i + 2) == 0)

{

return false;

}

}

return true;

}

static bool IsPrime(BigInteger x) //разложение на простые множители

{

bool p;

if (x <= 5U && (x <= 2U || x == 3U || x == 5U)) p = true;

else if (0U == x % 2U || 0U == x % 3U || 0U == x % 5U) p = false;

else

{

uint n;

for (n = 3U; n * n <= x && 0U != x % n; n += 2U) {; }

p = n * n > x;

}

return p;

}

static bool IsDivider(BigInteger x, BigInteger y)

{

return 0U == x % y;

}

static BigInteger[] FindingPrimeDivisors(BigInteger x)

{

var box = new List<BigInteger>();

while (IsDivider(x, 2U))

{

box.Add(2U);

x /= 2U;

}

var n = 3U;

while (!IsPrime(x))

{

while (IsDivider(x, n))

{

box.Add(n);

x /= n;

}

n += 2U;

while (!IsPrime(n)) n += 2U;

}

box.Add(x);

return box.ToArray();

}

public static BigInteger MultiplicativeElement(BigInteger a, BigInteger m) //мультик

{

BigInteger x, y;

BigInteger gcd = ExtendedEuclideanAlgorithm(a, m, out x, out y);

// находим положительное значение мультипликативного элемента

BigInteger result = x % m;

if (result == 0)

{

MessageBox.Show("Подберите другое значение H и U. Подпись не может быть сгенерирована.", "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Information);

return m;

}

if (result < 0)

{

result += m;

}

return result;

}

// функция для нахождения НОД и коэффициентов x и y при помощи расширенного алгоритма Евклида

public static BigInteger ExtendedEuclideanAlgorithm(BigInteger a, BigInteger b, out BigInteger x, out BigInteger y)

{

if (b == 0)

{

x = 1;

y = 0;

return a;

}

BigInteger x1, y1;

BigInteger gcd = ExtendedEuclideanAlgorithm(b, a % b, out x1, out y1);

x = y1;

y = x1 - (a / b) * y1;

return gcd;

}

static int FindLargestFactor(int n, int q)

{

int largestFactor = 1;

for (int i = 2; i <= n; i++)

{

while (n % i == 0)

{

n /= i;

if (i > largestFactor & i % q != 0)

{

largestFactor = i;

}

}

}

return largestFactor;

}

private void button2_Click(object sender, EventArgs e)

{

textBoxA.Text = "";

textBoxB.Text = "";

textBoxZ.Text = "";

textBoxS.Text = "";

textBoxY.Text = "";

textBoxK.Text = "";

textBoxG.Text = "";

textBoxQ.Text = "";

textBoxR.Text = "";

textBoxU.Text = "";

textBoxH.Text = "";

textBoxF.Text = "";

textBoxY1.Text = "";

textBoxY2.Text = "";

textBoxLv_4.Text = "";

textBoxPr_4.Text = "";

}

}

}