Skip to main content

Crate xchacha20_blake3_siv

Crate xchacha20_blake3_siv 

Source
Expand description

§XChaCha20-BLAKE3-SIV

A fast, deterministic Authenticated Encryption with Associated Data (AEAD) construction combining:

  • XChaCha20 for stream-cipher confidentiality (192-bit nonce, software-efficient)
  • BLAKE3 in keyed SIV (Synthetic Initialization Vector) mode for integrity and nonce-misuse resistance

§Design

This crate implements the SIV (Synthetic IV) construction defined informally as MAC-then-Encrypt:

  1. Derive the SIV — A 24-byte tag is produced by running keyed BLAKE3 over (context, nonce, len(AD), len(plaintext), AD, plaintext). The domain-separation context string "XCHACHA20-BLAKE3-SIV-01" is mixed in at key-setup time, so the MAC key is bound to this specific scheme version.
  2. Encrypt — The 24-byte SIV is used directly as the XChaCha20 nonce, producing ciphertext of exactly the same length as the plaintext (no padding).
  3. Authenticate — On decryption the SIV is recomputed from the recovered plaintext and compared in constant time against the stored tag. A mismatch causes the plaintext buffer to be zeroized before the error is returned.

Ciphertext layout:

┌──────────────────────┬──────────────────────────────┐
│  SIV / Tag (24 B)    │  Ciphertext (= plaintext len) │
└──────────────────────┴──────────────────────────────┘

§Security Properties

PropertyGuarantee
ConfidentialityXChaCha20 stream cipher
IntegrityBLAKE3 keyed MAC, constant-time verification
Nonce-misuse resistanceNonce reuse reveals only that the same plaintext was sent
DeterministicSame (key, nonce, AD, plaintext) → same ciphertext (useful for dedup)
Memory safetyzeroize wipes keys and failed-decryption buffers; #![forbid(unsafe_code)]

§Quick Start

§Allocating API

The simplest interface — allocates a Vec<u8> for the ciphertext/plaintext:

use xchacha20_blake3_siv::{Cipher, Key, Nonce};

// Keys must be exactly 64 bytes: first 32 for encryption, last 32 for the MAC.
// In real code, derive this from a KDF or CSPRNG.
let key: Key = [0u8; 64];
let nonce: Nonce = [1u8; 24];
let ad = b"invoice-id:7f3a9c";   // optional context bound to the ciphertext
let plaintext = b"Amount: $9999.00";

let cipher = Cipher::new(&key)?;

let ciphertext = cipher.encrypt(&nonce, plaintext, ad)?;
// ciphertext is  TAG_LEN (24) + plaintext.len() bytes — no padding.

let recovered = cipher.decrypt(&nonce, &ciphertext, ad)?;
assert_eq!(recovered, plaintext);

§In-Place (Zero-Copy) API

Avoids extra allocations by operating directly on a caller-supplied buffer. The buffer must be pre-sized to TAG_LEN + plaintext_len and the plaintext must start at offset TAG_LEN:

use xchacha20_blake3_siv::{Cipher, TAG_LEN};

let key = [0u8; 64];
let nonce = [1u8; 24];
let msg = b"Hello, zero-copy world!";

let cipher = Cipher::new(&key)?;

// Allocate buffer with room for the tag prefix.
let mut buffer = vec![0u8; TAG_LEN + msg.len()];
buffer[TAG_LEN..].copy_from_slice(msg);

// Encrypt: writes the SIV into `buffer[..TAG_LEN]` and encrypts the rest.
cipher.encrypt_in_place(&mut buffer, msg.len(), &nonce, b"")?;

// Decrypt: returns a sub-slice of `buffer` containing the plaintext.
let plaintext = cipher.decrypt_in_place(&mut buffer, &nonce, b"")?;
assert_eq!(plaintext, msg);

§When to Use This Crate

  • WebAssembly: Both XChaCha20 and BLAKE3 are pure-software primitives with no dependency on hardware AES instructions (AES-NI / VAES).
  • Large payloads: BLAKE3’s internal parallelism means this construction matches or exceeds AES-256-GCM throughput for payloads larger than ~256 KiB.
  • Deterministic / deduplication: If you need the same plaintext to always produce the same ciphertext (e.g., content-addressable encrypted storage), SIV is the right tool.
  • Nonce-misuse resilience: Accidental nonce reuse is catastrophic for GCM but only leaks equality information under SIV.

§Security Warnings

  • Key generation: always use a cryptographically secure RNG (e.g. getrandom).
  • Determinism: encrypting the same (nonce, AD, plaintext) twice reveals that you did so. Use unique nonces when traffic-analysis resistance is required.
  • No built-in nonce management: the caller is responsible for nonce uniqueness.

This construction is particularly well-suited for WebAssembly (WASM) environments and systems lacking hardware AES acceleration.

Structs§

Cipher
A SIV (Synthetic Initialization Vector) AEAD cipher using XChaCha20 and BLAKE3.

Enums§

Error
Errors that can occur during Cipher construction, encryption, or decryption.

Constants§

KEY_LEN
The required length of the master key in bytes (64 bytes).
NONCE_LEN
The length of the external nonce in bytes (24 bytes).
TAG_LEN
The length of the authentication tag (SIV) prepended to every ciphertext, in bytes (24 bytes).

Type Aliases§

Key
A 64-byte master key for the Cipher.
Nonce
A 24-byte external nonce passed by the caller on every encrypt/decrypt call.
Tag
A 24-byte Synthetic Initialization Vector / authentication tag.