🔐 Security Policy

Cryptographic Architecture

How Fialka protects your communications — algorithms, protocol stack, and reporting.

⚠️ Important: Fialka is a tool. The developers do not operate any infrastructure, do not store any user data, and cannot access any messages. There is no central server — all communication is peer-to-peer via Tor Hidden Services. Users are solely responsible for their use of the software.

Supported Versions

VersionStatus
V4.0.x✅ Current — security fixes
V3.4.x✅ Security fixes only
< V3.4❌ Unsupported

Report a Vulnerability

If you discover a security vulnerability, do not open a public issue.

Option 1 — GitHub private advisory (preferred):

🔒 Open private security advisory →

Please include: description, reproduction steps, potential impact, suggested fix. Expected response: 48–72 hours for acknowledgment.

Identity Architecture — "1 Seed → Everything"

Fialka derives the entire cryptographic identity from a single Ed25519 seed (32 bytes), backed up as 24 BIP-39 words:

Ed25519 seed (32 bytes)  ←  BIP-39 24 words restores this
│
├── Ed25519 keypair       → sign messages (authentication)
│
├── Ed25519 pubkey → SHA3-256 → Base58    = Account ID "Fa3x...9Z"
│
├── Ed25519 keypair → Tor v3 encoding     = .onion address
│
├── Ed25519 pubkey → SHA-256 → 16 emojis  = Fingerprint anti-MITM (96-bit)
│
├── Ed25519 pubkey → birational map        = X25519 DH pubkey
│   (Edwards → Montgomery)                  Contact only needs Ed25519 pubkey
│                                           → X25519 computes automatically
│
└── HKDF(seed, "fialka-ml-kem", 64 bytes) = ML-KEM-1024 keypair
    (d=32 + z=32 → deterministic KeyGen)    (post-quantum key derived from seed)
Key result: BIP-39 24 words restore everything: Ed25519, X25519, ML-KEM-1024, Account ID, .onion address, fingerprint.

Algorithms

Component Algorithm Key Size Library
Identity keyEd25519256-bitFialka-Core (Rust)
DH key agreementX25519256-bitFialka-Core (Rust)
Post-quantum KEMML-KEM-1024NIST Level 5Fialka-Core (Rust)
PQ signatureML-DSA-44NIST Level 2Fialka-Core (Rust)
Symmetric (primary)AES-256-GCM256-bitFialka-Core / HW
Symmetric (fallback)ChaCha20-Poly1305256-bitFialka-Core (Rust)
Key derivationHKDF-SHA256Fialka-Core (Rust)
Account IDSHA3-256 → Base58256-bitFialka-Core (Rust)
PIN hashingPBKDF2-HMAC-SHA256600K iterAndroid built-in
Local databaseSQLCipher AES-256256-bitSQLCipher 4.14.1
Key storageAndroid KeystoreHW-backedStrongBox / TEE
BackupBIP-39256-bitFialka-Core (Rust)
TransportTor Hidden Serviceslibtor.so

Protocol Stack (11 Layers)

Layer 1 — Identity Ed25519 seed (32 bytes) → derives everything
Layer 2 — Key Exchange PQXDH (X25519 + ML-KEM-1024 hybrid)
Layer 3 — Handshake Auth Ed25519 + ML-DSA-44 hybrid signature
Layer 4 — Ratcheting Double Ratchet (DH ratchet + KDF chains)
Layer 5 — PQ Maintenance SPQR (ML-KEM re-encapsulation every 10 messages)
Layer 6 — Encryption AES-256-GCM or ChaCha20-Poly1305 (auto-selected)
Layer 7 — Signing Ed25519 per-message signature
Layer 8 — Padding Fixed-size buckets (256B / 1KB / 4KB / 16KB)
Layer 9 — Transport Tor Hidden Services (.onion P2P — no relay)
Layer 10 — Cover Traffic Dummy messages (30–90s interval, per-conversation)
Layer 11 — Offline Fialka Mailbox (encrypted blob store via Tor)

Session Establishment — PQXDH

Alice                                   Bob
  │                                       │
  ├── X25519 DH(Alice, Bob) ─────────────►│  = ssClassic (32 bytes)
  ├── ML-KEM encaps(Bob pubkey) ─────────►│  = ssPQ (32 bytes) + kemCiphertext
  ├── Ed25519.sign(handshake data) ──────►│  = classicSig (64 bytes)
  ├── ML-DSA-44.sign(handshake data) ────►│  = pqSig (2420 bytes, one-time)
  │                                       │
  └── HKDF(ssClassic ‖ ssPQ) ──────────→ rootKey initial
                                          (hybrid classic + post-quantum)

Per-Message Encryption

rootKey ──→ DH Ratchet (X25519 ephemeral) ──→ new rootKey
         └─→ chainKey ──→ HMAC ──→ messageKey

messageKey ──→ AES-256-GCM(plaintext padded) ──→ ciphertext
Ed25519.sign(ciphertext ‖ conversationId ‖ createdAt) ──→ signature (64 bytes)

Every 10 messages (SPQR):
  ML-KEM encaps ──→ ssPQ (32 bytes)
  HKDF(rootKey ‖ ssPQ) ──→ new rootKey  (continuous PQ protection)