204 lines
4.0 KiB
C++
204 lines
4.0 KiB
C++
#include "cryptographer.h"
|
||
|
||
#include <QString>
|
||
//using namespace std;
|
||
constexpr int BYTE_SIZE = 8;
|
||
//Структура ключа
|
||
typedef struct {
|
||
uint64_t e;
|
||
uint64_t m;
|
||
} key;
|
||
|
||
Cryptographer::Cryptographer(QString key)
|
||
{
|
||
this->key = key;
|
||
p=173;
|
||
q=197;
|
||
n=p*q;
|
||
t = ( p - 1 ) * ( q - 1 );
|
||
e = calculateE( t );
|
||
d = calculateD( e, t );
|
||
|
||
///crypto = new SimpleCrypt(Q_UINT64_C(0x0c2ad4a4acb9f023));
|
||
}
|
||
Cryptographer::Cryptographer()
|
||
{
|
||
p=173;
|
||
q=197;
|
||
n=p*q;
|
||
t = ( p - 1 ) * ( q - 1 );
|
||
e = calculateE( t );
|
||
d = calculateD( e, t );
|
||
}
|
||
QString Cryptographer::encrypt(QString message){
|
||
std::string result = "";
|
||
std::string m = message.toStdString();
|
||
for (long int i = 0; i < m.length(); i++)
|
||
{
|
||
result+=(char)encrypt( m[i], e, n);
|
||
}
|
||
|
||
return QString::fromStdString(result);
|
||
}
|
||
|
||
QString Cryptographer::decrypt(QString message){
|
||
std::string result = "";
|
||
std::string m = message.toStdString();
|
||
for (long int i = 0; i < m.length(); i++)
|
||
{
|
||
result += (char)decrypt(encryptedText[i], d, n);
|
||
}
|
||
return QString::fromStdString(result);
|
||
}
|
||
|
||
bool Cryptographer::isPrime( long int prime)
|
||
{
|
||
long int i, j;
|
||
|
||
j = (long int)sqrt((long double)prime);
|
||
|
||
for ( i = 2; i <= j; i++)
|
||
{
|
||
if ( prime % i == 0 )
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
long int Cryptographer::calculateE( long int t )
|
||
{
|
||
// Выбирается целое число e ( 1 < e < t ) // взаимно простое со значением функции Эйлера (t)
|
||
|
||
long int e;
|
||
|
||
for ( e = 2; e < t; e++ )
|
||
{
|
||
if (greatestCommonDivisor( e, t ) == 1 )
|
||
{
|
||
return e;
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
long int Cryptographer::greatestCommonDivisor( long int e, long int t )
|
||
{
|
||
while ( e > 0 )
|
||
{
|
||
long int myTemp;
|
||
|
||
myTemp = e;
|
||
e = t % e;
|
||
t = myTemp;
|
||
}
|
||
|
||
return t;
|
||
}
|
||
|
||
long int Cryptographer::calculateD( long int e, long int t)
|
||
{
|
||
// Вычисляется число d, мультипликативно обратное к числу e по модулю φ(n), то есть число, удовлетворяющее сравнению:
|
||
// d ⋅ e ≡ 1 (mod φ(n))
|
||
|
||
long int d;
|
||
long int k = 1;
|
||
|
||
while ( 1 )
|
||
{
|
||
k = k + t;
|
||
|
||
if ( k % e == 0)
|
||
{
|
||
d = (k / e);
|
||
return d;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
long int Cryptographer::encrypt( long int i, long int e, long int n )
|
||
{
|
||
long int current, result;
|
||
|
||
current = i - 97;
|
||
result = 1;
|
||
|
||
for ( long int j = 0; j < e; j++ )
|
||
{
|
||
result = result * current;
|
||
result = result % n;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
long int Cryptographer::decrypt(long int i, long int d, long int n)
|
||
{
|
||
long int current, result;
|
||
|
||
current = i;
|
||
result = 1;
|
||
|
||
for ( long int j = 0; j < d; j++ )
|
||
{
|
||
result = result * current;
|
||
result = result % n;
|
||
}
|
||
|
||
return result + 97;
|
||
}
|
||
|
||
|
||
bool primeValidation(uint64_t n){
|
||
for(uint64_t i=2;i<=sqrt(n);i++)
|
||
if(n%i==0)
|
||
return false;
|
||
return true;
|
||
}
|
||
|
||
uint64_t PrimeGeneration(){
|
||
uint64_t num;
|
||
do{
|
||
num = rand()+1000000;
|
||
}while(!primeValidation(num));
|
||
return num;
|
||
}
|
||
|
||
//Расширенный алгоритм Евклида
|
||
int64_t advancedEuclidAlgorithm(int64_t a, int64_t b, int64_t &x, int64_t &y) {
|
||
if (a == 0) {
|
||
x = 0;
|
||
y = 1;
|
||
return b;
|
||
}
|
||
int64_t x1, y1;
|
||
int64_t d = advancedEuclidAlgorithm(b % a, a, x1, y1);
|
||
x = y1 - (b / a) * x1;
|
||
y = x1;
|
||
return d;
|
||
}
|
||
|
||
//Обратное по модулю
|
||
int64_t inverseModulo(int64_t a, int64_t m) {
|
||
int64_t x, y;
|
||
advancedEuclidAlgorithm(a, m, x, y);
|
||
x = (x % m + m) % m;
|
||
return x;
|
||
}
|
||
|
||
//Генерация пары ключей
|
||
std::pair<key, key> keysGeneration() {
|
||
uint64_t p=PrimeGeneration(), q=PrimeGeneration();
|
||
uint64_t phi = (p - 1) * (q - 1);
|
||
uint64_t n = p * q;
|
||
uint64_t e = PrimeGeneration();
|
||
uint64_t d = inverseModulo(e, phi);
|
||
return {{e, n},
|
||
{d, n}};
|
||
}
|