- •Темплан 2014г., п. 28
- •Предисловие
- •1. Арифметика остатков. Элементарные шифры
- •1.1. Шифр Цезаря
- •1.2. Аффинный шифр
- •1.3. Обобщенный алгоритм Евклида
- •1.4. Вскрытие аффинного шифра по двум паросочетаниям
- •1.5. Исходные данные для решения задач
- •2. Базовые теоретико-числовые алгоритмы
- •2.1. Китайская теорема об остатках
- •2.2. Возведение в квадрат
- •2.3. Символы Лежандра и Якоби, извлечение квадратного корня
- •2.4. Возведение в степень и нахождение порождающего элемента группы
- •2.5. Генерация простых чисел
- •2.6. Исходные данные для решения задач
- •3. Асимметричные криптографические протоколы и системы шифрования с открытым ключом
- •3.1. Протокол Диффи-Хеллмана
- •3.2. Трехпроходный протокол Шамира
- •3.3. Криптосистема rsa
- •3.4. Криптосистема Эль-Гамаля
- •3.5. Криптосистема Рабина
- •3.6. Исходные данные для решения задач
- •4. Асимметричные схемы электронно-цифровой подписи
- •4.1. Цифровая подпись rsa
- •4.2. Цифровая подпись Эль-Гамаля
- •4.3 Генерация сильно простого числа и порождающего элемента
- •4.4. Цифровая подпись dsa
- •4.5. Исходные данные для решения задач
- •5. Эллиптические кривые над конечным полем
- •5.1. Протокол Диффи-Хеллмана на эллиптических кривых
- •5.2. Цифровая подпись ec-dsa
- •5.3. Исходные данные для решения задач
- •Заключение
- •Приложение 1
- •Приложение 2
- •Приложение 3
- •Список использованной и рекомендуемой литературы
Приложение 2
Листинг программы для решения задач 5.3, 5.4 на языке C#
Программа реализует обобщенный алгоритм Евклида, сложение и удвоение точек.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public class Operations
{
public int Mod(int a,int p)
{
if (a < 0) { a = a + p; }
return a;
}
public int Evc(int h, int k) //Алгоритм Евклида
{
int[,] mt = new int[20, 7];
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 7; j++) mt[i, j] = -1;
}
mt[0, 0] = 1;
mt[0, 1] = 0;
mt[0, 2] = h;
mt[0, 3] = 0;
mt[0, 4] = 1;
mt[0, 5] = k;
mt[0, 6] = (h - (h % k)) / k;
int n = 0;
while (mt[n, 5] != 0)
{
n++;
int m = 0;
for (m = 0; m < 3; m++)
{
mt[n, m] = mt[n - 1, m + 3];
}
for (m = 3; m < 6; m++)
{
mt[n, m] = mt[n - 1, m - 3] - mt[n - 1, m] * mt[n - 1, 6];
}
if (mt[n, 5] != 0)
{
mt[n, 6] = (mt[n, m - 4] - (mt[n, 2] % mt[n, 5])) / mt[n, 5];
}
}
k = mt[n - 1, 4];
if (k < 0) {k += h; }
return (k);
}
}
class Program
{
static void Main(string[] args)
{
Operations op1 = new Operations();
int x=0;
int y=0;
int k;
int p = 199;
Console.WriteLine("Если требуется удвоение, нажмите 0, если сложение 1");
k = Convert.ToInt32(Console.ReadLine());
if (k==0) //Удвоение
{
Console.WriteLine("Введите координаты, для удвоения");
int x1;
Console.Write("x1=");
x1 = Convert.ToInt32(Console.ReadLine());
int y1;
Console.Write("y1=");
y1 = Convert.ToInt32(Console.ReadLine());
int a;
int a1 = 2*y1 % p;
a1 = op1.Evc(p, a1);
a = (3 * x1 * x1) % p;
a = a + 1;
a = (a * a1) % p;
x = (a * a) % p;
x = x - ((2 * x1)%p);
x = op1.Mod(x, p);
y = x1 - x;
y = op1.Mod(y, p);
y = (y * a) % p;
y = y - y1;
y = op1.Mod(y, p);
}
else //Сложение
{
Console.WriteLine("Введите координаты, для сложения");
int x1;
Console.Write("x1=");
x1 = Convert.ToInt32(Console.ReadLine());
int y1;
Console.Write("y1=");
y1 = Convert.ToInt32(Console.ReadLine());
int x2;
Console.Write("x2=");
x2 = Convert.ToInt32(Console.ReadLine());
int y2;
Console.Write("y2=");
y2 = Convert.ToInt32(Console.ReadLine());
int a;
int a1 = x2-x1;
a1 = op1.Mod(a1, p);
a1 = op1.Evc(p, a1);
a = y2 - y1;
a = op1.Mod(a, p);
a = (a * a1) % p;
x = (a * a) % p;
x = x - x1;
x = op1.Mod(x, p);
x = x - x2;
x = op1.Mod(x, p);
x = x % p;
y = (x1 - x);
y = op1.Mod(y, p);
y = (y * a) % p;
y = y - y1;
y = op1.Mod(y, p);
}
Console.WriteLine("x=" + x);
Console.WriteLine("y=" + y);
Console.ReadKey();
}
}
}
