《Fuchsia Merkle》根源

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 填充也一樣。

等級的運算

  1. 使用索引、從 0 開始的偏移量,以及空的雜湊清單,初始化層級。
  2. 針對每個 8kb (或其餘部分) 的輸入內容,請取取值為層級索引和目前偏移量,再加上輸入內容的長度,然後以二元 OR 運算來計算下一個區塊 ID。
  3. 初始化 SHA-256 摘要,並在其後附加身分、輸入內容,如果輸入內容少於 8kb,則附加 0 至 8kb。
  4. 將摘要的輸出內容附加至層級的雜湊清單。以輸入長度遞增偏移量。
  5. 重複執行 1 到 4 步驟,直到所有輸入內容都用完為止。
  6. 如果雜湊長度為 32,請結束。
  7. 如果雜湊長度未對齊 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