72 lines
1.6 KiB
C++
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;
|
|
}
|
|
};
|