0% found this document useful (0 votes)
15 views7 pages

Q6 Digital Signature With RSA

Uploaded by

Aravind krishna
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views7 pages

Q6 Digital Signature With RSA

Uploaded by

Aravind krishna
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

#include <NTL/ZZ.

h>
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <random>

using namespace std;


using namespace NTL;

int randomNumber(){
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, (int)1e9);

return dis(gen);
}

ZZ stringToZZ(const string &str) {


ZZ result = ZZ(0);
for (char ch : str) {
result *= 256; // Shift left by 8 bits
result += static_cast<unsigned char>(ch);
}
return result;
}

string ZZToString(const ZZ &num) {


ZZ temp = num;
string result;
while (temp > 0) {
result = static_cast<char>(to_int(temp % 256)) + result;
temp /= 256; // Shift right by 8 bits
}
return result;
}

ZZ mypow(ZZ a, ZZ b){
ZZ result = ZZ(1);
ZZ multi = ZZ(a);
while(b > 0){
if(b % 2 == 1){
result *= multi;
}
multi *= multi;
b >>= 1;
}
return result;
}

ZZ generate_large_number(int bits){
ZZ value = ZZ(1);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 1);

for(int i = 0; i < bits; i++){


if(dis(gen) == 0){
value += mypow(ZZ(2), ZZ(i));
}
}

return value;
}
ZZ myPowModN(ZZ a, ZZ b, ZZ mod){
ZZ result = ZZ(1);
ZZ multi = ZZ(a);
while(b > 0){
if(b%2 == 1){
result *= multi;
result %= mod;
}
multi *= multi;
multi %= mod;
b = b>>1;
}
return result%mod;
}

bool myProbPrime(ZZ number){


if(number < 2 || number %2 == 0) return false;

ZZ d = number - 1;
ZZ s = ZZ(0);
while(d % 2 == 0){
s++;
d /= 2;
}

ZZ random_between_two_and_n_minus_2 = number/randomNumber();

ZZ x_a_power_d_mod_n =
myPowModN(random_between_two_and_n_minus_2, d, number);

if(x_a_power_d_mod_n == 1 || x_a_power_d_mod_n == (number - 1)){


return true;
}
int tries = 2000;

while(tries > 0){


if(x_a_power_d_mod_n == 1 || x_a_power_d_mod_n == (number -
1)){
return true;
}
x_a_power_d_mod_n = myPowModN(x_a_power_d_mod_n, ZZ(2),
number);
tries--;
}
return false;
}

ZZ generate_prime(int bits){
ZZ prime;
// generate large number
int tries = 0;
ZZ number = generate_large_number(bits);
while(!myProbPrime(number)){
number = generate_large_number(bits);
cout<<number<<endl;
tries++;
}
cout<<"Number of tries: "<<tries<<endl;

return number;

ZZ extended_gcd(ZZ a, ZZ b, ZZ& x, ZZ& y){


if(a == 0){
x = 0;
y = 1;
return b;
}

ZZ x1, y1;
ZZ gcd = extended_gcd(b%a, a, x1, y1);

x = y1 - (b/a) * x1;
y = x1;

return gcd;
}

ZZ modInv(ZZ e, ZZ d){
// e * d = 1 (d)
ZZ x, y;
ZZ gcd = extended_gcd(e, d, x, y);

if(gcd != 1){
return ZZ(-1);
}else{
return x%d;
}
}
int main() {
// Step 1: Generate RSA keys
ZZ p, q, n, phi, e, d;
long keySize = 1024; // Minimum key size for RSA
p = generate_prime( keySize / 2);
q = generate_prime( keySize / 2);
n = p * q;
phi = (p - 1) * (q - 1);

// Choose public exponent e (commonly 65537)


e = ZZ(65537);
// Compute private exponent d
d = modInv(e, phi);

cout << "Keys generated successfully!" << endl;

// Step 2: Input the message to sign


string message = "Secure message";
ZZ m = stringToZZ(message);

if (m >= n) {
cerr << "Error: Message size too large for the chosen key
size." << endl;
return 1;
}

// Step 3: Sign the message (m^d mod n)


ZZ signature = myPowModN(m, d, n);
cout << "Message signed successfully!" << endl;

// Step 4: Verify the signature (s^e mod n == m)


ZZ verifiedMessage = myPowModN(signature, e, n);
if (verifiedMessage == m) {
cout << "Signature is valid!" << endl;
} else {
cout << "Signature is invalid!" << endl;
}

return 0;
}

You might also like