Міністерство освіти і науки України
Національний університет “Львівська політехніка”
Кафедра ІСМ
Звіт
до лабораторної роботи №6
з дисципліни
“Технології захисту інформації”
на тему:
“Ключовий обмін Діффі-Хеллмана”
Мета роботи: освоїти методи генерації великих простих чисел і методи перевірки великих чисел на простоту. Ознайомитися з теоремою Ейлера, навчитися будувати початкові корені по модулю n. Вивчити схему обміну ключами Діффі-Хеллмана.
Індивідуальне завдання:
1. Написати програму на мові програмування, яка надає засоби:
1.1. генерації великих простих чисел, які перевищують 264 .Програма за заданими t (кількість перевірок за тестом Рабіна-Міллера) та n (кількість біт) повинна генерувати просте n-бітне число, відображаючи при цьому кількість ітерацій алгоритму генерації простого числа, які необхідно виконати для його генерації та час який для цього був необхідний;
1.2. програма за заданими межами діапазону повинна виводити всі прості числа з цього діапазону, відображаючи час, витрачений на генерацію всіх чисел;
1.3. визначити для заданого числа перші 100 початкових коренів, відображаючи при цьому сумарний час витрачений програмою на їх пошук;
2. Змоделювати ключовий обмін між абонентами за схемою Діффі-Хеллмана. Програма повинна отримувати великі прості числа Xa, Xb та n випадковим чином з допомогою алгоритму генерації простого числа, а також надавати засоби з їх завдання користувачем.
Короткі теоретичні відомості:
/
/
Результати роботи:
1.1. Генеруємо велике просте число, відображаючи при цьому кількість ітерацій алгоритму генерації простого числа, які необхідно виконати для його генерації та час який для цього був необхідний.
Код програми:
import java.math.BigInteger;
public class Lab_062 {
public static boolean isPrime(BigInteger n, int precision) {
if (n.compareTo(new BigInteger("341550071728321")) >= 0) {
return n.isProbablePrime(precision); }
int intN = n.intValue();
if (intN == 1 || intN == 4 || intN == 6 || intN == 8) return false;
if (intN == 2 || intN == 3 || intN == 5 || intN == 7) return true;
int[] primesToTest = getPrimesToTest(n);
if (n.equals(new BigInteger("3215031751"))) {
return false; }
BigInteger d = n.subtract(BigInteger.ONE);
BigInteger s = BigInteger.ZERO;
while (d.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) {
d = d.shiftRight(1);
s = s.add(BigInteger.ONE); }
System.out.println("Кількість перевірок за тестом Рабіна-Міллера");
System.out.println("t = " + t);
System.out.println("Кількість ітерацій алгоритму генерації простого числа");
System.out.println(m);
System.out.println("Згенероване просте число");
System.out.println(k);
return true; }
private static int[] getPrimesToTest(BigInteger n) {
if (n.compareTo(new BigInteger("3474749660383")) >= 0) {
return new int[]{2, 3, 5, 7, 11, 13, 17}; }
if (n.compareTo(new BigInteger("2152302898747")) >= 0) {
return new int[]{2, 3, 5, 7, 11, 13}; }
return new int[]{2, 3}; }
private static boolean try_composite(int a, BigInteger d, BigInteger n, BigInteger s) {
BigInteger aB = BigInteger.valueOf(a);
if (aB.modPow(d, n).equals(BigInteger.ONE)) {
return false; }
for (int i = 0; BigInteger.valueOf(i).compareTo(s) < 0; i++) {
if (aB.modPow(BigInteger.valueOf(2).pow(i).multiply(d), n).equals(n.subtract(BigInteger.ONE))) {
return false; } }
return true; } }
Результати виконання програми:
/
Здійснюємо написання програми, яка за заданим діапазоном виводить всі прості числа, окрім цього відображається час на генерацію цього діапазону.
Код програми:
public class Lab_063 {
public static void main(String[] args) {
IsPrime myIsPrime = new IsPrime();
System.out.print("Введіть ліву межу діапазону чисел: ");
myIsPrime.setLimit();
myIsPrime.getAllPrimes();
System.out.println("Прості числа: ");
myIsPrime.display();
System.out.println("Час затрачений на генерацію всіх чисел");
System.out.println(time);
} }
class IsPrime {
private int limit;
private ArrayList<Integer> numbers = new ArrayList<Integer>();
private boolean isPrime(int num) {
boolean flag = true;
for (int j = 2; j < num; j++) {
if (num % j == 0) {
flag = false;
break;
}
}
return flag;
}
public void setLimit() {
Scanner scanner = new Scanner(System.in);
limit = scanner.nextInt();
System.out.print("Введіть праву межу діапазону чисел: ");
limit = scanner.nextInt();
System.out.println("");
}
public void display() {
System.out.println(numbers); } }
Результати виконання програми:
/
Визначаємо для заданого числа перші 100 початкових коренів, відображаючи при цьому сумарний час витрачений програмою на їх пошук.
Код програми:
import java.util.Arrays;
public class Lab_064 {
public static boolean IsPRoot(long p, long a) {
if (a == 0 || a == 1)
return false;
long last = 1;
Set<Long> set = new HashSet<>();
for (long i = 0; i < p - 1; i++) {
last = (last * a) % p;
if (set.contains(last)) // Если повтор
return false;
set.add(last); }
return true; }
public static void main(String args[] ) {
Scanner scanner = new Scanner(System.in);
System.out.println("Знайти корені для: ");
long root = scanner.nextInt();
System.out.println("Перші 100 коренів числа: " + root);
System.out.println(Arrays.toString(m));
System.out.println(IsPRoot(root, GetPRoot(root)));
System.out.println("Час витрачений на пошук 100 коренів простого числа:");
System.out.println(time); } }
Результати виконання програми:
/
Реалізовуємо програмну реалізацію ключового обміну між абонентами за схемою Діффі-Хеллмана.
Код програми:
import java.math.BigInteger;
public class Lab_061 {
public static void main(String[] args) {
int Xa, Xb;
generat(Xa, Xb)
BigInteger Ya = BigInteger.valueOf(0);
BigInteger Yb = BigInteger.valueOf(0);
BigInteger Ka = BigInteger.valueOf(0);
BigInteger Kb = BigInteger.valueOf(0);
BigInteger n = BigInteger.valueOf(3571);
BigInteger q = BigInteger.valueOf(75);
System.out.println("Згенероване випадкове число Ха");
System.out.println(Xa);
System.out.println("Згенероване випадкове число Хb");
System.out.println(Xb);
Ya = q.pow(Xa).mod(n);
Yb = q.pow(Xb).mod(n);
System.out.println("Обчислений елемент на стороні абонента А");
System.out.println(Ya);
System.out.println("Обчислений елемент на стороні абонента В");
System.out.println(Yb);
Ka = Yb.pow(Xa).mod(n);
Kb = Ya.pow(Xb).mod(n);
System.out.println("Секретний ключ абонента А");
System.out.println(Ka);
System.out.println("Секретний ключ абонента В");
System.out.println(Kb);} }
Результати виконання програми:
/
Висновок: Під час виконання даної лабораторної роботи було розглянуто методи генерації великих простих чисел і методи перевірки великих чисел на простоту, ознайомлено з теоремою Ейлера, побудовано початкові корені по модулю n, ознайомлено з схему обміну ключами Діффі-Хеллмана.