newsence
以太坊狀態的分片私密資訊檢索設計

以太坊狀態的分片私密資訊檢索設計

ethresear.ch·6 天前

本文提出了一種用於以太坊的分片私密資訊檢索(PIR)架構,透過將不同的數據切片與特定的 PIR 方案配對來優化性能,同時保持強大的隱私保證。

由 EF Private Reads 團隊的 Ali AtiiaKeewoo Lee 撰寫。

**
感謝 Ling Ren、Yue Chen、Dimitris MourisWill ScottSohamAdriaDanAndyDivyá Ranjan 以及 Felix Lin 對草案提供的反饋與建議。

同時感謝 Alex HooverNamVitalik Buterin 以及 Igor Barinov 早期對 PIR 的討論與實驗;感謝 Guillaume BalletCarlos PerezTakamichi TsutsumiTomás Arjovsky 在二元試行樹(binary tries)方面的討論與合作,以及 Leo 關於可證明的 UBT-MPT 等效性的討論。

內容摘要 (TLDR)

私密 資訊 檢索 (PIR) 可以讓以太坊用戶從遠端伺服器讀取鏈上數據,而伺服器無法得知用戶正在讀取什麼。不同的 PIR 方案具有不同的性能權衡以及用戶/伺服器開銷。另一方面,以太坊數據具有不同的更新特性,且在不同的情境下被使用,對延遲的敏感度也各不相同。

如果將以太坊數據進行分片(sharded),以便將每個數據集與其最佳 PIR 方案配對,我們就能在保持相同隱私保證的前提下,獲得比對整個以太坊狀態使用單一方案更好的整體性能——前提是用戶在進行真實查詢的同時,並行地向所有方案提交誘餌查詢(decoy queries)

本文提出了一組以太坊狀態數據的切片,探討了 PIR 方案及將其與數據切片配對的決策樹,提出了一個分片系統的設計草圖,並觸及了一些可能進一步擴展整體系統的以太坊特定優化

目錄

3.1 使用情境

4.1 分類法

5.1 分片

8.1 用於 Merkle 樹的 PIR

1. 簡介

以太坊用戶從遠端伺服器讀取鏈上數據,以了解並驗證感興趣的當前和歷史狀態,或構建與模擬交易。洩露讀取的內容(what)可能導致伺服器將用戶的鏈上與鏈下身份關聯起來,進而引發搶先交易(frontrunning)和其他榨取性 MEV 等問題。

「模糊讀取」(Oblivious Reads)的原語使客戶端能夠從資料庫主機伺服器讀取數據,而後者不知道正在讀取哪些數據。這與通過匿名路由實現的網路層不可連結性相結合,能為用戶帶來近乎完美的隱私。

其中一種原語是私密資訊檢索 (PIR),它允許客戶端從伺服器託管的資料庫中檢索一條分錄,而伺服器無法得知哪個分錄被訪問。一種常見構造(基於 FHE,儘管還有其他構造)的直觀原理是:客戶端的查詢被加密,伺服器處理加密查詢以產生加密響應——只有客戶端可以解密結果。

PIR 是實現模糊數據訪問的幾種方法之一,其他方法包括結合 ORAM 的受信任執行環境 (TEE+ORAM),這類方法通過硬體隔離和隱藏訪問模式來實現模糊性。TEE+ORAM 在實踐中比 PIR 快幾個數量級,但它依賴於對硬體的信任——具體來說,是信任 TEE 未被破解。我們專注於 PIR,因為它僅依賴於密碼學保證,而不依賴於硬體的可獲得性與信任。

本文提出了一個設計草圖,探討如何利用各種 PIR 方案(各有權衡)來服務不同切片的以太坊數據(各有特性),並應用於不同的使用情境(對延遲敏感度不同)。通過這種分片方法,我們可以獲得與對所有以太坊數據使用單一單體 PIR 引擎相同的隱私保證,同時保持針對每個使用情境量身定制的更好整體性能。

將以太坊數據拆分為 S 個分片,每個分片由針對其類型和訪問要求定制的 PIR 引擎提供服務,用戶查詢感興趣的引擎,但同時也向所有其他引擎提交誘餌查詢。這在隱私保護上等同於用戶向一個服務於全部鏈上數據的單體 PIR 引擎提交單個查詢。

2. 需求

  • 狀態讀取的客戶端可驗證性是一項要求,這決定了 PIR 切片如何提取。例如,我們假設存儲讀取將被驗證,因此每次存儲讀取時,我們還必須讀取帳戶、Merkle 根和區塊頭。

  • 「全有或全無」需求:如果除了(例如)getProof 之外的所有以太坊數據都受到 PIR 保護,那麼查詢未加密的數據就會「暴露」對加密數據的其他查詢,從而危害整體隱私。因此,必須保護所有用戶查詢的隱私。

  • 向後兼容以太坊 RPC:PIR 引擎的查詢對用戶是透明的,用戶繼續使用現有的以太坊 RPC 規範查詢以太坊狀態。對於以太坊節點也是如此,它們無需修改即可響應來自同步 PIR 引擎的 RPC 調用。

  • 我們僅專注於單伺服器 PIR,以避免協調非共謀方帶來的開銷。

3. 以太坊數據分片

3.1 使用情境

檢查在各種情境下查詢的區塊鏈數據類型(下圖)可以發現,幾乎所有類型的數據在所有情境中都會被查詢。

當我們考慮錢包和前端查詢背後的常見意圖時,這就很合理了:

  • 我的餘額是多少? \rightarrow 狀態 (帳戶標頭 (ETH) 或合約存儲 (ERC* 代幣))

  • 我是否收到了 ERC20 轉帳,或者我的 DeFi 存款是否成功 (cTokens) \rightarrow 收據 (Receipts)

  • 我的交易是否已確認/最終確定? \rightarrow 區塊交易

  • 此地址的交易歷史是什麼? \rightarrow 存檔(歷史)區塊交易,且指定的 blockNumber 早於最近的 128 個區塊。

    讀取相關的 RPC 調用 (點擊查看更多細節)

3.2 以太坊狀態的數據切片

對 PIR 性能影響最大的因素是:

  • 資料庫大小

  • 更新頻率。

另一方面,某些用戶查詢非常頻繁且對延遲敏感:

  • 我的餘額是多少?

  • 我的匯入或匯出交易是否已被包含

而其他查詢則頻率較低且/或對延遲較不敏感:

  • 我的交易歷史是什麼:通常隱藏在錢包的多次點擊或前端的分頁/進一步點擊之後。

  • 我能否獨立驗證我的餘額:驗證中依賴於內部(非數值)節點的部分,可以容忍由輕客戶端在後台運行。

  • 我的餘額變動歷史是什麼:用於資產組合或會計目的。前者對於資產組合前端可能對延遲敏感,並且由於此類數據源自「巨大(Huge)」數據集(見下文)而代表一項挑戰。對於會計 dApp,這可以容忍高延遲,因為用戶習慣於會計/稅務計算需要較長時間。

考慮到這些不同的數據類型(例如可變 vs 僅追加)和情境:

下圖顯示了以太坊活動狀態和歷史狀態的一個切片示例,旨在根據此類頻率和敏感度指標進行隔離。

當我們考慮到我們可以修剪掉大量「死」狀態(例如 nonce 為 1 的古老帳戶、僅為了 Gas 退稅而部署的「垃圾」合約(在 SELFDESTRUCT 被去勢之前的時代)、已創建但從未被訪問的合約等)時,下面切片中的估算值可能會有所波動:

總體而言,上圖中的切片涵蓋了以太坊執行層(EL)的所有熱數據和存檔狀態數據。

「中型(Medium)」和「大型(Large)」切片特別具有挑戰性,因為它們體積龐大且頻繁變動。這可以通過按狀態樹的每一層進一步進行「水平」切片來適應。

「巨大(Huge)」數據集中的高更新頻率是指每個區塊向存檔狀態追加新的快照。這可以通過 5.2 節討論的主引擎+邊車設計,以及 8.4 節討論的存檔狀態潛在 SNARK 化來解決。

4. 私密資訊檢索 (PIR)

簡介部分所述,PIR 是本文關注的私密讀取原語。

兩個範圍說明:

  • 對稱 PIR (SPIR) 額外向客戶端隱藏資料庫內容——僅顯示被查詢的分錄。由於以太坊數據本質上是公開的,資料庫隱私在此並非需求,因此 SPIR 不在討論範圍內。

  • 關鍵字 PIR (Keyword PIR)。標準 PIR 是基於索引的:客戶端通過其想要的分錄的數值索引進行查詢。關鍵字 PIR 允許通過鍵(例如以太坊地址)而非索引進行查詢,重要的是,其性能取決於資料庫的大小,而非關鍵字空間的大小。存在一種通過布穀鳥雜湊(cuckoo hashing)將索引 PIR 轉換為關鍵字 PIR 的通用變換。在實踐中,關鍵字 PIR 是更自然的介面——用戶通過地址查詢並接收餘額,而不是通過行號——因此在本文的其餘部分,我們簡稱為「PIR」,並默認關鍵字 PIR 是預期的訪問模式。

4.1 分類法

PIR 方案在許多維度上都有所不同——通信成本、單次查詢計算量等。我們在此根據其狀態架構進行分類:狀態存在於何處(客戶端、伺服器或兩者),以及它是如何建立的。這為為特定應用選擇合適方案提供了一個清晰且實用的視角。

客戶端無狀態 (Client-stateless) 方案要求客戶端在查詢之間不存儲任何內容。所有預處理都在伺服器端完成。當資料庫更新時,客戶端不受影響——僅伺服器重新進行預處理。在此類別中:

  • 伺服器有狀態 (Server-stateful) 方案(例如 SealPIR、MulPIR、Spiral、Respire、VIA-C)要求伺服器緩存每個客戶端的密碼學材料,如 FHE 評估密鑰。伺服器的存儲空間隨客戶端數量增長,且每次查詢必須與正確的密鑰匹配——這使得來自同一客戶端的查詢在不同對話中具有可連結性,即使使用洋蔥路由等網路層隱私技術隱藏了客戶端的 IP。此類方案中的資料庫預處理成本通常極低(例如僅進行 FHE 明文編碼)。

  • 伺服器無狀態 (Server-stateless) 方案(例如 HintlessPIR、YPIR、InsPIRe、VIA)完全不需要每個客戶端的狀態。伺服器將資料庫預處理成一個所有客戶端共享的結構。這是運作上最簡潔的類別。權衡之處在於:與伺服器有狀態方案相比,預處理成本往往更高,且在線通信量通常更大。然而,在此類別的前沿方案中,單次查詢的伺服器計算量通常表現更好。

客戶端有狀態 (Client-stateful) 方案要求客戶端下載或計算源自資料庫內容的「提示」(hints)。這些提示可以實現更快、更低通信量的在線查詢——但當資料庫更新時,提示會過時並必須刷新,這需要伺服器與客戶端之間的通信。子分類取決於提示生成期間的通信方向:

  • 下載提示 (Download-hint) 方案(例如 SimplePIR、DoublePIR):提示生成僅限於伺服器→客戶端。伺服器計算提示材料並廣播;客戶端下載並本地存儲。

  • 交互式提示 (Interactive-hint) 方案(例如 Piano、RMS24、Plinko):提示生成需要客戶端↔伺服器通信。通常,客戶端流式傳輸整個資料庫並將其壓縮成較小的提示。這是最繁瑣的設置,但在實用方案中,它是唯一實現次線性(伺服器不必觸及資料庫中的每個分錄)在線伺服器時間的方案——其擴展速度慢於資料庫大小。(原則上,客戶端在提示生成中的角色可以封裝在 FHE 下並委託給伺服器,但目前這在實踐中似乎過於昂貴。)

4.2 運作特性

類別子類別伺服器端每客戶端狀態預處理成本 (伺服器)預處理成本 (客戶端)可連結性示例
客戶端無狀態伺服器有狀態評估密鑰等極小 (FHE 打包)SealPIR, MulPIR, Spiral, Respire, VIA-C
伺服器無狀態中等 (客戶端共享)HintlessPIR, YPIR, InsPIRe, VIA
客戶端有狀態下載提示通常無中等 (客戶端共享)中等 (下載提示)SimplePIR, DoublePIR
交互式提示通常無中等 (每客戶端)通常沉重 (流式傳輸全庫)通常否Piano, RMS24, Plinko

4.3 性能基準對比

下圖顯示了一組 PIR 方案示例以及用於探索其性能權衡的典型指標:

**

更多基準測試

5. PIR 系統架構

5.1 分片

以太坊的邏輯切片具有不同的消費者特徵和情境,體積大小不一,且可能是熱數據且可變,或冷數據且不可變。

我們將這些數據屬性與 PIR 性能權衡相結合,構建一個自定義的分片私密讀取後端,該後端隱藏在穩定的介面(不受更換引擎/數據集的影響)之後,供不同的客戶端接入:錢包 [SDK]、前端、dApp 和節點。

關鍵觀察:考慮一個維護 k 個資料庫 d_1, d_2, \ldots, d_k 的伺服器。客戶端希望訪問其中一個資料庫(例如 d_i),同時隱藏其正在訪問哪一個。為此,客戶端按某種順序發出 k 個查詢 q_1, q_2, \ldots, q_k。查詢 q_i 是針對 d_i 的真實 PIR 查詢,而其餘查詢 { q_j }{j \ne i} 是誘餌查詢。每個查詢 q_j 落在託管資料庫 d_j 的引擎 n_j 上;每個引擎獨立處理其查詢並向客戶端返回響應。在這種構造下,產生的隱私保證等同於將 { q_1, \ldots, q_k } 中的一個或多個提交給託管整個資料庫 D = \bigcup{j=1}^{k} d_j 的單個引擎。當查詢並行處理時,這種方法具有性能優勢:如果目標資料庫 d_i 相對較小,與對整個資料庫 D 應用單體 PIR 相比,客戶端可以以更低的延遲獲得所需的響應。此外,在某個資料庫 d_j 顯著大於其他資料庫的情況下,總通信成本和總伺服器工作量仍與單體方法相當。

    安全說明:定時側信道
 [(點擊查看更多細節)](https://ethresear.ch/t/sharded-pir-design-for-the-ethereum-state/24552/1)

5.2 處理資料庫更新

(預處理)PIR 中的一個核心矛盾:伺服器和/或客戶端投入大量的預先工作——伺服器可能在資料庫上預計算數據結構,客戶端可能流式傳輸整個資料庫以將其處理成緊湊的提示——以實現快速、低通信的在線查詢。當底層資料庫發生變動時,這些預計算的結構和提示就會過時,必須重新推導。對於以太坊來說,狀態樹每 ~12 秒變化一次,如果預處理針對整個數據集,這是難以承受的。

我們根據資料庫的更新特性對其進行分類,並為每種情況提出架構策略。

更新問題的維度

我們從兩個維度描述每個資料庫的更新特性:

  • 更新頻率(相對於資料庫大小)。更新發生時重新預處理的成本有多高?小型資料庫或更新罕見的資料庫可以簡單地重新運行預處理;大型且每個區塊都更新的資料庫則不行。

  • 流失率 (Churn ratio)。每次更新中被修改的資料庫比例。僅追加數據(日誌、交易、收據)是低流失率的一種特殊情況——添加新分錄但不更改現有分錄。

這些維度產生了三種情況:

情況 1:每次更新的重新預處理成本較低

每次更新重新運行預處理不是主要問題。

這涵蓋了體積較小(無論頻率如何,重新預處理都很便宜)或體積較大但很少變動(重新預處理不頻繁)的資料庫。

以太坊示例大小更新頻率為何適用
合約字節碼從不小 + 不可變
最新區塊頭每個區塊足夠小,每區塊重新預處理很便宜
存檔狀態快照從不 (歷史)一旦最終確定即不可變

架構: 直接預處理。每次更新時重新預處理——這在經濟上是可行的,因為資料庫要麼很小(每次重新運行很便宜),要麼更新不頻繁(很少重新運行)。不需要特殊的更新機制。

情況 2a:更新頻率相對於資料庫大小較高,高流失率

無法避免重新運行預處理。盡量降低其成本。

當資料庫很大、更新頻繁且每次更新有很大比例的分錄發生變化時,增量方法幾乎無法節省成本——大多數提示無論如何都會失效。這種情況在以太坊中很少見(即使在峰值負載下,狀態流失也僅佔總樹的一小部分),但在其他領域可能會出現。

關鍵約束:避免使用客戶端有狀態 PIR 方案。 如果重新預處理不可避免且頻繁,客戶端依賴的預處理會加重雙方的負擔:客戶端必須在每次更新時重新完成其預處理工作,伺服器必須為每個客戶端重新完成每客戶端工作。兩者在高更新頻率下擴展性都很差。

情況 2b:更新頻率相對於資料庫大小較高,低流失率

這包括僅追加的情況。使用帶有延遲重新預處理的邊車架構。

資料庫很大且更新頻繁,但每次更新只有很小比例的分錄發生變化。現有提示大多仍然有效——我們只需要處理更新的分錄。

以太坊示例大小更新頻率流失率為何適用
活動狀態樹每個區塊低 (數十億個鍵中約數千個)大資料庫,頻繁更新,極小變更集
交易、日誌、收據每個區塊低 (僅新分錄)大資料庫,頻繁追加,無變動
Blobs每個區塊低 (僅新分錄)同上,且具有有限保留期

5.3 架構 — 邊車模式 (Sidecar pattern)

主 PIR 引擎託管大部分數據,並在某個參考快照處進行預處理。一個小型邊車 PIR 引擎託管自上次快照以來發生更改的鍵的完整更新分錄。為了回答查詢,客戶端並行查詢兩者:

  • 主引擎用於基礎快照(使用預處理提示——快速、低通信)。

  • 邊車引擎用於更新的分錄(資料庫很小,因此即使是非預處理方案在此也很便宜)。

由於邊車持有完整值,客戶端可以在邊車響應到達後立即使用它——如果查詢的鍵已更新,答案是自包含的,客戶端無需等待主引擎。只有當鍵在邊車中不存在時,客戶端才回退到主引擎的響應。

定期(延遲地——例如每 E 個區塊,或當邊車增長超過閾值時),邊車的分錄會併入主資料庫並重新運行預處理。然後重置邊車。關鍵屬性:重新預處理在後台以寬鬆的速度進行,不在每次更新的關鍵路徑上。 邊車吸收了實時更新壓力。在合併期間,舊的主引擎繼續服務查詢,同時構建新的預處理版本。一旦就緒,客戶端切換過來,邊車重置以僅累積自新快照以來更新的分錄。

對於僅追加資料庫,邊車甚至更簡單:它僅持有新分錄。主引擎的提示永遠不會失效,因此重新預處理主引擎純粹是為了吸收邊車累積的分錄,以保持邊車體積微小。

安全說明:**

重新預處理在各個資料庫之間必須保持一致——如果客戶端重新預處理了一個資料庫而沒有預處理另一個,這種差異可能會洩露它真正目標的是哪一個。

6. PIR 方案選擇

第 4 節中的分類法根據結構屬性對 PIR 方案進行了分類。下面的決策樹將其反轉:給定資料庫及其消費者的特徵,哪一組方案最合適?

7. 通用 PIR 介面

在以太坊情境下,任何 PIR 系統都必須適應兩個現實:

  • 邊緣端(錢包、前端、dApp 等)必須能夠繼續使用與現在完全相同的以太坊 RPC 調用來表達其查詢。

  • PIR 後端必須能夠持續演進而不影響邊緣端:更換方案、更改數據切片、更改鍵到索引的適配器等。

挑戰在於建立一個中間件,通過清晰的抽象來滿足這兩個要求,使得任何一方的更改都不會影響另一方。中間件本身應該只感知一個抽象的 PIR 介面,該介面由每個 PIR 方案(引擎)具體實現。

一種可行的方法:

  • 定義一個固定的 GraphQL Schema,因為以太坊狀態的結構和語義基本不變(特別是在 UBT 升級之後)。

  • 實現一個位於規範 RPC 處理邏輯和 Schema 之間的客戶端適配器。在實際操作中,這將封裝客戶端現有的 RPC 處理邏輯。

關鍵考量:

  • 適配器在邊緣端如何以及在哪裡集成。一個吸引人的選擇是在少數錢包 SDK 中(前端也會集成這些 SDK),這樣眾多集成的邊緣客戶端就無需承擔任何負擔。

  • 如何處理需要客戶端依賴預處理的 PIR 方案,以及預處理邏輯和相關存儲如何與適配器緊密耦合。

下圖勾勒了一個粗略的設計(細節留待以後的文章討論)。

8. 持續研究與優化

8.1 用於 Merkle 樹的 PIR
(點擊查看更多細節)

8.2 可驗證的 UBT > MPT (點擊查看更多細節)

8.3 隔離可變性 (點擊查看更多細節)

8.4 將存檔狀態 SNARK 化以減小資料庫體積 (點擊查看更多細節)

8.5 在交互式提示方案中委託提示生成
(點擊查看更多細節)

8.6 具體高效的 DEPIR
(點擊查看更多細節)

9. 資源

https://ethresear.ch/t/sharded-pir-design-for-the-ethereum-state/24552