Skip to content

RSA Algorithm

// Generate a public-private key pair for RSA encryption
function generateRSAKeyPair() {
  // Choose two distinct prime numbers p and q
  const p = 13;
  const q = 17;
 
  // Calculate n = p * q and phi = (p - 1) * (q - 1)
  const n = p * q;
  const phi = (p - 1) * (q - 1);
 
  // Choose an integer e such that 1 < e < phi and e is coprime to phi
  let e = 5;
  while (gcd(e, phi) !== 1) {
    e++;
  }
 
  // Calculate d such that d * e = 1 (mod phi)
  const d = modInverse(e, phi);
 
  // Return the public and private keys
  return { publicKey: [e, n], privateKey: [d, n] };
}
 
// Encrypt a message using the public key
function encryptRSA(message, publicKey) {
  const [e, n] = publicKey;
  const cipher = message.split('').map((char) => {
    const charCode = char.charCodeAt(0);
    const encryptedCharCode = modPow(charCode, e, n);
    return String.fromCharCode(encryptedCharCode);
  });
  return cipher.join('');
}
 
// Decrypt a message using the private key
function decryptRSA(cipher, privateKey) {
  const [d, n] = privateKey;
  const message = cipher.split('').map((char) => {
    const charCode = char.charCodeAt(0);
    const decryptedCharCode = modPow(charCode, d, n);
    return String.fromCharCode(decryptedCharCode);
  });
  return message.join('');
}
 
// Helper function to calculate the greatest common divisor (GCD) of two numbers
function gcd(a, b) {
  if (b === 0) {
    return a;
  }
  return gcd(b, a % b);
}
 
// Helper function to calculate the modular inverse of a number
function modInverse(a, m) {
  const [gcd, x] = extendedGCD(a, m);
  if (gcd !== 1) {
    throw new Error(`No modular inverse for ${a} (mod ${m})`);
  }
  return (x % m + m) % m;
}
 
// Helper function to calculate the extended GCD of two numbers
function extendedGCD(a, b) {
  if (b === 0) {
    return [a, 1, 0];
  }
  const [gcd, x1, y1] = extendedGCD(b, a % b);
  const x = y1;
  const y = x1 - Math.floor(a / b) * y1;
  return [gcd, x, y];
}
 
// Helper function to calculate the modular exponentiation of a number
function modPow(base, exponent, modulus) {
  let result = 1;
  while (exponent > 0) {
    if (exponent % 2 === 1) {
      result = (result * base) % modulus;
    }
    base = (base * base) % modulus;
    exponent = Math.floor(exponent / 2);
  }
  return result;
}
 

In this implementation, generateRSAKeyPair() generates a public-private key pair for RSA encryption, encryptRSA(message, publicKey) encrypts a message using the public key, and decryptRSA(cipher, privateKey) decrypts a cipher using the private key.