Rust 的可重现加密哈希 structs/enums

Reproducable cryptographic hashes of Rust structs/enums

目前我正在使用以下代码获取 Rust 结构和枚举的 sha256 哈希值。

pub fn sha256<T: Sized + Serialize>(ser: T) -> [u8; 32] {
    let str = ron::ser::to_string(&ser).expect("serialization has failed");

    let mut hasher = Sha256::new();
    hasher.update(str);
    let hash = hasher.finalize();
    *hash.as_ref()
}

这可行,但远非理想:

许多类型都有 .hash() 方法,但这似乎适用于 64 位非加密哈希(HashMap 等)。

我如何加密散列任意 Rust 结构和枚举,这样散列将是相同的,而不管 architecture/word-size/endianess? (我不在其中使用 usize。)

如果你想用加密散列来散列一个对象,你必须把它变成一个字节流,因为这是加密散列唯一接受的东西。我们一般会称之为序列化。

您可以做一些事情:

  • 找到最快的通用序列化格式。 JSON 对此不利,因为它不能有效地序列化字节序列,因此您可以尝试 CBOR、Msgpack 或其他一些二进制格式。
  • 将常见结构散列到预期值的代码添加测试,以便您可以验证它们是否按预期工作并避免意外中断。
  • 如果可能,将版本字段添加到您的散列中,以便在需要更改序列化程序或序列化的字节结构时可以更改版本。
  • 使用比 SHA-256 更快的散列,例如 SHA-512,SHA-512/256,或 BLAKE2b(在 64 位系统上)或 BLAKE2s(在 32 位系统上)以降低成本整体运行。

或者,您可以尝试构建自定义 Hasher 实现,它也可以输出 SHA-256 值。然后您的结构将需要实现 Hash 而不是 Serialize 并且您将逐步进行散列。这可能会或可能不会更快。