|
| 1 | +# RSA Implementation |
| 2 | + |
| 3 | +This is an implementation of the RSA cryptographic algorithm in Rust. RSA is one of the first public-key cryptosystems widely used for secure data transmission. |
| 4 | + |
| 5 | + |
| 6 | +## ⚠️ Disclaimer |
| 7 | + |
| 8 | +This implementation is not cryptographically secure due to non-constant time operations and other considerations, so it must not be used in production. It is intended to be just an educational example. |
| 9 | + |
| 10 | +## Overview |
| 11 | + |
| 12 | +RSA is an asymmetric cryptographic algorithm that uses a pair of keys: |
| 13 | +- **Public key**: Used for encryption and is shared openly |
| 14 | +- **Private key**: Used for decryption and must be kept secret |
| 15 | + |
| 16 | +The security of RSA relies on the practical difficulty of factoring the product of two large prime numbers. |
| 17 | + |
| 18 | +## Mathematical Background |
| 19 | + |
| 20 | +### Key Generation |
| 21 | + |
| 22 | +1. Choose two distinct prime numbers $p$ and $q$ (these should be randomly generated, should be sufficiently large, and their magnitudes should not be similar) |
| 23 | +2. Compute $n = p \cdot q$ |
| 24 | +3. Calculate Euler's totient function: $\phi(n) = (p-1) \cdot (q-1)$ |
| 25 | +4. Choose an integer $e$ such that $1 < e < \phi(n)$ and $\gcd(e, \phi(n)) = 1$ |
| 26 | +5. Compute $d$ such that $d \cdot e \equiv 1 \pmod{\phi(n)}$ |
| 27 | + |
| 28 | +The public key is $(e, n)$, and the private key is $d$. In practice, $e$ is chosen as a number with low Hamming weight (such as Fermat primes) and $d$ is computed by finding the inverse. |
| 29 | + |
| 30 | +### Encryption and Decryption |
| 31 | + |
| 32 | +- **Encryption**: $c = m^e \pmod{n}$ where $m$ is the message and $c$ is the ciphertext |
| 33 | +- **Decryption**: $m = c^d \pmod{n}$ |
| 34 | + |
| 35 | +### PKCS#1 v1.5 Padding |
| 36 | + |
| 37 | +For secure encryption of arbitrary byte data, we implement PKCS#1 v1.5 padding: |
| 38 | + |
| 39 | +``` |
| 40 | +00 || 02 || PS || 00 || M |
| 41 | +``` |
| 42 | + |
| 43 | +Where: |
| 44 | +- `00`: First byte (block type) |
| 45 | +- `02`: Second byte (block type for encryption) |
| 46 | +- `PS`: Padding string of non-zero random bytes |
| 47 | +- `00`: Separator |
| 48 | +- `M`: Original message |
| 49 | + |
| 50 | +### Basic Example |
| 51 | + |
| 52 | +```rust |
| 53 | +use rsa::RSA; |
| 54 | +use lambdaworks_math::unsigned_integer::element::UnsignedInteger; |
| 55 | + |
| 56 | +// Create an RSA instance with primes that ensure e < φ(n) |
| 57 | +let p = UnsignedInteger::<16>::from_u64(65539); |
| 58 | +let q = UnsignedInteger::<16>::from_u64(65521); |
| 59 | +let rsa = RSA::<16>::new(p, q)?; |
| 60 | + |
| 61 | +// Encrypt and decrypt a numeric message |
| 62 | +let message = UnsignedInteger::<16>::from_u64(42); |
| 63 | +let ciphertext = rsa.encrypt(&message)?; |
| 64 | +let decrypted = rsa.decrypt(&ciphertext)?; |
| 65 | + |
| 66 | +assert_eq!(message, decrypted); |
| 67 | +``` |
| 68 | + |
| 69 | +### Byte Data with Padding |
| 70 | + |
| 71 | +```rust |
| 72 | +use rsa::RSA; |
| 73 | +use lambdaworks_math::unsigned_integer::element::UnsignedInteger; |
| 74 | + |
| 75 | +// Create an RSA instance with primes that ensure e < φ(n) |
| 76 | +let p = UnsignedInteger::<16>::from_u64(65539); |
| 77 | +let q = UnsignedInteger::<16>::from_u64(65521); |
| 78 | +let rsa = RSA::<16>::new(p, q)?; |
| 79 | + |
| 80 | +// Encrypt and decrypt byte data using PKCS#1 v1.5 padding |
| 81 | +let msg_bytes = b"Hello RSA with padding!"; |
| 82 | +let cipher_bytes = rsa.encrypt_bytes_pkcs1(msg_bytes)?; |
| 83 | +let plain_bytes = rsa.decrypt_bytes_pkcs1(&cipher_bytes)?; |
| 84 | + |
| 85 | +assert_eq!(msg_bytes.to_vec(), plain_bytes); |
| 86 | +``` |
| 87 | + |
| 88 | +--- |
| 89 | + |
| 90 | +**Note**: This implementation is for educational purposes. Production systems should use established cryptographic libraries that have undergone security audits. |
0 commit comments