Post-quantum readiness infrastructure for the Stellar network.
A developer toolkit that helps accounts, wallets, and enterprises assess their exposure to quantum-computing risk, simulate a migration to post-quantum cryptography, and eventually execute that migration on-chain — built in direct alignment with the Stellar Development Foundation's (SDF) published Quantum Preparedness Plan (QPP).
- Why This Exists
- The Threat Model, Precisely
- Alignment with SDF's Quantum Preparedness Plan
- Glossary
- Architecture Overview
- User Journeys
- Data Model
- Contract Interfaces
- API Reference (Backend)
- Tech Stack
- Feasibility Constraints
- Algorithm Comparison
- Repository Structure
- Getting Started
- Configuration & Environment Variables
- Testing Strategy
- CI/CD
- Roadmap
- Risk Register
- Design Decisions & Open Questions
- FAQ
- Contributing
- Security
- License
- References
- Acknowledgments
Every Stellar account today is secured by classical Ed25519 signatures. Large-scale quantum computers, once available, would be capable of breaking that cryptography — meaning an attacker could forge signatures and drain any account whose public key has been exposed on-chain (which, on Stellar, is effectively every active account).
SDF has publicly committed to a phased transition of the network toward post-quantum cryptography. But a network-level upgrade path does not, by itself, migrate a single existing account, wallet, or institutional treasury. Someone still has to:
- Know how exposed they are today
- Understand what a migration actually looks like, safely, before touching real funds
- Execute that migration with tooling they can trust
No such tooling exists yet for Stellar. This project aims to be it.
It's worth being precise about the actual risk, since "quantum computers will break blockchains" is often stated too loosely.
What's actually at risk: Stellar accounts use Ed25519, an elliptic-curve signature scheme. A sufficiently large, fault-tolerant quantum computer running Shor's algorithm could derive a private key from its corresponding public key. On Stellar, an account's public key is visible on-chain the moment it transacts — meaning every account that has ever sent a transaction has already exposed the exact information a quantum attacker would need.
What's not at immediate risk: Funds in accounts that have never transacted (public key not yet revealed) are safer in the interim, though this is a fragile protection that disappears the moment the account is used.
The realistic timeline: Cryptographically-relevant quantum computers (CRQCs) capable of running Shor's algorithm at the scale needed to break Ed25519 do not exist today, and credible estimates for when they might vary widely — anywhere from the early 2030s to considerably later, with significant expert disagreement. This project does not assume an imminent break; it assumes migration takes years, so preparation should start now, matching SDF's own stated rationale for publishing the QPP well ahead of any concrete threat.
"Harvest now, decrypt later": The most urgent near-term risk isn't a sudden break — it's adversaries recording currently-public signatures and keys today, to be decrypted retroactively once quantum capability arrives. This is precisely why exposure scanning and early migration tooling has value now, even though no CRQC exists yet.
What this project does NOT attempt to solve:
- It does not make Stellar's consensus or network layer quantum-safe — that is squarely SDF's and the validator community's responsibility, not an application-layer toolkit's.
- It does not attempt to protect historical transaction data from retroactive decryption — once a signature is on-chain, it's on-chain permanently; this toolkit is about protecting future signing capability, not erasing past exposure.
- It does not implement its own novel post-quantum cryptographic scheme — it uses established, publicly vetted PQC algorithms (see Algorithm Comparison), not experimental cryptography.
SDF's QPP is a three-stage roadmap:
| Stage | Target | Description |
|---|---|---|
| Stage 1 | 2026 | Post-quantum signature verification introduced as native host functions within Soroban smart contracts |
| Stage 2 | 2027 | New quantum-safe signer types available via opt-in channels for existing accounts; account identity decoupled from signing keys |
| Stage 3 | TBD | Broader network-level enforcement / deprecation pathways for classical-only signing |
This toolkit is designed to sit directly on top of Stage 1 and ahead of Stage 2 — providing the assessment and simulation tooling the ecosystem will need once native host function support lands, and serving as an early reference implementation while that support matures.
Note: This is an independent, community-built project. It is not officially affiliated with or endorsed by the Stellar Development Foundation. It is built in the spirit of, and in preparation for, SDF's publicly documented roadmap.
| Term | Meaning |
|---|---|
| PQC | Post-Quantum Cryptography — cryptographic algorithms believed to resist attacks from both classical and quantum computers |
| QPP | SDF's Quantum Preparedness Plan — the three-stage roadmap this project aligns with |
| CRQC | Cryptographically-Relevant Quantum Computer — a quantum computer powerful enough to break current elliptic-curve cryptography via Shor's algorithm |
| Soroban | Stellar's smart contract platform; contracts are written in Rust and compiled to WebAssembly |
| Horizon | Stellar's primary REST API for reading ledger and account data |
| Signer | A public key (and associated weight) authorized to sign transactions for a Stellar account; accounts can have multiple weighted signers |
| Signer weight / threshold | Stellar's multisig mechanism — each signer has a weight, and transactions require signatures totaling at least the relevant operation's threshold |
| Hybrid signing | A transitional state where a transaction (or account) is protected by both a classical and a post-quantum signature simultaneously |
| Dilithium | A lattice-based PQC digital signature scheme, one of the NIST-selected post-quantum standards (standardized as ML-DSA) |
| Falcon | A lattice-based PQC signature scheme with smaller signatures than Dilithium but reliant on floating-point arithmetic |
| SPHINCS+ | A hash-based, stateless PQC signature scheme; conservative security assumptions, larger signatures, slower verification |
| SAC | Stellar Asset Contract — the built-in Soroban contract type that lets classic Stellar assets interoperate with smart contracts |
| Host function | A function implemented natively by the Soroban host environment (as opposed to in contract WASM code) — typically far cheaper than the WASM equivalent |
env.budget() |
The Soroban Rust SDK's test utility for measuring actual CPU instruction and memory consumption of contract execution |
The toolkit is composed of three independently useful, progressively deeper layers.
┌─────────────────────────────────────────────────────────────┐
│ Angular Frontend │
│ (Dashboard · Scan Reports · Migration Wizard) │
└───────────────────────────┬───────────────────────────────────┘
│ REST / WebSocket
┌───────────────────────────▼───────────────────────────────────┐
│ NestJS Backend │
│ ┌────────────┐ ┌──────────────┐ ┌────────────────────┐ │
│ │ Scanner │ │ Simulator │ │ Migration │ │
│ │ Module │ │ Module │ │ Orchestrator │ │
│ └─────┬──────┘ └──────┬───────┘ └─────────┬──────────┘ │
└─────────┼──────────────────┼─────────────────────┼────────────┘
│ │ │
▼ ▼ ▼
Horizon / RPC Testnet Sandbox Soroban Contracts
(read accounts) (Stellar Quickstart) (Rust / WASM)
│
▼
PQC Signature Verification
(Dilithium / Falcon primitives)
Purpose: Given a Stellar account or a set of accounts, produce a plain-language quantum-readiness report.
What it does:
- Reads account signer configuration via Horizon (master weight, additional signers, thresholds)
- Flags high-risk patterns, e.g.:
- Single classical signer holding a large balance
- Multisig setups with no quantum-safe signer present
- Long-lived accounts whose public keys have had maximum on-chain exposure time
- Produces a readiness score and a prioritized remediation list
Status: Buildable today, no dependency on native QPP host functions.
Purpose: Let a user rehearse a migration on a disposable testnet account before touching anything real.
What it does:
- Spins up a funded testnet account (via Friendbot)
- Adds a simulated post-quantum signer alongside the existing classical signer (hybrid state)
- Walks through what a hybrid-signed transaction looks like — signed by both classical and PQC keys during a transition window, mirroring the pattern SDF's own two-stage plan implies
- Visualizes signer weights and thresholds before/after in the Angular dashboard
Status: Requires a working Soroban contract (or local mock) to simulate signature checks against.
Purpose: The real technical contribution — a Soroban smart contract capable of verifying a post-quantum signature, plus the orchestration logic to add a PQC signer to a live account and eventually retire the classical key.
What it does:
- Implements PQC signature verification (Dilithium, primary candidate) as a Soroban contract function
- Exposes a workflow to: generate a PQC keypair → register it as a new account signer → adjust threshold/weights → (later) drop the legacy classical signer
- Benchmarks actual CPU instruction and memory cost of on-chain verification against Soroban's resource ceiling (see Feasibility Constraints)
Status: Active R&D. This is the layer most likely to be genuinely novel and the one most relevant to SDF's own engineering priorities.
1. User pastes their Stellar public key into the Scanner
2. Scanner reads signer config via Horizon, returns a readiness score
(e.g., "High Exposure — single classical signer, 3-year-old key, no PQC signer present")
3. User clicks "Simulate Migration"
4. Simulator clones the account's signer config onto a funded testnet account
5. User walks through adding a PQC signer, adjusting thresholds, in a safe sandbox
6. User feels confident enough to click "Migrate on Mainnet" (Phase 4+ only)
7. Migration Orchestrator builds and submits the real transaction, confirms success,
and updates the Scanner's readiness score for that account
1. Team uploads a CSV / connects via API a list of managed account public keys
2. Scanner batch-processes all accounts, ranks by exposure severity and balance size
3. Team exports a prioritized remediation report (PDF/CSV) for internal risk review
4. Team uses Simulator to test a proposed multisig reconfiguration against
their actual signer/threshold setup before scheduling a real migration window
5. Migration Orchestrator supports scheduled/batched execution with
pre-flight simulation checks (simulateTransaction) before submission
1. Developer imports the toolkit's client SDK (TypeScript) into their own wallet
2. Calls scanAccount() to surface a quantum-readiness badge/warning in their own UI
3. Optionally integrates the migration flow as a guided in-wallet feature,
rather than sending users to a separate app
Core entities used across the backend and database layer.
Account
├── publicKey: string (Stellar StrKey, e.g., "G...")
├── lastScannedAt: timestamp
├── readinessScore: enum { CRITICAL, HIGH, MEDIUM, LOW, MIGRATED }
├── balanceXLM: decimal
├── signers: Signer[]
└── scanHistory: ScanResult[]
Signer
├── key: string
├── weight: integer
├── type: enum { ED25519, PQC_DILITHIUM, PQC_FALCON, PRE_AUTH_TX, HASH_X }
└── addedAt: timestamp
ScanResult
├── id: uuid
├── accountId: FK -> Account
├── scannedAt: timestamp
├── score: enum
├── findings: Finding[]
└── rawSignerSnapshot: jsonb
Finding
├── code: string (e.g., "SINGLE_CLASSICAL_SIGNER", "NO_PQC_SIGNER_PRESENT")
├── severity: enum { CRITICAL, HIGH, MEDIUM, LOW, INFO }
└── message: string
MigrationPlan
├── id: uuid
├── accountId: FK -> Account
├── status: enum { DRAFT, SIMULATED, PENDING, SUBMITTED, CONFIRMED, FAILED }
├── proposedSigners: Signer[]
├── proposedThresholds: { low, medium, high: integer }
├── simulationResult: jsonb (nullable, populated after sandbox run)
└── submittedTxHash: string (nullable, populated after mainnet/testnet submission)
Illustrative Soroban contract interfaces (Rust). Exact signatures will evolve as Phase 0 benchmarking informs real constraints.
pqc-verify contract — core signature verification:
#[contract]
pub struct PqcVerifyContract;
#[contractimpl]
impl PqcVerifyContract {
/// Verifies a Dilithium signature against a message and public key.
/// Returns true if valid, false otherwise. Panics on malformed input.
pub fn verify_dilithium(
env: Env,
public_key: BytesN<1312>, // Dilithium2 public key size, exact size TBD by variant
signature: BytesN<2420>, // Dilithium2 signature size, exact size TBD by variant
message: Bytes,
) -> bool {
// Implementation benchmarked in Phase 0 — see /benchmarks/results
todo!()
}
}migration-registry contract — tracks per-account migration state:
#[contract]
pub struct MigrationRegistryContract;
#[contractimpl]
impl MigrationRegistryContract {
/// Registers a new PQC signer as pending for the given account.
pub fn propose_signer(env: Env, account: Address, pqc_public_key: BytesN<1312>) -> u64;
/// Marks a previously proposed signer as confirmed, once added on-chain
/// via a standard Stellar set_options operation.
pub fn confirm_signer(env: Env, proposal_id: u64) -> bool;
/// Returns the current migration status for an account.
pub fn get_status(env: Env, account: Address) -> MigrationStatus;
}
#[contracttype]
pub enum MigrationStatus {
NotStarted,
PqcSignerProposed,
PqcSignerConfirmed,
ClassicalSignerRemoved,
}These signatures are illustrative and will be finalized once Phase 0 benchmarking determines exact byte sizes and whether verification is feasible on-chain at all (see Feasibility Constraints).
Representative NestJS REST endpoints (subject to change as modules are implemented).
| Method | Endpoint | Description |
|---|---|---|
POST |
/scanner/scan |
Scans a single account by public key, returns a ScanResult |
POST |
/scanner/batch-scan |
Scans multiple accounts (institutional use case) |
GET |
/scanner/history/:publicKey |
Returns historical scan results for an account |
POST |
/simulator/sandbox |
Creates a funded testnet account cloned from a real account's signer config |
POST |
/simulator/hybrid-sign |
Simulates a hybrid classical+PQC signed transaction |
POST |
/migration/plan |
Creates a draft MigrationPlan for an account |
POST |
/migration/plan/:id/simulate |
Runs the plan against simulateTransaction for a dry-run cost/feasibility check |
POST |
/migration/plan/:id/submit |
Submits the real migration transaction (testnet first; mainnet gated behind Phase 6) |
GET |
/migration/plan/:id |
Returns current status of a migration plan |
Example request/response:
POST /scanner/scan
Content-Type: application/json
{ "publicKey": "GABC...XYZ" }{
"accountId": "GABC...XYZ",
"readinessScore": "HIGH",
"findings": [
{
"code": "SINGLE_CLASSICAL_SIGNER",
"severity": "HIGH",
"message": "This account has a single Ed25519 signer with no post-quantum signer configured."
},
{
"code": "LARGE_BALANCE_SINGLE_SIGNER",
"severity": "CRITICAL",
"message": "Balance exceeds risk threshold with no multisig or PQC protection."
}
],
"scannedAt": "2026-07-05T12:00:00Z"
}| Layer | Technology | Notes |
|---|---|---|
| Frontend | Angular, ngx-charts / Chart.js | Signer visualization, scan reports, migration wizard |
| Backend | NestJS, TypeScript | Orchestration, scanning logic, Stellar SDK integration |
| Blockchain SDK | @stellar/stellar-sdk |
Account reads, transaction construction, multisig handling |
| Data layer | PostgreSQL (or SQLite for local/MVP) | Cache of scanned accounts and historical reports |
| Smart contracts | Rust, soroban-sdk |
Core PQC verification logic |
| Target | wasm32-unknown-unknown |
Soroban's compilation target |
| PQC primitives | pqcrypto-dilithium (candidate) / evaluating pure-Rust alternatives |
See open questions below |
| Local dev network | Stellar Quickstart (Docker) | Local Horizon + Soroban RPC + Friendbot |
| Contract tooling | stellar-cli (formerly soroban-cli) |
Build, deploy, invoke, test contracts |
| Optimization | wasm-opt (Binaryen) |
WASM size/performance optimization |
| Testing | Jest (Nest/Angular), soroban-sdk native test harness (Rust) |
|
| CI | GitHub Actions | Contract build + test automation |
Soroban transactions are bound by a network-defined resource budget, most notably a CPU instruction ceiling on the order of 100 million instructions per transaction, alongside separately metered ledger I/O, transaction size, and events/return value size.
This matters because post-quantum signature schemes are meaningfully heavier than the Ed25519 verification Stellar uses today:
- Dilithium — larger public keys and signatures (~1.3KB / ~2.4KB for Dilithium2) than Ed25519 (32/64 bytes); verification involves lattice/polynomial-ring arithmetic rather than a single elliptic-curve operation
- Falcon — smaller signatures than Dilithium, but implementations typically rely on floating-point arithmetic, which is a known complication in
no_std/ WASM environments like Soroban
Before committing to an architecture, this project benchmarks actual on-chain verification cost using env.budget() in Soroban's Rust test harness. Two outcomes are planned for:
- On-chain verification fits comfortably within the instruction budget alongside real contract logic → PQC verification becomes a first-class Soroban contract capability.
- On-chain verification is too expensive → pivot to an off-chain-verify, on-chain-attest pattern, where a relayer performs PQC verification off-chain and submits a lightweight cryptographic proof or hash commitment on-chain.
Either outcome is a legitimate, documentable engineering result — this README will be updated with real benchmark numbers once Phase 1 (below) is complete.
A working comparison of the candidate PQC signature schemes, to be validated empirically in Phase 0.
| Scheme | Type | Public Key Size | Signature Size | Verify Speed (general) | WASM/no_std Friendliness |
NIST Status |
|---|---|---|---|---|---|---|
| Ed25519 (current baseline) | Elliptic curve | 32 bytes | 64 bytes | Very fast | Excellent (already in production on Stellar) | Not post-quantum |
| Dilithium2/3 (ML-DSA) | Lattice-based | ~1.3–1.9 KB | ~2.4–3.3 KB | Fast, integer-only arithmetic | Good — pure-Rust implementations exist, main risk is crate maturity for wasm32-unknown-unknown |
NIST-standardized (FIPS 204) |
| Falcon | Lattice-based (NTRU) | ~0.9–1.8 KB | ~0.6–1.3 KB (smallest of the candidates) | Fast, but relies on floating-point arithmetic | Poor-to-moderate — floating-point in no_std WASM is a known friction point |
NIST-standardized (FIPS 206, pending) |
| SPHINCS+ (SLH-DSA) | Hash-based | ~32–64 bytes (small) | Large — several KB to tens of KB | Slower verification, especially for smaller-signature parameter sets | Good — purely hash-based, no exotic arithmetic | NIST-standardized (FIPS 205) |
Working hypothesis (to be validated in Phase 0): Dilithium is the most likely first candidate for on-chain Soroban verification due to integer-only arithmetic and reasonable signature sizes, with SPHINCS+ as a conservative fallback if Dilithium's crate ecosystem proves difficult to compile to wasm32-unknown-unknown, and Falcon deprioritized specifically because of its floating-point dependency in a no_std context.
stellar-pqc-toolkit/
├── contracts/ # Rust / Soroban smart contracts
│ ├── pqc-verify/ # Core PQC signature verification contract
│ ├── migration-registry/ # Tracks signer migration state per account
│ └── shared/ # Shared Rust types/utilities across contracts
├── backend/ # NestJS application
│ ├── src/
│ │ ├── scanner/ # Assessment layer module
│ │ ├── simulator/ # Simulation layer module
│ │ ├── migration/ # Migration orchestration module
│ │ └── stellar/ # Shared Stellar SDK / Horizon integration
│ └── test/
├── frontend/ # Angular application
│ ├── src/app/
│ │ ├── dashboard/
│ │ ├── scan-report/
│ │ └── migration-wizard/
├── benchmarks/ # CPU/memory benchmark scripts and results
│ └── results/ # Recorded env.budget() output per PQC scheme
├── docker/ # Stellar Quickstart local network config
├── docs/ # Architecture decision records, design notes
└── README.md
- Rust (stable) +
wasm32-unknown-unknowntarget stellar-cli- Node.js (LTS) + npm/yarn
- Docker (for Stellar Quickstart local network)
docker run --rm -it \
-p 8000:8000 \
--name stellar-quickstart \
stellar/quickstart:latest \
--local --enable-soroban-rpccd contracts/pqc-verify
rustup target add wasm32-unknown-unknown
cargo build --target wasm32-unknown-unknown --release
cargo test -- --nocapture # prints env.budget() CPU/memory usagecd backend
npm install
npm run start:devcd frontend
npm install
ng serve(Detailed setup docs and contract deployment scripts to be added as each module is built out.)
Backend (.env in /backend):
# Stellar network
HORIZON_URL=https://horizon-testnet.stellar.org
SOROBAN_RPC_URL=http://localhost:8000/soroban/rpc
NETWORK_PASSPHRASE="Test SDF Network ; September 2015"
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/pqc_toolkit
# App
PORT=3000
LOG_LEVEL=debug
# Friendbot (testnet funding)
FRIENDBOT_URL=https://friendbot.stellar.orgFrontend (environment.ts in /frontend):
export const environment = {
production: false,
apiBaseUrl: 'http://localhost:3000',
horizonUrl: 'https://horizon-testnet.stellar.org',
};Contracts (contracts/pqc-verify/.cargo/config.toml or equivalent build config):
[build]
target = "wasm32-unknown-unknown"Never commit real secret keys, mainnet signing keys, or
.envfiles to the repository. All examples above use testnet-safe defaults. See Security.
| Layer | Approach | Tooling |
|---|---|---|
| Smart contracts | Unit tests via Soroban's native Rust test harness; resource usage assertions via env.budget() |
soroban-sdk test utilities, cargo test |
| Contract fuzz/property testing | Property-based tests for signature verification edge cases (malformed keys, wrong-length inputs, replay attempts) | proptest or soroban-sdk fuzzing hooks |
| Backend unit tests | Isolated tests for scanner logic, risk scoring, migration state machine | Jest |
| Backend integration tests | Full request/response cycle against a local Soroban Quickstart network | Jest + Docker Compose (Quickstart container) |
| Frontend unit tests | Component-level tests for dashboard, scan report, migration wizard | Jest + Angular Testing Library |
| End-to-end tests | Full user journey — scan → simulate → migrate — run against local testnet | Playwright or Cypress |
| Security-focused tests | Verify contract behavior under adversarial inputs (signature malleability, replay, wrong network passphrase) | Manual + automated adversarial test suite (contracts/*/tests/security/) |
Testing philosophy: Given this project eventually touches real account signer configuration, testnet-first and simulation-first testing is non-negotiable at every layer — no code path that mutates account signers should be exercised against mainnet without first passing the full test suite against testnet.
GitHub Actions workflows (.github/workflows/):
contracts.yml— builds all Soroban contracts forwasm32-unknown-unknown, runscargo test, recordsenv.budget()output as a build artifact for tracking resource cost over timebackend.yml— installs dependencies, runs lint + unit + integration tests against a Dockerized Quickstart network spun up as a CI service containerfrontend.yml— installs dependencies, runs lint + unit tests, builds production bundlee2e.yml— runs full Playwright/Cypress suite against a CI-provisioned local network (nightly or on-demand, given cost/time)
All contract changes require CI-verified benchmark results attached to the PR before merge, since resource cost regressions are a first-class concern for this project.
- Phase 0 — Feasibility spike: Minimal Soroban contract with a single Dilithium
verifyfunction; benchmark CPU instructions and memory viaenv.budget(); document results inbenchmarks/results/ - Phase 1 — Scanner MVP: NestJS + Angular quantum-exposure scanner for individual Stellar accounts, no contract dependency
- Phase 2 — Simulation sandbox: Testnet-based hybrid signer simulation with visual before/after dashboard
- Phase 3 — Migration contract: Production-quality Soroban contract for PQC signer registration and management
- Phase 4 — End-to-end migration flow: Full user journey from scan → simulate → migrate on testnet
- Phase 5 — Stellar Community Fund submission: Package Phase 0–4 results for SCF Build Award application
- Phase 6 — Mainnet readiness: Security review, audit considerations, and mainnet deployment path once SDF's native QPP host functions ship
Tracked openly so the project's assumptions and failure modes are visible, not discovered late.
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| PQC verification exceeds Soroban's CPU instruction budget | Medium | High — forces off-chain architecture pivot | Phase 0 benchmarking spike before any further build-out; off-chain-attest fallback design already sketched |
No pure-Rust, no_std-compatible PQC crate available |
Medium | High — blocks on-chain approach entirely | Evaluate multiple crates early; contribute upstream fixes if close but not quite compatible; fallback to hand-rolled minimal implementation of core verify logic if needed |
| SDF ships native QPP host functions before this project reaches Phase 3 | Medium | Low/Positive — reduces required scope, this project can adapt to consume native functions instead of implementing its own | Design migration-registry contract to be swappable/forward-compatible with native host functions from the start |
| Users migrate real mainnet funds using early, unaudited tooling | Low (if guardrails respected) | Critical | Hard testnet-only gate in code until Phase 6 security review; explicit UI warnings; no mainnet submission path exists until then |
| PQC key/signature sizes make transactions expensive or hit transaction size limits | Medium | Medium | Benchmark transaction size costs alongside CPU costs in Phase 0; consider off-chain storage of large keys with on-chain hash commitments if needed |
| Scope creep — the toolkit tries to do too much before anything is solid | Medium | Medium | Phased roadmap explicitly sequences scanner (low-risk, high-value) before migration (high-risk, high-value) |
| SDF's actual QPP implementation diverges from public roadmap assumptions used here | Low | Medium | Treat SDF's public QPP posts/docs as living documents; revisit design assumptions each time SDF publishes updates |
These are tracked openly rather than hidden, since they materially affect architecture:
- Dilithium vs. Falcon vs. SPHINCS+: Dilithium is the current leading candidate due to (relatively) simpler integer-only arithmetic vs. Falcon's floating-point dependency. SPHINCS+ is stateless and conservative but has larger signatures and slower verification — under evaluation as a fallback.
- Pure-Rust vs. FFI-wrapped crates: Many available PQC crates (e.g., those wrapping
liboqs) are C-dependent and may not compile cleanly towasm32-unknown-unknown, which is ano_stdtarget with no libc. Identifying or building a pure-Rust,no_std-compatible implementation is a near-term blocker to resolve. - On-chain vs. off-chain verification: Pending Phase 0 benchmark results (see Feasibility Constraints).
- Identity/key decoupling: SDF's Stage 2 plan decouples account identity from signing keys. This project's migration-registry contract is designed to be forward-compatible with that model rather than inventing a competing one.
Is this an official Stellar Development Foundation project? No. This is an independent, community-built project developed in preparation for and alignment with SDF's publicly published Quantum Preparedness Plan. It is not endorsed by SDF unless/until stated otherwise.
Can I use this on mainnet today? No. Until Phase 6 (security review) is complete, mainnet submission paths are intentionally not implemented. The Scanner (read-only) is the only component safe to point at real mainnet accounts today, since it makes no changes to account state.
Why not just wait for SDF to ship native PQC host functions? Native host functions handle the cryptographic primitive efficiently at the protocol level, but they don't solve the migration problem — someone still needs tooling to assess exposure, simulate changes, and safely execute a transition for a specific account. This project is designed to consume native host functions once available rather than compete with them.
What happens if Dilithium verification simply doesn't fit in Soroban's resource budget? The project pivots to an off-chain-verify, on-chain-attest architecture (see Feasibility Constraints) — this is a planned fallback, not a project-ending outcome.
Does this project implement its own cryptography? No. It uses established, independently vetted post-quantum algorithms (Dilithium, Falcon, SPHINCS+ — all NIST-standardized or NIST-track schemes). This project's novel contribution is the integration and migration tooling, not new cryptographic primitives.
How is this different from a general-purpose Stellar wallet? Wallets manage keys and sign transactions. This toolkit specifically assesses and migrates cryptographic posture — it's closer to a security auditing and migration tool than a wallet, though it's designed to be integrated into wallets via its client SDK.
This project is in early, active development. Issues, discussion, and PRs are welcome — particularly around:
- Pure-Rust PQC crate evaluation for
no_std/ WASM compatibility - Soroban resource benchmarking methodology
- UX for the migration wizard (making a genuinely high-stakes action feel safe and reversible)
- Threat-model review and adversarial test case design
Please open an issue before submitting large PRs so design direction can be discussed first. When contributing to contract code, include env.budget() output in your PR description so resource cost changes are visible to reviewers.
- Rust:
rustfmt+clippyclean, no warnings suppressed without a documented reason - TypeScript (backend/frontend): ESLint + Prettier, shared config at the repo root
- Commits: Conventional Commits style (
feat:,fix:,docs:,chore:) to keep changelog generation clean
This toolkit will, by design, eventually touch real account signer configurations. Until the Migration Layer has been reviewed and tested extensively on testnet, it should not be used against mainnet accounts holding real value. A formal security review is planned ahead of any mainnet-facing release (see Roadmap, Phase 6).
Specific safeguards built into the design:
- No mainnet transaction-submission code path exists until Phase 6
- All migration actions require an explicit simulate-then-confirm step — no one-click mainnet mutation of signer configuration will ever be offered
- Private keys are never persisted server-side; all signing happens client-side, and the backend only ever handles public keys and unsigned transaction envelopes
- Contract code is designed to reject malformed, wrong-length, or replayed signatures explicitly, with adversarial test coverage tracked in
contracts/*/tests/security/
If you discover a security issue, please report it privately rather than via a public issue — a dedicated security contact and disclosure policy will be published before any testnet-to-mainnet transition work begins.
(To be finalized — MIT or Apache 2.0 recommended for maximum compatibility with the Stellar/Soroban ecosystem's existing open-source norms.)
- Stellar Development Foundation — Quantum Preparedness Plan announcement (June 2026)
- Stellar Developer Docs — Smart Contracts Overview
- Stellar Developer Docs — Fees, Resource Limits, and Metering
- NIST Post-Quantum Cryptography Standardization — FIPS 204 (ML-DSA / Dilithium), FIPS 205 (SLH-DSA / SPHINCS+), FIPS 206 (FN-DSA / Falcon, pending)
- Open Quantum Safe (OQS) Project — reference implementations and
liboqs - Stellar Community Fund — Grants and Funding
(Links to be replaced with archived/versioned references as the project matures, since SDF documentation URLs and content evolve over time.)
- The Stellar Development Foundation, for publishing the Quantum Preparedness Plan and the broader Stellar/Soroban documentation this project builds on
- The Open Quantum Safe project and the broader post-quantum cryptography research community
- The NIST Post-Quantum Cryptography Standardization project, whose selected algorithms form the cryptographic foundation of this toolkit