logo

RSA algoritem v kriptografiji

RSA algoritem je asimetrični kriptografski algoritem. Asimetrično dejansko pomeni, da deluje na dveh različnih tipkah, tj. Javni ključ in Zasebni ključ. Kot že ime pove, je javni ključ dan vsem, zasebni ključ pa ostane zaseben.

kako velik je ta monitor

Primer asimetrične kriptografije:

  1. Odjemalec (na primer brskalnik) pošlje svoj javni ključ strežniku in zahteva nekaj podatkov.
  2. Strežnik šifrira podatke z odjemalčevim javnim ključem in pošlje šifrirane podatke.
  3. Odjemalec prejme te podatke in jih dešifrira.

Ker je to asimetrično, nihče drug razen brskalnika ne more dešifrirati podatkov, tudi če ima tretja oseba javni ključ brskalnika.



Ideja! Ideja RSA temelji na dejstvu, da je težko faktorizirati veliko celo število. Javni ključ je sestavljen iz dveh števil, pri čemer je eno število množenje dveh velikih praštevil. In zasebni ključ je prav tako izpeljan iz istih dveh praštevil. Torej, če lahko nekdo faktorizira veliko število, je zasebni ključ ogrožen. Zato je moč šifriranja v celoti odvisna od velikosti ključa in če podvojimo ali potrojimo velikost ključa, se moč šifriranja eksponentno poveča. Ključi RSA so običajno lahko dolgi 1024 ali 2048 bitov, vendar strokovnjaki menijo, da bi lahko 1024-bitne ključe v bližnji prihodnosti zlomili. A do zdaj se zdi, da je to neizvedljiva naloga.

Spoznajmo mehanizem za algoritmom RSA:>> Generiranje javnega ključa:

Select two prime no's. Suppose   P = 53 and Q = 59.    Now First part of the Public key : n = P*Q = 3127.   We also need a small exponent say   e :     But e Must be     An integer.    Not be a factor of Φ(n).     1     Φ(n) [Φ(n) is discussed below],>> Generiranje zasebnega ključa: Izračunati moramo Φ(n) : Tako, da je Φ(n) = (P-1)(Q-1), torej Φ(n) = 3016 Zdaj izračunajte zasebni ključ, d : d = (k *Φ(n) + 1) / e za neko celo število k Za k = 2 je vrednost d 2011. Zdaj smo pripravljeni z našim – javnim ključem ( n = 3127 in e = 3) in zasebnim ključem (d = 2011 ) Zdaj bomo šifrirali HI : Pretvorili črke v številke : H = 8 in I = 9 Tako šifrirani podatki c = (89 e )mod n Tako bodo naši šifrirani podatki 1394 Zdaj bomo dešifrirali 1394 : Dešifrirani podatki = (c d )mod n Tako so naši šifrirani podatki 89 8 = H in I = 9, tj. 'HI'.    Spodaj je implementacija algoritma RSA za 1. metodo: šifriranje in dešifriranje majhnih številskih vrednosti: C++ // program C za asimetrični kriptografski // algoritem RSA. Za predstavitvene vrednosti so // razmeroma majhne v primerjavi s praktičnimi // aplikacija #include using namespace std; // Vrne gcd a in b int gcd(int a, int h) { int temp;  medtem ko (1) { temp = a % h;  if (temp == 0) vrni h;  a = h;  h = temp;  } } // Koda za prikaz algoritma RSA int main() { // Dve naključni praštevili double p = 3;  dvojni q = 7;  // Prvi del javnega ključa: double n = p * q;  // Iskanje drugega dela javnega ključa.  // e pomeni encrypt double e = 2;  dvojni fi = (p - 1) * (q - 1);  medtem ko (e // e mora biti enako praštevilsko s phi in // manjši od phi. if (gcd(e, phi) == 1) break; else e++; } // Zasebni ključ (d pomeni dešifriranje) // izbira d tako, da izpolnjuje // d*e = 1 + k * totient int k = 2; // Konstantna vrednost double d = (1 + (k * phi)) / e; // Sporočilo za šifriranje dvojno sporočilo = 12; printf('Message data = %lf', msg); // Šifriranje c = (msg ^ e) % n double c = pow(msg, e); c = fmod(c, n); ('
Šifrirani podatki = %lf', c); // Dešifriranje m = (c ^ d) % n double m = pow(c, d); m = fmod(m, n); 
Originalno sporočilo = %lf', m); return 0; } // To kodo je prispeval Akash Sharan java.math.*; import java.util.*; /* * Program Java za asimetrični kriptografski algoritem * Za predstavitev so razmeroma majhne v primerjavi s praktično uporabo */ public static double gcd(double a. , double h) { /* * Ta funkcija vrne gcd ali največji skupni * delitelj */ double temp;  medtem ko (true) { temp = a % h;  if (temp == 0) vrni h;  a = h;  h = temp;  } } public static void main(String[] args) { double p = 3;  dvojno q = 7;  // Shrani prvi del javnega ključa: double n = p * q;  // Iskanje drugega dela javnega ključa.  // dvojni e pomeni encrypt double e = 2;  dvojni fi = (p - 1) * (q - 1);  medtem ko (e /* * e mora biti enako praštevilo s phi in * manjše od phi. */ if (gcd(e, phi) == 1) break; sicer e++; } int k = 2; // Konstantna vrednost double d = (1 + (k * phi)) / e; // Šifriranje sporočila double msg = 12; ^ e) % n double c = Math.pow(msg, e); c = c % n('Šifrirani podatki = ' + c); % n double m = Math.pow(c, d); m = m % n;'Original Message Sent = ' + m} // To kodo prispeva Pranay Arora. Python3 # Python za asimetrični kriptografski algoritem # Za predstavitev so vrednosti relativno majhne v primerjavi s praktično aplikacijo import math def gcd(a, h): temp = 0 while(1): temp = a % h if (temp ==). 0): vrni h a = h h = temp p = 3 q = 7 n = p*q e = 2 phi = (p-1)*(q-1) medtem ko (e # e mora biti enako praštevilo phi in # manjše kot phi. if(gcd(e, phi) == 1): break else: e = e+1 # Zasebni ključ (d pomeni dešifriranje) # izbira d tako, da izpolnjuje # d*e = 1 + k * totient k = 2 d = (1 + (k*phi))/e # Sporočilo za šifriranje msg = 12.0 print('Podatki sporočila = ', msg) # Šifriranje c = (msg ^ e) % n c = pow( msg, e) c = math.fmod(c, n) print('Šifrirani podatki = ', c) # Dešifriranje m = (c ^ d) % n m = pow(c, d) m = math.fmod( m, n) print('Originalno sporočilo poslano = ', m) # To kodo je prispeval Pranay Arora.  C# /* * Program C# za asimetrični kriptografski algoritem RSA.  * Za predstavitev so vrednosti * razmeroma majhne v primerjavi s praktično uporabo */ z uporabo sistema; public class GFG { public static double gcd(double a, double h) { /* * Ta funkcija vrne gcd ali največji skupni * delitelj */ double temp;  medtem ko (true) { temp = a % h;  if (temp == 0) vrni h;  a = h;  h = temp;  } } static void Main() { double p = 3;  dvojno q = 7;  // Shrani prvi del javnega ključa: double n = p * q;  // Iskanje drugega dela javnega ključa.  // dvojni e pomeni encrypt double e = 2;  dvojni fi = (p - 1) * (q - 1);  medtem ko (e /* * e mora biti enako praštevilo s phi in * manjše od phi. */ if (gcd(e, phi) == 1) break; sicer e++; } int k = 2; // Konstantna vrednost double d = (1 + (k * phi)) / e; // Sporočilo, ki ga je treba šifrirati double msg = 12; ', msg)); // Šifriranje c = (msg ^ e) % n double c = Math.Pow(msg, e); c = c % n; Format('{0:F6}', c)); // Dešifriranje m = (c ^ d) % double m = Math.Pow(c, d); m = m % n; 'Izvirno sporočilo poslano = ' + String.Format('{0:F6}', m)); // To kodo je prispeval Pranay Arora. Javascript //GFG //Koda JavaScript za ta pristop funkcija gcd(a, h) { /* * Ta funkcija vrne gcd ali največji skupni */ let temp medtem ko (true) { temp = a % h; if (temp == 0) return h; h = temp; } let p = 7; // Shrani prvi del javnega ključa: let n = p * q; // Iskanje drugega dela javnega ključa. // e pomeni encrypt let e = 2; naj bo phi = (p - 1) * (q - 1); medtem ko (e /* * e mora biti enako praštevilo s phi in * manjše od phi. */ if (gcd(e, phi) == 1) break; sicer e++; } naj k = 2; // Konstantna vrednost let d = (1 + (k * phi)) / e; // Sporočilo za šifriranje let msg = 12; // Šifriranje c = (msg ^ e ) % n let c = Math.pow(msg, e); c = c % n; console.log('Šifrirani podatki = ' + c); // Dešifriranje m = (c ^ d) % n let m = Math.pow(c, d); m = m % n; console.log('Original Message Sent = ' + m); //To kodo je napisal Sundaram Output Message data = 12,000000 Šifrirani podatki = 3,000000 Poslano sporočilo = 12,000000 2. način: Šifriranje in dešifriranje navadnih besedilnih sporočil, ki vsebujejo črke in številke, z uporabo njihove vrednosti ASCII: C++ #include using namespace std; prime; // niz bo zbirka praštevil, // kjer lahko izberemo naključna praštevila p in q int public_key; int zasebni_ključ; int n; // funkcijo bomo zagnali samo enkrat, da zapolnimo niz // praštevil void primefiller() { // metoda, uporabljena za zapolnitev niza praštevil, je seive of // eratosthenes (metoda za zbiranje praštevil) vektor seive (250, res);  seive[0] = false;  seive[1] = false;  za (int i = 2; i<250; i++) {  for (int j = i * 2; j <250; j += i) {  seive[j] = false;  }  } // filling the prime numbers  for (int i = 0; i   if (seive[i])  prime.insert(i);  } } // picking a random prime number and erasing that prime // number from list because p!=q int pickrandomprime() {  int k = rand() % prime.size();  auto it = prime.begin();  while (k--)  it++;  int ret = *it;  prime.erase(it);  return ret; } void setkeys() {  int prime1 = pickrandomprime(); // first prime number  int prime2 = pickrandomprime(); // second prime number  // to check the prime numbers selected  // cout<  n = prime1 * prime2;  int fi = (prime1 - 1) * (prime2 - 1);  int e = 2;  while (1) {  if (__gcd(e, fi) == 1)  break;  e++;  } // d = (k*Φ(n) + 1) / e for some integer k  public_key = e;  int d = 2;  while (1) {  if ((d * e) % fi == 1)  break;  d++;  }  private_key = d; } // to encrypt the given number long long int encrypt(double message) {  int e = public_key;  long long int encrpyted_text = 1;  while (e--) {  encrpyted_text *= message;  encrpyted_text %= n;  }  return encrpyted_text; } // to decrypt the given number long long int decrypt(int encrpyted_text) {  int d = private_key;  long long int decrypted = 1;  while (d--) {  decrypted *= encrpyted_text;  decrypted %= n;  }  return decrypted; } // first converting each character to its ASCII value and // then encoding it then decoding the number to get the // ASCII and converting it to character vector kodirnik(sporočilo niza) { vektor oblika;  // klic šifrirne funkcije v kodirni funkciji za (auto& letter : message) form.push_back(encrypt((int)letter));  obrazec za vračilo; } dekoder nizov (vektor kodirano) { niz s;  // klic funkcije dešifriranja funkcije dekodiranja za (auto& num : encoded) s += decrypt(num);  vrni s; } int main() { primefiller();  setkeys();  string message = 'Testno sporočilo';  // odpirajte komentarje spodaj za ročni vnos // cout<<'enter the message
';getline(cin,message);  // calling the encoding function  vector kodirano = kodirnik(sporočilo);  cout<< 'Initial message:
' << message;  cout << '

The encoded message(encrypted by public '  'key)
';  for (auto& p : coded)  cout << p;  cout << '

The decoded message(decrypted by private '  'key)
';  cout << decoder(coded) << endl;  return 0; }  Java       import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Random; public class GFG {  private static HashSet prime = new HashSet();  private static Integer public_key = null;  private static Integer private_key = null;  private static Integer n = null;  private static Random random = new Random();  public static void main(String[] args)  {  primeFiller();  setKeys();  String message = 'Test Message';  // Uncomment below for manual input  // System.out.println('Enter the message:');  // message = new Scanner(System.in).nextLine();  List coded = encoder(message);  System.out.println('Initial message:');  System.out.println(message);  System.out.println(  '

The encoded message (encrypted by public key)
');  System.out.println(  String.join('', coded.stream()  .map(Object::toString)  .toArray(String[] ::new)));  System.out.println(  '

The decoded message (decrypted by public key)
');  System.out.println(decoder(coded));  }  public static void primeFiller()  {  boolean[] sieve = new boolean[250];  for (int i = 0; i <250; i++) {  sieve[i] = true;  }  sieve[0] = false;  sieve[1] = false;  for (int i = 2; i <250; i++) {  for (int j = i * 2; j <250; j += i) {  sieve[j] = false;  }  }  for (int i = 0; i   if (sieve[i]) {  prime.add(i);  }  }  }  public static int pickRandomPrime()  {  int k = random.nextInt(prime.size());  List primeList = new ArrayList(prime);  int ret = primeList.get(k);  prime.remove(ret);  return ret;  }  public static void setKeys()  {  int prime1 = pickRandomPrime();  int prime2 = pickRandomPrime();  n = prime1 * prime2;  int fi = (prime1 - 1) * (prime2 - 1);  int e = 2;  while (true) {  if (gcd(e, fi) == 1) {  break;  }  e += 1;  }  public_key = e;  int d = 2;  while (true) {  if ((d * e) % fi == 1) {  break;  }  d += 1;  }  private_key = d;  }  public static int encrypt(int message)  {  int e = public_key;  int encrypted_text = 1;  while (e>0) { šifrirano_besedilo *= sporočilo;  šifrirano_besedilo %= n;  e = 1;  } vrni šifrirano_besedilo;  } public static int decrypt(int encrypted_text) { int d = zasebni_ključ;  int dešifrirano = 1;  medtem ko (d> 0) { dešifrirano *= šifrirano_besedilo;  dešifrirano %= n;  d = 1;  } vrni dešifrirano;  } public static int gcd(int a, int b) { if (b == 0) { return a;  } return gcd(b, a % b);  } public static List encoder(String message) { List encoded = new ArrayList();  for (char letter : message.toCharArray()) { encoded.add(encrypt((int)letter));  } vrni kodirano;  } public static String decoder(List encoded) { StringBuilder s = new StringBuilder();  for (int num : encoded) { s.append((char)decrypt(num));  } vrni s.toString();  } } Python3 import random import math # Nabor bo zbirka praštevil, # kjer lahko izberemo naključna praštevila p in q prime = set() public_key = None private_key = None n = None # Funkcijo bomo zagnali samo enkrat za zapolnitev nabora # praštevil def primefiller(): # Metoda, uporabljena za zapolnitev nabora praštevil, je sito # Eratostena (metoda za zbiranje praštevil) seive = [True] * 250 seive[0] = False seive[1 ] = False za i v obsegu (2, 250): za j v obsegu (i * 2, 250, i): seive [j] = False # Polnjenje praštevil za i v obsegu (len (seive)): če seive[i]: prime.add(i) # Izbira naključnega praštevila in brisanje tega # praštevila s seznama, ker p!=q def pickrandomprime(): globalno praštevilo k = random.randint(0, len(prime) - 1) it = iter(prime) for _ in range(k): next(it) ret = next(it) prime.remove(ret) return ret def setkeys(): global public_key, private_key, n prime1 = pickrandomprime() # Prvo praštevilo prime2 = pickrandomprime() # Drugo praštevilo n = praštevilo * praštevilo2 fi = (prime1 - 1) * (prime2 - 1) e = 2 while True: if math.gcd(e, fi) == 1: break e += 1 # d = (k*Φ(n) + 1) / e za neko celo število k public_key = e d = 2 medtem ko je True: if (d * e) % fi == 1: break d += 1 private_key = d # Za šifriranje dane številke def encrypt(message): global public_key, n e = public_key encrypted_text = 1 while e> 0: encrypted_text *= message encrypted_text %= n e -= 1 return encrypted_text # Za dešifriranje dane številke def decrypt( šifrirano_besedilo): globalni zasebni_ključ, n d = zasebni_ključ dešifriran = 1 medtem ko d> 0: dešifrirano *= šifrirano_besedilo dešifrirano %= n d -= 1 vrni dešifrirano # Najprej pretvorba vsakega znaka v njegovo vrednost ASCII in # nato kodiranje in nato dekodiranje številke, da dobimo # ASCII in pretvorba v znakovno def encoder(message): encoded = [] # Klicanje šifrirne funkcije v kodirni funkciji za črko v sporočilu: encoded.append(encrypt(ord(letter))) return encoded def decoder(encoded) : s = '' # Klicanje funkcije dešifriranja funkcije dekodiranja za num v encoded: s += chr(decrypt(num)) return s if __name__ == '__main__': primefiller() setkeys() message =  'Testno sporočilo' # Odstranite komentar spodaj za ročni vnos # message = input('Vnesite sporočilo
') # Klicanje funkcije kodiranja coded = encoder(message) print('Initial message:') print(message ) print('

Kodirano sporočilo (šifrirano z javnim ključem)
') print(''.join(str(p) za p v kodiranem)) print('

Dekodirano sporočilo (dešifrirano z javnim ključem)
') print(''.join(str(p) za p v dekoderju(kodirano))) C# z uporabo sistema; z uporabo System.Collections.Generic; javni razred GFG { zasebni statični HashSet prime = nov HashSet ();  zasebni statični int? javni_ključ = nič;  zasebni statični int? zasebni_ključ = nič;  zasebni statični int? n = nič;  zasebno statično Naključno naključno = novo Naključno();  public static void Main() { PrimeFiller();  SetKeys();  string message = 'Testno sporočilo';  // Odstranite komentarje spodaj za ročni vnos // Console.WriteLine('Vnesite sporočilo:');  // sporočilo = Console.ReadLine();  Seznam kodirano = Encoder(sporočilo);  Console.WriteLine('Začetno sporočilo:');  Console.WriteLine(message);  Console.WriteLine('

Kodirano sporočilo (šifrirano z javnim ključem)
');  Console.WriteLine(string.Join('', kodirano));  Console.WriteLine('

Dekodirano sporočilo (dešifrirano z javnim ključem)
');  Console.WriteLine(Dekoder(kodirano));  } public static void PrimeFiller() { bool[] sieve = new bool[250];  za (int i = 0; i<250; i++)  {  sieve[i] = true;  }  sieve[0] = false;  sieve[1] = false;  for (int i = 2; i <250; i++)  {  for (int j = i * 2; j <250; j += i)  {  sieve[j] = false;  }  }  for (int i = 0; i   {  if (sieve[i])  {  prime.Add(i);  }  }  }  public static int PickRandomPrime()  {  int k = random.Next(0, prime.Count - 1);  var enumerator = prime.GetEnumerator();  for (int i = 0; i <= k; i++)  {  enumerator.MoveNext();  }  int ret = enumerator.Current;  prime.Remove(ret);  return ret;  }  public static void SetKeys()  {  int prime1 = PickRandomPrime();  int prime2 = PickRandomPrime();  n = prime1 * prime2;  int fi = (prime1 - 1) * (prime2 - 1);  int e = 2;  while (true)  {  if (GCD(e, fi) == 1)  {  break;  }  e += 1;  }  public_key = e;  int d = 2;  while (true)  {  if ((d * e) % fi == 1)  {  break;  }  d += 1;  }  private_key = d;  }  public static int Encrypt(int message)  {  int e = public_key.Value;  int encrypted_text = 1;  while (e>0) { šifrirano_besedilo *= sporočilo;  šifrirano_besedilo %= n.Vrednost;  e = 1;  } vrni šifrirano_besedilo;  } public static int Dešifriraj(int šifrirano_besedilo) { int d = zasebni_ključ.Vrednost;  int dešifrirano = 1;  medtem ko (d> 0) { dešifrirano *= šifrirano_besedilo;  dešifrirano %= n.Value;  d = 1;  } vrni dešifrirano;  } public static int GCD(int a, int b) { if (b == 0) { return a;  } vrni GCD(b, a % b);  } javni statični seznam Encoder(string message) { List kodirano = nov seznam ();  foreach (char črka v sporočilu) { encoded.Add(Encrypt((int)letter));  } vrni kodirano;  } javni statični niz Decoder(List kodirano) { niz s = '';  foreach (int num v kodiranem) { s += (char)Decrypt(num);  } vrni s;  } } Izhod Začetno sporočilo: Testno sporočilo (šifrirano z javnim ključem) 863312887135951593413927434912887135951359583051879012887 Dekodirano sporočilo (dešifrirano z zasebnim ključem) Testno sporočilo Izvedba kriptosistema RSA z uporabo primitivnih korenin v C++ we bo implementiral preprosto različico RSA z uporabo primitivnih korenin.   1. korak: Generiranje ključev Za začetek moramo ustvariti dve veliki praštevili, p in q. Ta praštevila morajo biti približno enake dolžine in njihov produkt mora biti veliko večji od sporočila, ki ga želimo šifrirati. Praštevila lahko ustvarimo s katerim koli algoritmom za testiranje primalite, kot je Miller-Rabinov test. Ko imamo obe praštevili, lahko izračunamo njun produkt n = p*q, kar bo modul za naš sistem RSA. Nato moramo izbrati celo število e tako, da 1 Za izračun eksponenta zasebnega ključa d moramo najti celo število d tako, da je d*e = 1 (mod phi(n)). To je mogoče storiti z uporabo razširjenega evklidskega algoritma. Naš javni ključ je (n, e) in naš zasebni ključ je (n, d).   2. korak: Šifriranje Če želite šifrirati sporočilo m, ga moramo pretvoriti v celo število med 0 in n-1. To je mogoče storiti z uporabo reverzibilne sheme kodiranja, kot je ASCII ali UTF-8. Ko imamo celoštevilsko predstavitev sporočila, izračunamo šifrirano besedilo c kot c = m^e (mod n). To je mogoče učinkovito narediti z uporabo modularnih algoritmov potenciranja, kot je binarno potenciranje.   3. korak: Dešifriranje Za dešifriranje šifriranega besedila c izračunamo odprto besedilo m kot m = c^d (mod n). Spet lahko uporabimo modularne algoritme potenciranja, da to naredimo učinkovito.   4. korak: Primer Oglejmo si primer z uporabo majhnih vrednosti za ponazoritev delovanja kriptosistema RSA. Recimo, da izberemo p = 11 in q = 13, kar nam daje n = 143 in phi(n) = 120. Izberemo lahko e = 7, ker je gcd(7, 120) = 1. Z uporabo razširjenega evklidskega algoritma lahko izračunamo d = 103, ker je 7*103 = 1 (mod 120). Naš javni ključ je (143, 7), naš zasebni ključ pa (143, 103). Recimo, da želimo šifrirati sporočilo HELLO. To lahko pretvorimo v celo število 726564766 z uporabo kodiranja ASCII. Z uporabo javnega ključa izračunamo šifrirano besedilo kot c = 726564766^7 (mod 143) = 32. Za dešifriranje šifriranega besedila uporabimo zasebni ključ za izračun m = 32^103 (mod 143) = 726564766, kar je izvirnik sporočilo. Primer kode: C++ #include #include using namespace std; // izračunaj phi(n) za dano število n int phi(int n) { int rezultat = n;  za (int i = 2; i<= sqrt(n); i++) {  if (n % i == 0) {  while (n % i == 0) {  n /= i;  }  result -= result / i;  }  }  if (n>1) { rezultat -= rezultat / n;  } vrni rezultat; } // izračunaj gcd(a, b) z uporabo evklidskega algoritma int gcd(int a, int b) { if (b == 0) { return a;  } return gcd(b, a % b); } // izračunaj a^b mod m z uporabo modularnega potenciranja int modpow(int a, int b, int m) { int rezultat = 1;  medtem ko (b> 0) { if (b & 1) { rezultat = (rezultat * a) % m;  } a = (a * a) % m;  b>>= 1;  } vrni rezultat; } // generiraj naključni osnovni koren modulo n int generatePrimitiveRoot(int n) { int phiN = phi(n);  int faktorji [phiN], numFactors = 0;  int temp = phiN;  // pridobi vse prafaktorje phi(n) za (int i = 2; i<= sqrt(temp); i++) {  if (temp % i == 0) {  factors[numFactors++] = i;  while (temp % i == 0) {  temp /= i;  }  }  }  if (temp>1) {faktorji[številoFaktorjev++] = temp;  } // preizkus možnih primitivnih korenov za (int i = 2; i<= n; i++) {  bool isRoot = true;  for (int j = 0; j   if (modpow(i, phiN / factors[j], n) == 1) {  isRoot = false;  break;  }  }  if (isRoot) {  return i;  }  }  return -1; } int main() {  int p = 61;  int q = 53;  int n = p * q;  int phiN = (p - 1) * (q - 1);  int e = generatePrimitiveRoot(phiN);  int d = 0;  while ((d * e) % phiN != 1) {  d++;  }  cout << 'Public key: {' << e << ', ' << n << '}' << endl;  cout << 'Private key: {' << d << ', ' << n << '}' << endl;  int m = 123456;  int c = modpow(m, e, n);  int decrypted = modpow(c, d, n);  cout << 'Original message: ' << m << endl;  cout << 'Encrypted message: ' << c << endl;  cout << 'Decrypted message: ' << decrypted << endl;  return 0; }  Output:  Public key: {3, 3233} Private key: {2011, 3233} Original message: 123456 Encrypted message: 855 Decrypted message: 123456   Advantages:    Security:   RSA algorithm is considered to be very secure and is widely used for secure data transmission.   Public-key cryptography:   RSA algorithm is a public-key cryptography algorithm, which means that it uses two different keys for encryption and decryption. The public key is used to encrypt the data, while the private key is used to decrypt the data.   Key exchange:   RSA algorithm can be used for secure key exchange, which means that two parties can exchange a secret key without actually sending the key over the network.   Digital signatures:   RSA algorithm can be used for digital signatures, which means that a sender can sign a message using their private key, and the receiver can verify the signature using the sender’s public key.   Speed:   The RSA technique is suited for usage in real-time applications since it is quite quick and effective.   Widely used:   Online banking, e-commerce, and secure communications are just a few fields and applications where the RSA algorithm is extensively developed.  Disadvantages:    Slow processing speed:   RSA algorithm is slower than other encryption algorithms, especially when dealing with large amounts of data.   Large key size:   RSA algorithm requires large key sizes to be secure, which means that it requires more computational resources and storage space.   Vulnerability to side-channel attacks:   RSA algorithm is vulnerable to side-channel attacks, which means an attacker can use information leaked through side channels such as power consumption, electromagnetic radiation, and timing analysis to extract the private key.   Limited use in some applications:   RSA algorithm is not suitable for some applications, such as those that require constant encryption and decryption of large amounts of data, due to its slow processing speed.   Complexity:   The RSA algorithm is a sophisticated mathematical technique that some individuals may find challenging to comprehend and use.   Key Management:   The secure administration of the private key is necessary for the RSA algorithm, although in some cases this can be difficult.   Vulnerability to Quantum Computing:   Quantum computers have the ability to attack the RSA algorithm, potentially decrypting the data.>