ngcc_bench:基于 C11 的跨平台 NGCC 算法测试基准工具

NGCC benchmark

分支1Tags0

ngcc_bench

English

简介

基于 C11 的跨平台 NGCC 算法测试基准工具(Linux / macOS)。程序通过 dlopen / dlsym 动态加载被测动态库,并执行正确性、性能、内存和稳定性测试。

ARM 平台自评估资源申请

如需申请“下一代商用密码征集”ARM 平台自评估资源,请按照以下流程提交申请:

  1. 发送申请邮件至:team@openhitls.net

  2. 邮件主题请填写:

    下一代商用密码征集-ARM平台自评估资源申请
    
  3. 请在邮件正文中提供以下信息:

    • 姓名
    • 联系电话
    • 所属单位或团队
    • 预计使用时间或其他说明(可选)

收到申请后,工作人员将通过申请人预留的联系电话进行沟通,并预约自评估资源的使用时间。

邮件示例

邮件主题:下一代商用密码征集-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 依次执行全部四类算法 依次执行全部四类算法

测试模式:

  • correctness
  • performance
  • memory
  • stability
  • all

构建

要求:

  • 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。