Cryptographically secure one-time pad implementation for Node.js using XOR encryption.
One-Time Pad is the ONLY mathematically proven unbreakable encryption method - it provides "perfect secrecy" when used correctly.
The Basic Concept
Imagine you have a secret message and a random key:
Message: H E L L O
ASCII: 72 69 76 76 79
Random Key (pad): 15 203 88 142 91
XOR Operation:
Result: 87 138 24 214 20 β Ciphertext (completely random!)Step-by-Step Process
- Encryption:
Each byte of message XOR each byte of secret
ciphertext[i] = message[i] ^ secret[i]
// Example:
'H' (72) ^ 15 = 87
'E' (69) ^ 203 = 138
'L' (76) ^ 88 = 24- Decryption:
XOR is reversible - same operation!
plaintext[i] = ciphertext[i] ^ secret[i]
// Example:
87 ^ 15 = 72 ('H')
138 ^ 203 = 69 ('E')
24 ^ 88 = 76 ('L')XOR (exclusive OR) has a special property:
A ^ B = C
C ^ B = A β Decrypt by XORing again!
Truth table:
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
Without the key, the ciphertext could decrypt to ANY message of the same length:
Ciphertext: [87, 138, 24, 214, 20]
With key A: "HELLO"
With key B: "WORLD"
With key C: "12345"
With key D: "ZZZZZ"
All equally likely! An attacker learns NOTHING.
OTP is only secure if ALL three rules are followed:
- Truly Random Key
β
GOOD: Cryptographically secure
const secret = crypto.randomBytes(length);
// β BAD: Predictable
const secret = [1, 2, 3, 4, 5];- Key = Message Length
β
GOOD
const message = "HELLO";
const secret = GenerateSecret(5); // Same length
// β BAD
const secret = GenerateSecret(3); // Too short- Never Reuse Keys
β FATAL MISTAKE - REUSING KEY
const secret = GenerateSecret(10);
const cipher1 = Encrypt("message1aa", secret);
const cipher2 = Encrypt("message2bb", secret); // NEVER DO THIS!
// Attacker can XOR the two ciphertexts:
// cipher1 ^ cipher2 = (msg1 ^ key) ^ (msg2 ^ key)
// = msg1 ^ msg2 (keys cancel out!)
// Now attacker can extract patterns from your messages!| Method | Security | Speed | Key Size | Reusable? |
|---|---|---|---|---|
| OTP | Perfect (proven) | β‘ Fast | = Message | β Once only |
| AES | Very Strong | β‘β‘ Very Fast | 128/256 bits | β Yes |
| RSA | Strong | π Slow | 2048+ bits | β Yes |
Here's what happens when you encrypt "HELLO":
Step 1: Generate Random Key
βββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ
β 15 β 203 β 88 β 142 β 91 β
βββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ
Step 2: Convert Message to Bytes
H E L L O
βββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ
β 72 β 69 β 76 β 76 β 79 β
βββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ
Step 3: XOR Each Byte
72^15 69^203 76^88 76^142 79^91
βββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ
β 87 β 138 β 24 β 214 β 20 β β Ciphertext
βββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ
Step 4: To Decrypt, XOR Again
87^15 138^203 24^88 214^142 20^91
βββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ
β 72 β 69 β 76 β 76 β 79 β β Back to HELLO!
βββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ
- Spy agencies (Moscow-Washington hotline during Cold War)
- Military communications (top secret messages)
- Banking (high-value transactions)
- Diplomatic cables
The key management problem:
Send 1 GB file β Need 1 GB random key
But how do you securely share 1 GB key?
If you can share the key securely, why not just share the message? π€
This is why we use AES/RSA for most things - they're secure enough and practical.
npm install otp-encryption,import { Encrypt, Decrypt, GenerateSecret } from 'otp-encryption';
const message = "Hello, World!";
// Generate a random one-time pad
const secret = GenerateSecret(message.length);
// Encrypt
const ciphertext = Encrypt(message, secret);
// Decrypt
const plaintext = Decrypt(ciphertext, secret);
console.log(plaintext); // "Hello, World!"Generates a cryptographically secure random one-time pad.
Parameters:
length- Length of the secret in bytes
Returns: Uint8Array containing random bytes
Encrypts a message using XOR with the provided secret.
Parameters:
message- The plaintext message to encryptsecret- The one-time pad (must be same length as message)
Returns: Uint8Array containing the ciphertext
Decrypts a ciphertext using XOR with the provided secret.
Parameters:
ciphertext- The encrypted datasecret- The one-time pad used for encryption
Returns: Decrypted plaintext string
One-Time Pad encryption provides perfect secrecy when used correctly:
β
The key is truly random (uses crypto.randomBytes)
β
The key is as long as the message (enforced)
Never reuse keys! Each message requires a new random key.
Contributions are welcome! Please feel free to submit a Pull Request.
MIT Β© caesarsage