Skip to content

feat: post-quantum dual-signature (Ed25519 + Dilithium3)#6

Closed
HaraldeRoessler wants to merge 1 commit into
MoltyCel:mainfrom
HaraldeRoessler:feat/pqc-dual-signature
Closed

feat: post-quantum dual-signature (Ed25519 + Dilithium3)#6
HaraldeRoessler wants to merge 1 commit into
MoltyCel:mainfrom
HaraldeRoessler:feat/pqc-dual-signature

Conversation

@HaraldeRoessler
Copy link
Copy Markdown
Contributor

Summary

Add quantum-safe signing to all Verifiable Credentials using ML-DSA-65 (Dilithium3) via liboqs (MIT licensed).

Every credential is now signed with both Ed25519 and Dilithium3. Old verifiers check Ed25519 and ignore Dilithium. New verifiers check both. This is Phase 1 of the PQC migration.

New files

File Purpose
app/crypto/dilithium.py Dilithium3 key management (KMS + env fallback), sign, verify
app/crypto/hybrid.py dual_sign() and verify_proof() for single or dual proofs
scripts/generate_dilithium_keys.py One-time keypair generation utility

Modified files

File Change
app/credentials.py issue_credential() uses dual_sign(), verify_credential() supports both formats
app/swarm/endorsement.py Endorsement VCs use dual_sign()
app/main.py DID document dynamically includes Dilithium key when configured

Graceful degradation

If DILITHIUM_PRIVATE_KEY_HEX (or KMS equivalent) is not set, the system issues Ed25519-only credentials exactly as before. No breaking change on deploy. Enable PQC by:

pip install liboqs-python
python scripts/generate_dilithium_keys.py
# Set the output as env vars
export DILITHIUM_PRIVATE_KEY_HEX=...
export DILITHIUM_PUBLIC_KEY_HEX=...

Credential format

Before (Ed25519 only):

{"proof": {"type": "Ed25519Signature2020", "proofValue": "64 bytes..."}}

After (dual-signature):

{"proof": [
  {"type": "Ed25519Signature2020", "verificationMethod": "...#key-ed25519", "proofValue": "64 bytes..."},
  {"type": "DilithiumSignature2026", "verificationMethod": "...#key-dilithium", "proofValue": "~2420 bytes..."}
]}

Migration path

  • Phase 1 (this PR): Dual-signature, Ed25519 + Dilithium
  • Phase 2 (future): Dilithium-first, Ed25519 deprecated
  • Phase 3 (future): Ed25519 sunset

Test plan

  • Deploy without Dilithium keys — verify Ed25519-only credentials still work
  • Generate Dilithium keypair and set env vars
  • Issue credential — verify proof is an array with both signatures
  • Verify dual-signed credential via /credentials/verify
  • Verify old Ed25519-only credential still passes verification
  • Check /.well-known/did.json includes Dilithium key when configured

Generated with Claude Code

Add quantum-safe signing to all Verifiable Credentials using ML-DSA-65
(Dilithium3) from liboqs (Open Quantum Safe, MIT licensed).

Architecture:
- app/crypto/dilithium.py: Dilithium3 key management, sign, verify
  with KMS-encrypted key support and plaintext fallback for dev
- app/crypto/hybrid.py: dual_sign() produces both Ed25519 and Dilithium
  proofs; verify_proof() validates single or dual proofs
- Graceful degradation: if Dilithium keys are not configured, falls
  back to Ed25519-only (no breaking change on deploy)

Changes:
- credentials.py: issue_credential() now uses dual_sign(), verify uses
  verify_proof() supporting legacy single-proof and new dual-proof
- endorsement.py: endorsement VCs use dual_sign()
- main.py: DID document dynamically includes Dilithium verification key
  when configured, with legacy key-1 alias for backward compatibility
- scripts/generate_dilithium_keys.py: utility to generate keypair

Migration path (from earlier discussion):
  Phase 1 (this PR): dual-signature, Ed25519 + Dilithium
  Phase 2 (future): Dilithium-first, Ed25519 deprecated
  Phase 3 (future): Ed25519 sunset

Dependency: liboqs-python (pip install liboqs-python)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@HaraldeRoessler
Copy link
Copy Markdown
Contributor Author

Superseded by #7 which combines JCS + PQC to avoid merge conflicts.

@HaraldeRoessler HaraldeRoessler deleted the feat/pqc-dual-signature branch May 12, 2026 00:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant