1. PQC算法库选型与集成环境搭建
为什么选型要先于写代码
PQC 算法库的差异不只在算法实现本身,还体现在 API 风格、许可证、构建系统、平台支持与是否提供 KEM 高层封装。选错库会导致后续封装层反复重写。本例以“跑通首个 KEM 握手”为验收目标,对三类主流实现做横向对比后完成环境搭建。
三类主流实现对比
| 实现 | 定位 | API 风格 | 许可证 | 平台支持 | 集成成本 |
|---|---|---|---|---|---|
| liboqs | 算法聚合库 + 高层 KEM/SIG API | C,OQS_KEM 对象式 | MIT | Linux/macOS/Windows,CMake | 低,开箱即用 |
| PQClean | 纯净参考实现集合 | C,按算法独立目录,无统一高层 API | CC0 / 各算法自带 | 跨平台,Makefile/CMake | 中,需自行封装 |
| BoringSSL+OQS | 在 TLS 栈中启用 PQC 混合握手 | EVP_PKEY / SSL_CTX 扩展 | OpenSSL 系 + OQS 补丁 | Linux/macOS 为主 | 高,需打补丁并重编 |
选型结论:本例目标是“快速跑通 KEM 握手并保留后续封装空间”,liboqs 提供统一的
OQS_KEM 抽象,接口稳定、许可证宽松、构建简单,作为首选;PQClean 适合需要审计算法源码的场景;BoringSSL+OQS 适合最终要落到 TLS 握手的集成阶段。选型决策关系
环境搭建与首个 KEM 握手
以下步骤在 Linux/macOS 上验证,使用 liboqs 的 CMake 构建流程。先安装依赖并编译安装库,再编写一个最小 KEM 握手程序。
# 1. 获取源码
git clone --depth 1 https://github.com/open-quantum-safe/liboqs.git
cd liboqs && mkdir build && cd build
# 2. 配置并编译(关闭不需要的算法可加速构建)
cmake -GNinja -DCMAKE_INSTALL_PREFIX=$HOME/liboqs-install \
-DOQS_BUILD_ONLY_LIB=ON -DOQS_USE_OPENSSL=ON ..
ninja && ninja install
# 3. 验证安装
ls $HOME/liboqs-install/lib/liboqs.*
ls $HOME/liboqs-install/include/oqs/
接着编写最小 KEM 握手示例,使用 Kyber512 完成密钥生成、封装与解封装,并校验双方共享密钥一致。
#include <stdio.h>
#include <string.h>
#include <oqs/oqs.h>
int main(void) {
OQS_KEM *kem = OQS_KEM_new(OQS_KEM_alg_kyber_512);
if (kem == NULL) { printf("KEM 不可用\n"); return 1; }
uint8_t *pk = malloc(kem->length_public_key);
uint8_t *sk = malloc(kem->length_secret_key);
uint8_t *ct = malloc(kem->length_ciphertext);
uint8_t *ss1 = malloc(kem->length_shared_secret);
uint8_t *ss2 = malloc(kem->length_shared_secret);
/* 接收方生成密钥对 */
OQS_KEM_keypair(kem, pk, sk);
/* 发送方用公钥封装,得到密文与共享密钥 ss1 */
OQS_KEM_encaps(kem, ct, ss1, pk);
/* 接收方用私钥解封装,恢复共享密钥 ss2 */
OQS_KEM_decaps(kem, ss2, ct, sk);
printf("共享密钥一致: %s\n",
memcmp(ss1, ss2, kem->length_shared_secret) == 0 ? "是" : "否");
OQS_MEM_secure_free(sk, kem->length_secret_key);
OQS_MEM_secure_free(ss1, kem->length_shared_secret);
OQS_MEM_secure_free(ss2, kem->length_shared_secret);
free(pk); free(ct);
OQS_KEM_free(kem);
return 0;
}
编译并运行:
gcc kem_demo.c -o kem_demo \
-I$HOME/liboqs-install/include \
-L$HOME/liboqs-install/lib -loqs -lcrypto
LD_LIBRARY_PATH=$HOME/liboqs-install/lib ./kem_demo
# 预期输出:共享密钥一致: 是
若链接时报
undefined reference to OQS_KEM_new,检查 -loqs 是否在源文件之后;若运行时报找不到动态库,设置 LD_LIBRARY_PATH(macOS 用 DYLD_LIBRARY_PATH)。验收清单
- liboqs 编译安装成功,
liboqs.so与oqs/oqs.h存在。 - Kyber512 的
OQS_KEM_new返回非空,说明算法已启用。 - 封装与解封装得到的共享密钥
memcmp为 0。 - 私钥与共享密钥使用
OQS_MEM_secure_free清零释放。