⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rsacryptosystem.cpp

📁 C++ implementaion for RSA together with the Wiener attack. It uses NTL library for big numbers
💻 CPP
字号:
#include "RSACryptoSystem.h"
#include <time.h>
using namespace std;
//***************************************************************
// Constructors
//***************************************************************
// if bitsNr is little then 512 the bitNr is automaticly set on 512
// if privateKeyFile or publickKeyFile is Empty String the key are automaticaly Generated;
RSACryptoSystem::RSACryptoSystem(string privateKeyFile, string publicKeyFile, long bitsNr)
{

	if (privateKeyFile == "" || publicKeyFile == "")
	{
		if (bitsNr > 512)
			m_lBitsNr = bitsNr;
		else
			m_lBitsNr = 512;
		GenerateKeys();
	}
	else
		LoadKeys(publicKeyFile, privateKeyFile);

	ofstream ofs("Voter4PrvKey.txt");
	ofs << m_privateKey.P << '\n';
	ofs << m_privateKey.Q << '\n'; 
	ofs << m_privateKey.D << '\n';

	ofstream ofs1("Voter4PubKey.txt");
	ofs1 << m_publicKey.N << '\n';
	ofs1 << m_publicKey.E << '\n';

	ofs.close();
	ofs1.close();

	//cout << "Weak D: " << m_privateKey.D <<"\n\n";
	
}

RSACryptoSystem::~RSACryptoSystem(void)
{
}

//***************************************************************
// Utils
//***************************************************************
// Generate
//	P,Q  - large prime number ( >= 512 bits)
//	N = p*Q
//  E,D from FI(N), E*D congr 1 mod FI(N) / E small but D > (1/3)*N^(1/4)
//					eqv with D represented on at least ((nrB + 1)/4) + 1 bits
void RSACryptoSystem::GenerateKeys()
{
	time_t t;
	time( &t );
	NTL::SetSeed(NTL::to_ZZ((unsigned long)(t + 15))); 

	// P, Q
	NTL::GenPrime(m_privateKey.P, m_lBitsNr, 100);
	do
	{
		NTL::GenPrime(m_privateKey.Q, m_lBitsNr, 100);
	}
	while (m_privateKey.Q < m_privateKey.P && m_privateKey.P < 2* m_privateKey.Q);

	// N
	NTL::ZZ phiN;
	NTL::mul(m_publicKey.N, m_privateKey.P, m_privateKey.Q);

	NTL::mul(phiN, m_privateKey.P -1, m_privateKey.Q - 1);
	//D
	
	do 
	{
		NTL::RandomPrime(m_privateKey.D, m_lBitsNr - 32, 100);
	}
	while (NTL::divide(phiN, m_privateKey.D) == 1);

	if ( NTL::InvModStatus(m_publicKey.E, m_privateKey.D, phiN) != 0) //error InvMod doesn't exists
		throw "InvMod of D doesn't exists";
}

void RSACryptoSystem::LoadKeys(std::string publicKeyFile,std::string privateKeyFile)
{
	ifstream ifsPublic(publicKeyFile.c_str());
	ifstream ifsPrivate(privateKeyFile.c_str());
	if (!ifsPublic.is_open())
	{
		cout << "The Public Key File couldn't be open. The Keys were automaticaly generated";
		return;
	}
	if (!ifsPrivate.is_open())
	{
		cout << "The Private Key File couldn't be open. The Keys were automaticaly generated";
		return;
	}

	ifsPrivate >> m_privateKey.P;
	ifsPrivate >> m_privateKey.Q;
	ifsPrivate >> m_privateKey.D;

	ifsPublic >> m_publicKey.N;
	ifsPublic >> m_publicKey.E;

	ifsPrivate.close();
	ifsPublic.close();
}
//***************************************************************
// Get Methods
//***************************************************************
RSACryptoSystem::PublicKey RSACryptoSystem::GetPublicKey() const
{
	return m_publicKey;
}

//***************************************************************
// Crypto Function
//***************************************************************

void RSACryptoSystem::Encode(const NTL::ZZ &x, NTL::ZZ &y, const RSACryptoSystem::PublicKey &key)
{
	if (x > key.N)
		throw "Plain Text must be from Z_N";
	NTL::PowerMod(y, x, key.E, key.N);
}

void RSACryptoSystem::Decode(const NTL::ZZ &y, NTL::ZZ &x)
{
	// Clasic Decoding
	//NTL::PowerMod(x, y, m_privateKey.D, m_publicKey.N);

	// Decode using Chiness Remainder Theorem
	//	x = solution  for
	//		x congr xp mod p;
	//		x congr xq mod q;

	//		x1 = (q % p)^(-1) * xp mod p
	//		x1 = (p % q)^(-1) * xq mod q
	//		x = (q*x1 + p*x2) mod n;
	
	
	NTL::ZZ xp;
	NTL::ZZ xq;

	NTL::PowerMod(xp, y % m_privateKey.P, m_privateKey.D % (m_privateKey.P - 1) , m_privateKey.P);
	NTL::PowerMod(xq, y % m_privateKey.Q, m_privateKey.D % (m_privateKey.P - 1), m_privateKey.Q);

	NTL::ZZ x1;
	NTL::InvMod(x1, m_privateKey.Q % m_privateKey.P, m_privateKey.P);
	NTL::MulMod(x1, x1, xp, m_privateKey.P);

	NTL::ZZ x2;
	NTL::InvMod(x2, m_privateKey.P % m_privateKey.Q, m_privateKey.Q);
	NTL::MulMod(x2, x2, xq, m_privateKey.Q);

	NTL::MulMod(x1, x1, m_privateKey.Q, m_publicKey.N);
	NTL::MulMod(x2, x2, m_privateKey.P, m_publicKey.N);
	NTL::AddMod(x, x1, x2, m_publicKey.N);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -