Merkle 樹狀結構可用於 Fuchsia 生態系統中的各個位置,包括 FAR 封存格式、Blob 儲存體檔案系統,以及 ffx 中包含的套件管理工具。
在 Zircon 中,zx-verity
提供 API,讓應用程式元件可讀取本機儲存空間中的資料。擷取資料時,系統會驗證資料的完整性,並在資料遭到修改或損毀時導致讀取失敗。zx-verity 是以 Merkle Tree 為基礎,並源自 ChromeOS 中的類似系統。
所有這些實作方式都會使用本文件所述的演算法。
Merkle 樹的參數
- 區塊大小:8kb,填充 0。
- 根摘要大小:32 位元組。
- 雜湊演算法:SHA-256。
- 區塊摘要運算:SHA-256(u64(offset | level) + u32(length) + data)
定義
Merkle 樹狀結構包含層級。層級是樹狀結構的一列,從 0 開始往上計算。層級 0 代表包含輸入串流區塊雜湊值的層級。
每個層級都包含前一個層級的雜湊值。層級中的雜湊值是根據前一層級的 8 KB 區塊 (如果是第 0 層級,則是資料) 計算而得,並在開頭加上區塊 ID。
區塊 ID 是目前層級中區塊的起始位元組索引與目前層級索引的二元 OR 運算結果,後面接著區塊的長度。對於層級 0,區塊的長度為 8kb,但最後一個區塊可能小於 8kb。所有其他層級都使用 8kb 長度,即使最後一個區塊是 0 填充也一樣。
等級的運算
- 使用索引、從 0 開始的偏移量,以及空的雜湊清單,初始化層級。
- 針對每個 8kb (或其餘部分) 的輸入內容,請取取值為層級索引和目前偏移量,再加上輸入內容的長度,然後以二元 OR 運算來計算下一個區塊 ID。
- 初始化 SHA-256 摘要,並在其後附加身分、輸入內容,如果輸入內容少於 8kb,則附加 0 至 8kb。
- 將摘要的輸出內容附加至層級的雜湊清單。以輸入長度遞增偏移量。
- 重複執行 1 到 4 步驟,直到所有輸入內容都用完為止。
- 如果雜湊長度為 32,請結束。
- 如果雜湊長度未對齊 8kb,0 會填入 8kb 對齊,並計算更多層級,直到根層級包含單一 32 位元摘要為止。
根摘要的運算
使用輸入資料計算第 0 層。使用先前層級的雜湊值做為輸入資料,建構及計算後續層級,直到某個層級的雜湊值包含 32 個位元組為止。這個最後一層包含梅克爾樹的根摘要。
空白摘要的注意事項
在特殊情況下,如果沒有輸入資料,實作可能需要獨立處理計算作業。空白輸入內容的摘要,就是 12 個 0 位元組的 SHA-256,也就是單一長度為 0 的區塊的區塊 ID。
範例值
- 空白摘要:
15ec7bf0b50732b49f8228e07d24365338f9e3ab994b00af08e5a3bffe55fd8b
- 8192 位元組的
0xff
- 「oneblock」68d131bc271f9c192d4f6dcd8fe61bef90004856da19d0f2f514a7f4098b0737
- 65536 個位元組的
0xff
-「小」f75f59a944d2433bc6830ec243bfefa457704d2aed12f30539cd4f18bf1d62cf
- 2105344 個位元組的
0xff
- 「large」7d75dfb18bfd48e03b5be4e8e9aeea2f89880cb81c1551df855e0d0a0cc59a67
- 2109440 個位元組的
0xff
-「未對齊」7577266aa98ce587922fdc668c186e27f3c742fb1b732737153b70ae46973e43
0xff0080
位元組填入重複的0xff0080
- "fuchsia"2feb488cffc976061998ac90ce7292241dfa86883c0edc279433b5c4370d0f30