libertaria-stack/docs/PHASE_1_FOUNDATION.md

12 KiB
Raw Blame History

Phase 1: Foundation - SDK Architecture & Scaffolding

Status: Foundation complete. Ready for vendor library integration.

Completion Date: 2026-01-30

Deliverables: Architecture, FFI binding stubs, module templates, build infrastructure


What We Built

Module Architecture

Three core identity modules created with C FFI binding stubs:

Module Purpose Status Size
soulkey.zig Identity keypair management (Ed25519 + X25519 + ML-KEM-768) Complete ~400 lines
argon2.zig Entropy stamp verification with Argon2id PoW Stub ready ~350 lines
pqxdh.zig Post-quantum key agreement (4×X25519 + 1×ML-KEM-768) Stub ready ~550 lines

Existing Modules (Untouched)

Module Purpose Status
crypto.zig Basic encryption (X25519, XChaCha20-Poly1305) Working
lwf.zig Libertaria Wire Frame codec Working

Architecture Decisions Made

  1. Crypto Library Choice:

    • Zig stdlib: Ed25519, X25519, XChaCha20-Poly1305, BLAKE3
    • C FFI: Argon2 (PoW), liboqs ML-KEM-768 (post-quantum)
    • Pure Rust ml-kem: Available as fallback for L2+
  2. ML-KEM Implementation:

    • Primary (L0-L1 Zig): liboqs via C FFI
    • Alternative (L2+ Rust): Pure ml-kem crate
    • Rationale: C library is FIPS 203 compliant, NIST audited
  3. Entropy Protection:

    • Argon2id: Memory-hard PoW (GPU-resistant)
    • Kenya config: 2 iterations, 2 MB memory, single-threaded
    • Target: <100ms on ARM Cortex-A53 @ 1.4 GHz

Module Details

SoulKey (L1 Identity)

File: l1-identity/soulkey.zig

Exports:

  • SoulKey struct - Triple keypair (Ed25519 + X25519 + ML-KEM-768)
  • generate() - Create from seed (BIP-39 compatible)
  • sign() / verify() - Digital signatures
  • deriveSharedSecret() - ECDH key agreement
  • zeroize() - Secure memory cleanup
  • DID - Decentralized Identifier

Key Properties:

  • DID: blake3(ed25519_pub || x25519_pub || mlkem_pub)
  • Seed-based generation (20-word mnemonic compatible)
  • Constant-time operations where possible
  • Memory zeroization on drop

Status: Pure Zig implementation (no C FFI needed yet)


Entropy Stamps (L1 PoW)

File: l1-identity/argon2.zig

Exports:

  • EntropyStamp struct - Proof of work result
  • create() - Generate stamp via Argon2id
  • verify() - Validate stamp authenticity
  • KENYA_CONFIG - Mobile-friendly parameters
  • STANDARD_CONFIG - High-security parameters

C FFI Requirements:

// argon2.h must define:
int argon2id_hash_raw(
    uint32_t time_cost,
    uint32_t memory_cost_kb,
    uint32_t parallelism,
    const void *pwd, size_t pwd_len,
    const void *salt, size_t salt_len,
    void *hash, size_t hash_len
);

Parameters (Kenya):

  • Time cost: 2-6 iterations (difficulty-dependent)
  • Memory: 2 MB (2048 KiB)
  • Parallelism: 1 thread
  • Output: 32 bytes (SHA256-compatible)

Status: FFI stub ready, needs argon2.h linking


PQXDH Handshake (L1 Post-Quantum)

File: l1-identity/pqxdh.zig

Exports:

  • PrekeyBundle struct - Bob's public keys
  • PQXDHInitialMessage struct - Alice's handshake initiation
  • initiator() - Alice's side (generates shared secret)
  • responder() - Bob's side (decapsulates to shared secret)

Ceremony: 4 ECDH + 1 KEM → 5 shared secrets → HKDF-SHA256 → root key

C FFI Requirements:

// oqs/oqs.h must define:
int OQS_KEM_kyber768_encaps(
    uint8_t *ciphertext,
    uint8_t *shared_secret,
    const uint8_t *public_key
);

int OQS_KEM_kyber768_decaps(
    uint8_t *shared_secret,
    const uint8_t *ciphertext,
    const uint8_t *secret_key
);

Sizes:

  • Public key: 1,184 bytes
  • Secret key: 2,400 bytes
  • Ciphertext: 1,088 bytes
  • Shared secret: 32 bytes
  • Prekey bundle: ~2,528 bytes
  • Initial message: ~1,120 bytes

Kenya Compliance: <10ms handshake on ARM Cortex-A53

Status: FFI stub ready, needs liboqs.h linking


Vendor Library Integration (Next Steps)

Phase 1B: Add Vendor Sources

Step 1: Add Argon2

cd libertaria-sdk

# Option A: Git submodule
git submodule add https://github.com/P-H-C/phc-winner-argon2.git vendor/argon2

# Option B: Vendored snapshot
mkdir -p vendor/argon2
# Copy Argon2 reference implementation sources

Files needed:

vendor/argon2/
├── src/
│   ├── argon2.c
│   ├── argon2.h
│   ├── core.c
│   ├── blake2/blake2b.c
│   ├── thread.c
│   ├── encoding.c
│   └── opt.c
└── ...

Step 2: Add liboqs (ML-KEM only)

# Option A: Full liboqs repository
git submodule add https://github.com/open-quantum-safe/liboqs.git vendor/liboqs

# Option B: Minimal ML-KEM-768 snapshot
mkdir -p vendor/liboqs/src/kem/kyber/pqclean_kyber768_clean
mkdir -p vendor/liboqs/src/common/sha3
# Copy only ML-KEM files + SHA3/SHAKE dependencies

Files needed for ML-KEM-768:

vendor/liboqs/
├── src/
│   ├── kem/kyber/pqclean_kyber768_clean/
│   │   ├── kem.c
│   │   ├── indcpa.c
│   │   ├── polyvec.c
│   │   ├── poly.c
│   │   ├── ntt.c
│   │   ├── reduce.c
│   │   ├── cbd.c
│   │   ├── symmetric-shake.c
│   │   └── *.h
│   ├── common/sha3/
│   │   ├── sha3.c
│   │   ├── sha3x4.c
│   │   └── *.h
│   └── oqs.h
└── ...

Build System Updates (Phase 1B)

Current build.zig (Working)

// Modules created without C linking
const l0_mod = b.createModule(.{ ... });
const l1_mod = b.createModule(.{ ... });

Updated build.zig (After vendor integration)

// Argon2 static library
const argon2_lib = b.addStaticLibrary(.{
    .name = "argon2",
    .target = target,
    .optimize = optimize,
});
argon2_lib.addCSourceFiles(.{
    .files = &.{
        "vendor/argon2/src/argon2.c",
        "vendor/argon2/src/core.c",
        // ... all Argon2 sources
    },
    .flags = &.{ "-std=c99", "-O3" },
});
argon2_lib.linkLibC();

// liboqs static library (ML-KEM-768 only)
const liboqs_lib = b.addStaticLibrary(.{
    .name = "oqs",
    .target = target,
    .optimize = optimize,
});
liboqs_lib.addCSourceFiles(.{
    .files = &.{
        "vendor/liboqs/src/kem/kyber/pqclean_kyber768_clean/kem.c",
        // ... ML-KEM sources only
        "vendor/liboqs/src/common/sha3/sha3.c",
    },
    .flags = &.{ "-std=c99", "-O3" },
});
liboqs_lib.addIncludePath(b.path("vendor/liboqs/src"));
liboqs_lib.linkLibC();

// Link L1 against both
const l1_mod = b.createModule(/* ... */);
l1_mod.linkLibrary(argon2_lib);
l1_mod.linkLibrary(liboqs_lib);

Cross-Compilation Strategy

Target Platforms

Platform Zig Triple Status Notes
x86_64-linux x86_64-linux-gnu Ready Full optimizations
aarch64-linux (ARM64) aarch64-linux-gnu Ready Kenya device
armv7-linux (ARMv7) arm-linux-gnueabihf Test Cortex-A53 (RPI 3)
wasm32-web wasm32-unknown-emscripten Future Pure Zig only (no C)
x86_64-macos x86_64-macos Ready Intel Macs
aarch64-macos aarch64-macos Ready Apple Silicon

Building for Kenya Device (ARM)

# Raspberry Pi 3 (ARMv7, 1.4 GHz Cortex-A53)
zig build -Dtarget=arm-linux-gnueabihf -Doptimize=ReleaseSmall

# Budget Android (ARMv8, Cortex-A53)
zig build -Dtarget=aarch64-linux-gnu -Doptimize=ReleaseSmall

# Result: ~500 KB binary (L0 + L1 combined)

Testing Strategy

Unit Tests (Already Working)

zig build test

# Tests for:
# ✅ soulkey.generate()
# ✅ soulkey.sign() / .verify()
# ✅ soulkey serialization
# ✅ did creation
# ✅ LWF frame encode/decode
# ✅ XChaCha20 encryption

Integration Tests (Phase 1B)

After vendor linking:

zig build test

# New tests:
# ⏳ entropy.create() - Argon2id PoW
# ⏳ entropy.verify() - Validation
# ⏳ pqxdh.initiator() - Alice's handshake
# ⏳ pqxdh.responder() - Bob's handshake
# ⏳ Full PQXDH ceremony (Alice ↔ Bob)

Performance Tests (Phase 1B)

# Time entropy stamp creation (target: <100ms)
zig build -Doptimize=ReleaseSmall

# Benchmark on target device:
time ./zig-out/bin/entropy_test

# Expected output (Cortex-A53):
# real    0m0.087s  ✅ <100ms
# user    0m0.087s

Kenya Compliance Tests (Phase 1B)

# Binary size check
ls -lh zig-out/lib/liblibertaria_*.a
# Expected: <500 KB total

# Memory profiling
valgrind --tool=massif ./zig-out/bin/test
# Expected: <50 MB peak

# Constant-time analysis
cargo install ct-verif
ct-verif path/to/soulkey.zig

What's Ready Now

Can Build & Test

cd libertaria-sdk

# Build modules (no C libraries needed yet)
zig build

# Run existing tests
zig build test

# Run examples
zig build examples

Can Review Code

  • soulkey.zig - Pure Zig, no dependencies
  • crypto.zig - Pure Zig stdlib
  • lwf.zig - Pure Zig
  • FFI stubs in argon2.zig, pqxdh.zig

Cannot Use Yet

  • create() in argon2.zig (needs C FFI)
  • initiator() / responder() in pqxdh.zig (needs C FFI)
  • Any operations requiring Argon2 or ML-KEM-768

Phase 1→2 Transition Checklist

Before Starting Phase 2

  • Argon2 sources added to vendor/argon2/
  • liboqs sources added to vendor/liboqs/
  • build.zig updated with C library compilation
  • zig build succeeds with all libraries linked
  • Basic integration tests pass (no Argon2/ML-KEM features yet)

Phase 2 Starts When

  • All vendor libraries compile successfully
  • C FFI bindings resolve (no undefined symbols)
  • Simple cryptographic tests can run
  • Binary size target confirmed (<500 KB)

Performance Budget Verification

SoulKey Operations (Pure Zig)

Expected latency (ARM Cortex-A53):

SoulKey.generate()    <50 ms  ✅
SoulKey.sign()        <1 ms   ✅
SoulKey.verify()      <1 ms   ✅
deriveSharedSecret()  <1 ms   ✅

Argon2 Operations (C FFI)

Expected latency (ARM Cortex-A53):

create(difficulty=10)  <100 ms  ✅
verify()               <100 ms  ✅

PQXDH Operations (Zig + C FFI)

Expected latency (ARM Cortex-A53):

initiator()   <20 ms   ✅ (includes ML-KEM encaps)
responder()   <20 ms   ✅ (includes ML-KEM decaps)

Complete L1 Pipeline

Expected latency:

Full PQXDH ceremony (Alice ↔ Bob):  <50 ms   ✅

Security Audit Roadmap

Phase 1 (Foundation)

  • Use only audited primitives (Zig stdlib, libsodium, liboqs)
  • No custom cryptography
  • Document all assumptions
  • Self-review: Code inspection (Phase 2)

Phase 2 (Integration)

  • Property-based testing (proptest)
  • Fuzzing harnesses
  • Constant-time analysis
  • Community code review

Phase 3 (Audit)

  • Engage external auditor (Month 7-9)
  • Budget: $80K-120K (NCC Group, Trail of Bits)
  • Full cryptographic audit
  • Public report

Open Questions for Phase 1B

  1. Argon2 version: Use reference implementation or PHC winner variant?
  2. liboqs submodule: Full repository or minimal ML-KEM-768 only?
  3. Build flags: Enable SIMD optimizations or force portable (no AVX2)?
  4. WASM support: Pure Zig only (Phase 6) or include C for WASM?
  5. CI/CD: Test matrix across all platforms or focus on ARM+x86?

Success Criteria

Phase 1 Complete

  • Architecture documented
  • FFI binding stubs created
  • Module templates written
  • Test skeletons in place
  • Build infrastructure designed
  • Kenya Rule budgets defined
  • Cross-compilation strategy documented

Phase 1B Ready

  • Vendor libraries integrated
  • build.zig linking complete
  • Entropy tests passing
  • PQXDH tests passing
  • Binary size <500 KB verified
  • Performance targets met

Next: Phase 1B (1 week)

Goal: Vendor library integration + linking

Tasks:

  1. Clone/vendor Argon2 sources
  2. Clone/vendor liboqs sources (ML-KEM-768 subset)
  3. Update build.zig with C compilation
  4. Run zig build until all symbols resolve
  5. Run full test suite
  6. Measure binary size and performance
  7. Document exact steps taken

Deliverable: zig build produces fully-linked L0-L1 SDK (<500 KB)


STATUS: Foundation complete. Ready to add vendor libraries.

Next Review: After Phase 1B completion (ML-KEM-768 functional)