# KyberSDK — iOS / macOS Swift Package 基于 CRYSTALS-Kyber(ML-KEM,NIST FIPS 203)后量子密钥封装机制的 Swift Package, 支持 iOS 14+ / macOS 11+ 及全平台架构(arm64 真机、arm64/x86_64 模拟器)。 --- ## 环境要求 | 工具 | 最低版本 | |------|---------| | Xcode | 15.0 | | iOS | 14.0 | | macOS | 11.0 | | Swift | 5.9 | --- ## 支持的平台与架构 | 平台 | 架构 | |------|-----| | iOS 真机 | `arm64` | | iOS 模拟器(Intel Mac) | `x86_64` | | iOS 模拟器(Apple Silicon Mac) | `arm64` | | macOS | `arm64`、`x86_64` | --- ## 集成方法 ### 方式一:本地 Swift Package(推荐开发阶段) 1. 在 Xcode 中选择 **File → Add Package Dependencies → Add Local…** 2. 选择本仓库中的 `ios/` 目录(包含 `Package.swift`) 3. 在弹出框中勾选 **KyberSDK**,选择目标 Target,点击 Add Package ### 方式二:SPM 依赖声明 ```swift // Package.swift .package(path: "../ios"), // 本地路径 // 或使用远程 URL: // .package(url: "https://your-repo/KyberSDK", from: "1.0.0"), ``` --- ## API 使用示例 ```swift import KyberSDK // ── 接收方:生成密钥对 ──────────────────────────────────────────────── let keyPair = try KyberKEM.generateKeyPair(variant: .kyber768) // keyPair.publicKey → 可公开分发(Data) // keyPair.secretKey → 安全存储,建议存入 iOS Keychain // ── 发送方:封装共享密钥 ────────────────────────────────────────────── let result = try KyberKEM.encapsulate(variant: .kyber768, publicKey: keyPair.publicKey) // result.ciphertext → 传输给接收方(Data) // result.sharedSecret → 本地保留,用于对称加密(AES-GCM、ChaCha20-Poly1305) // ── 接收方:解封装恢复共享密钥 ─────────────────────────────────────── let sharedSecret = try KyberKEM.decapsulate( variant: .kyber768, ciphertext: result.ciphertext, secretKey: keyPair.secretKey ) // result.sharedSecret == sharedSecret ✓(密文合法时) ``` > **注意**:所有方法均为同步调用,建议在后台队列执行: > ```swift > let kp = try await Task.detached(priority: .userInitiated) { > try KyberKEM.generateKeyPair(variant: .kyber768) > }.value > ``` --- ## 支持的安全级别 | 枚举值 | KYBER_K | NIST 级别 | 经典安全性 | 公钥 | 私钥 | 密文 | |--------|---------|----------|----------|-----|-----|-----| | `.kyber512` | 2 | Level 1 | ~AES-128 | 800 B | 1632 B | 768 B | | `.kyber768` | 3 | Level 3 | ~AES-192 | 1184 B | 2400 B | 1088 B | | `.kyber1024` | 4 | Level 5 | ~AES-256 | 1568 B | 3168 B | 1568 B | 共享密钥固定为 **32 字节**(三种变体相同)。 --- ## 运行测试 ```bash cd ios swift test # 预期输出:11 项测试全部通过 ``` 测试覆盖: | 测试名称 | 说明 | |---------|------| | `testKyber512/768/1024KeySizes` | 密钥尺寸符合规范 | | `testKyber512/768/1024RoundTrip` | 完整 KEM 流程,共享密钥必须一致 | | `testKyber512WrongKey` | 错误私钥不能恢复正确共享密钥(IND-CCA2) | | `testInvalidPublicKeySize` | 公钥长度不符时抛出错误 | | `testInvalidSecretKeySize` | 私钥长度不符时抛出错误 | | `testInvalidCiphertextSize` | 密文长度不符时抛出错误 | | `testKyber768Performance` | 密钥生成性能基线 | --- ## 包结构详解 ``` ios/ ├── Package.swift # SPM 包描述(iOS 14+ / macOS 11+) ├── Sources/ │ ├── CKyber/ # C 实现层(单 target 包含三种变体) │ │ ├── include/ # 对外暴露的头文件 │ │ │ ├── kyber_sdk.h # 伞头文件(包含 api.h 及 randombytes 声明) │ │ │ ├── api.h # 三种变体函数声明 │ │ │ └── ...(其余内部头文件) │ │ ├── internal/ # .inc 文件(不直接编译,由变体 .c 文件 #include) │ │ │ ├── kem.inc # kem.c 内容副本 │ │ │ ├── indcpa.inc # indcpa.c 内容副本 │ │ │ └── ...(poly / ntt / cbd / reduce / verify / symmetric_shake) │ │ ├── kyber512.c # 翻译单元:#define KYBER_K 2 │ │ ├── kyber768.c # 翻译单元:#define KYBER_K 3 │ │ ├── kyber1024.c # 翻译单元:#define KYBER_K 4 │ │ ├── fips202.c # SHA3/SHAKE(与 KYBER_K 无关,编译一次) │ │ └── randombytes_ios.c # arc4random_buf 包装 │ └── KyberSDK/ # Swift 封装层 │ ├── KyberTypes.swift # KyberVariant / KyberKeyPair / KyberError │ └── KyberKEM.swift # 主 API:generateKeyPair / encapsulate / decapsulate ├── Tests/ │ └── KyberSDKTests/ │ └── KyberSDKTests.swift # 11 项单元测试 └── KyberDemo/ # SwiftUI 演示 App 源文件 ├── KyberDemoApp.swift ├── ContentView.swift └── README.md # Demo 集成说明 ``` --- ## 多变体编译原理(.inc 翻译单元技巧) Kyber C 实现通过编译时常量 `KYBER_K` 区分变体,同一源文件在不同 `KYBER_K` 下产生不同符号名。 为在单一 SPM target 中同时支持三种变体: 1. 将所有变体相关的 `.c` 文件重命名为 `.inc`(放在 `internal/`),SPM 不直接编译它们。 2. 创建三个"驱动"翻译单元(`kyber512/768/1024.c`),各自先 `#define KYBER_K`,再 `#include` 所有 `.inc` 文件。 3. `fips202.c` 与 KYBER_K 无关,单独编译一次;链接器对三份对象文件中的相同符号自动去重。 ``` kyber512.c (#define KYBER_K 2) → pqcrystals_kyber512_ref_keypair 等 kyber768.c (#define KYBER_K 3) → pqcrystals_kyber768_ref_keypair 等 kyber1024.c (#define KYBER_K 4) → pqcrystals_kyber1024_ref_keypair 等 fips202.c → pqcrystals_kyber_fips202_ref_* (共享,去重) ``` --- ## 安全注意事项 1. **私钥存储**:私钥应存入 iOS Keychain(`kSecClassKey`),不应明文持久化。 2. **共享密钥用途**:建议通过 HKDF 从共享密钥派生实际加密/认证密钥。 3. **密文完整性**:解封装不抛出错误不代表密文合法(IND-CCA2 特性), 应通过上层协议(TLS / AEAD)保证完整性。