daily3014/cryptography
Luau implementations of popular hashing/encryption algorithms
Luau Cryptography
A tested, high performance cryptography library for Roblox built in Luau. Has over 30+ cryptographic functions including modern algorithms like SHA-3, BLAKE3, ChaCha20-Poly1305, and EdDSA alongside classic implementations. Through alot of optimizations, the implementations are 200-900% faster than alternatives while having actual readable code.
I can't believe I have to spell this out, but this cryptography library was NOT made for users to exploit, harass, or engage in any illegal activities whatsoever. If I had known what sick things people were going to use this for, I wouldn't have released it in the first place. If you see this being used for explicit content, illegal purposes, harassment, or any other disgusting misuse REPORT IT. This kind of abuse is absolutely unacceptable.
Discord: https://discord.gg/Fg3sM8qKPp
Links:
Authors
daily3014 - Developer - @daily3014
Xoifail - Developer - @xoifail
Acknowledgments
- Thanks to those who gave feedback and testing
- Special thanks to all contributors and bug reporters
- AES was originally made by @RobloxGamerPro200007
Features
- High Performance: 2x-8.7x faster than alternative implementations
- Algorithm Support: 30+ cryptographic functions covering all major use cases
- Modern Cryptography: Latest algorithms including SHA-3, BLAKE3, ChaCha20-Poly1305, EdDSA and post quantum cryptography
- Easy Integration: Clean modular API designed for Roblox environments
- Multiple Package Managers: Available on both Wally and Pesde
- Buffer Based: Efficient buffer usage for everything
- Fully Testing: Every algorithm is tested with NIST test vectors
- Type Safe: Complete type definitions
- Well Documented: Good documentation and examples
Supported Algorithms
Hashing Functions (20):
- SHA-2 Family: SHA-224, 256, 384, 512 (optional salt support)
- SHA-3 Family: SHA3-224, 256, 384, 512, Shake128, Shake256 (latest NIST standard)
- BLAKE Family: BLAKE3 (fastest available), BLAKE3-Keyed, BLAKE3-DeriveKey
- Authentication: HMAC (works with any hash function)
- Fast Hashing: XXH32 (ultra-fast non-cryptographic)
Encryption Functions (6):
- Stream Cipher: ChaCha20 (stream cipher)
- Block Cipher: AES-GCM, Simon, Speck
- Additive Cipher: XOR
- Authenticated Encryption: ChaCha20-Poly1305 AEAD, AES-GCM
Digital Signatures (2):
- EdDSA: Ed25519 key generation, signing, and verification
- ML-DSA: Post-quantum digital signature scheme (Dilithium-based), secure against quantum attacks, standardized in NIST PQC
Key Encapsulation (2):
- ML-KEM: Post-quantum key encapsulation mechanism (Kyber-based), used for secure key exchange and hybrid encryption
- X25519: Elliptic curve Diffie–Hellman (ECDH) over Curve25519 with cofactor clearing
Utility Functions (10+):
- Encoding: Base64 encode/decode
- Conversions: Hex to/from buffer, string utilities
- Random Generation: Generates random strings
- Checksums: CRC32 (JAM/ISO modes), Adler
Performance
(Only some of the algorithms are present!)
Every implementation is faster than all alternatives
Hashing / Checksum
| Algorithm | Data Size | This Library | HashLib | Alternative | Other Libraries | Improvement | 
|---|---|---|---|---|---|---|
| Adler32 | 200k | 190 us | - | 1.65 ms (Naive Approach) | - | 8.7x faster | 
| SHA256 | 20k | 370 μs | 2058 μs | 493 μs (Old Version) | 596 μs (Dekkonot) | 5.5x faster than HashLib | 
| SHA512 | 20k | 822 μs | 4348 μs | 1066 μs (Dekkonot) | - | 5.6x faster than HashLib | 
| Keccak/SHA3-512 | 20k | 1.74 ms | 10.60 ms | - | - | 6.1x faster than HashLib | 
| CRC32 | 200k | 2.01 ms | - | 6.26 ms (DevForum) | - | 3.1x faster | 
Encryption
| Algorithm | Data Size | This Library | Alternative | Other Libraries | Improvement | 
|---|---|---|---|---|---|
| XOR (Encrypt) | 1 million | 1.10 ms | ~49.5 ms (@TwiistedRoyalty) | 4000ms (daily) | 64.3x faster | 
| XOR (Roundtrip) | 1 million | 2.20 ms | 98.9 ms (@TwiistedRoyalty) | ~8000ms (daily) | 64.3x faster | 
| ChaCha20 (Encrypt) | 20k | 0.31 ms | 7.87 ms (EncryptedNet) | - | 25.3x faster | 
| ChaCha20 (Roundtrip) | 20k | 0.64 ms | ~15 ms (EncryptedNet) | - | 25.3x faster | 
| Simon (Encrypt) | 20k | 0.42 ms | - | - | - | 
| Simon (Roundtrip) | 20k | 0.85 ms | - | - | - | 
| Speck (Encrypt) | 20k | 0.48 ms | - | - | - | 
| Speck (Roundtrip) | 20k | 0.98 ms | - | - | - | 
| AES-GCM (Encrypt) | 20k | 16.41 ms | - | - | - | 
| AES-GCM (Roundtrip) | 20k | 32.40 ms | - | - | - | 
Benchmarks performed in Roblox Studio on an Intel Core i7-12700
Plugin used: Benchmarker by @boatbomber
Roundtrip: Encrypt and Decrypt
Installation
Wally
https://wally.run/package/daily3014/cryptography
Pesde
https://pesde.dev/packages/daily3014/cryptography
Manual Installation
- Download the latest release from GitHub
- Drag the rbxm/rbxmx file into studio
- Require the module in your scripts
Quick Start
Basic Setup
-- Require the library
local Cryptography = require(game:GetService("ReplicatedStorage").Cryptography)
-- Module shortcuts
local Hashing = Cryptography.Hashing
local Encryption = Cryptography.Encryption
local Utilities = Cryptography.Utilities
local Verification = Cryptography.Verification
local Checksums = Cryptography.ChecksumsHash Something Quickly
-- Hash a message with SHA-256
local MessageBuffer = buffer.fromstring("Hello World!")
local Hash = Hashing.SHA2.SHA256(MessageBuffer)
print("SHA256:", Hash) -- Output is already in hex formatSecure Password Hashing
-- Hash a password with salt
local function HashPassword(Password, Salt)
    local PasswordBuffer = buffer.fromstring(Password)
    local SaltBuffer = buffer.fromstring(Salt or "defaultsalt")
    return Hashing.SHA2.SHA256(PasswordBuffer, SaltBuffer)
end
-- Example usage
local UserPassword = "MySecurePassword123"
local HashedPassword = HashPassword(UserPassword, "randomsalt")
print("Hashed password:", HashedPassword)
-- Verify password by comparing hashes
local function VerifyPassword(InputPassword, StoredHash, Salt)
    local InputHash = HashPassword(InputPassword, Salt)
    return InputHash == StoredHash
end
local IsValid = VerifyPassword("MySecurePassword123", HashedPassword, "randomsalt")
print("Password is valid:", IsValid)Authenticated Encryption (AEAD)
local PlainText = buffer.fromstring("Hello World")
local Key = buffer.fromstring(string.rep("k", 32))
local Nonce = buffer.fromstring(string.rep("n", 12))
local AAD = buffer.fromstring("additional data")
local Ciphertext, Tag = Encryption.AEAD.Encrypt(PlainText, Key, Nonce, AAD)
local DecryptedText = Encryption.AEAD.Decrypt(Ciphertext, Key, Nonce, Tag, AAD)Verification/CSPRNG Usage
print("Check examples.")API Reference
Hashing Functions
SHA-2 Family:
Hashing.SHA2.SHA224(Message: buffer, Salt?: buffer) -> string
Hashing.SHA2.SHA256(Message: buffer, Salt?: buffer) -> string
Hashing.SHA2.SHA384(Message: buffer, Salt?: buffer) -> string
Hashing.SHA2.SHA512(Message: buffer, Salt?: buffer) -> string
Hashing.SHA2.SHA512_224(Message: buffer, Salt?: buffer) -> string
Hashing.SHA2.SHA512_256(Message: buffer, Salt?: buffer) -> string
-- Computes SHA2-xxx hash with optional salt. Most commonly used cryptographic hash function.SHA-3 Family:
Hashing.SHA3.SHA3_224(Message: buffer) -> string
Hashing.SHA3.SHA3_256(Message: buffer) -> string
Hashing.SHA3.SHA3_384(Message: buffer) -> string
Hashing.SHA3.SHA3_512(Message: buffer) -> string
-- Modern SHA3-xxx hash function.
Hashing.SHA3.SHAKE_128(Message: buffer) -> string
Hashing.SHA3.SHAKE_256(Message: buffer) -> string
-- Modern SHAKE-xxx hash function.BLAKE Family:
Hashing.Blake3.Digest(Message: buffer, Length?: number) -> string
-- Fastest cryptographic hash function available. Optimized for performance.
Hashing.Blake3.DigestKeyed(Key: buffer, Message: buffer, Length?: number) -> string
-- Keyed Blake3 hash for authenticated hashing scenarios.
Hashing.Blake2b(InputData: buffer, OutputLength: number?, KeyData: buffer?) -> string
-- Secure cryptographic hash function with optional keying (1-64 byte output, 0-64 byte key).Authentication:
Hashing.HMAC(Message: buffer, Key: buffer, HashFn: function, BlockSize: number) -> string
-- Hash based message authentication code. Works with any underlying hash function.Fast Hashing:
Hashing.XXH32(Message: buffer, Seed?: number) -> number
-- Fast non cryptographic hash function. Perfect for hash tables and checksums.Encryption Functions
Stream Cipher:
Encryption.AEAD.ChaCha20(Data: buffer, Key: buffer, Nonce: buffer, Counter?: number, Rounds?: number) -> buffer
-- ChaCha20 stream cipher encryption/decryption.Additive Cipher:
Encryption.XOR(Data: buffer, Key: buffer) -> buffer
-- XOR additive cipher encryption/decryption.Block Cipher: AES
AES.Encrypt(Key: buffer, IV: buffer, Plaintext: buffer, AAD: buffer?): (buffer, buffer)
-- AES-GCM Encryption Mode. Returns the result and tag.
AES.Decrypt(Key: buffer, IV: buffer, Ciphertext: buffer, AAD: buffer?, Tag: buffer): (boolean, buffer?)
-- AES-GCM Decryption Mode. Returns false on tag failure, true and result buffer on success.Block Cipher: Simon and Speck
Encryption.Simon.Encrypt(PlaintextBuffer: buffer, KeyBuffer: buffer) -> buffer
-- Simon cipher encryption. Recommended key size is 16 bytes
Encryption.Simon.Decrypt(CipherBuffer: buffer, KeyBuffer: buffer) -> buffer
-- Simon cipher decryption. Recommended key size is 16 bytes
Encryption.Speck.Encrypt(PlaintextBuffer: buffer, KeyBuffer: buffer) -> buffer
-- Speck cipher encryption. Recommended key size is 8 bytes
Encryption.Speck.Decrypt(CipherBuffer: buffer, KeyBuffer: buffer) -> buffer
-- Speck cipher decryption. Recommended key size is 8 bytesAuthenticated Encryption:
Encryption.AEAD.Encrypt(Message: buffer, Key: buffer, Nonce: buffer, AAD?: buffer, Rounds?: number) -> (buffer, buffer)
-- ChaCha20-Poly1305 authenticated encryption. Returns ciphertext and authentication tag.
Encryption.AEAD.Decrypt(Ciphertext: buffer, Key: buffer, Nonce: buffer, Tag: buffer, AAD?: buffer, Rounds?: number) -> buffer?
-- ChaCha20-Poly1305 authenticated decryption. Returns plaintext or nil if authentication fails.Digital Signatures
EdDSA (Ed25519):
Verification.EdDSA.PublicKey(SecretKey: buffer) -> buffer
-- Generate public key from secret key using Ed25519 algorithm.
Verification.EdDSA.Sign(SecretKey: buffer, PublicKey: buffer, Message: buffer) -> buffer
-- Create digital signature for a message using Ed25519.
Verification.EdDSA.Verify(PublicKey: buffer, Message: buffer, Signature: buffer) -> boolean
-- Returns true if signature is valid.
Verification.EdDSA.MaskedX25519.Mask(SecretKey: buffer) -> buffer
-- Creates a 64-byte masked key from a 32-byte secret key for side-channel attack protection.
Verification.EdDSA.MaskedX25519.MaskSignature(SignatureSecretKey: buffer) -> buffer
-- Creates a masked key from an EdDSA signature secret key (applies SHA512 then masking).
Verification.EdDSA.MaskedX25519.Remask(MaskedKey: buffer) -> buffer
-- Refreshes the masking on a 64-byte masked key with new randomness.
Verification.EdDSA.MaskedX25519.PublicKey(MaskedKey: buffer) -> buffer
-- Generates a 32-byte public key from a 64-byte masked key.
Verification.EdDSA.MaskedX25519.Exchange(MaskedSecretKey: buffer, TheirPublicKey: buffer) -> (buffer, buffer)
-- Performs double key exchange returning (PrimarySecret, MaskSecret).
Verification.EdDSA.MaskedX25519.MaskComponent(MaskedKey: buffer) -> buffer
-- Extracts the 32-byte random mask component from a 64-byte masked key.MlDSA:
Mldsa.ML_DSA_44.GenerateKeys() -> (PublicKey: buffer, SecretKey: buffer)
-- Generate a ML-DSA-44 keypair (128-bit security).
Mldsa.ML_DSA_44.Sign(RandomSeed: buffer, SecretKey: buffer, Message: buffer, Context: buffer, Signature: buffer) -> boolean
-- Sign a message with ML-DSA-44. Returns true if signing succeeded.
Mldsa.ML_DSA_44.Verify(PublicKey: buffer, Message: buffer, Context: buffer, Signature: buffer) -> boolean
-- Verify a ML-DSA-44 signature. Returns true if valid.
Mldsa.ML_DSA_65.GenerateKeys() -> (PublicKey: buffer, SecretKey: buffer)
-- Generate a ML-DSA-65 keypair (192-bit security).
Mldsa.ML_DSA_65.Sign(RandomSeed: buffer, SecretKey: buffer, Message: buffer, Context: buffer, Signature: buffer) -> boolean
-- Sign a message with ML-DSA-65.
Mldsa.ML_DSA_65.Verify(PublicKey: buffer, Message: buffer, Context: buffer, Signature: buffer) -> boolean
-- Verify a ML-DSA-65 signature.
Mldsa.ML_DSA_87.GenerateKeys() -> (PublicKey: buffer, SecretKey: buffer)
-- Generate a ML-DSA-87 keypair (256-bit security).
Mldsa.ML_DSA_87.Sign(RandomSeed: buffer, SecretKey: buffer, Message: buffer, Context: buffer, Signature: buffer) -> boolean
-- Sign a message with ML-DSA-87.
Mldsa.ML_DSA_87.Verify(PublicKey: buffer, Message: buffer, Context: buffer, Signature: buffer) -> boolean
-- Verify a ML-DSA-87 signature.MlKEM:
MlKem.MLKEM_512.GenerateKeys() -> (PublicKey: buffer, SecretKey: buffer)
-- Generate a ML-KEM-512 keypair (128-bit security). Uses cryptographically secure random number generation.
MlKem.MLKEM_512.KeyGen(D: buffer, Z: buffer) -> (PublicKey: buffer, SecretKey: buffer)
-- Generate a ML-KEM-512 keypair using provided entropy. D and Z must be 32-byte buffers.
MlKem.MLKEM_512.Encapsulate(PublicKey: buffer, Message: buffer) -> (Ciphertext: buffer?, SharedSecret: buffer?)
-- Encapsulate a message using ML-KEM-512. Returns ciphertext and shared secret, or nil on failure.
MlKem.MLKEM_512.Decapsulate(SecretKey: buffer, Ciphertext: buffer) -> SharedSecret: buffer
-- Decapsulate a ciphertext using ML-KEM-512. Returns the shared secret.
MlKem.MLKEM_768.GenerateKeys() -> (PublicKey: buffer, SecretKey: buffer)
-- Generate a ML-KEM-768 keypair (192-bit security). Uses cryptographically secure random number generation.
MlKem.MLKEM_768.KeyGen(D: buffer, Z: buffer) -> (PublicKey: buffer, SecretKey: buffer)
-- Generate a ML-KEM-768 keypair using provided entropy. D and Z must be 32-byte buffers.
MlKem.MLKEM_768.Encapsulate(PublicKey: buffer, Message: buffer) -> (Ciphertext: buffer?, SharedSecret: buffer?)
-- Encapsulate a message using ML-KEM-768. Returns ciphertext and shared secret, or nil on failure.
MlKem.MLKEM_768.Decapsulate(SecretKey: buffer, Ciphertext: buffer) -> SharedSecret: buffer
-- Decapsulate a ciphertext using ML-KEM-768. Returns the shared secret.
MlKem.MLKEM_1024.GenerateKeys() -> (PublicKey: buffer, SecretKey: buffer)
-- Generate a ML-KEM-1024 keypair (256-bit security). Uses cryptographically secure random number generation.
MlKem.MLKEM_1024.KeyGen(D: buffer, Z: buffer) -> (PublicKey: buffer, SecretKey: buffer)
-- Generate a ML-KEM-1024 keypair using provided entropy. D and Z must be 32-byte buffers.
MlKem.MLKEM_1024.Encapsulate(PublicKey: buffer, Message: buffer) -> (Ciphertext: buffer?, SharedSecret: buffer?)
-- Encapsulate a message using ML-KEM-1024. Returns ciphertext and shared secret, or nil on failure.
MlKem.MLKEM_1024.Decapsulate(SecretKey: buffer, Ciphertext: buffer) -> SharedSecret: buffer
-- Decapsulate a ciphertext using ML-KEM-1024. Returns the shared secret.Utility Functions
Encoding:
Utilities.Base64.Encode(Input: buffer) -> buffer
-- Encode buffer data to Base64 string representation.
Utilities.Base64.Decode(Input: buffer) -> string
-- Decode Base64 string.Conversions:
Utilities.Conversions.ToHex(Buffer: buffer) -> string
-- Convert buffer to hexadecimal string representation.
Utilities.Conversions.FromHex(Hex: string) -> buffer
-- Convert hexadecimal string to buffer.Random Generation:
Utilities.RandomString(Length: number) -> string
-- Generate random string of specified length.CSPRNG:
Utilities.CSPRNG.Random()
-- Generate a random number between 0 and 1
Utilities.CSPRNG.RandomInt(Min: number, Max: number?): number
-- Generate a random integer between Min and Max or 0 - Min
Utilities.CSPRNG.RandomNumber(Min: number, Max: number?): number
-- Generate a random number between Min and Max or 0 - Min
Utilities.CSPRNG.RandomBytes(Count: number): buffer
-- Generate a buffer with random bytes of length Count
Utilities.CSPRNG.RandomHex(Length: number): string
-- Generate a random hexadecimal string
Utilities.CSPRNG.RandomString(Length: number, AsBuffer: boolean?): buffer | string
-- Generate a random string / buffer
Utilities.CSPRNG.Ed25519ClampedBytes(Input: buffer): buffer
-- Clamp the bytes to always work with EdDSA
Utilities.CSPRNG.Ed25519Random(): buffer
-- Generate a clamped buffer with random bytes for use with EdDSA
Utilities.CSPRNG.Reseed(CustomEntropy: buffer?)
-- Add new entropy to the CSPRNG with up to 1024 bytes of custom entropy (in most cases it will be less)
CSPRNG.AddEntropyProvider(ProviderFunction: () -> buffer?)
-- Option to pass a custom function that supplies the entropy, only called once its used up all the entropy from init
-- So you need to do `CSPRNG.Reseed(CustomEntropy())` if you want it from the gecko
CSPRNG.RemoveEntropyProvider(ProviderFunction: () -> buffer?)
-- Removes the given provider for CSPRNGChecksum Functions:
Checksums.CRC32(Message: buffer, Mode: "Jam" | "Iso"?, Hex: boolean?) -> number
-- Calculate CRC32 checksum with optional mode and output format.
Checksums.Adler(Message: buffer) -> number
-- Calculate Adler checksum.Testing
Running Tests
To run the complete test suite:
bash scripts/test.shThis will launch Roblox Studio, execute all tests, and display results in your terminal.
Development Testing
For continuous testing during development:
bash scripts/dev.shThis starts a Rojo server. Open Roblox Studio and sync Rojo into a Baseplate. Whenever you run the game server, the test suites will run and results will show in the Output widget.
Contributing
Please read the CONTRIBUTING.md file.
License
This project is licensed under the MIT License. See the LICENSE file for details.
FAQ
Will you add other algorithms?
Maybe! Depends if its possible in Luau without needing really expensive calculations like RSA.
How is this library faster?
Through many optimizations including buffer operations, algorithm tuning and Luau specific optimizations.
Which algorithms should I use?
- Hashing: SHA-256 for general use, XXHASH32 for speed, Blake3 for speed and security, SHA3-256 for latest standards
- Encryption: ChaCha20-Poly1305 AEAD for speed, AES for compatibility and security
- Signatures: Ed25519 for fast digital signatures and key exchange, MlDSA if you need security.