Skip to main content
The RSA module implements the RSA (Rivest-Shamir-Adleman) encryption algorithm, a public-key cryptosystem used for secure data transmission.

gen_keys

Generates a pair of RSA keys (public and private) for encryption and decryption.
def gen_keys(bits)
bits
int
required
The bit length for the RSA keys. Larger values provide stronger security but slower performance. Common values: 32 (testing), 512, 1024, 2048 (recommended for production).
return
tuple[int, int, int]
A tuple containing:
  • e (int): The public exponent (encryption key)
  • d (int): The private exponent (decryption key)
  • n (int): The modulus used by both keys
Key generation involves finding two prime numbers and calculating related values. The function validates the keys by performing a test encryption/decryption cycle before returning them.

Example

import RSA

# Generate RSA keys
bits = 32  # Use 1024 or 2048 for production
e, d, n = RSA.gen_keys(bits)

print(f"Public key (e, n): ({e}, {n})")
print(f"Private key (d, n): ({d}, {n})")

From application code

import RSA

# Generate keys for encryption
bits = 32
e, d, n = RSA.gen_keys(bits)

# Store keys securely
public_key = (e, n)
private_key = (d, n)

encrypt

Encrypts a text message using RSA public key encryption.
def encrypt(msg, e, n)
msg
str
required
The message to encrypt. Can contain any characters.
e
int
required
The public exponent from the key pair.
n
int
required
The modulus from the key pair.
return
list[int]
A list of encrypted integers, where each integer represents an encrypted character from the original message.

How it works

The encryption process:
  1. Converts each character to its ASCII value using ord()
  2. Encrypts each ASCII value using modular exponentiation: ciphertext = (plaintext^e) mod n
  3. Returns a list of encrypted values

Example

import RSA

# Generate keys
bits = 32
e, d, n = RSA.gen_keys(bits)

# Encrypt a message
mensaje = "HOLA"
mensaje_cifrado = RSA.encrypt(mensaje, e, n)

print(f"Encrypted: {mensaje_cifrado}")
# Output: [123456, 789012, 345678, 901234] (example values)

decrypt

Decrypts an RSA-encrypted message using the private key.
def decrypt(cipher, d, n)
cipher
list[int]
required
A list of encrypted integers (typically from the encrypt function).
d
int
required
The private exponent from the key pair.
n
int
required
The modulus from the key pair (must match the one used for encryption).
return
str
The decrypted message as a string. Only includes valid ASCII characters in the range 32-126.
The function filters the decrypted characters to only include valid ASCII printable characters (32-126). This prevents garbage characters from appearing in the output.

How it works

The decryption process:
  1. Takes each encrypted integer from the cipher list
  2. Decrypts each value using modular exponentiation: plaintext = (ciphertext^d) mod n
  3. Converts the decrypted value back to a character using chr()
  4. Filters out invalid ASCII characters
  5. Returns the reconstructed message

Example

import RSA

# Generate keys
bits = 32
e, d, n = RSA.gen_keys(bits)

# Encrypt then decrypt
mensaje = "HOLA"
mensaje_cifrado = RSA.encrypt(mensaje, e, n)
mensaje_descifrado = RSA.decrypt(mensaje_cifrado, d, n)

print(f"Original: {mensaje}")
print(f"Decrypted: {mensaje_descifrado}")

encrypt_number

Encrypts a single number using RSA encryption.
def encrypt_number(num, e, n)
num
int
required
The number to encrypt.
e
int
required
The public exponent from the key pair.
n
int
required
The modulus from the key pair.
return
int
The encrypted number calculated as (num^e) mod n.

Example

import RSA

# Generate keys
e, d, n = RSA.gen_keys(32)

# Encrypt a number
num = 42
encrypted = RSA.encrypt_number(num, e, n)

print(f"Encrypted number: {encrypted}")

decrypt_number

Decrypts a single RSA-encrypted number.
def decrypt_number(cipher, d, n)
cipher
int
required
The encrypted number to decrypt.
d
int
required
The private exponent from the key pair.
n
int
required
The modulus from the key pair.
return
int
The decrypted number calculated as (cipher^d) mod n.

Example

import RSA

# Generate keys
e, d, n = RSA.gen_keys(32)

# Encrypt and decrypt a number
num = 42
encrypted = RSA.encrypt_number(num, e, n)
decrypted = RSA.decrypt_number(encrypted, d, n)

print(f"Original: {num}")
print(f"Decrypted: {decrypted}")  # Should match original

gcd

Calculates the greatest common divisor (GCD) of two numbers using the Euclidean algorithm.
def gcd(a, b)
a
int
required
The first number.
b
int
required
The second number.
return
int
The greatest common divisor of a and b.
This function is used internally during key generation to ensure that the public exponent e is coprime with phi(n).

Example

import RSA

result = RSA.gcd(48, 18)
print(result)  # Output: 6

mod_inverse

Calculates the modular multiplicative inverse using the Extended Euclidean algorithm.
def mod_inverse(a, m)
a
int
required
The number to find the inverse of.
m
int
required
The modulus.
return
int
The modular multiplicative inverse of a modulo m, such that (a * result) mod m = 1.
This function is used internally to calculate the private key exponent d from the public exponent e and phi(n).

Example

import RSA

# Find inverse of 3 modulo 11
inverse = RSA.mod_inverse(3, 11)
print(inverse)  # Output: 4 (because 3 * 4 mod 11 = 1)

gen_prime

Generates a random prime number of the specified bit length.
def gen_prime(bits)
bits
int
required
The bit length of the prime number to generate.
return
int
A random prime number with the specified bit length.

Example

import RSA

# Generate a 16-bit prime number
prime = RSA.gen_prime(16)
print(f"Generated prime: {prime}")
print(f"Is prime: {RSA.is_prime(prime)}")

is_prime

Checks whether a number is prime using trial division.
def is_prime(n)
n
int
required
The number to check for primality.
return
bool
True if the number is prime, False otherwise.
This implementation uses a simple trial division method. For larger numbers, more sophisticated primality tests (like Miller-Rabin) would be more efficient.

Example

import RSA

print(RSA.is_prime(17))  # True
print(RSA.is_prime(18))  # False
print(RSA.is_prime(97))  # True

Complete RSA workflow

Here’s a complete example showing the full RSA encryption/decryption process:
import RSA

# Step 1: Generate keys
print("Generating RSA keys...")
bits = 32
e, d, n = RSA.gen_keys(bits)

print(f"Public key (e, n): ({e}, {n})")
print(f"Private key (d, n): ({d}, {n})")

# Step 2: Encrypt a message
mensaje = "Hello, World!"
print(f"\nOriginal message: {mensaje}")

mensaje_cifrado = RSA.encrypt(mensaje, e, n)
print(f"Encrypted: {mensaje_cifrado}")

# Step 3: Decrypt the message
mensaje_descifrado = RSA.decrypt(mensaje_cifrado, d, n)
print(f"Decrypted: {mensaje_descifrado}")

Security considerations

Important security notes:
  • Use at least 2048 bits for production systems
  • Keep private keys (d) secure and never share them
  • Public keys (e, n) can be shared freely
  • The same key pair can encrypt multiple messages
  • For the educational implementation, 32-bit keys are used for speed but are NOT secure

Build docs developers (and LLMs) love