扩展库 / blake2
blake2
哈希校验BLAKE2b/BLAKE2s 的字节、UTF-8 文本、文件和增量接口。内嵌便携 C 实现,复用宿主 XRT/xruntime,不需要额外 BLAKE2 DLL。
2026-10-30:修复读取错误在关闭后重新构造、丢失完整诊断及被二次OOM覆盖的问题。 24组读取/关闭/OOM由旧失败24变为0,另补6组限额对照;ABI、正常复制与临时区所有权不变。 Windows63阶段61符合要求、Linux59阶段57符合要求,两个真实失败仍是M2顶层AOT退役与M3私有构造器被接受; 其余C/语言/双语/普通独立EXE通过,不将包侧修复等同于整包发布完成。
一次性与文件 API
下表的 b/s 分别对应 blake2b 和 blake2s 两组函数。BLAKE2b 默认摘要 64 字节、范围 1..64; BLAKE2s 默认 32 字节、范围 1..32。十六进制结果为小写,字符数量是摘要字节数的两倍。
| 函数 | 参数与返回 |
|---|---|
version() | 返回内置实现的版本字符串。 |
blake2b/sHashHex(data, digestSize) | data 为 Buffer 或 string,返回 string。 |
blake2b/sHashBytes(data, digestSize) | 相同输入,返回独立拥有型 Buffer。 |
blake2b/sKeyedHex(data, key, digestSize) | 两个 Buffer 或两个 string,返回 string。 |
blake2b/sKeyedBytes(data, key, digestSize) | 相同输入,返回独立拥有型 Buffer。 |
blake2b/sFileHex(path, maxInput, digestSize, onProgress) | 读取 UTF-8 路径的文件,返回 string。maxInput=268435456,onProgress=null。 |
文本及密钥按 UTF-8 字节计算;任意二进制使用 Buffer。BLAKE2b 密钥上限为 64 字节, BLAKE2s 为 32 字节,超过上限报错,不截断;空密钥等价于未使用密钥。 keyed hash 是原生 MAC,不是 HMAC,也不是口令存储的密码派生函数。
公开常量:BLAKE2B_OUT_LEN、BLAKE2S_OUT_LEN、
BLAKE2B_KEY_MAX、BLAKE2S_KEY_MAX。短摘要是独立初始化参数,
不是完整摘要的前缀截断。
增量对象
原生 *Native 成员仅供类内部包装使用;公开 keyed 构造器接收自带真实长度的 bytes,工厂将 Buffer 密钥复制成 bytes 后调用。C 指针/长度入口由 C 调用方保证配对;XLang 导入方不能自行伪造长度。
blake2b/sHasher(digestSize, maxInput=268435456) 创建无密钥对象,
blake2b/sKeyedHasher(Buffer key, digestSize, maxInput=268435456) 创建持有密钥副本的对象。
对应类为 Blake2bHasher、Blake2sHasher、Blake2bKeyedHasher、Blake2sKeyedHasher。
| 成员 | 合同 |
|---|---|
update(Buffer|string) | 追加输入,空输入有效。 |
digestHex() / digestBytes() | 读取快照,不结束状态;摘要长度由构造确定,没有额外长度参数。 |
inputBytes / valid | 成功接收的输入字节数,以及句柄是否非空。 |
clone() | 独立的增量状态,后续输入不影响原对象。 |
reset() as bool | 清除数据及失败状态,保留摘要长度、密钥和限额,成功返回 true。 |
import blake2
auto hash = blake2.blake2bHasher(16)
hash.update("ab")
auto branch = hash.clone()
hash.update("c")
branch.update("d")
assert hash.digestHex() == blake2.blake2bHashHex("abc", 16)
println(blake2.blake2bKeyedHex("你好 xlang", "密钥", 16))
update 的参数或限额失败后,需要 reset 才能继续使用;失败的输入不增加计数。 不同对象可独立运行,同一个可变对象须串行访问。对象析构释放并清零自己的密钥和状态, 不承诺擦除调用方副本、寄存器或系统交换页。
进度与错误
可选回调类型为 (func(int, int, int) as bool)?,参数依次为 inputBytes、
totalBytes、outputBytes;均按字节,未知总长为 0,outputBytes 恒为 0。
每块输入通知一次,最后再通知一次;空文件也通知完成。
string digest = blake2.blake2sFileHex("data.bin",
onProgress = func(int inputBytes, int totalBytes, int outputBytes) as bool
return true
end)
回调同步执行,可以嵌套另一独立哈希。返回 false 抛 CancelledError;回调异常保留原类型和消息。 文件路径中的 NUL 报 ValueError,不会读取前缀文件。读取文件只借用输入,不修改源文件;失败或取消不会返回部分摘要。 读取期间不提供防止其他进程修改文件的一致性快照。
- 非法摘要/密钥长度为 ValueError;输入超限为 RangeError;分配失败为 MemoryError。
- 打开失败沿用 XRT FileError,读取失败为 IOError;clone 失败状态对象为 RuntimeError。
- xlang 工厂及文件接口要求 maxInput 为正,默认 256 MiB;这是累计字节限额,不是 CPU 时间预算。
C API 与范例
核心头为 include/xrt_blake2.h,薄绑定头为 include/blake2_native.h。
xrtBlake2OptionsInit 初始化流对象配置,文件接口的显式限额使用 xrtBlake2LimitsInit;xrtBlake2b/sHash 写入调用方缓冲。
HasherCreate/Update/Digest/Reset/Clone/Destroy 提供相同增量语义。
C Digest 的长度必须等于 HasherDigestSize。File 借用 reader,从当前游标读到 EOF,不接管 reader 寿命。 C 调用方须检查 Reader 的关闭结果;XLang 文件哈希自行关闭文件,关闭失败不返回摘要。Reader 读取内存失败保留 MEMORY 分类和原始消息,不误报 IO。配置长度/版本必须匹配,除输入预算外的限额、标志和保留字段必须为零;通用资源初始化会设置无关的非零限额。错误配置在读取前拒绝。核心输入限额为零时关闭业务限制,但仍检查计数溢出。模块选择应在首次包含 XRT 前完成,依赖见包清单。
薄绑定 char* 借用当前 XRT 临时区,清理或回退后失效;长期保留需复制。 返回 Buffer 由调用方 xrtBufferDestroy。接管同一个句柄多次会破坏所有权,不允许重复 adopt。
文件薄绑定保留Reader原始XRT错误的身份、类别、域/码、系统码、操作、详情和cause; 关闭失败及后续诊断OOM不能覆盖首错。算法自身的限额/普通取消没有Reader首错,仍报告本包的对应错误。
教学:examples/extlibs/blake2.xl。对照:
examples/extlibs/blake2_basic.xl 与 extlibs/blake2/examples/basic.c,
共同预期输出位于 examples/extlibs/blake2_basic.expected.txt。
从仓库根目录可直接运行 release/xl.exe run release/extlibs/blake2/examples/basic.c,无需额外源文件参数。
新增file_progress.xl与file_progress_c.c:相同9字节NUL/中文文件、进度、取消、超限、 源文件保持和摘要快照,六行固定输出。两者均可直接xl run/build,独占临时资源并检查清理; C原始File接口由调用方检查关闭,XLang文件函数自动检查。
验证范围
2026-10-30:216已知答案、16分配失败点、四线程与新旧双语范例通过,Linux C含ASan/UBSan/泄漏检测。 38实际生成原型/4常量对正式头验证;错误bool返回声明在LLP64/LP64拒绝。52复制源和原件执行前后不变。 同操作局部生命周期对照的JIT/build/AOT均0,合法顶层正例仍失败;不通过移动对象绕过M2。 门禁逐阶段有界、保存原始状态/双流/输入身份,失败不删现场;官网结果只做隔离生成验证。
2026-09-27 Windows 固定输入门禁包含 36 项检查:216 条 hashlib 已知答案、38 个实际生成原型、 C/xlang JIT/AOT/GCC、回调异常/取消、reader、16 个分配失败点、四线程独立结果与错误状态、双语黄金输出。
Linux 联合门禁同次运行 C ASan/UBSan 与泄漏检查、三组 XLang JIT 用例及 C/XLang 基础范例逐字节黄金输出对照。门禁为 tools/check_extlib_blake2.ps1 与 tools/check_extlib_blake2.sh;tools/check_extlib_linux_xl.sh blake2 可单独复跑语言用例。不代表 Linux AOT、32 位/ARM、共享对象并发或性能基准已验收。
当前 API 不含 salt/personalization、树模式或 SIMD 加速,也不宣称密码学审计认证。
2026-10-18:BLAKE2b/s 文件哈希的 Reader 关闭失败红绿负例、Windows 严格 C/JIT 与 Linux ASan/UBSan/XLang 双语联合门禁通过。当前完整 AOT 构建缺主线 xl6NativeHandleTraceLeaf,不签收发布级。
2026-10-20:C 单文件范例的直接运行和生成可执行文件均通过固定输出;Windows 门禁可加 -SkipAot 独立检查 C/JIT,Linux ASan/UBSan 与 XLang 双语对照同次通过。完整 XLang AOT 和私有接管构造器访问边界仍待主线修复。
同日 b/s keyed 类的公开构造改为 bytes 真实长度校验;两条伪造指针/长度负例现被 create 重载拒绝,C 与 XLang 正例、Windows 严格 C/JIT、Linux ASan/UBSan/双语门禁通过。私有 point 接管与完整 AOT 继续阻断发布签收。
2026-10-26 当前发布物的正例复验:Windows C/语言 JIT/AOT、216 条已知答案、分配故障、生成 ABI 与双语范例通过;Linux C ASan/UBSan、六条独立 EXE AOT 和输出对照通过,旧 AOT 缺符号不再复现。但包外仍能通过 xl check 调用四类哈希器的 private extern create(point)。默认包门禁现纳入只编译访问控制负例;该主线缺陷修复前,BLAKE2 不签收整包发布级,绝不执行危险负例。
2026-10-21:完整教学范例的文件哈希改用独占临时目录并在 finally 清理;完整 XLang JIT 范例通过。Windows 门禁每次隔离本次工作目录,Linux 使用 mktemp;Windows -SkipAot 与 Linux C ASan/UBSan、XLang、双语对照通过。默认 Windows AOT 仍缺 xl6NativeHandleTraceLeaf,包外私有句柄构造器仍被 xl check 错误放行,不签收发布级。