Skip to content

Latest commit

Β 

History

History
405 lines (317 loc) Β· 15.9 KB

File metadata and controls

405 lines (317 loc) Β· 15.9 KB

πŸ”¬ Formal Verification for Meow-Encode

This directory contains formal specifications and proofs for Meow-Encode's security-critical components.

Overview

Tool Purpose Location Status
TLA+/TLC State machine model checking tla/ βœ… Complete
ProVerif Symbolic protocol analysis (MEOW2-5) proverif/ βœ… Complete
Tamarin Observational equivalence (MEOW3/4/5 PQ) tamarin/ βœ… Optional
Lean 4 Mathematical proofs lean/ βœ… Complete
Verus Rust implementation proofs ../crypto_core/ βœ… Complete

Protocol source of truth: docs/protocol.md

Quick Start

One-command verification:

make verify

Note: Tamarin runs only if tamarin-prover is installed. Local make verify will fail if it is missing; CI skips Tamarin unless installed.

TLA+ Model Checking (1-5 minutes)

cd /workspaces/meow-decoder/formal/tla

# Option 1: Direct Java (if you have tla2tools.jar)
java -jar tla2tools.jar -config MeowEncode.cfg MeowEncode.tla

# Option 2: Download TLC first
wget -q https://github.com/tlaplus/tlaplus/releases/download/v1.8.0/tla2tools.jar
java -jar tla2tools.jar -config MeowEncode.cfg MeowEncode.tla

# Option 3: Docker (no Java required)
docker run --rm -v $(pwd):/models toolsmiths/tla:latest tlc -config MeowEncode.cfg MeowEncode.tla

Expected output (success):

Model checking completed. No error has been found.
  States found: XXXX, distinct: XXXX

ProVerif Analysis (10-30 seconds)

cd /workspaces/meow-decoder/formal/proverif

# Option 1: Local ProVerif
eval $(opam env)
proverif meow_encode.pv

# Option 2: With HTML report
proverif -html output meow_encode.pv

# Option 3: Docker
docker run --rm -v $(pwd):/work proverif/proverif proverif /work/meow_encode.pv

Tamarin Equivalence (optional)

cd /workspaces/meow-decoder/formal/tamarin
./run.sh

You can also use Makefile shortcuts:

make formal-proverif
make formal-proverif-html

Expected output (success):

Query not attacker(real_secret[]) is true.
Query not attacker(real_password[]) is true.
...
RESULT All queries proved.

Verus Verification

cd /workspaces/meow-decoder/crypto_core

# Verify with Verus
verus src/lib.rs

Or run all formal checks at once:

make formal-all

Optimization Notes (January 2026)

The TLA+ model has been optimized for practical run times:

Parameter Original Optimized Reason
MaxFrames 4 2 Fewer frame combinations
MaxSessions 3 1 Single session sufficient
MaxNonces 10 3 Still catches nonce reuse
Passwords {1,2,3,4} {1,2} Real + duress only
AttackerActionLimit none 3 Prevents state explosion

Result: ~10K-50K states in 1-5 minutes (vs. 10M+ states in hours)

The optimized config still verifies all 6 security invariants.

Security Properties Verified

1. TLA+ State Machine Properties

The TLA+ model verifies these safety invariants over all reachable states:

Invariant Description
DuressNeverOutputsReal Duress password β†’ only decoy output
NoOutputOnAuthFailure Auth failure β†’ error state, no output
ReplayNeverSucceeds Replayed frames always rejected
NonceNeverReused Fresh nonce for each encryption
TamperedFramesRejected Modified ciphertext β†’ auth failure
NoAuthBypass Output requires successful auth
UnsealRequiresMatchingPCRs TPM unseal only with correct PCRs
TamperPreventsUnseal Platform tampering prevents key access
NoRealOutputWithoutUnsealedKey Real output requires unsealed hardware key
SealedKeyNeverInChannel Hardware-sealed keys never appear in channel
FailedUnsealBlocksDecrypt Failed unseal β†’ no successful decryption
KeyDerivationRequiresUnsealedOrSoftware Key derivation bound to hardware state
AttackerCannotForgeUnseal Unseal is outside attacker's capabilities

2. ProVerif Protocol Properties

The ProVerif model proves these properties against a Dolev-Yao attacker:

Query Description
attacker(real_secret) Plaintext confidentiality
attacker(real_password) Password never leaked
DecoderOutputReal ==> EncoderEncrypted Payload authenticity
ReplayRejected Replay attack resistance
DuressCorrectness Duress mode works correctly
NoAuthBypass No authentication bypass

3. Verus Implementation Properties

The Verus proofs verify these implementation-level invariants:

Property Description
nonce_uniqueness_invariant Nonce counter is strictly monotonic
auth_then_output_invariant Plaintext only after GCM auth
key_zeroization_invariant Key zeroed on drop
no_nonce_reuse All encryptions use unique nonces

GuardedBuffer / SecureBox bounds proofs (verus_guarded_buffer.rs):

Property ID Property Lemma
GB-001 Guard-page layout: data_ptr == mmap_base + page_size lemma_guard_layout_established
GB-002 Overflow prevention: index β‰₯ data_size hits upper PROT_NONE guard lemma_overflow_hits_upper_guard
GB-003 Underflow prevention: data_ptr - k hits lower PROT_NONE guard lemma_underflow_hits_lower_guard
GB-004 Data size correctness: data_size() == size_of::<T>() lemma_data_size_correctness
GB-005 Total size β‰₯ data_size + 2 Γ— page_size lemma_total_size_at_least_data_plus_two_guards
GB-006 data_region_size % page_size == 0 (mprotect alignment) lemma_data_region_page_aligned
GB-007 Zeroize-on-drop: bytes set to 0 before munmap lemma_zeroize_erases_data
GB-008 Valid access strictly within data region (not in either guard) theorem_guarded_buffer_safety

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     FORMAL VERIFICATION STACK                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚  β”‚     TLA+/TLC    β”‚  β”‚    ProVerif     β”‚  β”‚      Verus      β”‚        β”‚
β”‚  β”‚  State Machine  β”‚  β”‚    Protocol     β”‚  β”‚  Implementation β”‚        β”‚
β”‚  β”‚     Model       β”‚  β”‚    Analysis     β”‚  β”‚     Proofs      β”‚        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β”‚           β”‚                    β”‚                    β”‚                  β”‚
β”‚           β–Ό                    β–Ό                    β–Ό                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                    VERIFIED PROPERTIES                          β”‚  β”‚
β”‚  β”‚                                                                 β”‚  β”‚
β”‚  β”‚  β€’ Nonce uniqueness (TLA+, Verus)                              β”‚  β”‚
β”‚  β”‚  β€’ Auth-then-output (TLA+, Verus)                              β”‚  β”‚
β”‚  β”‚  β€’ Replay resistance (TLA+, ProVerif)                          β”‚  β”‚
β”‚  β”‚  β€’ Tamper detection (TLA+, ProVerif)                           β”‚  β”‚
β”‚  β”‚  β€’ Duress mode correctness (TLA+, ProVerif)                    β”‚  β”‚
β”‚  β”‚  β€’ Key confidentiality (ProVerif)                              β”‚  β”‚
β”‚  β”‚  β€’ Forward secrecy (ProVerif)                                  β”‚  β”‚
β”‚  β”‚  β€’ Key zeroization (Verus)                                     β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                              β”‚                                         β”‚
β”‚                              β–Ό                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                     IMPLEMENTATION                              β”‚  β”‚
β”‚  β”‚                                                                 β”‚  β”‚
β”‚  β”‚  meow_decoder/crypto.py    ◄──── Python Implementation         β”‚  β”‚
β”‚  β”‚  rust_crypto/src/lib.rs    ◄──── Rust Backend                  β”‚  β”‚
β”‚  β”‚  crypto_core/src/*.rs      ◄──── Verified Crypto Core          β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Threat Model Coverage

The formal verification covers the following threat model:

Attacker Capabilities (Dolev-Yao)

  • βœ… Intercept - Attacker can read all network traffic
  • βœ… Inject - Attacker can send arbitrary messages
  • βœ… Replay - Attacker can replay old messages
  • βœ… Reorder - Attacker can reorder messages
  • βœ… Tamper - Attacker can modify messages (detected)
  • ❌ Break crypto - Cannot break AES-256-GCM, Argon2id

Attack Scenarios Modeled

Attack TLA+ ProVerif Verus
Nonce reuse βœ… βœ… βœ…
Replay attack βœ… βœ… -
Frame tampering βœ… βœ… -
Frame injection βœ… βœ… -
Auth bypass βœ… βœ… βœ…
Duress mode abuse βœ… βœ… -
Key extraction - βœ… βœ…
Forward secrecy break - βœ… -
Guard page underflow βœ… (Tamarin symbolic) - βœ… (GB-003, real verus!{})
Buffer layout violation - - βœ… (GB-001, GB-005, GB-006)

Files

formal/
β”œβ”€β”€ README.md                    # This file
β”œβ”€β”€ tla/
β”‚   β”œβ”€β”€ MeowEncode.tla          # TLA+ state machine specification
β”‚   β”œβ”€β”€ MeowEncode.cfg          # TLC model checker configuration
β”‚   └── README.md               # TLA+ documentation
β”œβ”€β”€ proverif/
β”‚   β”œβ”€β”€ meow_encode.pv          # ProVerif protocol specification
β”‚   └── README.md               # ProVerif documentation
└── ../crypto_core/
    β”œβ”€β”€ Cargo.toml              # Rust crate configuration
    β”œβ”€β”€ src/lib.rs              # Crate entry point
    β”œβ”€β”€ src/aead_wrapper.rs     # AEAD wrapper (Verus annotations)
    β”œβ”€β”€ src/verus_guarded_buffer.rs  # ← NEW: real verus!{} bounds proofs (GB-001–GB-008)
    β”œβ”€β”€ src/verus_proofs.rs     # AEAD/nonce invariants (doc-comment annotations)
    β”œβ”€β”€ src/verus_kdf_proofs.rs # KDF invariants (doc-comment annotations)
    └── README.md               # Verus documentation

Verification Results

TLA+ (Expected Output)

All 3 models should report "No error has been found":

  • MeowEncode: ~300K distinct states (main protocol pipeline)
  • MeowFountain: ~44 states (fountain code properties)
  • MeowStreaming: ~57K states (streaming protocol)
Model checking completed. No error has been found.

ProVerif (Expected Output)

22 queries should report TRUE (critical security properties). 13 session-correspondence queries report FALSE β€” this is expected and documented (ProVerif overapproximates; these are not security violations).

Critical properties verified:

  • Confidentiality: attacker(real_secret) = FALSE
  • Password secrecy: attacker(real_password) = FALSE
  • Authentication: DecoderAuthenticated ==> EncoderStarted = TRUE
  • Duress safety: duress password never reveals real secret = TRUE
  • PQ secrecy: attacker(pq_shared_marker) = FALSE
  • Replay: ReplayAttempted ==> ReplayRejected = TRUE

Lean 4 (Expected Output)

lake build
# Exit 0, no errors

Sorry gate: no unapproved sorry keywords (documentation references excluded).

Cargo crypto_core (Expected Output)

cargo build --release
# Finished `release` profile

Verus (Expected Output)

verification results:: verified: 16 errors: 0
  nonce_uniqueness_invariant ... verified
  auth_then_output_invariant ... verified
  key_zeroization_invariant ... verified
  no_nonce_reuse ... verified
  lemma_guard_layout_established ... verified
  lemma_overflow_hits_upper_guard ... verified
  lemma_underflow_hits_lower_guard ... verified
  lemma_data_size_correctness ... verified
  lemma_total_size_at_least_data_plus_two_guards ... verified
  lemma_data_region_page_aligned ... verified
  lemma_zeroize_erases_data ... verified
  lemma_valid_access_in_data_region ... verified
  theorem_guarded_buffer_safety ... verified
  (+ 3 spec fn definitions)

Continuous Integration

Add to .github/workflows/formal-verification.yml:

name: Formal Verification

on: [push, pull_request]

jobs:
  tla-model-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run TLC
        uses: docker://talex5/tlaplus
        with:
          args: tlc -config formal/tla/MeowEncode.cfg formal/tla/MeowEncode.tla

  proverif-analysis:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install ProVerif
        run: |
          sudo apt-get update
          sudo apt-get install -y proverif
      - name: Run ProVerif
        run: proverif formal/proverif/meow_encode.pv

  verus-verification:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Verus
        run: |
          git clone https://github.com/verus-lang/verus
          cd verus && ./tools/get-z3.sh && ./tools/build.sh
      - name: Verify
        run: ./verus/target-verus/release/verus crypto_core/src/lib.rs

References

TLA+

ProVerif

Verus

Cryptographic Foundations

Contributing

To add new verified properties:

  1. TLA+: Add invariant to MeowEncode.tla and MeowEncode.cfg
  2. ProVerif: Add query to meow_encode.pv
  3. Verus: Add proof to aead_wrapper.rs

All verification must pass before merging security-critical changes.

License

CC BY-NC-SA 4.0 - See LICENSE file