rbx-cryptography

Cryptography for Roblox, as fast as Luau can run it. Hashing, encryption, signatures, post quantum key exchange and a secure random number generator, all in strictly typed Luau.

local Cryptography = require(ReplicatedStorage.Cryptography)

local SHA256 = Cryptography.Hashing.SHA2.SHA256
local AEAD = Cryptography.Encryption.AEAD
local EdDSA = Cryptography.Verification.EdDSA
local CSPRNG = Cryptography.Utilities.CSPRNG

-- hash
local Hex: string, Digest: buffer = SHA256(buffer.fromstring("Hello World"))

-- encrypt, and decrypt
local Key: buffer = CSPRNG.RandomBytes(32)
local Nonce: buffer = CSPRNG.RandomBytes(12)
local Ciphertext: buffer, Tag: buffer = AEAD.Encrypt(buffer.fromstring("secret"), Key, Nonce)
local Plaintext: buffer? = AEAD.Decrypt(Ciphertext, Key, Nonce, Tag)

-- sign, and verify
local SecretKey: buffer = CSPRNG.RandomBytes(32)
local PublicKey: buffer = EdDSA.PublicKey(SecretKey)
local Signature: buffer = EdDSA.Sign(Digest, SecretKey, PublicKey)
print(EdDSA.Verify(Digest, PublicKey, Signature)) -- true

As fast as Luau goes

Every hot loop is unrolled and tuned against the native code it compiles to. SHA-256 hashes 50 KB in 121 μs, and ChaCha20 encrypts it in 76 μs.

Roblox's own hashing when it can

SHA-256, SHA-1, MD5, Base64 and 32 byte BLAKE3 and BLAKE2b go through EncodingService, which runs as native code inside Roblox.

Authenticated encryption

ChaCha20-Poly1305, XChaCha20-Poly1305 and AES-GCM. Decrypt gives you nil when anything was changed, so tampered data never reaches your code.

Signatures and key exchange

Ed25519 signatures, and X25519 key exchange, so two sides can agree on a key without ever sending it.

Post quantum

ML-KEM and ML-DSA from FIPS 203 and 204, at every security level, checked against the official test vectors.

Only loads what you use

Requiring the library takes about 2 ms. Each algorithm loads the first time you touch it, or when you call Preload.