A pure Lua implementation of the IPCrypt specification for IP address encryption and obfuscation.
- Deterministic encryption - AES-128 based, always produces same output for same input
- Non-deterministic (ND) - KIASU-BC with 8-byte random tweaks
- Non-deterministic extended (NDX) - AES-XTS with 16-byte random tweaks
- Prefix-preserving (PFX) - Format-preserving encryption that maintains IPv4/IPv6 type
- IPv4 and IPv6 support - Full support for both address families
- Zero dependencies - Pure Lua implementation
- Lua 5.3++ - Native bitwise operators required
- Unix-like OS - /dev/urandom or /dev/random required for secure random
# Run tests
make test
# Generate a secure key
make keygen
# Run examples
make example# Install to system (default: /usr/local)
sudo make install
# Custom prefix
sudo make install PREFIX=/opt/local
# Uninstall
sudo make uninstallluarocks install ipcrypt-1.0.1-1.rockspeclocal ipcrypt = require("ipcrypt")
-- Generate secure keys
local key16 = ipcrypt.utils.generate_key(16) -- For deterministic/ND
local key32 = ipcrypt.utils.generate_key(32) -- For NDX/PFX
-- Deterministic encryption (same input = same output)
local encrypted = ipcrypt.deterministic.encrypt("192.0.2.1", key16)
print(encrypted) -- IPv6 format: "fa71:fba4:8e6c:205e:3805:2dae:3fba:39f1"
local decrypted = ipcrypt.deterministic.decrypt(encrypted, key16)
print(decrypted) -- "192.0.2.1"-- ND mode with KIASU-BC (8-byte tweak)
local encrypted_nd = ipcrypt.nd.encrypt("10.0.0.1", key16)
-- Returns 24 bytes: 8-byte tweak + 16-byte ciphertext
local decrypted_nd = ipcrypt.nd.decrypt(encrypted_nd, key16)
print(decrypted_nd) -- "10.0.0.1"
-- NDX mode with AES-XTS (16-byte tweak)
local encrypted_ndx = ipcrypt.ndx.encrypt("2001:db8::1", key32)
-- Returns 32 bytes: 16-byte tweak + 16-byte ciphertext
local decrypted_ndx = ipcrypt.ndx.decrypt(encrypted_ndx, key32)
print(decrypted_ndx) -- "2001:db8::1"-- PFX mode maintains IP address type (IPv4 stays IPv4, IPv6 stays IPv6)
local key32 = ipcrypt.utils.generate_key(32) -- PFX requires 32-byte key
-- IPv4 addresses remain IPv4
local encrypted_v4 = ipcrypt.pfx.encrypt("192.168.1.1", key32)
print(encrypted_v4) -- e.g., "172.31.45.67" (still IPv4)
local decrypted_v4 = ipcrypt.pfx.decrypt(encrypted_v4, key32)
print(decrypted_v4) -- "192.168.1.1"
-- IPv6 addresses remain IPv6
local encrypted_v6 = ipcrypt.pfx.encrypt("2001:db8::1", key32)
print(encrypted_v6) -- e.g., "c180:5dd4:2587:3524:30ab:fa65:6ab6:f88" (still IPv6)
local decrypted_v6 = ipcrypt.pfx.decrypt(encrypted_v6, key32)
print(decrypted_v6) -- "2001:db8::1"# Command-line tool
./bin/ipcrypt-keygen # Generate 16-byte key
./bin/ipcrypt-keygen -l 32 # Generate 32-byte key
./bin/ipcrypt-keygen -n 5 # Generate 5 keys
./bin/ipcrypt-keygen --check # Check random source-- Programmatic key generation
local utils = require("ipcrypt.utils")
-- Generate keys (fails if no secure random available)
local key16 = utils.generate_key(16)
local key32 = utils.generate_key(32)
-- Get hex representation
local hex_key = utils.generate_key_hex(16)
print(hex_key) -- "a1b2c3d4..."
-- Check security
if utils.has_secure_random() then
print("Secure random available: " .. utils.get_random_source())
endipcrypt.VERSION- Library version stringipcrypt.deterministic- Deterministic mode moduleipcrypt.nd- Non-deterministic mode (KIASU-BC)ipcrypt.ndx- Non-deterministic extended mode (AES-XTS)ipcrypt.pfx- Prefix-preserving modeipcrypt.utils- Utility functions
encrypt(ip_string, key16)- Encrypt IP address deterministicallydecrypt(encrypted_ip, key16)- Decrypt to original IP
encrypt(ip_string, key16, [tweak8])- Encrypt with optional tweakdecrypt(encrypted_bytes, key16)- Decrypt (tweak included in data)
encrypt(ip_string, key32, [tweak16])- Encrypt with optional tweakdecrypt(encrypted_bytes, key32)- Decrypt (tweak included in data)
encrypt(ip_string, key32)- Encrypt preserving IP type (IPv4/IPv6)decrypt(encrypted_ip, key32)- Decrypt to original IP
generate_key(length)- Generate secure key (16 or 32 bytes)generate_key_hex(length)- Generate key as hex stringhas_secure_random()- Check if secure random availableget_random_source()- Get random source namerandom_bytes(n)- Generate n random byteshex_to_bytes(hex)- Convert hex string to bytesbytes_to_hex(bytes)- Convert bytes to hex stringip_to_bytes(ip_string)- Convert IP to 16-byte formatbytes_to_ip(bytes16)- Convert 16 bytes to IP string
# Run all tests
make test
# Run specific tests
cd tests
lua test_vectors.lua
lua test_random.lua
# Run test suite with colored output
./run-tests.sh- Ensure /dev/urandom exists (standard on Linux/macOS/BSD)
- Check file permissions
- For Windows, use WSL or consider alternative implementations
- Check Lua version:
lua -v(must be 5.3+) - Verify installation paths
- Use proper require paths or package.path configuration