jpp/lab3/zad1/include/DHSetup.hpp
2024-05-10 14:12:10 +02:00

72 lines
1.6 KiB
C++

#pragma once
#include <random>
#include <cstdint>
#include <iostream>
template <typename T>
class DHSetup {
T generator;
std::vector<uint64_t> sieve_of_eratosthenes(uint64_t n) {
std::vector<bool> is_prime(n + 1, true);
is_prime[0] = is_prime[1] = false;
for (size_t i = 2; i <= n; ++i) {
if (is_prime[i] && i * i <= n) {
for (size_t j = i * i; j <= n; j += i) {
is_prime[j] = false;
}
}
}
std::vector<uint64_t> primes;
for (size_t i = 0; i <= n; ++i) {
if (is_prime[i]) {
primes.push_back(i);
}
}
return primes;
}
bool checkGenerator(T a) {
uint64_t p = a.characteristic() - 1;
for (uint64_t q : sieve_of_eratosthenes(std::sqrt(p))) {
if (p % q == 0 && a * (p / q) == 1) {
return false;
}
}
return true;
}
public:
DHSetup() {
std::random_device rand;
std::mt19937 gen(rand());
std::uniform_int_distribution<uint64_t> dist(1, this->generator.characteristic() - 1);
uint64_t num = dist(gen);
do {
num = dist(gen);
} while (!checkGenerator(num));
this->generator = T(num);
}
T getGenerator() {
return generator;
}
T power(T a, uint64_t b) {
T res = a;
while (b > 0) {
if (b % 2 == 1) {
res *= a;
}
a *= a;
b /= 2;
}
return res;
}
};