Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МиСКЗИ Лабораторная работа 3.pdf
Скачиваний:
0
Добавлен:
08.08.2026
Размер:
398 Кб
Скачать

Заключение

В ходе лабораторной работы были изучены шифр RSA, криптосистема Эль-Гамаля и ранцевая криптосистема, алгоритм быстрого возведения в степень по модулю, тест Ферма и создана программная реализация алгоритмов, код программы приведен в приложении А.

9

Приложение А

(обязательное)

Код программы

using static System.Runtime.InteropServices.JavaScript.JSType; using System.Numerics;

internal class Program

{

private static void Main(string[] args)

{

BigInteger longPowerWithMod(BigInteger a, BigInteger pow, BigInteger

module)

{

if (module == 1) return 0;

BigInteger result = 1;

while (pow > 0)

{

if ((pow & 1) == 1)

{

result = result * a % module;

}

pow = pow >> 1;

a = a * a % module;

}

return result;

}

bool testFerma(long number)

{

bool testFermaPassed = false; int iterations = 10;

for (int i = 0; i < iterations; i++)

{

Console.WriteLine($"Итерация {i + 1}:"); long a = Random.Shared.NextInt64(2, number); while (a % 2 == 0)

{

10

a = Random.Shared.NextInt64(2, number);

}

long aPow = (long)longPowerWithMod(a, number - 1, number); if (aPow == 1)

{

Console.WriteLine($"Число {number} – псевдопростое,

ура!");

 

testFermaPassed = true;

 

}

 

else

 

{

 

Console.WriteLine($"Число {number} – точно

 

составное, попробуй другое число...");

 

testFermaPassed = false;

 

}

 

}

 

Console.WriteLine("-----------------------------------------

");

return testFermaPassed;

 

}

 

BigInteger NOD(BigInteger a, BigInteger b)

 

{

 

while (b != 0)

 

{

 

BigInteger temp = b;

 

b = a % b;

 

a = temp;

 

}

 

return a;

 

}

 

BigInteger inverseNumberMod(BigInteger a, BigInteger module)

 

{

 

BigInteger m0 = module;

 

BigInteger y2 = 0, y1 = 1;

 

if (module == 1) return 0;

 

while (a > 1)

 

{

 

BigInteger q = a / module;

 

BigInteger r = module;

 

module = a % module;

 

11

a = r; r = y2;

y2 = y1 - q * y2;

y1 = r;

}

if (y1 < 0) y1 += m0;

return y1;

}

long Mod(long a, long n)

{

while (a > n)

{

a -= n;

}

return a;

}

bool isPrimitiveRoot(long g, long p, List<long> primeFactors)

{

if (longPowerWithMod(g, p - 1, p) != 1) return false;

foreach (long q in primeFactors)

{

if (longPowerWithMod(g, (p - 1) / q, p) == 1)

{

return false;

}

}

return true;

}

List<long> getPrimeFactors(long n)

{

List<long> factors = new List<long>();

if (n % 2 == 0)

{

factors.Add(2);

while (n % 2 == 0) n /= 2;

}

12

for (long i = 3; i * i <= n; i += 2)

{

if (n % i == 0)

{

factors.Add(i);

while (n % i == 0) n /= i;

}

}

if (n > 1) factors.Add(n);

return factors;

}

int fastPower(int a, int b, int mod)

{

string binaryB = Convert.ToString(b, 2); List<char> inverseBinaryB =

binaryB.AsEnumerable().Reverse().ToList();

if (inverseBinaryB[0] == '1')

{

b = a;

}

else

{

b = 1;

}

inverseBinaryB.RemoveAt(0);

foreach (char x in inverseBinaryB)

{

long aNext = Mod(a*a, mod);

if (x == '1')

{

b = (int)Mod(aNext * b, mod); a = (int)aNext;

}

else

{

13

a = (int)aNext; continue;

}

}

return b;

}

void RSA(BigInteger q, BigInteger p, BigInteger m)

{

BigInteger d = 0; BigInteger n = p * q;

BigInteger fi = (p - 1) * (q - 1);

BigInteger exp = Random.Shared.NextInt64(2, (long)p); while (NOD(exp, fi) != 1)

{

exp = Random.Shared.NextInt64(2, (long)p);

}

Console.WriteLine($"Сгенерированное значение е: {exp}");

d = inverseNumberMod(exp, fi);

BigInteger y = longPowerWithMod(m, exp, n);

Console.WriteLine($"Зашифрованное сообщение E(m): {y}"); Console.WriteLine($"Расшифрованное сообщение D(y):

{longPowerWithMod(y, d, n)}"); Console.WriteLine();

}

void Knapsack(long q, List<long> w, string m)

{

long wSum = 0; foreach (long x in w)

{

wSum += x;

}

long r = Random.Shared.NextInt64(2, q); Console.WriteLine($"Сгенерированное значение r: {r}");

List<long> eps = new List<long>(); for (int i = 0; i < w.Count; i++)

{

14

eps.Add(Mod(w[i]*r, q));

}

long knapsackE = 0;

for(int i = 0; i < m.Length; i++)

{

if (m[i] == '1')

{

knapsackE += eps[i];

}

}

Console.WriteLine($"Зашифрованное сообщение E(m): {knapsackE}");

long rInverse = (long)inverseNumberMod(r, q);

long l = Mod(rInverse * knapsackE, q);

List<long> wInverse = w.AsEnumerable().Reverse().ToList();

string result = "";

foreach (long x in wInverse)

{

if (l - x >= 0)

{

l = l - x; result += "1";

}

else

{

l = l;

result += "0";

}

}

result = new string(result.Reverse().ToArray());

Console.WriteLine($"Расшифрованное сообщение D(y): {result}");

}

void Elgamal(long p, long m)

{

List<long> factors = getPrimeFactors(p - 1);

long g = Random.Shared.NextInt64(2, p);

15

while (!isPrimitiveRoot(g, p, factors))

{

g = Random.Shared.NextInt64(2, p);

}

Console.WriteLine($"Сгенерированное значение g: {g}");

long x = Random.Shared.NextInt64(2, p); Console.WriteLine($"Сгенерированное значение x: {x}");

long y = (long)longPowerWithMod(g, x, p);

long k = Random.Shared.NextInt64(2, p); Console.WriteLine($"Сгенерированное значение k: {k}");

long a = (long)longPowerWithMod(g, k, p);

long b = Mod(m * (long)longPowerWithMod(y, k, p),p);

Console.WriteLine($"Зашифрованное сообщение E(m): {a} {b}");

BigInteger Dy = Mod((long)(b * inverseNumberMod(longPowerWithMod(a, x, p), p)), p);

Console.WriteLine($"Расшифрованное сообщение D(y): {Dy}");

}

Console.WriteLine("Введите значение q, p, m для RSA через пробел:"); try

{

string[] RSAparam = Console.ReadLine().Split(new char[] {' '}); for (int i = 0; i < RSAparam.Length; i++)

{

if (Convert.ToInt64(RSAparam[i]) <= 0)

{

throw new FormatException();

}

}

long qRSA = Convert.ToInt64(RSAparam[0]); long pRSA = Convert.ToInt64(RSAparam[1]); long mRSA = Convert.ToInt64(RSAparam[2]);

Console.WriteLine("\nВведите значения w для задачи ранца через

пробел:");

16

string[] knapsackWParam = Console.ReadLine().Split(new char[] {'

'});

List<long> knapsackW = new List<long>();

for (int i = 0; i < knapsackWParam.Length; i++)

{

if (Convert.ToInt64(knapsackWParam[i]) <= 0)

{

throw new FormatException();

}

else

{

knapsackW.Add(Convert.ToInt64(knapsackWParam[i]));

}

}

Console.WriteLine("\nВведите значение q, m для задачи ранца

через пробел:");

string[] knapsackParam = Console.ReadLine().Split(new char[] {'

'});

for (int i = 0; i < knapsackParam.Length; i++)

{

if (Convert.ToInt64(RSAparam[i]) <= 0)

{

throw new FormatException();

}

}

long qKnapsack = Convert.ToInt64(knapsackParam[0]); string mKnapsack = knapsackParam[1];

Console.WriteLine("\nВведите значение p, m для Эль-Гамаля через

пробел:");

string[] elgamalParam = Console.ReadLine().Split(new char[] { '

' });

for (int i = 0; i < elgamalParam.Length; i++)

{

if (Convert.ToInt64(elgamalParam[i]) <= 0)

{

throw new FormatException();

}

}

long pElgamal = Convert.ToInt64(elgamalParam[0]); long mElgamal = Convert.ToInt64(elgamalParam[1]);

17

Console.WriteLine("\nПроверка введенных значений тестом

Ферма:");

if (testFerma(qRSA) == false || testFerma(pRSA) == false || testFerma(qKnapsack) == false || testFerma(pElgamal) == false)

{

Console.WriteLine("Одно из введенных значений не является

простым числом :(");

return;

}

Console.WriteLine("\nПроверка введенных значений w:"); for (int i = 2; i < knapsackW.Count; i++)

{

if (knapsackW[i - 2] + knapsackW[i - 1] >= knapsackW[i])

{

Console.WriteLine("Введенные значения не образуют резко возрастающую последовательность :(");

return;

}

else

{

Console.WriteLine("Резко возрастает...");

}

}

Console.WriteLine("Это и правда резко возрастающая последовательность! Продолжаем...");

Console.WriteLine("\nПроверка значения q для задачи ранца:"); long wSum = 0;

foreach (long x in knapsackW)

{

wSum += x;

}

if (qKnapsack <= wSum)

{

Console.WriteLine("Введенное значение q меньше или равно

сумме значений w :(");

return;

}

else

{

Console.WriteLine("Значение подходит, продолжаем...");

}

18

Console.WriteLine("\nПроверка сообщения m для задачи ранца:"); if (mKnapsack.Length < 5 && knapsackW.Count != mKnapsack.Length)

{

Console.WriteLine("Сообщение не подходит по размеру :("); return;

}

foreach (char x in mKnapsack)

{

if (x == '0' || x == '1')

{

continue;

}

else

{

Console.WriteLine("Сообщение не является двочиным

числом :(");

return;

}

}

Console.WriteLine("Сообщение нужного размера и является двочиным числом, продолжаем...");

Console.WriteLine("\nПроверка значения p для Эль-Гамаля:"); if (pElgamal < 100 || pElgamal > 999)

{

Console.WriteLine("Значение p не подходит по размеру :("); return;

}

else

{

Console.WriteLine("Значение подходит, продолжаем...");

}

Console.WriteLine("\nRSA");

RSA(qRSA, pRSA, mRSA);

Console.WriteLine("\nЗадача ранца");

Knapsack(qKnapsack, knapsackW, mKnapsack);

Console.WriteLine("\nЭль-Гамаль");

Elgamal(pElgamal, mElgamal);

19

Console.WriteLine($"\nРезультат возведения 12^11 mod 481 = {fastPower(12, 11, 481)}");

Console.WriteLine($"Результат возведения 181^275 mod 481 =

{fastPower(181, 275, 481)}");

Console.WriteLine($"Результат возведения 17^131 mod 2201 =

{fastPower(17, 131, 2201)}");

}

catch (FormatException)

{

Console.WriteLine("Введите целые положительные числа в качестве

значений >:(");

}

}

}

20