NGCC benchmark
当前访问频次受限,请登录后继续访问
ngcc_bench
简介
基于 C11 的跨平台 NGCC 算法测试基准工具(Linux / macOS)。程序通过
dlopen / dlsym 动态加载被测动态库,并执行正确性、性能、内存和稳定性测试。
ARM 平台自评估资源申请
如需申请“下一代商用密码征集”ARM 平台自评估资源,请按照以下流程提交申请:
-
发送申请邮件至:
team@openhitls.net -
邮件主题请填写:
下一代商用密码征集-ARM平台自评估资源申请 -
请在邮件正文中提供以下信息:
- 姓名
- 联系电话
- 所属单位或团队
- 预计使用时间或其他说明(可选)
收到申请后,工作人员将通过申请人预留的联系电话进行沟通,并预约自评估资源的使用时间。
邮件示例
邮件主题:下一代商用密码征集-ARM平台自评估资源申请
姓名:张老师
联系电话:138XXXXXXXX
所属单位:XXXXXXXX
其他说明:计划申请 ARM 平台资源进行算法性能自评估。
测试目标
| 目标 | correctness | performance |
|---|---|---|
hash |
对同一随机消息重复计算摘要并比对,或执行 KAT | 按固定消息长度分别输出吞吐量和耗时 |
sig |
执行 keygen + sign + verify,或执行 verify KAT |
分别输出 keygen、sign、verify 指标 |
kem |
执行 keygen + encap + decap,或执行 decap KAT |
分别输出 keygen、encap、decap 指标 |
kex |
执行完整密钥协商链路,或执行 KAT | 分别输出 derive_ss_a、derive_ss_b 指标 |
all |
依次执行全部四类算法 | 依次执行全部四类算法 |
测试模式:
correctnessperformancememorystabilityall
构建
要求:
- CMake >= 3.16
- 支持 C11 的 GCC
- Linux 下需要
libdl、libm
mkdir build
cd build
cmake ..
make -j
主程序:
./ngcc_bench
被测动态库不需要在编译 ngcc_bench 时配置。直接运行 ./ngcc_bench 会进入交互模式,
程序会提示输入动态库路径。需要脚本化执行时,也可以使用 --lib PATH 通过命令行传入。
两种方式最终都会使用 dlopen / dlsym 动态加载被测库。
快速开始
无参数运行会进入交互模式:
./ngcc_bench
程序会依次提示输入动态库路径、测试目标、测试模式,以及当前模式需要的附加配置。
查看帮助或版本:
./ngcc_bench --help
./ngcc_bench --version
以下为适合脚本或 CI 使用的非交互式示例。
执行 KEM correctness:
./ngcc_bench \
--lib /path/to/libalgo.so \
--test kem \
--mode correctness
执行 SIG performance:
./ngcc_bench \
--lib /path/to/libalgo.so \
--test sig \
--mode performance
执行全量测试并输出中英文 JSON 报告:
./ngcc_bench \
--lib /path/to/libalgo.so \
--test all \
--mode all \
--digest-len-bits 256 \
--key-len-bits 256 --block-len-bits 256 \
--json-out full_report.json
该命令实际生成:
full_report.json.zh
full_report.json.en
CLI 参数
| 参数 | 说明 | 默认值 |
|---|---|---|
--lib PATH |
被测动态库路径;仅非交互模式必填 | 交互模式中提示输入 |
--test block|hash|sig|kem|kex|all |
测试目标 | all |
--mode correctness|performance|memory|stability|all |
测试模式 | all |
--key-len-bits BITS |
分组密钥位数,正数且为 8 的倍数;选中 block 时必填,仅带 KAT 的纯正确性测试可省略 |
无 |
--block-len-bits BITS |
分组位数,正数且为 8 的倍数;必填条件同上,须与待测算法一致 | 无 |
--digest-len-bits BITS |
Hash 摘要位数;选中 hash 时必填 |
无 |
--duration-hours H |
stability 最长运行时间,必须大于 0 |
6.0 |
--stability-max-cases N |
stability 最大 case 数,必须大于 0 |
3000 |
--kat DIR |
KAT 向量目录,仅在包含 correctness 的模式下可用 |
无 |
--json-out PATH |
JSON 输出前缀,实际写出 PATH.zh 和 PATH.en |
无 |
--help |
输出帮助 | - |
--version |
输出版本 | - |
当前以下配置不可通过 CLI 修改:
- performance 迭代次数:
10000 - Hash 及分组 ECB/CBC performance 消息长度:
32、128、512、1024、4096、8192、16384、65536字节 - stability 消息长度:
131072字节 - stability 采样窗口:
1.0毫秒 - stability 会尝试采集 cycles;平台不支持时输出
unavailable - stability 判定阈值:吞吐 CV
< 5%、耗时 CV< 5%、cycles CV< 5%、内存增长绝对值< 1%、错误率<= 0%
KAT 目录
--kat 接收目录。程序按测试目标匹配文件名前缀:
| 目标 | 文件名前缀 |
|---|---|
block |
KAT_DifKey_、KAT_DifMsg_、KAT_ECB_、KAT_CBC_、KAT_Loop_,目录须包含五类 |
hash |
KAT_2_12_、KAT_2_23_、KAT_2_33_、KAT_Loop_,四类均必需 |
sig |
KAT_SIG_ |
kem |
KAT_KEM_ |
kex |
KAT_KEX_ |
KAT 解析支持 #、;、// 注释,以及 0x 前缀和常见字段别名。
输出与限制
- 加载器按
--test按需加载符号;动态库只需导出实际被测算法的符号。 memory在主进程串行执行,每个待测操作统计一次。SIG 分别测密钥生成、签名、验签;KEM 分别测密钥生成、封装、解封装;KEX 仅测协商 A/B,初始化和消息交互作为准备步骤。哈希和签名消息长度为 32 字节。- 分配桩编入
ngcc_bench,通过dlsym(RTLD_NEXT, ...)获取真实分配函数,无需额外程序、插桩共享库或 Valgrind。要求 Linux 动态链接环境及实现所需分配符号的 libc;当前在 glibc 上验证,其他 libc 尚未实测,不依赖__libc_malloc等私有入口。 static_memory_bytes为待测 ELF 库.text/.data/.bss/.rodata节大小之和,包含 NOBITS 类型的.bss,不计依赖库及其他节。同一库中的算法共用该值;无法读取节元数据时内存测试失败,不继续动态测试。memory_metrics按操作标签报告单次调用的堆申请峰值,不输出大类动态内存汇总值。库加载、框架缓冲区和校验等接口调用区间外的分配不计入;密钥生成作为独立待测操作时,其内部申请正常计入。- 每次调用只记录本次新申请且尚未释放的字节数,并取其最大值。释放旧块不扣减本次计数;成功 realloc 的完整新大小归入本次调用,失败保留原记录。0 仅表示未捕获到堆申请。
- 不计栈、静态区、分配器管理开销和直接 mmap;内存池内部子分配或静态绑定的分配可能无法捕获,但内存池在统计区间内调用被拦截的 malloc 等函数仍会计入。
- 包括待测库在内限定为单线程,不支持并发分配。内存测试结束后,无论成功失败都关闭记账并清空记录。其他测试直接转发到已解析的分配函数,仍有桩函数分支和转发开销。
- 支持 GCC 动态 ASan 构建(已验证 GCC 13):
-DENABLE_ASAN=ON。桩文件自身不做 ASan 插桩,分配及释放转发到 ASan。普通构建转发到 libc;原生性能和普通分配器内存测量使用普通构建。不支持任意其他分配器或分配桩叠加。 - 性能模式在加载待测库前完成分配器准备;初始化临时内存若仍存活,报告初始化失败,与待测库泄漏无关。记账容量不足时内存测试失败。
- stability 输出
STABLE、UNSTABLE,收到SIGINT/SIGTERM时输出STOPPED。 - stability 为
UNSTABLE、测试失败、参数错误或缺失符号时,程序返回非0。 --json-out生成中英文双份 JSON 报告。
动态库接口
被测动态库需要导出所选算法对应的接口符号。接口定义见
ngcc_bench/include/ngcc_api.h。