Rust XChaCha20-Poly1305 Argon2id License
MX2 (MAX 2 eXcryption) is an open, verifiable, password-protected container format.
It provides a minimal, portable ASCII-safe way to encrypt long-term, high-entropy secrets using only standard, well-studied cryptography (Argon2id + XChaCha20-Poly1305).
MX2 is designed to be small, auditable, fully reproducible across platforms, and independent of any specific application or ecosystem.
• Portable ASCII-safe container
• Deterministic format and key-derivation logic
• Based exclusively on standard, well-studied cryptography
• Zero cloud dependency
• Suitable for QR encoding
• Fully auditable by researchers
• Reproducible across platforms
Encrypt a JSON file:
cargo run -- encrypt secret.json
Decrypt an MX2 container:
cargo run -- decrypt secret.mx2
Generate a new MX2 backup with two random phrases:
cargo run
MX2 aims to provide a transparent and reproducible way to protect long-term secrets without relying on proprietary algorithms or platform-specific behaviour.
It is not a password manager and does not generate the user’s secrets.
MX2 is simply a portable, auditable container built on Argon2id and XChaCha20-Poly1305.
Most cryptographic systems either:
• store keys directly inside a vault
• derive a single key from a password (KDFs)
• or use a seed phrase tied to one specific ecosystem
MX2 introduces a different model:
A password-protected, portable container that stores two high-entropy secret phrases
from which unlimited deterministic keys can be derived — for any purpose and on any implementation.
The password only unlocks the container.
The two phrases act as a root secret, enabling deterministic derivation of:
• per-message encryption keys
• per-device or per-application keys
• post-quantum keypairs
• identity material
• long-term recovery flows
Because derivation is deterministic, MX2 guarantees:
• infinite keys from a single root
• no private keys stored on disk
• long-term recoverability (container + password = full regeneration)
• interoperability across independent implementations
• auditability without revealing internal secrets
MX2 does not enforce how the phrases must be used.
It simply defines a secure, portable, inspectable container for storing them.
MX2 can be used for:
• portable encrypted backups
• QR-safe secret transport
• cross-platform password-based vaults
• deterministic key derivation in cryptographic systems
• offline recovery workflows
• reproducible secret containers for research and auditing
MX2 uses a simple but powerful three-layer model:
-
Password – the only secret the user must remember.
It does not generate cryptographic material; it simply unlocks the container. -
MX2 Container – a portable encrypted vault that stores a JSON record
(named MAXREC) containing long-term secret material.
The container is encrypted with key material derived from the password
(via SHA-256 → Argon2id → XChaCha20-Poly1305). -
Secret Phrases (p1, p2) – two high-entropy phrases stored inside MAXREC.
These phrases act as the root secret, allowing applications to deterministically
derive unlimited encryption keys, authentication keys, or identity material.
No private keys are stored on disk.
All keys are derived on demand from p1 and p2 and disappear after use.
MX2 uses a user password to encrypt and protect a JSON payload containing
two long, high-entropy secret phrases (p1, p2).
The password does not generate these phrases — it only derives the key
used to protect them.
Steps performed:
- Derives two internal passcodes from the password (via SHA-256).
- Hardens the password using Argon2id (64 MiB, 3 iterations).
- Encrypts the data using XChaCha20-Poly1305 (AEAD).
- Produces a portable ASCII-safe string:
MX2:pc:v1|xchacha20poly1305|salt_b64|nonce_b64|tag_b64|ct_b64
Example internal JSON payload:
{"type":"MAXREC","v":2,"ts":1730000000,"p1":"...","p2":"..."}
Full specification:
👉 SPEC_MX2_v1.md
The MX2 container is constructed through the following steps:
[ Secret Phrases ]
p1 , p2
│
▼
JSON payload (MAXREC)
│
│ (encrypted by key32)
│
▼
password ───► SHA-256 ───► internal passcodes ───► Argon2id ───► key32
│
▼
XChaCha20-Poly1305
│
▼
MX2:pc:v1 container
MX2 guarantees:
• Reproducible format and key-derivation logic
• Portability across platforms and implementations
• Auditability of parameters and on-disk representation
• Use of modern, well-studied cryptographic primitives
MX2 is deterministic in its format and key-derivation logic: given the same password, parameters and JSON payload, an implementation will always derive the same key material and produce a structurally equivalent container.
The encryption itself is randomized: each container uses a fresh random salt and XChaCha20-Poly1305 nonce, so two containers created from the same input will have different ciphertexts and tags. This is intentional and follows standard AEAD best practices.
- src/main.rs — command-line demo tool
- SPEC_MX2_v1.md — technical specification for MX2
- Cargo.toml — Rust crate definition
- LICENSE — MIT license
- .gitignore — Rust standard ignores
This repository includes a small command-line tool that demonstrates how MX2 works.
You can build and run it with:
git clone https://github.com/max-russo-com/mx2.git
cd mx2
cargo run
After running the tool, you will see a menu:
• Option 1: generate two new secret phrases and create an encrypted MX2 backup
• Option 2: decrypt an existing MX2 backup and recover the stored phrases
The demo enforces the same password policy as the MAX App:
- at least 14 characters
- at least 1 lowercase
- at least 1 uppercase
- at least 3 digits
- at least 3 symbols
MX2 uses modern, well-studied cryptographic primitives.
Password Hardening — Argon2id
- memory: 64 MiB
- iterations: 3
- lanes: 1
- output: 32 bytes
AEAD Encryption — XChaCha20-Poly1305
- nonce: 24 bytes
- tag: 16 bytes
- AAD: "MAX|MX2|pc|v1"
Randomness
- Salt: 16 bytes
- Nonce: 24 bytes
- RNG: OsRng
Security properties
- Fully authenticated encryption
- Stateless format
- No server involved
- No key material leaves the device
MX2 is a secure building block, not a standalone key manager.
MX2 does not attempt to solve key management, multi-device synchronization, or authenticated identity; it only defines a portable encrypted container format that other systems can build on.
Researchers can:
- inspect the MX2 format
- verify Argon2id parameters
- reproduce MX2 containers
- decrypt MAXREC payloads
- write compatible implementations
The entire format is intentionally simple and fully auditable.
- macOS
- Linux
- Windows (WSL recommended)
MX2 relies exclusively on standard, verifiable cryptographic primitives.
Argon2id (Password Hardening) https://datatracker.ietf.org/doc/draft-irtf-cfrg-argon2/ https://github.com/P-H-C/phc-winner-argon2
XChaCha20-Poly1305 (AEAD Encryption) https://datatracker.ietf.org/doc/rfc8439/ https://datatracker.ietf.org/doc/draft-irtf-cfrg-xchacha/ https://cr.yp.to/chacha.html
Poly1305 MAC https://cr.yp.to/mac/poly1305-20050329.pdf
SHA-256 (Hash Function) https://csrc.nist.gov/publications/detail/fips/180/4/final
AEAD — Authenticated Encryption with Associated Data https://datatracker.ietf.org/doc/rfc5116/
Base64 Encoding https://datatracker.ietf.org/doc/rfc4648/
All cryptographic components used by MX2 are open, standardized, and independently verifiable.
MX2 was originally designed as the local container for two long-term, high-entropy secret phrases used in a broader deterministic identity system (the MAX App).
These two phrases (p1, p2) allow the MAX App to reproducibly derive:
- MAX-ID (mathematical identity)
- SPHINCS+ private key (PQC Login)
- FrodoKEM keypair (PQC Chat)
- MAX Lock encryption keys
- MAX Signature keys
- All deterministic MAX modules in the architecture
MX2 is also used as the encrypted transport container inside MAX Chat, where messages and metadata are wrapped in an MX2 envelope before transmission.
This context is optional: MX2 is a standalone, general-purpose container format.
The deterministic MAX-ID derivation logic is proprietary and not part of this repository.
MX2 remains fully open, auditable, and independently verifiable.
MX2 originally stood for "MAX 2 eXcryption" and "MAX level 2" inside the MAX identity architecture.
The name reflects its role as the second cryptographic layer used to protect the two long-term secret phrases (p1, p2) that power all deterministic modules of the MAX App.
This naming history is kept for completeness. MX2 remains a standalone, general-purpose container format, independent of any specific application.
The MAX App uses MX2 to store and recover two secret phrases locally.
This repository implements the exact same container format:
SHA-256 → internal passcodes Argon2id parameters XChaCha20-Poly1305 AEAD Header MX2:pc:v1 JSON MAXREC payload
This allows full independent verification.
This repository allows researchers to perform a full interoperability test between the open MX2 implementation (this Rust code) and the MAX App.
You can verify mathematically that the MAX App uses the exact same MX2 format:
- SHA-256 for deriving internal passcodes
- Argon2id (64 MiB, 3 iterations, 1 lane)
- XChaCha20-Poly1305 (AEAD, 24-byte nonce, 16-byte tag)
- JSON MAXREC payload
MX2:pc:v1header
You can install the MAX App Beta here:
👉 https://testflight.apple.com/join/pc6PdFz5
Create an MX2 container with this Rust tool (cargo run)
and import it inside the MAX App.
The MAX App will correctly decrypt the payload.
Create an MX2 backup inside the MAX App.
Then use this repository to decrypt it on your computer.
The Rust implementation will correctly recover the JSON payload.
These two tests provide cryptographic transparency: anyone can confirm that the MAX App truly implements MX2 exactly as specified, without requiring access to any internal deterministic logic of MAX-ID.
This level of interoperability is intentional:
MX2 is designed to be open, verifiable and reproducible across platforms.
This project is released under the MIT License.
See the LICENSE file for details.
Massimo Russo
Version 1.0
• First public specification of MX2:pc:v1
• Introduced the MAXREC structured JSON payload
• Added deterministic SHA-256 passcode derivation
• Added Argon2id password hardening (64 MiB, 3 iterations, 1 lane)
• Implemented the XChaCha20-Poly1305 AEAD container format
• Included a cross-platform Rust CLI for demonstration and testing