6.7 KiB
6.7 KiB
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(推荐开发阶段)
- 在 Xcode 中选择 File → Add Package Dependencies → Add Local…
- 选择本仓库中的
ios/目录(包含Package.swift) - 在弹出框中勾选 KyberSDK,选择目标 Target,点击 Add Package
方式二:SPM 依赖声明
// Package.swift
.package(path: "../ios"), // 本地路径
// 或使用远程 URL:
// .package(url: "https://your-repo/KyberSDK", from: "1.0.0"),
API 使用示例
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 ✓(密文合法时)
注意:所有方法均为同步调用,建议在后台队列执行:
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 字节(三种变体相同)。
运行测试
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 中同时支持三种变体:
- 将所有变体相关的
.c文件重命名为.inc(放在internal/),SPM 不直接编译它们。 - 创建三个"驱动"翻译单元(
kyber512/768/1024.c),各自先#define KYBER_K,再#include所有.inc文件。 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_* (共享,去重)
安全注意事项
- 私钥存储:私钥应存入 iOS Keychain(
kSecClassKey),不应明文持久化。 - 共享密钥用途:建议通过 HKDF 从共享密钥派生实际加密/认证密钥。
- 密文完整性:解封装不抛出错误不代表密文合法(IND-CCA2 特性), 应通过上层协议(TLS / AEAD)保证完整性。