λ¬Έμ
곡κ°ν€ μκ³ λ¦¬μ¦ μ€ Rivest, Shamir, Adlemanμ μν΄ μ€κ³λ RSA μκ³ λ¦¬μ¦μ ꡬννλΌ
λ‘μ§
- 2κ°μ μμ (p, q)κ° νμνλ€
- n = p * q
- Ο(n) = (p-1) * (q-1)
- e = eμ Ο(n)μ μλ‘μ
- d = e*d mod Ο(n) = 1
- c = m^e mod n
- m = c^d mod n
μ£Όμ μ¬ν
- μνΈννλ νλ¬Έμ nμ μλ¦Ώμλ³΄λ€ μμ μλ¦Ώμλ₯Ό κ°μ ΈμΌνλ€.
a. νλ¬Έμ΄ '123456789'μ΄κ³ , nμ΄ '1234'μ΄λ©΄ νλ¬Έμ '123', '456', 789'λ‘ λλ μ μνΈνν΄μΌνλ€.
- pμ qλ λ€μ 쑰건μ λ§μ‘±ν΄μΌ νλ€.
a. pμ qλ κ°μ§ μκ³ κ±°μ κ°μ ν¬κΈ°μ μλ¦ΏμμΌμΌ νλ€.
b. p-1κ³Ό q-1μ 컀λ€λ μμΈμλ₯Ό κ°κ° κ°μ ΈμΌ νλ€.
c. p-1κ³Ό q-1μ μ΅λ 곡μ½μλ μμ μμ¬μΌ νλ€
ꡬννμ§ μμμ§λ§, TMI
- μ€μ RSAμμ μ¬μ©νλ pμ qλ 100μ리 μ λμ μμλ‘ κ±°μ κ°μ ν¬κΈ°μ μλ¦Ώμλ₯Ό κ°μ§λ μλ₯Ό μ ννλ€.
μ½λ
rsa.h
#ifndef _RSA
#define _RSA
typedef struct key
{
long pkey; // μ΄κΈ° 2κ°μ μμ pμ qκ° κ³±ν΄μ λμ€λ nμ΄ μ μ₯λ λ³μ
long ekey; // public-key
long dkey; // private-key
int pkey_size;
} Key;
class Rsa
{
public:
Rsa();
virtual ~Rsa();
public:
Key produce_keys();
long endecrypt(const long msg, const long key, const long pkey);
int sizeof_int(long data);
private:
long produce_pkey(const long prime1, const long prime2);
long produce_ekey(const long orla);
long produce_dkey(const long ekey, const long orla);
long produce_prime();
long produce_orla(const long prime1, const long prime2);
long produce_gcd(const long a, const long b);
bool is_prime(const long digit);
};
#endif
main.cpp
#include "rsa.h"
#include <iostream>
using namespace std;
int main(void)
{
Rsa rsa;
Key key = rsa.produce_keys();
cout << "=============================" << endl;
cout << "=========== R S A ===========" << endl;
cout << "=============================\n" << endl;
cout << "=====================================" << endl;
cout << "μνΈν ν μ»μ ν€λ λ€μκ³Ό κ°μ΅λλ€."<< endl;
cout << "n ν€ : " << key.pkey << endl;
cout << "μνΈν ν€ (곡κ°ν€) : " << key.ekey << endl;
cout << "μνΈ ν΄λ
ν€ (κ°μΈν€) : " << key.dkey << endl;
cout << "=====================================\n" << endl;
long msg;
cout << "μνΈνν μ 보λ₯Ό μ
λ ₯νμμμ€ (μ«μ, λ무 ν΄ μ μμ) : ";
cin >> msg;
cout << "\n=====================================" << endl;
long msg_des = rsa.endecrypt(msg, key.ekey, key.pkey);
cout << "μνΈνλ μ 보λ λ€μκ³Ό κ°μ΅λλ€ : " << msg_des << endl;
msg_des = rsa.endecrypt(msg_des, key.dkey, key.pkey);
cout << "μνΈ ν΄λ
λ λ©μμ§λ λ€μκ³Ό κ°μ΅λλ€ : " << msg_des << endl;
cout << "=====================================" << endl;
return 0;
}
rsa.cpp
#include "rsa.h"
#include <cstdlib>
#include <ctime>
#include <string>
#include <bitset>
#include <iostream>
using namespace std;
Rsa::Rsa()
{
}
Rsa::~Rsa()
{
}
/***********************************************************************
μνΈν 볡νΈνλ₯Ό λμμ μ§ννλ λ©μλ
c = m^e mod n
m = c^d mod n
λΌλ μμ κ°κ³ λ³μλ§ λ§€κ°κ°λ§ λ°λλ©΄ λλ―λ‘ νλμ λ©μλμμ μ²λ¦¬ν¨
***********************************************************************/
long Rsa::endecrypt(const long msg, const long key, const long pkey)
{
long msg_des = 1;
long root = msg;
long index = key;
//int n_size = sizeof_int(pkey);
//int msg_size = sizeof_int(msg);
//int size = msg_size / n_size;
//if (msg_size % n_size)
// size = size + 1;
while (index)
{
//cout << bitset<32>(index) << endl;
if (index & 1) {
msg_des = (msg_des * root) % pkey;
//cout << "msg_des : " << msg_des << endl;
}
index >>= 1;
//cout << "b root : " << root << endl;
root = (root * root) % pkey;
//cout << "a root : " << root << endl;
}
return msg_des;
}
/************************************
pμ qλ₯Ό μμ±ν΄μ
n, e, d ν€λ₯Ό μμ±
* *********************************/
Key Rsa::produce_keys()
{
long prime1 = produce_prime(); // p
long prime2 = produce_prime(); // q
while (prime2 == prime1) // pμ qλ nμ λ§λ€κ³ νκΈ°ν΄μΌ νκΈ° λλ¬Έμ
prime2 = produce_prime(); // λ°λ‘ μ μ₯ν΄μ λ©μλ λ°μΌλ‘ λΉΌμ§ μμ
Key key;
long orla = produce_orla(prime1, prime2); // μ€μΌλ¬ n μμ±
key.pkey = produce_pkey(prime1, prime2); // n μμ±
key.ekey = produce_ekey(orla); // e μμ±
key.dkey = produce_dkey(key.ekey, orla); // d μμ±
return key;
}
/************************************
N ν€ μμ±
p * q
* *********************************/
long Rsa::produce_pkey(const long prime1, const long prime2)
{
return prime1 * prime2;
}
/************************************
μ€μΌλ¬ n μμ±
************************************/
long Rsa::produce_orla(const long prime1, const long prime2)
{
return (prime1 - 1) * (prime2 - 1);
}
/************************************
μνΈν ν€ (곡κ°ν€) e μμ±
* *********************************/
long Rsa::produce_ekey(const long orla)
{
long ekey;
while (true)
{
ekey = rand() % orla; // λλ€ μλ₯Ό μ€μΌλ¬ nμΌλ‘ λλ¨Έμ§ μ°μ°
if (ekey >= 2 && produce_gcd(ekey, orla) == 1) // e-keyμ μ€μΌλ¬ nμ΄ μλ‘μμΈμ§ νλ³
break;
}
return ekey;
}
/************************************
볡νΈν ν€ (κ°μΈν€) d μμ±
* *********************************/
long Rsa::produce_dkey(const long ekey, const long orla)
{
long dkey = orla / ekey;
while (true)
{
if (((dkey * ekey) % orla) == 1)
break;
else
++dkey;
}
return dkey;
}
/************************************
[100, 200] λ²μμμ μμμ μμ μμ±
* *********************************/
long Rsa::produce_prime()
{
long prime = 0;
srand(time(0));
while (true)
{
prime = rand() % 100 + 100;
if (is_prime(prime))
break;
}
return prime;
}
/************************************
λ μ«μμ μ΅λ 곡μ½μ μμ±
* *********************************/
long Rsa::produce_gcd(const long a, const long b)
{
long dividend = a;
long divisor = b;
long residual = dividend % divisor;
while (residual)
{
dividend = divisor;
divisor = residual;
residual = dividend % divisor;
}
return divisor;
}
/************************************
μμμΈμ§ νλ¨
* *********************************/
bool Rsa::is_prime(const long digit)
{
int tmp = 2;
while (tmp < digit)
if (!(digit % tmp++))
break;
if (tmp == digit)
return true;
return false;
}
/************************************
μ
λ ₯κ°μ μλ¦Ώμ νλ¨
* *********************************/
int Rsa::sizeof_int(long data)
{
int pos = 1;
if (data < 0)
data *= (-1);
for (int i = 0; ; i++, pos++) {
if ((data /= 10) <= 0)
break;
}
return pos;
}
κ²°κ³Ό
- μνΈννλ νλ¬Έμ nμ μλ¦Ώμλ³΄λ€ μμ μλ¦Ώμλ₯Ό κ°μ ΈμΌνλ€. a. νλ¬Έμ΄ '123456789'μ΄κ³ , nμ΄ '1234'μ΄λ©΄ νλ¬Έμ '123', '456', 789'λ‘ λλ μ μνΈνν΄μΌνλ€.
- pμ qλ λ€μ 쑰건μ λ§μ‘±ν΄μΌ νλ€. a. pμ qλ κ°μ§ μκ³ κ±°μ κ°μ ν¬κΈ°μ μλ¦ΏμμΌμΌ νλ€. b. p-1κ³Ό q-1μ 컀λ€λ μμΈμλ₯Ό κ°κ° κ°μ ΈμΌ νλ€. c. p-1κ³Ό q-1μ μ΅λ 곡μ½μλ μμ μμ¬μΌ νλ€
ꡬννμ§ μμμ§λ§, TMI
- μ€μ RSAμμ μ¬μ©νλ pμ qλ 100μ리 μ λμ μμλ‘ κ±°μ κ°μ ν¬κΈ°μ μλ¦Ώμλ₯Ό κ°μ§λ μλ₯Ό μ ννλ€.
μ½λ
rsa.h
#ifndef _RSA
#define _RSA
typedef struct key
{
long pkey; // μ΄κΈ° 2κ°μ μμ pμ qκ° κ³±ν΄μ λμ€λ nμ΄ μ μ₯λ λ³μ
long ekey; // public-key
long dkey; // private-key
int pkey_size;
} Key;
class Rsa
{
public:
Rsa();
virtual ~Rsa();
public:
Key produce_keys();
long endecrypt(const long msg, const long key, const long pkey);
int sizeof_int(long data);
private:
long produce_pkey(const long prime1, const long prime2);
long produce_ekey(const long orla);
long produce_dkey(const long ekey, const long orla);
long produce_prime();
long produce_orla(const long prime1, const long prime2);
long produce_gcd(const long a, const long b);
bool is_prime(const long digit);
};
#endif
main.cpp
#include "rsa.h"
#include <iostream>
using namespace std;
int main(void)
{
Rsa rsa;
Key key = rsa.produce_keys();
cout << "=============================" << endl;
cout << "=========== R S A ===========" << endl;
cout << "=============================\n" << endl;
cout << "=====================================" << endl;
cout << "μνΈν ν μ»μ ν€λ λ€μκ³Ό κ°μ΅λλ€."<< endl;
cout << "n ν€ : " << key.pkey << endl;
cout << "μνΈν ν€ (곡κ°ν€) : " << key.ekey << endl;
cout << "μνΈ ν΄λ
ν€ (κ°μΈν€) : " << key.dkey << endl;
cout << "=====================================\n" << endl;
long msg;
cout << "μνΈνν μ 보λ₯Ό μ
λ ₯νμμμ€ (μ«μ, λ무 ν΄ μ μμ) : ";
cin >> msg;
cout << "\n=====================================" << endl;
long msg_des = rsa.endecrypt(msg, key.ekey, key.pkey);
cout << "μνΈνλ μ 보λ λ€μκ³Ό κ°μ΅λλ€ : " << msg_des << endl;
msg_des = rsa.endecrypt(msg_des, key.dkey, key.pkey);
cout << "μνΈ ν΄λ
λ λ©μμ§λ λ€μκ³Ό κ°μ΅λλ€ : " << msg_des << endl;
cout << "=====================================" << endl;
return 0;
}
rsa.cpp
#include "rsa.h"
#include <cstdlib>
#include <ctime>
#include <string>
#include <bitset>
#include <iostream>
using namespace std;
Rsa::Rsa()
{
}
Rsa::~Rsa()
{
}
/***********************************************************************
μνΈν 볡νΈνλ₯Ό λμμ μ§ννλ λ©μλ
c = m^e mod n
m = c^d mod n
λΌλ μμ κ°κ³ λ³μλ§ λ§€κ°κ°λ§ λ°λλ©΄ λλ―λ‘ νλμ λ©μλμμ μ²λ¦¬ν¨
***********************************************************************/
long Rsa::endecrypt(const long msg, const long key, const long pkey)
{
long msg_des = 1;
long root = msg;
long index = key;
//int n_size = sizeof_int(pkey);
//int msg_size = sizeof_int(msg);
//int size = msg_size / n_size;
//if (msg_size % n_size)
// size = size + 1;
while (index)
{
//cout << bitset<32>(index) << endl;
if (index & 1) {
msg_des = (msg_des * root) % pkey;
//cout << "msg_des : " << msg_des << endl;
}
index >>= 1;
//cout << "b root : " << root << endl;
root = (root * root) % pkey;
//cout << "a root : " << root << endl;
}
return msg_des;
}
/************************************
pμ qλ₯Ό μμ±ν΄μ
n, e, d ν€λ₯Ό μμ±
* *********************************/
Key Rsa::produce_keys()
{
long prime1 = produce_prime(); // p
long prime2 = produce_prime(); // q
while (prime2 == prime1) // pμ qλ nμ λ§λ€κ³ νκΈ°ν΄μΌ νκΈ° λλ¬Έμ
prime2 = produce_prime(); // λ°λ‘ μ μ₯ν΄μ λ©μλ λ°μΌλ‘ λΉΌμ§ μμ
Key key;
long orla = produce_orla(prime1, prime2); // μ€μΌλ¬ n μμ±
key.pkey = produce_pkey(prime1, prime2); // n μμ±
key.ekey = produce_ekey(orla); // e μμ±
key.dkey = produce_dkey(key.ekey, orla); // d μμ±
return key;
}
/************************************
N ν€ μμ±
p * q
* *********************************/
long Rsa::produce_pkey(const long prime1, const long prime2)
{
return prime1 * prime2;
}
/************************************
μ€μΌλ¬ n μμ±
************************************/
long Rsa::produce_orla(const long prime1, const long prime2)
{
return (prime1 - 1) * (prime2 - 1);
}
/************************************
μνΈν ν€ (곡κ°ν€) e μμ±
* *********************************/
long Rsa::produce_ekey(const long orla)
{
long ekey;
while (true)
{
ekey = rand() % orla; // λλ€ μλ₯Ό μ€μΌλ¬ nμΌλ‘ λλ¨Έμ§ μ°μ°
if (ekey >= 2 && produce_gcd(ekey, orla) == 1) // e-keyμ μ€μΌλ¬ nμ΄ μλ‘μμΈμ§ νλ³
break;
}
return ekey;
}
/************************************
볡νΈν ν€ (κ°μΈν€) d μμ±
* *********************************/
long Rsa::produce_dkey(const long ekey, const long orla)
{
long dkey = orla / ekey;
while (true)
{
if (((dkey * ekey) % orla) == 1)
break;
else
++dkey;
}
return dkey;
}
/************************************
[100, 200] λ²μμμ μμμ μμ μμ±
* *********************************/
long Rsa::produce_prime()
{
long prime = 0;
srand(time(0));
while (true)
{
prime = rand() % 100 + 100;
if (is_prime(prime))
break;
}
return prime;
}
/************************************
λ μ«μμ μ΅λ 곡μ½μ μμ±
* *********************************/
long Rsa::produce_gcd(const long a, const long b)
{
long dividend = a;
long divisor = b;
long residual = dividend % divisor;
while (residual)
{
dividend = divisor;
divisor = residual;
residual = dividend % divisor;
}
return divisor;
}
/************************************
μμμΈμ§ νλ¨
* *********************************/
bool Rsa::is_prime(const long digit)
{
int tmp = 2;
while (tmp < digit)
if (!(digit % tmp++))
break;
if (tmp == digit)
return true;
return false;
}
/************************************
μ
λ ₯κ°μ μλ¦Ώμ νλ¨
* *********************************/
int Rsa::sizeof_int(long data)
{
int pos = 1;
if (data < 0)
data *= (-1);
for (int i = 0; ; i++, pos++) {
if ((data /= 10) <= 0)
break;
}
return pos;
}
κ²°κ³Ό
rsa.h
#ifndef _RSA
#define _RSA
typedef struct key
{
long pkey; // μ΄κΈ° 2κ°μ μμ pμ qκ° κ³±ν΄μ λμ€λ nμ΄ μ μ₯λ λ³μ
long ekey; // public-key
long dkey; // private-key
int pkey_size;
} Key;
class Rsa
{
public:
Rsa();
virtual ~Rsa();
public:
Key produce_keys();
long endecrypt(const long msg, const long key, const long pkey);
int sizeof_int(long data);
private:
long produce_pkey(const long prime1, const long prime2);
long produce_ekey(const long orla);
long produce_dkey(const long ekey, const long orla);
long produce_prime();
long produce_orla(const long prime1, const long prime2);
long produce_gcd(const long a, const long b);
bool is_prime(const long digit);
};
#endif
main.cpp
#include "rsa.h"
#include <iostream>
using namespace std;
int main(void)
{
Rsa rsa;
Key key = rsa.produce_keys();
cout << "=============================" << endl;
cout << "=========== R S A ===========" << endl;
cout << "=============================\n" << endl;
cout << "=====================================" << endl;
cout << "μνΈν ν μ»μ ν€λ λ€μκ³Ό κ°μ΅λλ€."<< endl;
cout << "n ν€ : " << key.pkey << endl;
cout << "μνΈν ν€ (곡κ°ν€) : " << key.ekey << endl;
cout << "μνΈ ν΄λ
ν€ (κ°μΈν€) : " << key.dkey << endl;
cout << "=====================================\n" << endl;
long msg;
cout << "μνΈνν μ 보λ₯Ό μ
λ ₯νμμμ€ (μ«μ, λ무 ν΄ μ μμ) : ";
cin >> msg;
cout << "\n=====================================" << endl;
long msg_des = rsa.endecrypt(msg, key.ekey, key.pkey);
cout << "μνΈνλ μ 보λ λ€μκ³Ό κ°μ΅λλ€ : " << msg_des << endl;
msg_des = rsa.endecrypt(msg_des, key.dkey, key.pkey);
cout << "μνΈ ν΄λ
λ λ©μμ§λ λ€μκ³Ό κ°μ΅λλ€ : " << msg_des << endl;
cout << "=====================================" << endl;
return 0;
}
rsa.cpp
#include "rsa.h"
#include <cstdlib>
#include <ctime>
#include <string>
#include <bitset>
#include <iostream>
using namespace std;
Rsa::Rsa()
{
}
Rsa::~Rsa()
{
}
/***********************************************************************
μνΈν 볡νΈνλ₯Ό λμμ μ§ννλ λ©μλ
c = m^e mod n
m = c^d mod n
λΌλ μμ κ°κ³ λ³μλ§ λ§€κ°κ°λ§ λ°λλ©΄ λλ―λ‘ νλμ λ©μλμμ μ²λ¦¬ν¨
***********************************************************************/
long Rsa::endecrypt(const long msg, const long key, const long pkey)
{
long msg_des = 1;
long root = msg;
long index = key;
//int n_size = sizeof_int(pkey);
//int msg_size = sizeof_int(msg);
//int size = msg_size / n_size;
//if (msg_size % n_size)
// size = size + 1;
while (index)
{
//cout << bitset<32>(index) << endl;
if (index & 1) {
msg_des = (msg_des * root) % pkey;
//cout << "msg_des : " << msg_des << endl;
}
index >>= 1;
//cout << "b root : " << root << endl;
root = (root * root) % pkey;
//cout << "a root : " << root << endl;
}
return msg_des;
}
/************************************
pμ qλ₯Ό μμ±ν΄μ
n, e, d ν€λ₯Ό μμ±
* *********************************/
Key Rsa::produce_keys()
{
long prime1 = produce_prime(); // p
long prime2 = produce_prime(); // q
while (prime2 == prime1) // pμ qλ nμ λ§λ€κ³ νκΈ°ν΄μΌ νκΈ° λλ¬Έμ
prime2 = produce_prime(); // λ°λ‘ μ μ₯ν΄μ λ©μλ λ°μΌλ‘ λΉΌμ§ μμ
Key key;
long orla = produce_orla(prime1, prime2); // μ€μΌλ¬ n μμ±
key.pkey = produce_pkey(prime1, prime2); // n μμ±
key.ekey = produce_ekey(orla); // e μμ±
key.dkey = produce_dkey(key.ekey, orla); // d μμ±
return key;
}
/************************************
N ν€ μμ±
p * q
* *********************************/
long Rsa::produce_pkey(const long prime1, const long prime2)
{
return prime1 * prime2;
}
/************************************
μ€μΌλ¬ n μμ±
************************************/
long Rsa::produce_orla(const long prime1, const long prime2)
{
return (prime1 - 1) * (prime2 - 1);
}
/************************************
μνΈν ν€ (곡κ°ν€) e μμ±
* *********************************/
long Rsa::produce_ekey(const long orla)
{
long ekey;
while (true)
{
ekey = rand() % orla; // λλ€ μλ₯Ό μ€μΌλ¬ nμΌλ‘ λλ¨Έμ§ μ°μ°
if (ekey >= 2 && produce_gcd(ekey, orla) == 1) // e-keyμ μ€μΌλ¬ nμ΄ μλ‘μμΈμ§ νλ³
break;
}
return ekey;
}
/************************************
볡νΈν ν€ (κ°μΈν€) d μμ±
* *********************************/
long Rsa::produce_dkey(const long ekey, const long orla)
{
long dkey = orla / ekey;
while (true)
{
if (((dkey * ekey) % orla) == 1)
break;
else
++dkey;
}
return dkey;
}
/************************************
[100, 200] λ²μμμ μμμ μμ μμ±
* *********************************/
long Rsa::produce_prime()
{
long prime = 0;
srand(time(0));
while (true)
{
prime = rand() % 100 + 100;
if (is_prime(prime))
break;
}
return prime;
}
/************************************
λ μ«μμ μ΅λ 곡μ½μ μμ±
* *********************************/
long Rsa::produce_gcd(const long a, const long b)
{
long dividend = a;
long divisor = b;
long residual = dividend % divisor;
while (residual)
{
dividend = divisor;
divisor = residual;
residual = dividend % divisor;
}
return divisor;
}
/************************************
μμμΈμ§ νλ¨
* *********************************/
bool Rsa::is_prime(const long digit)
{
int tmp = 2;
while (tmp < digit)
if (!(digit % tmp++))
break;
if (tmp == digit)
return true;
return false;
}
/************************************
μ
λ ₯κ°μ μλ¦Ώμ νλ¨
* *********************************/
int Rsa::sizeof_int(long data)
{
int pos = 1;
if (data < 0)
data *= (-1);
for (int i = 0; ; i++, pos++) {
if ((data /= 10) <= 0)
break;
}
return pos;
}
κ²°κ³Ό
#ifndef _RSA
#define _RSA
typedef struct key
{
long pkey; // μ΄κΈ° 2κ°μ μμ pμ qκ° κ³±ν΄μ λμ€λ nμ΄ μ μ₯λ λ³μ
long ekey; // public-key
long dkey; // private-key
int pkey_size;
} Key;
class Rsa
{
public:
Rsa();
virtual ~Rsa();
public:
Key produce_keys();
long endecrypt(const long msg, const long key, const long pkey);
int sizeof_int(long data);
private:
long produce_pkey(const long prime1, const long prime2);
long produce_ekey(const long orla);
long produce_dkey(const long ekey, const long orla);
long produce_prime();
long produce_orla(const long prime1, const long prime2);
long produce_gcd(const long a, const long b);
bool is_prime(const long digit);
};
#endif
#include "rsa.h"
#include <iostream>
using namespace std;
int main(void)
{
Rsa rsa;
Key key = rsa.produce_keys();
cout << "=============================" << endl;
cout << "=========== R S A ===========" << endl;
cout << "=============================\n" << endl;
cout << "=====================================" << endl;
cout << "μνΈν ν μ»μ ν€λ λ€μκ³Ό κ°μ΅λλ€."<< endl;
cout << "n ν€ : " << key.pkey << endl;
cout << "μνΈν ν€ (곡κ°ν€) : " << key.ekey << endl;
cout << "μνΈ ν΄λ
ν€ (κ°μΈν€) : " << key.dkey << endl;
cout << "=====================================\n" << endl;
long msg;
cout << "μνΈνν μ 보λ₯Ό μ
λ ₯νμμμ€ (μ«μ, λ무 ν΄ μ μμ) : ";
cin >> msg;
cout << "\n=====================================" << endl;
long msg_des = rsa.endecrypt(msg, key.ekey, key.pkey);
cout << "μνΈνλ μ 보λ λ€μκ³Ό κ°μ΅λλ€ : " << msg_des << endl;
msg_des = rsa.endecrypt(msg_des, key.dkey, key.pkey);
cout << "μνΈ ν΄λ
λ λ©μμ§λ λ€μκ³Ό κ°μ΅λλ€ : " << msg_des << endl;
cout << "=====================================" << endl;
return 0;
}
rsa.cpp
#include "rsa.h"
#include <cstdlib>
#include <ctime>
#include <string>
#include <bitset>
#include <iostream>
using namespace std;
Rsa::Rsa()
{
}
Rsa::~Rsa()
{
}
/***********************************************************************
μνΈν 볡νΈνλ₯Ό λμμ μ§ννλ λ©μλ
c = m^e mod n
m = c^d mod n
λΌλ μμ κ°κ³ λ³μλ§ λ§€κ°κ°λ§ λ°λλ©΄ λλ―λ‘ νλμ λ©μλμμ μ²λ¦¬ν¨
***********************************************************************/
long Rsa::endecrypt(const long msg, const long key, const long pkey)
{
long msg_des = 1;
long root = msg;
long index = key;
//int n_size = sizeof_int(pkey);
//int msg_size = sizeof_int(msg);
//int size = msg_size / n_size;
//if (msg_size % n_size)
// size = size + 1;
while (index)
{
//cout << bitset<32>(index) << endl;
if (index & 1) {
msg_des = (msg_des * root) % pkey;
//cout << "msg_des : " << msg_des << endl;
}
index >>= 1;
//cout << "b root : " << root << endl;
root = (root * root) % pkey;
//cout << "a root : " << root << endl;
}
return msg_des;
}
/************************************
pμ qλ₯Ό μμ±ν΄μ
n, e, d ν€λ₯Ό μμ±
* *********************************/
Key Rsa::produce_keys()
{
long prime1 = produce_prime(); // p
long prime2 = produce_prime(); // q
while (prime2 == prime1) // pμ qλ nμ λ§λ€κ³ νκΈ°ν΄μΌ νκΈ° λλ¬Έμ
prime2 = produce_prime(); // λ°λ‘ μ μ₯ν΄μ λ©μλ λ°μΌλ‘ λΉΌμ§ μμ
Key key;
long orla = produce_orla(prime1, prime2); // μ€μΌλ¬ n μμ±
key.pkey = produce_pkey(prime1, prime2); // n μμ±
key.ekey = produce_ekey(orla); // e μμ±
key.dkey = produce_dkey(key.ekey, orla); // d μμ±
return key;
}
/************************************
N ν€ μμ±
p * q
* *********************************/
long Rsa::produce_pkey(const long prime1, const long prime2)
{
return prime1 * prime2;
}
/************************************
μ€μΌλ¬ n μμ±
************************************/
long Rsa::produce_orla(const long prime1, const long prime2)
{
return (prime1 - 1) * (prime2 - 1);
}
/************************************
μνΈν ν€ (곡κ°ν€) e μμ±
* *********************************/
long Rsa::produce_ekey(const long orla)
{
long ekey;
while (true)
{
ekey = rand() % orla; // λλ€ μλ₯Ό μ€μΌλ¬ nμΌλ‘ λλ¨Έμ§ μ°μ°
if (ekey >= 2 && produce_gcd(ekey, orla) == 1) // e-keyμ μ€μΌλ¬ nμ΄ μλ‘μμΈμ§ νλ³
break;
}
return ekey;
}
/************************************
볡νΈν ν€ (κ°μΈν€) d μμ±
* *********************************/
long Rsa::produce_dkey(const long ekey, const long orla)
{
long dkey = orla / ekey;
while (true)
{
if (((dkey * ekey) % orla) == 1)
break;
else
++dkey;
}
return dkey;
}
/************************************
[100, 200] λ²μμμ μμμ μμ μμ±
* *********************************/
long Rsa::produce_prime()
{
long prime = 0;
srand(time(0));
while (true)
{
prime = rand() % 100 + 100;
if (is_prime(prime))
break;
}
return prime;
}
/************************************
λ μ«μμ μ΅λ 곡μ½μ μμ±
* *********************************/
long Rsa::produce_gcd(const long a, const long b)
{
long dividend = a;
long divisor = b;
long residual = dividend % divisor;
while (residual)
{
dividend = divisor;
divisor = residual;
residual = dividend % divisor;
}
return divisor;
}
/************************************
μμμΈμ§ νλ¨
* *********************************/
bool Rsa::is_prime(const long digit)
{
int tmp = 2;
while (tmp < digit)
if (!(digit % tmp++))
break;
if (tmp == digit)
return true;
return false;
}
/************************************
μ
λ ₯κ°μ μλ¦Ώμ νλ¨
* *********************************/
int Rsa::sizeof_int(long data)
{
int pos = 1;
if (data < 0)
data *= (-1);
for (int i = 0; ; i++, pos++) {
if ((data /= 10) <= 0)
break;
}
return pos;
}
κ²°κ³Ό
#include "rsa.h"
#include <cstdlib>
#include <ctime>
#include <string>
#include <bitset>
#include <iostream>
using namespace std;
Rsa::Rsa()
{
}
Rsa::~Rsa()
{
}
/***********************************************************************
μνΈν 볡νΈνλ₯Ό λμμ μ§ννλ λ©μλ
c = m^e mod n
m = c^d mod n
λΌλ μμ κ°κ³ λ³μλ§ λ§€κ°κ°λ§ λ°λλ©΄ λλ―λ‘ νλμ λ©μλμμ μ²λ¦¬ν¨
***********************************************************************/
long Rsa::endecrypt(const long msg, const long key, const long pkey)
{
long msg_des = 1;
long root = msg;
long index = key;
//int n_size = sizeof_int(pkey);
//int msg_size = sizeof_int(msg);
//int size = msg_size / n_size;
//if (msg_size % n_size)
// size = size + 1;
while (index)
{
//cout << bitset<32>(index) << endl;
if (index & 1) {
msg_des = (msg_des * root) % pkey;
//cout << "msg_des : " << msg_des << endl;
}
index >>= 1;
//cout << "b root : " << root << endl;
root = (root * root) % pkey;
//cout << "a root : " << root << endl;
}
return msg_des;
}
/************************************
pμ qλ₯Ό μμ±ν΄μ
n, e, d ν€λ₯Ό μμ±
* *********************************/
Key Rsa::produce_keys()
{
long prime1 = produce_prime(); // p
long prime2 = produce_prime(); // q
while (prime2 == prime1) // pμ qλ nμ λ§λ€κ³ νκΈ°ν΄μΌ νκΈ° λλ¬Έμ
prime2 = produce_prime(); // λ°λ‘ μ μ₯ν΄μ λ©μλ λ°μΌλ‘ λΉΌμ§ μμ
Key key;
long orla = produce_orla(prime1, prime2); // μ€μΌλ¬ n μμ±
key.pkey = produce_pkey(prime1, prime2); // n μμ±
key.ekey = produce_ekey(orla); // e μμ±
key.dkey = produce_dkey(key.ekey, orla); // d μμ±
return key;
}
/************************************
N ν€ μμ±
p * q
* *********************************/
long Rsa::produce_pkey(const long prime1, const long prime2)
{
return prime1 * prime2;
}
/************************************
μ€μΌλ¬ n μμ±
************************************/
long Rsa::produce_orla(const long prime1, const long prime2)
{
return (prime1 - 1) * (prime2 - 1);
}
/************************************
μνΈν ν€ (곡κ°ν€) e μμ±
* *********************************/
long Rsa::produce_ekey(const long orla)
{
long ekey;
while (true)
{
ekey = rand() % orla; // λλ€ μλ₯Ό μ€μΌλ¬ nμΌλ‘ λλ¨Έμ§ μ°μ°
if (ekey >= 2 && produce_gcd(ekey, orla) == 1) // e-keyμ μ€μΌλ¬ nμ΄ μλ‘μμΈμ§ νλ³
break;
}
return ekey;
}
/************************************
볡νΈν ν€ (κ°μΈν€) d μμ±
* *********************************/
long Rsa::produce_dkey(const long ekey, const long orla)
{
long dkey = orla / ekey;
while (true)
{
if (((dkey * ekey) % orla) == 1)
break;
else
++dkey;
}
return dkey;
}
/************************************
[100, 200] λ²μμμ μμμ μμ μμ±
* *********************************/
long Rsa::produce_prime()
{
long prime = 0;
srand(time(0));
while (true)
{
prime = rand() % 100 + 100;
if (is_prime(prime))
break;
}
return prime;
}
/************************************
λ μ«μμ μ΅λ 곡μ½μ μμ±
* *********************************/
long Rsa::produce_gcd(const long a, const long b)
{
long dividend = a;
long divisor = b;
long residual = dividend % divisor;
while (residual)
{
dividend = divisor;
divisor = residual;
residual = dividend % divisor;
}
return divisor;
}
/************************************
μμμΈμ§ νλ¨
* *********************************/
bool Rsa::is_prime(const long digit)
{
int tmp = 2;
while (tmp < digit)
if (!(digit % tmp++))
break;
if (tmp == digit)
return true;
return false;
}
/************************************
μ
λ ₯κ°μ μλ¦Ώμ νλ¨
* *********************************/
int Rsa::sizeof_int(long data)
{
int pos = 1;
if (data < 0)
data *= (-1);
for (int i = 0; ; i++, pos++) {
if ((data /= 10) <= 0)
break;
}
return pos;
}
μ°Έκ³ λ¬Έν
GitHub, "RSA Encryption Decryption", https://github.com/cassvin/Rsa, (2020.06.05.)
GitHub, "RSA Encryption Decryption", https://github.com/cassvin/Rsa, (2020.06.05.)
μ΄ κΈμ΄ λμμ΄ λμλμ?
Ghost