arkavo-org / arkavo-org/OpenTDFKit
Adopt Post-Quantum Cryptography with Hybrid Approach
- Dominant language
- Swift
- Stars
- 1
- Forks
- 1
- Avg merge
- 9d 4h
- Merged PRs (30d)
- 1
Description
## Overview
OpenTDFKit should adopt post-quantum (PQ) cryptography to protect against future quantum computing threats. This issue proposes an incremental migration strategy using a hybrid classical + PQ approach for the Swift implementation of OpenTDF.
## Current Cryptographic Architecture
**OpenTDFKit currently uses (via CryptoKit and CryptoSwift):**
- **Symmetric encryption**: AES-256-GCM (payload encryption) ✅ Quantum-resistant
- **Asymmetric crypto**: NIST elliptic curves for ECDH and ECDSA ⚠️ Vulnerable to quantum attacks
- **P-256 (secp256r1)** - Most common, default curve
- **P-384 (secp384r1)** - Higher security level
- **P-521 (secp521r1)** - Highest security level
- ECDH key agreement for deriving symmetric keys
- ECDSA signatures for policy binding
- **Key derivation**: HKDF-SHA256 ✅ Quantum-resistant
- **Authentication**: GMAC (via AES-GCM AAD) ✅ Quantum-resistant
### Key Components Using ECC
1. **NanoTDF Header** (`NanoTDF.swift`):
- Ephemeral public key (P-256/P-384/P-521)
- Policy binding (GMAC or ECDSA signature)
2. **Key Agreement** (`CryptoHelper.swift`):
- `customECDH()` methods for P-256, P-384, P-521
- Derives shared secret via ECDH
- Uses HKDF to derive AES symmetric key
3. **KAS Rewrap** (`KASRewrapClient.swift`):
- Client ephemeral key generation
- Key unwrapping via ECDH with KAS session public key
4. **Signatures** (`CryptoHelper.swift`):
- ECDSA signatures for NanoTDF integrity
- Policy binding verification
## Quantum Threat Assessment
**Vulnerable to quantum attacks (Shor's algorithm):**
- ❌ **P-256/P-384/P-521 ECDH** - Used for key agreement
- ❌ **ECDSA** - Used for signatures and policy binding
**Already quantum-resistant:**
- ✅ **AES-256-GCM** - 256-bit symmetric keys provide adequate post-quantum security
- ✅ **GMAC** - Hash-based authentication remains secure
- ✅ **HKDF-SHA256** - Key derivation is hash-based
## Why OpenTDFKit Needs PQ Crypto
1. **Long-term data protection**: NanoTDF files may be stored long-term (harvest-now-decrypt-later threat)
2. **Mobile security**: iOS/macOS devices are high-value targets for quantum decryption
3. **Zero Trust alignment**: PQ crypto strengthens data-centric security
4. **Future compliance**: Regulatory requirements likely to mandate PQ
5. **Ecosystem leadership**: First Swift TDF implementation with PQ support
## Proposed Timeline
### Near-term (6-12 months): Research & Planning
- Monitor Swift crypto ecosystem for PQ support
- Evaluate available Swift packages:
- [swift-crypto](https://github.com/apple/swift-crypto) - Apple's CryptoKit additions
- [PQClean-swift](https://github.com/PQClean/PQClean) - Swift bindings
- Native C/C++ PQ libraries with Swift bridging
- Study NanoTDF spec extensions for PQ
- Propose PQ extension to OpenTDF standard (coordinate with opentdf-rs)
### Medium-term (1-2 years): Hybrid Implementation
- Implement hybrid ML-KEM + ECDH for key encapsulation
- Implement hybrid ML-DSA + ECDSA for signatures
- Maintain backward compatibility with classical-only NanoTDF
### Long-term (2+ years): PQ-Only Mode
- Transition to pure post-quantum when ecosystem matures
- Deprecate classical-only mode
## Implementation Strategy
### Phase 1: Hybrid Key Encapsulation
Replace ECDH with **ML-KEM-768 + ECDH(P-256)**
```swift
public enum KasKeyCurve: UInt8, Sendable, CaseIterable {
case secp256r1 = 0x00
case secp384r1 = 0x01
case secp521r1 = 0x02
// Add new hybrid curves
case mlkem768_secp256r1 = 0x10 // Hybrid: ML-KEM-768 + P-256
case mlkem1024_secp384r1 = 0x11 // Hybrid: ML-KEM-1024 + P-384
}
// Key agreement combines both mechanisms
func deriveSharedSecret(
pqKeyPair: MlKemKeyPair,
classicalKeyPair: EphemeralKeyPair,
recipientPqPublicKey: MlKemPublicKey,
recipientClassicalPublicKey: Data
) throws -> Data {
// 1. ML-KEM encapsulation
let pqSharedSecret = try mlKemEncapsulate(
publicKey: recipientPqPublicKey,
using: pqKeyPair
)
// 2. ECDH agreement
let ecdhSharedSecret = try customECDH(
privateKey: classicalKeyPair.privateKey,
publicKey: recipientClassicalPublicKey
)
// 3. Combine: concat(pq_secret || ecdh_secret) -> HKDF
return try deriveSymmetricKey(
sharedSecrets: [pqSharedSecret, ecdhSharedSecret]
)
}
```
### Phase 2: Hybrid Signatures
Replace ECDSA with **ML-DSA-65 + ECDSA-P256** for policy binding
```swift
public struct PolicyBinding {
let classicalSignature: Data // ECDSA
let pqSignature: Data? // ML-DSA (optional for hybrid)
let algorithm: String // "ECDSA-P256" or "HYBRID-MLDSA65-P256"
}
func createHybridSignature(
data: Data,
classicalKey: P256.Signing.PrivateKey,
pqKey: MlDsaPrivateKey
) throws -> PolicyBinding {
let ecdsaSig = try classicalKey.signature(for: data)
let mldsaSig = try pqKey.signature(for: data)
return PolicyBinding(
classicalSignature: ecdsaSig.rawRepresentation,
pqSignature: mldsaSig.rawRepresentation,
algorithm: "HYBRID-MLDSA65-P256"
)
}
```
### Phase 3: NanoTDF Format Extension
Extend NanoTDF header to support hybrid keys:
```swift
public struct Header {
// Existing fields
public var kas: KasMetadata
public var ephemeralKey: Data // Now can be classical OR hybrid
// New fields for hybrid mode
public var pqEphemeralKey: Data? // ML-KEM public key
public var pqPolicyBinding: Data? // ML-DSA signature
// Version negotiation
public static let versionV12: UInt8 = 0x4C // "L1L" - classical
public static let version: UInt8 = 0x4D // "L1M" - classical
public static let versionV14Hybrid: UInt8 = 0x4E // "L1N" - hybrid PQ
}
```
## Swift Ecosystem Challenges
### Challenge 1: Limited PQ Libraries
- **Issue**: Swift lacks mature PQ crypto libraries compared to Rust
- **Mitigation**:
- Use C/C++ PQ libraries with Swift bridging (e.g., liboqs via C interop)
- Contribute to Swift crypto ecosystem
- Consider wrapping Rust libcrux via Swift/Rust FFI
### Challenge 2: CryptoKit API Constraints
- **Issue**: Apple's CryptoKit doesn't support PQ algorithms yet
- **Mitigation**:
- Use CryptoSwift or custom implementations for PQ
- Monitor Apple's roadmap for CryptoKit PQ support
- Abstract crypto operations behind protocol for easy swapping
### Challenge 3: Performance on Mobile
- **Issue**: PQ operations are more expensive than ECC
- ML-KEM-768: ~1200 byte public key vs ~33 byte P-256 key
- Slower key generation and encapsulation
- **Mitigation**:
- KAS operations are already network-bound
- Implement async/await efficiently
- Cache PQ keys where appropriate
- Optimize hot paths with profiling
## Recommended Approach
### Option A: C Library Bridging (Fastest Path)
```swift
// Use liboqs via C interop
import liboqs
public class PQCrypto {
static func mlKemKeypair() throws -> (publicKey: Data, privateKey: Data) {
// Call liboqs C functions via Swift C interop
}
}
```
**Pros**: Proven library, well-tested
**Cons**: C bridging complexity, potential safety issues
### Option B: Pure Swift Implementation (Long-term)
```swift
// Implement ML-KEM in pure Swift
public struct MlKem768 {
// Pure Swift implementation
}
```
**Pros**: Type-safe, no FFI overhead
**Cons**: Requires extensive crypto expertise, slower initial development
### Option C: Rust FFI via swift-bridge (Hybrid)
```swift
// Use libcrux-ml-kem from Rust via FFI
@_cdecl("ml_kem_keypair")
public func mlKemKeypair() -> KeyPair { ... }
```
**Pros**: Leverage proven libcrux, good performance
**Cons**: Complex build setup, two language toolchains
**Recommendation**: Start with **Option A (liboqs)** for prototyping, migrate to **Option B or C** for production.
## Action Items
- [ ] Research Swift PQ crypto libraries (liboqs, PQClean, swift-crypto roadmap)
- [ ] Create spike: Prototype ML-KEM-768 key agreement in Swift
- [ ] Benchmark PQ operations on iOS/macOS (target devices)
- [ ] Design NanoTDF v1.4 hybrid format specification
- [ ] Propose PQ extension to OpenTDF standard (coordinate with opentdf-rs team)
- [ ] Implement C bridging for liboqs ML-KEM and ML-DSA
- [ ] Add hybrid key agreement to CryptoHelper
- [ ] Add hybrid signatures to signature generation
- [ ] Update NanoTDF header parser for hybrid format
- [ ] Implement backward compatibility layer
- [ ] Add integration tests for hybrid mode
- [ ] Benchmark performance on target platforms
- [ ] Documentation and migration guide
- [ ] Gradual rollout: optional PQ → default hybrid → PQ-only
## Performance Targets
Based on current OpenTDFKit benchmarks:
| Operation | Current (P-256) | Target (Hybrid) | Notes |
|-----------|-----------------|-----------------|-------|
| Key generation | ~1.1ms | <5ms | Acceptable for async operations |
| Key agreement | ~1.3ms | <10ms | Network-bound, tolerable overhead |
| Signature | ~1.6ms | <8ms | Policy binding, infrequent |
| NanoTDF size | ~250 bytes | <2KB | Acceptable for mobile data transfer |
## References
- [NIST Post-Quantum Cryptography Standards](https://csrc.nist.gov/projects/post-quantum-cryptography)
- [liboqs - Open Quantum Safe](https://github.com/open-quantum-safe/liboqs)
- [Signal's SPQR (Rust reference)](https://github.com/signalapp/SparsePostQuantumRatchet)
- [Swift Crypto](https://github.com/apple/swift-crypto)
- [PQClean](https://github.com/PQClean/PQClean)
- [OpenTDF Specification](https://github.com/opentdf/spec)
## Related Work
- **Signal SPQR**: Production PQ ratcheting using ML-KEM (Rust)
- **opentdf-rs**: Sister project also adopting PQ (Issue #9)
- **Apple CryptoKit**: Monitor for potential future PQ support
## Cross-Platform Considerations
OpenTDFKit targets iOS, macOS, tvOS, watchOS - ensure PQ implementation works across:
- Different CPU architectures (ARM64, x86_64)
- Minimum OS versions (iOS 18+, macOS 14+)
- Watchdog constraints on watchOS (performance budget)
---
**Priority**: Medium-High
**Complexity**: High
**Timeline**: 12-24 months for full hybrid implementation
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading CryptoHelper.swift, NanoTDF.swift, and KASRewrapClient.swift to map the existing ECDH, signatures, and header handling. No failing test or single entry point is specified; the action items describe a multi-phase effort spanning library research, C bridging, format design, compatibility, integration tests, and mobile benchmarks. Done would require agreement on scope and completion criteria before implementation begins.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- cryptography, mobile-dev, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100