A tiny, self-contained cryptography library, implementing authenticated encryption and keyed hashing.
Charm was especially designed for memory-constrained devices, but can also be used to add encryption support to WebAssembly modules with minimal overhead.
Any number of hashing and authenticated encryption operations can be freely chained using a single rolling state. In this mode, each authentication tag authenticates the whole transcript since the beginning of the session.
The original implementation was written in C and is used by the dsvpn VPN software.
This is a port to the Zig language. It is fully compatible with the C version.
Charm requires a 256-bit key, and, if the key is reused for different sessions, a unique session identifier (nonce
):
var key: [Charm.key_length]u8 = undefined;
std.crypto.random.bytes(&key);
var charm = Charm.new(key, null);
const h = charm.hash("data");
const tag = charm.encrypt(msg[0..]);
Encrypts msg
in-place and returns a 128-bit authentication tag.
Starting from the same state as the one used for encryption:
try charm.decrypt(msg[0..], tag);
Returns error.AuthenticationFailed
if the authentication tag is invalid for the given message and the previous transcript.
128-bit security, no practical limits on the size and length of messages.