跳到主要内容

哈希方法

  • 块哈希 - 从块数据为每个块计算。
  • Xorb 哈希 - 从其块哈希为每个 xorb 计算。
  • 文件哈希 - 从其块哈希为每个文件计算。
  • Term 验证哈希 - 在序列化 shard 时,从该 term 中使用的 xorb 的块哈希为重建中的每个 term 计算。

Xet 协议使用几种不同的哈希类型。

所有引用的哈希都是 32 字节(256 位)长。

块哈希

在切割数据块后,块哈希通过使用以下密钥(DATA_KEY)的 blake3 密钥哈希计算:

DATA_KEY

[
102, 151, 245, 119, 91, 149, 80, 222, 49, 53, 203, 172, 165, 151, 24, 28, 157, 228, 33, 16, 155, 235, 43, 88, 180, 208, 176, 75, 147, 173, 242, 41
]

参考实现

Xorb 哈希

Xorbs 由一系列块组成;给定组成 xorb 的一系列块,要计算哈希或 xorb 哈希,我们将使用具有自定义哈希函数的 Merkle 树 数据结构计算 MerkleHash。 xorb 哈希将是 MerkleTree 的根节点哈希。

叶节点哈希是上一节中描述的块哈希。

用于计算内部节点哈希的哈希函数如下:

  • 将哈希连接在一起,使得每个块按顺序有一行,格式为 {chunk_hash:x} : {size}\n
    • 哈希首先以小写十六进制格式(64 个十六进制字符,例如 a3f91d6e8b47c20ff9d84a1c77dcb8e5a91e6fbf2b2d483af6d3c1e90ac57843
    • 一个空格、一个冒号、一个空格(:
    • 块长度数字,例如 64000
    • 最后是一个换行符 \n 字符
  • 然后从此字符串中获取字节,并使用以下密钥(INTERNAL_NODE_KEY)计算 blake3 密钥哈希

参考实现

INTERNAL_NODE_KEY

[
1, 126, 197, 199, 165, 71, 41, 150, 253, 148, 102, 102, 180, 138, 2, 230, 93, 221, 83, 111, 55, 199, 109, 210, 248, 99, 82, 230, 74, 83, 113, 63
]

内部节点数据示例

考虑一个节点有 4 个块,具有以下哈希和长度对:

hash,length (bytes)
1f6a2b8e9d3c4075a2e8c5fd4f0b763e6f3c1d7a9b2e6487de3f91ab7c6d5401,10000
7c94fe2a38bdcf9b4d2a6f7e1e08ac35bc24a7903d6f5a0e7d1c2b93e5f748de,20000
cfd18a92e0743bb09e56dbf76ea2c34d99b5a0cf271f8d429b6cd148203df061,25000
e38d7c09a21b4cf8d0f92b3a85e6df19f7c20435e0b1c78a9d635f7b8c2e4da1,64000

然后为了形成计算内部节点哈希的缓冲区,我们将创建此字符串(注意末尾的 \n 换行符):

"1f6a2b8e9d3c4075a2e8c5fd4f0b763e6f3c1d7a9b2e6487de3f91ab7c6d5401 : 10000
7c94fe2a38bdcf9b4d2a6f7e1e08ac35bc24a7903d6f5a0e7d1c2b93e5f748de : 20000
cfd18a92e0743bb09e56dbf76ea2c34d99b5a0cf271f8d429b6cd148203df061 : 25000
e38d7c09a21b4cf8d0f92b3a85e6df19f7c20435e0b1c78a9d635f7b8c2e4da1 : 64000
"

然后使用 INTERNAL_NODE_KEY 计算 blake3 密钥哈希以获得最终哈希。

内部哈希函数的示例 Python 代码

from blake3 import blake3

def internal_hash_function(node):
buffer = ""
for chunk in node:
size = len(chunk)
chunk_hash = compute_chunk_hash(chunk)
buffer += f"{chunk_hash:x} : {size}\n"

blake3(bytes(buffer), key=INTERNAL_NODE_KEY)

文件哈希

在对整个文件进行分块后,要计算文件哈希,请遵循用于计算 xorb 哈希的相同过程,然后将该最终哈希作为数据,使用全为 0 的密钥计算 blake3 密钥哈希。

这意味着使用上一节中描述的相同哈希函数创建 MerkleTree。 然后获取根节点的哈希,并使用 32 个 0 值字节作为密钥计算 blake3 密钥哈希。

参考实现

Term 验证哈希

上传 shard 时,shard 中每个文件信息中的每个 term 必须有一个包含哈希的匹配 FileVerificationEntry 部分。

要生成此哈希,请获取组成该 term 的特定块范围的块哈希,然后:

  1. 连接原始哈希字节:获取范围内的所有块哈希(从 term 中指定的 xorb 中的 chunk_index_startchunk_index_end),并按顺序连接它们的原始 32 字节表示。

  2. 应用密钥哈希:使用以下验证密钥(VERIFICATION_KEY)计算连接字节的 blake3 密钥哈希:

VERIFICATION_KEY

[
127, 24, 87, 214, 206, 86, 237, 102, 18, 127, 249, 19, 231, 165, 195, 243, 164, 205, 38, 213, 181, 219, 73, 230, 65, 36, 152, 127, 40, 251, 148, 195
]

blake3 密钥哈希的结果是必须在 term 的 FileVerificationEntry 中使用的验证哈希。

参考实现

验证哈希的示例 Python 代码

def verification_hash_function(term):
buffer = bytes()
# 注意块范围是端部独占的
for chunk_hash in term.xorb.chunk_hashes[term.chunk_index_start : term.chunk_index_end]:
buffer.extend(bytes(chunk_hash))
return blake3(buffer, key=VERIFICATION_KEY)

参考文件

参考文件在 Hugging Face 数据集仓库 xet-team/xet-spec-reference-files 中提供。

在此仓库中,有多个不同的示例,实现者可以使用它们来验证哈希计算。

请注意,所有哈希都表示为字符串。 要获取这些哈希的原始值,你必须反转哈希字符串中每个字节八位组的字节序,反转 api 中描述的过程。

块哈希示例

有 3 个块文件,对于每个文件名,前 64 个字符是文件中数据的块哈希的字符串格式:

文件哈希示例

xet-team/xet-spec-reference-files 仓库包含原始文件 Electric_Vehicle_Population_Data_20250917.csv

通过 Xet 上传协议处理时,为此文件生成的块列在文件 Electric_Vehicle_Population_Data_20250917.csv.chunks 中(格式为 <hash> <length>)。

使用这些块计算整个文件的文件哈希,结果是存储在文件 Electric_Vehicle_Population_Data_20250917.csv.xet-file-hash 中的哈希,或原始值 118a53328412787fee04011dcf82fdc4acf3a4a1eddec341c910d30a306aaf97

Xorb 哈希示例

Electric_Vehicle_Population_Data_20250917.csv 的所有块可以放入 1 个单独的 xorb。

使用此文件的所有块按顺序生成的 xorb 可以在文件 eea25d6ee393ccae385820daed127b96ef0ea034dfb7cf6da3a950ce334b7632.xorb 中找到序列化形式。

此 xorb 的哈希是 eea25d6ee393ccae385820daed127b96ef0ea034dfb7cf6da3a950ce334b7632,即 Electric_Vehicle_Population_Data_20250917.csv.xet-xorb-hash 中的值。

组成此 xorb 的块列在文件 eea25d6ee393ccae385820daed127b96ef0ea034dfb7cf6da3a950ce334b7632.xorb.chunks 中; 请注意,此文件等同于 Electric_Vehicle_Population_Data_20250917.csv.chunks

范围哈希示例

Electric_Vehicle_Population_Data_20250917.csv 的重建中 使用 xorb eea25d6ee393ccae385820daed127b96ef0ea034dfb7cf6da3a950ce334b7632,有 1 个包含所有 796 个块的范围。

此范围的验证范围哈希是 eea25d6ee393ccae385820daed127b96ef0ea034dfb7cf6da3a950ce334b7632.xorb.range-hash 中的值 即 d81c11b1fc9bc2a25587108c675bbfe65ca2e5d350b0cd92c58329fcc8444178