Download ZelEn CLI

Release files are hosted directly on this site at https://zelen.rocheston.com/zelen-releases/.

Install and Verify

bash
# 1. Download the build for your platform from this page
unzip zelen-1.2.0-macos-arm64.zip
# or: unzip zelen-1.2.0-linux-x86_64.zip

# 2. Put the binary somewhere on PATH
chmod +x zelen
sudo mv zelen /usr/local/bin/zelen

# 3. Initialize and check the installation
zelen init
zelen version
zelen doctor
zelen self-test

CLI Command Reference

ZelEn quantum-safe encryption CLI — ML-KEM + ML-DSA, NIST FIPS 203/204.

zelen --help
Usage: zelen [OPTIONS] <COMMAND>

Commands:
  version      Show version information
  init         Initialize ZelEn home directory
  keys         Key management
  cert         Certificate operations
  encrypt      Encrypt data
  enc          Encrypt data (alias for encrypt)
  decrypt      Decrypt data
  dec          Decrypt data (alias for decrypt)
  sign         Sign a file
  verify       Verify a signature
  armor        ASCII armor a file
  dearmor      De-armor an ASCII-armored file
  container    Container operations
  config       Configuration management
  trust        Trust store management
  doctor       Check system health and provider availability
  self-test    Run self-tests
  bench        Benchmark cryptographic operations
  completions  Generate shell completions
  man          Generate man pages
  playground   Launch local web playground
  keygen       Alias: zelen keys generate
  pub          Alias: zelen keys public
  inspect      Inspect any ZelEn file
  seal         Encrypt text (alias for encrypt text)
  open         Decrypt (alias for decrypt text)
  tau          tau datum management for MTE-PQ5
  mte          Explain MTE-PQ5

Options:
      --config <CONFIG>      Configuration file path [env: ZELEN_CONFIG=]
      --home <HOME>          ZelEn home directory [env: ZELEN_HOME=]
      --provider <PROVIDER>  PQC provider selection [env: ZELEN_PROVIDER=]
      --suite <SUITE>        Cryptographic suite [possible values: pq3, pq5, pq5-slh, mte-pq5]
      --json                 Output JSON instead of human-readable text
  -q, --quiet                Suppress non-error output
  -v, --verbose              Verbose output
      --debug                Debug output
      --no-progress          Disable progress bars
  -y, --yes                  Skip confirmation prompts
  -f, --force                Force overwrite existing files
      --strict               Strict validation mode
      --compat               Allow unknown suite IDs
      --insecure-allow-mock  Allow mock provider
  -h, --help                 Print help
  -V, --version              Print version

Common Workflows

key management
zelen keys generate --subject [email protected] --name Alice --suite pq5 --out alice
zelen keys generate --subject [email protected] --suite mte-pq5 --out alice
zelen keys generate --subject [email protected] --suite pq3 --out bob --passphrase-file pass.txt
zelen keys inspect alice.zpub
zelen keys inspect alice.zkey --secret-metadata
zelen keys fingerprint alice.zpub
zelen keys fingerprint alice.zpub --short
zelen keys public --key alice.zkey --out alice.zpub
zelen keys change-passphrase --key alice.zkey
zelen keys unlock-test --key alice.zkey
encryption
zelen encrypt text --recipient alice.zpub --text "Secret message" --out msg.zelen
zelen encrypt text --recipient alice.zpub --text "Signed!" --sign-key bob.zkey --out msg.zelen
zelen encrypt file --recipient alice.zpub --in report.pdf --out report.pdf.zelen
zelen encrypt file --recipient alice.zpub --in photo.jpg --out photo.jpg.zelen --armor
zelen encrypt file --recipient alice.zpub --in data.zip --sign-key bob.zkey --out data.zip.zelen
cat secret.txt | zelen encrypt stream --recipient alice.zpub --stdout > secret.zelen
zelen seal --recipient alice.zpub --text "Short secret" --out sealed.zelen
decryption
zelen decrypt text --key alice.zkey --input msg.zelen
zelen decrypt file --key alice.zkey --input report.pdf.zelen --out report.pdf
zelen decrypt file --key alice.zkey --input msg.zelen --verify-sender bob.zpub --require-signature
zelen decrypt stream --key alice.zkey --stdin --stdout < secret.zelen > plain.txt
zelen decrypt text --key alice.zkey --input msg.zelen --passphrase-env MY_PASSPHRASE
zelen open --key alice.zkey --input msg.zelen
sign and verify
zelen sign --key alice.zkey --in document.pdf --out document.zsig
zelen verify --pub alice.zpub --in document.pdf --signature document.zsig
zelen sign --key alice.zkey --in data.bin --out data.zsig --context "contract-v1"
zelen inspect alice.zpub
zelen inspect msg.zelen --header-map
zelen container inspect --input msg.zelen --json
mte-pq5
zelen mte
zelen keys generate --subject [email protected] --suite mte-pq5 --out alice
zelen tau inspect alice.ztau
zelen tau inspect alice.ztau --json
zelen tau generate --key alice.zkey --out alice.ztau
zelen encrypt file --recipient alice.zpub --suite mte-pq5 --tau alice.ztau --in doc.pdf --out doc.pdf.zelen
zelen decrypt file --key alice.zkey --tau alice.ztau --input doc.pdf.zelen --out doc.pdf

PHP Usage

KeyService.php
<?php
// Bootstrap
require 'vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->safeLoad();

use ZelenVault\Crypto\{ProviderFactory, ZelenKeyService, ZelenSuite};

$provider   = ProviderFactory::getProvider();
$keyService = new ZelenKeyService($provider);

$bundle = $keyService->generateBundle([
    'subject'      => '[email protected]',
    'display_name'  => 'Alice',
    'organization'  => 'Zelfire',
    'suite_id'      => ZelenSuite::SUITE_PQ5, // 0x0101
    'passphrase'    => 'correct-horse-battery-staple',
    'expires_days'  => 365,
    'key_usage'     => ['encrypt', 'decrypt', 'sign', 'verify'],
]);

file_put_contents('alice.zkey', $bundle['zkey']);
file_put_contents('alice.zpub', $bundle['zpub']);
echo "Fingerprint: " . $bundle['fingerprint'] . PHP_EOL;
Encrypt.php
use ZelenVault\Crypto\{ProviderFactory, ZelenKeyService, ZelenContainer, ZelenSuite};

$provider     = ProviderFactory::getProvider();
$keyService   = new ZelenKeyService($provider);
$container    = new ZelenContainer($provider);

// Parse recipient's public key
$recipientPub = $keyService->parseZpub(file_get_contents('alice.zpub'));

// Encrypt
$zelenBytes = $container->encrypt(
    'Hello, Alice! This is a quantum-safe message.',
    $recipientPub,
    [], // sender key (optional)
    ['suite_id' => ZelenSuite::SUITE_PQ5]
);

file_put_contents('message.zelen', $zelenBytes);
echo "Container size: " . strlen($zelenBytes) . " bytes\n";
Decrypt.php
use ZelenVault\Crypto\{ProviderFactory, ZelenKeyService, ZelenContainer};

$provider   = ProviderFactory::getProvider();
$keyService = new ZelenKeyService($provider);
$container  = new ZelenContainer($provider);

// Unlock private key
$zkeyData = $keyService->parseZkey(file_get_contents('alice.zkey'));
$unlocked = $keyService->unlockZkey($zkeyData, 'correct-horse-battery-staple');

$recipientKey = [
    'kem_secret_key' => $unlocked['kem_secret_key'],
];

// Decrypt — throws on any authentication failure
$result = $container->decrypt(
    file_get_contents('message.zelen'),
    $recipientKey
);

echo $result['plaintext'];
echo "Suite: " . $result['metadata']['suite_name'] . PHP_EOL;

Object Schemas

schema.zkey
{
  "type":          "zkey",
  "version":       "1.0",
  "suite_id":      "0x0101",
  "suite_name":    "ZELEN-PQ5",
  "subject":       "[email protected]",
  "display_name":  "Alice",
  "organization":  "Zelfire",
  "key_id":        "uuid-v4",
  "fingerprint":   "sha3-256-hex-identity-fingerprint",
  "kdf": {
    "alg":           "argon2id",
    "salt":          "base64-encoded-salt",
    "params": { "memory_cost": 65536, "time_cost": 3, "threads": 4 }
  },
  "kem_secret_key": "base64-aes-gcm-encrypted",
  "sig_secret_key": "base64-aes-gcm-encrypted",
  "kem_public_key": "base64-raw-bytes",
  "sig_public_key": "base64-raw-bytes",
  "key_usage":     ["encrypt", "decrypt", "sign", "verify"],
  "export_policy": "protected",
  "hardware_binding": false,
  "created_at":    "ISO8601",
  "expires_at":    "ISO8601"
}
schema.zpub
{
  "type":          "zpub",
  "version":       "1.0",
  "suite_id":      "0x0101",
  "suite_name":    "ZELEN-PQ5",
  "subject":       "[email protected]",
  "display_name":  "Alice",
  "organization":  "Zelfire",
  "key_id":        "uuid-v4",
  "fingerprint":   "sha3-256-hex",
  "kem_public_key": "base64",  // ML-KEM-1024 = 1568 bytes
  "sig_public_key": "base64",  // ML-DSA-87 = 2592 bytes
  "key_usage":     ["encrypt", "verify"],
  "policy_hash":   "sha3-256-hex",
  "created_at":    "ISO8601",
  "expires_at":    "ISO8601"
}
schema.zcert
{
  "type":          "zcert",
  "version":       "1.0",
  "serial":        "hex-128bit",
  "issuer":        { "subject": "...", "fingerprint": "..." },
  "subject":       { "subject": "...", "display_name": "...", "organization": "..." },
  "suite_id":      "0x0101",
  "suite_name":    "ZELEN-PQ5",
  "subject_public_key": { /* zpub object */ },
  "validity": {
    "not_before": "ISO8601",
    "not_after":  "ISO8601"
  },
  "key_usage":     ["encrypt", "verify"],
  "certificate_fingerprint": "sha3-256-hex",
  "issuer_signature": "base64-ml-dsa-signature",
  "signature_algorithm": "ML-DSA-87",
  "self_signed":   true
}

Environment Variables

VariableDefaultDescription
APP_ENV development Application environment. Set to "production" to enforce security restrictions.
APP_DEBUG true Enable debug output. MUST be false in production.
APP_URL http://localhost:8080 Base URL for the application.
ZELEN_PQC_PROVIDER mock Provider: mock | oqs_cli | python_oqs | auto
ZELEN_OQS_HELPER_PATH /usr/local/bin/zelen-oqs-helper Path to OQS CLI helper binary (for oqs_cli provider).
ZELEN_PYTHON_WORKER workers/oqs_worker.py Path to Python OQS worker (for python_oqs provider).
ZELEN_MAX_UPLOAD_MB 128 Maximum file upload size in megabytes.
ZELEN_ALLOW_MOCK_PROVIDER true Allow mock provider. Automatically false when APP_ENV=production.
ZELEN_STORAGE_PATH storage Base path for temp files and audit logs.
ZELEN_DELETE_TEMP_AFTER_SECONDS 600 TTL for temporary files (seconds).

Provider Configuration

🐍

python_oqs

Uses workers/oqs_worker.py with liboqs-python.

pip install liboqs-python
ZELEN_PQC_PROVIDER=python_oqs

oqs_cli

Calls a compiled zelen-oqs-helper binary via JSON stdin/stdout.

ZELEN_PQC_PROVIDER=oqs_cli
ZELEN_OQS_HELPER_PATH=/usr/local/bin/zelen-oqs-helper

mock (DEMO ONLY)

Random bytes. Zero security. For UI testing only.

ZELEN_PQC_PROVIDER=mock
ZELEN_ALLOW_MOCK_PROVIDER=true
APP_ENV=development

Suite Identifiers

Suite IDNameKEMSignatureLevelStatus
0x0100ZELEN-PQ3ML-KEM-768ML-DSA-65NIST 3Enabled
0x0101ZELEN-PQ5ML-KEM-1024ML-DSA-87NIST 5Default
0x0102ZELEN-PQ5-SLHML-KEM-1024ML-DSA-87 + SLH-DSANIST 5Enabled
0x0301ZELEN-HQC-RESERVEDDisabled