如何组合加密哈希?

How to combine crypto hashes?

最终目标:我想确定网格几何数据(和其他属性)的相等性

我选择的均值:通过比较他们的“top sha1 hash”。

但是要制作顶级哈希,我需要组合来自散列自己数据的子例程的哈希。

TLDR

问题:如何组合加密哈希,例如 sha1 哈希?
(我想要一个boost::hash_combine<160>(h1, h2)


NLEWTRM (Not Long Enough Want To Read M矿石)

在典型的过程式编程中,你有一个 "funtion call tree",相当于让编译器生成你的复制构造函数时发生的情况,当你从顶部使用它时 -class,你会得到一个执行 "deep copy".

的级联调用

所以,例如等效地,您可以(手动)编写一系列实现 size_t hash_value()unordered 容器要求)的可散列类型,并且在任何类型上调用 hash_value()(通过 ADL)将导致 "deep hash" 因为您在计算对象时关心使用 boost::hash_combine "local top hash."

我已经看到了 boost::hash_combine 是如何实现的,这对 size_t 来说很好。

这种组合对于从尊重封装的子程序中逐步计算哈希值是必要的。

我认为这个问题在某种程度上类似于 "hash tree" 或 "hash lists",并且在对流进行哈希处理时,也已根据 "blocks"(据我所知)在 MD5 中得到解决您无法一次存储所有数据。

请注意,在我的使用中,我不需要通过一次散列所有数据来生成的散列。因为我的实现(调用树)是稳定的,如果 2 个不同的网格对象具有相同的数据,它们将产生相同的散列,这是唯一重要的事情。 (因为我需要可比性,而不是官方主义或规范主义,我也不需要加密强度。但我需要合理的唯一性保证(比 size_t 提供的更多))

显而易见的方法1:我现在想到的解决方案是将子哈希本身用作消息,连接并重新哈希。 newsha = sha1(hash1 + hash2) with + a message (buffer) concatenation operation.

第二种明显的方法:应用newsha = hash1 ^ hash2 ^一个模运算符.

obvious way: what I think about now as a solution, is to use the sub hash themselves as a message, concatenate and re-hash. newsha = sha1(hash1 + hash2) with + a message (buffer) concatenation operation.

是的,这基本上就是您已经提到的 hash-list

不要使用 XOR 方法,每次使用它都会让别人更容易制造冲突(而且通常要散列的数据量会比低层散列的数据量少得多哈希列表的层,因此性能应该不是什么大问题)。并且完全忘记了相同哈希相互抵消的问题,感谢 Tony D 提到它。

请注意,哈希列表的概念确实需要对元素进行隐式 排序。如果您没有特定的顺序,那么您可以在执行串联之前对内存中的哈希进行排序。订购哈希将例如非常适合计算 std:unordered_set.

中元素的加密安全散列

如果您 "seen how hash_combine is implemented" - 为什么不对 160 位 SHA-1 值使用相同的通用逻辑?也就是说,而不是...

seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);

...添加一个 160 位常量,它有大约一半的位在一个很好的随机排列中。 (您需要实施 160 位算法或使用合适的库 - 例如 GMP)。考虑到您的 SHA1 哈希是高质量输入,没有特别需要大量移动 - 没有理由认为不太重要的位始终或多或少比其他位随机。如果您想按照 boost 的示例选择常量,请使用 2^160 而不是 2^32:

重新应用逻辑
phi = (1 + sqrt(5)) / 2
the_constant = 2^160 / phi
             = 0x4F1B BCDC BFA5 3E0A F9CE 6030 2E76 E41A 0841 13B5

警告我还没有分析这种方法对加密应用程序的影响。