audio bus crypto display ez global gps keyboard mesh net radio sprite storage synth system wifi

Cryptographic primitives for hashing, encryption, and encoding

Provides SHA-256/512 hashing, HMAC, AES-128-ECB encryption, base64 and hex encoding/decoding, and secure random number generation. Used internally for MeshCore channel encryption and message authentication. All operations use hardware-accelerated mbedTLS where available.

Functions

aes128_ecb_decrypt() → string Decrypt data with AES-128-ECB
ez.crypto.aes128_ecb_decrypt(key, ciphertext) -> string
Decrypts data encrypted with aes128_ecb_encrypt. The ciphertext must be a multiple of 16 bytes. The decrypted output includes zero padding bytes, so you may need to trim trailing zeros for text data.
ParameterDescription
key16-byte key (must match encryption key)
ciphertextData to decrypt (must be multiple of 16 bytes)
Returns: Decrypted data as binary string (with padding zeros), or nil and error
local key = ez.crypto.derive_channel_key("my secret")
local encrypted = ez.crypto.aes128_ecb_encrypt(key, "hello")
local decrypted = ez.crypto.aes128_ecb_decrypt(key, encrypted)
print(decrypted:gsub("%z+$", ""))  -- Trim trailing zeros
aes128_ecb_encrypt() → string Encrypt data with AES-128-ECB
ez.crypto.aes128_ecb_encrypt(key, plaintext) -> string
Encrypts data using AES-128 in ECB mode. ECB mode encrypts each 16-byte block independently - use for short data or when simplicity is needed. Input is zero-padded to 16-byte boundary. For secure encryption of longer data, consider using channel encryption which uses proper IV/nonce handling.
ParameterDescription
key16-byte key (use derive_channel_key to create from password)
plaintextData to encrypt (will be zero-padded to block boundary)
Returns: Encrypted data as binary string, or nil and error on failure
local key = ez.crypto.derive_channel_key("my secret")
local encrypted = ez.crypto.aes128_ecb_encrypt(key, "hello")
print("Encrypted:", ez.crypto.bytes_to_hex(encrypted))
base64_decode() → string Decode base64 string to binary data
ez.crypto.base64_decode(encoded) -> string
Decodes a base64 encoded string back to binary data. Returns nil and error message if the input contains invalid base64 characters or has incorrect padding.
ParameterDescription
encodedBase64 encoded string
Returns: Binary string, or nil and error on failure
local decoded = ez.crypto.base64_decode("SGVsbG8sIFdvcmxkIQ==")
print(decoded)  -- "Hello, World!"
base64_encode() → string Encode binary data to base64 string
ez.crypto.base64_encode(data) -> string
Encodes binary data to base64 format. Base64 represents binary data using only printable ASCII characters (A-Z, a-z, 0-9, +, /). The output is about 33% larger than the input. Useful for transmitting binary data in text formats.
ParameterDescription
dataBinary string to encode
Returns: Base64 encoded string, or nil and error on failure
local encoded = ez.crypto.base64_encode("Hello, World!")
print(encoded)  -- "SGVsbG8sIFdvcmxkIQ=="
bytes_to_hex() → string Convert binary data to hex string
ez.crypto.bytes_to_hex(data) -> string
Converts binary data to a lowercase hexadecimal string representation. Each byte becomes two hex characters. Useful for displaying keys, hashes, and other binary data in a readable format.
ParameterDescription
dataBinary string
Returns: Hex string (lowercase)
local hash = ez.crypto.sha256("test")
print(ez.crypto.bytes_to_hex(hash))
-- Shows 64-character hex string
channel_hash() → integer Compute channel hash from key (SHA256(key)[0])
ez.crypto.channel_hash(key) -> integer
Computes a single-byte channel identifier from a channel key. This is the first byte of SHA256(key) and is used in the MeshCore protocol to quickly filter packets by channel. Each channel has a unique hash that identifies it without revealing the encryption key.
ParameterDescription
key16-byte channel key
Returns: Single byte hash as integer (0-255)
local key = ez.crypto.public_channel_key()
local hash = ez.crypto.channel_hash(key)
print("Public channel hash:", hash)
derive_channel_key() → string Derive 16-byte channel key from password/name using SHA256
ez.crypto.derive_channel_key(input) -> string
Derives a 16-byte AES-128 key from a password or channel name by taking the first 16 bytes of SHA256(input). This allows users to join channels using a memorable password instead of raw key bytes. All devices with the same password will derive the same key.
ParameterDescription
inputPassword or channel name string
Returns: 16-byte key as binary string
local key = ez.crypto.derive_channel_key("SecretChannel2024")
print("Key:", ez.crypto.bytes_to_hex(key))
local hash = ez.crypto.channel_hash(key)
print("Channel hash:", hash)
hex_to_bytes() → string Convert hex string to binary data
ez.crypto.hex_to_bytes(hex) -> string
Converts a hexadecimal string to binary data. Accepts both upper and lowercase hex characters. The input must have even length. Returns nil and error message if the string contains invalid characters or has odd length.
ParameterDescription
hexHex string (case-insensitive, must have even length)
Returns: Binary string, or nil and error message on failure
local key = ez.crypto.hex_to_bytes("8b3387e9c5cdea6ac9e5edbaa115cd72")
print("Key length:", #key)  -- 16 bytes
hmac_sha256() → string Compute HMAC-SHA256
ez.crypto.hmac_sha256(key, data) -> string
Computes a keyed-hash message authentication code (HMAC) using SHA-256. Unlike plain hashing, HMAC requires a secret key, making it suitable for message authentication where both parties share a secret. Returns nil and error message on failure.
ParameterDescription
keyBinary string key (any length, but 32 bytes recommended)
dataBinary string to authenticate
Returns: 32-byte MAC as binary string, or nil and error on failure
local key = ez.crypto.random_bytes(32)
local mac = ez.crypto.hmac_sha256(key, "message to authenticate")
-- Verify by recomputing and comparing
local verify = ez.crypto.hmac_sha256(key, "message to authenticate")
if mac == verify then print("Authentic") end
public_channel_key() → string Get the well-known #Public channel key
ez.crypto.public_channel_key() -> string
Returns the pre-defined key for the #Public channel. This is the default channel that all MeshCore devices join on startup. The key is well-known (8b3387e9c5cdea6ac9e5edbaa115cd72) so all devices can communicate without configuration. For private communication, use a custom channel with derive_channel_key.
Returns: 16-byte key as binary string
local public_key = ez.crypto.public_channel_key()
print("Public key:", ez.crypto.bytes_to_hex(public_key))
-- Output: 8b3387e9c5cdea6ac9e5edbaa115cd72
random_bytes() → string Generate cryptographically secure random bytes
ez.crypto.random_bytes(count) -> string
Generates cryptographically secure random bytes using the ESP32's hardware random number generator. Suitable for key generation, nonces, and other security-sensitive applications. Maximum 256 bytes per call.
ParameterDescription
countNumber of bytes to generate (1-256)
Returns: Random bytes as binary string, or nil and error if count invalid
local key = ez.crypto.random_bytes(16)  -- Generate 128-bit key
local nonce = ez.crypto.random_bytes(12)  -- 96-bit nonce
print("Key:", ez.crypto.bytes_to_hex(key))
sha256() → string Compute SHA-256 hash
ez.crypto.sha256(data) -> string
Computes a SHA-256 cryptographic hash of the input data. Returns a 32-byte binary string. Use bytes_to_hex() to convert to readable hex format. SHA-256 is used for message digests, integrity checks, and key derivation.
ParameterDescription
dataBinary string to hash
Returns: 32-byte hash as binary string
local hash = ez.crypto.sha256("hello world")
print("SHA256:", ez.crypto.bytes_to_hex(hash))
-- Output: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
sha512() → string Compute SHA-512 hash
ez.crypto.sha512(data) -> string
Computes a SHA-512 cryptographic hash of the input data. Returns a 64-byte binary string. SHA-512 provides stronger security than SHA-256 but is slower. Use for high-security applications or when 256-bit hash is insufficient.
ParameterDescription
dataBinary string to hash
Returns: 64-byte hash as binary string
local hash = ez.crypto.sha512("secret data")
print("SHA512:", ez.crypto.bytes_to_hex(hash))