為 DApp 提供安全的隨機數技術

maz3r.sol
SATS Community 多鏈社群
8 min readFeb 9, 2024

許多區塊鏈應用需要使用從安全數據源處生成的隨機數。

舉例來說,一個 NFT PFP 系列空投需要為每張 NFT 圖片選擇隨機的屬性組合;鏈上遊戲可能需要在打開寶箱時隨機抽取物品。在這兩種情況下,一個安全的隨機數生成器可以保障用戶在應用程式面前的公平性。這些也僅僅是隨機數的一些可能的應用場景 — — 一般來說,隨機性是解決許多不同類型算法問題的有用工具。

不幸的是,區塊鏈的固有屬性讓生成隨機數的過程並不那麼容易完成。區塊鏈的狀態是根據一組確定性的規則進行發展的,其中每個交易都會在給定其輸入值的情況下生成特定的輸出狀態。這些規則必須是確定性的,因為區塊鏈要求每個驗證器能夠驗證每筆交易的處理過程。如果規則不是確定性的,那麼驗證者就可能會對狀態持不同意見。

區塊鏈上有很多種隨機數的生成方法。本文解釋並分析了其中的一些方法及其優缺點。

參與者

隨機數生成協議通常涉及多個不同的參與者。每個參與者都是協議的參與者或是對生成結果感興趣的人。根據不同的方法,參與者都會涉及不同的子集。可能的參與者有:

Dapp開發者 — — 開發者負責編寫請求並使用隨機數的軟體。儘管開發者通常不會參與到生成隨機數的過程中,但開發者往往希望結果是真正隨機的。例如,一個 NFT 系列的開發者希望能夠確保沒有人可以在 NFT 鑄造協議中作弊,以獲得具有所有稀有屬性的 NFT。

用戶 — — 用戶通過與協議互動以發起隨機數生成請求。例如,用戶可以是鑄造 NFT 的人。

驗證者 — — 許多隨機數生成協議使用來自區塊鏈的輸入數據。區塊鏈的驗證者(或礦工/序列器,視情況而定)可能會對輸入數據有一定的控制權。

服務提供者 — — 許多協議都有一個指定的鏈下服務提供者,負責隨機數生成流程的某些部分。該服務提供者應該是一個中立的第三方,但這需要更複雜的隨機數生成方法來將授予該參與者的信任度最小化。

請注意,一個人可能扮演多個參與者的角色。例如,用戶自身可以在區塊鏈網絡上運行驗證者。這些協議上的許多攻擊向量都是由於多個參與者的秘密合作。

屬性

在我們討論隨機數生成方法之前,我們應該對期望的隨機數生成器屬性有一致的了解。

每個隨機數生成器都分兩個階段運行。首先,在請求階段,用戶向生成器請求一個隨機數。然後,在發布階段,生成器生成隨機數並發布到區塊鏈上。每個階段都需要至少一個區塊鏈交易 — — 在單個交易中安全地生成鏈上隨機數是不可能的。然而,在不同的協議中,每個階段執行的精確計算是不同的。

我們關注的安全屬性主要有三個:

不可預測性 — — 在請求隨機數之前,沒有一個參與者能夠預測隨機數。這個屬性是“隨機”的正式定義。

確定性 — — 在請求隨機數之後,它只有一個可能的值。這個屬性確保了參與者在請求結果後無法影響結果。

活動性 — — 在請求隨機數後,協議運行立即完成。也就是說,請求階段完成與揭示階段完成在同一時刻發生。

關於隨機數生成協議的關鍵問題是:這些屬性在什麼條件下成立?例如,協議可能要求服務提供者保持誠信。這些條件是協議的信任假設。信任假設越少,協議就越安全。

隨機數生成方法

可信第三方

最簡單的隨機數協議是讓一個服務提供者生成隨機數。當用戶請求隨機數時,服務提供者只需在鏈下生成一個隨機數並將其發布回區塊鏈即可。

這種方法非常簡單,但需要強有力的信任假設:參與者必須信任服務提供者的誠實性。服務提供者可以自由選擇隨機數,也有能力中止協議。這些假設可以通過讓服務提供者在一個安全的隔離環境(如 Intel SGX)內進行計算而得到一定程度的改進,然而這樣的隔離環境已經多次被證明它們是不完美的(SgxPectre 攻擊)。

區塊哈希

一個簡單的隨機數生成策略是使用未來區塊的區塊哈希值。隨機數生成請求交易將保存當前(或未來)的區塊數字。然後,網絡驗證者將計算該區塊的區塊哈希。一旦區塊哈希可用,生成器即發布生成交易。

區塊哈希的生成方法簡單,易於在任何區塊鏈上使用。然而,它需要強有力的信任假設:參與者必須信任驗證者的誠實性。驗證器可以進行重新排序或忽略交易來修改區塊哈希值。因此,協議的用戶運行驗證器或與驗證器勾結會帶來潛在的攻擊風險,以確保用戶選擇到有利的隨機數。

可驗證隨機函數(VRF)

之前我們討論的方法的問題主要來自於單個參與者可以影響隨機數的生成結果(從而使其變得可預測)。而可驗證隨機函數(VRF)通過要求多個參與者共同協作影響隨機數生成結果來消除這種攻擊向量。

VRF 是一個函數f_s(x) = (y, p),這個函數的特點是輸出值 y 看起來是隨機的,但它是由輸入值 x 和秘鑰 s 確定計算出來的。此外,該函數還會返回一個證明值 p,任何人都可以通過它來驗證 y 是否是正確的輸出值(這是一個非常簡要的解釋。有關 VRF 的更詳細解釋,請參閱 IETF RFC)。

在區塊鏈上,VRF 通常如下所示。首先,輸入值 x 部分由用戶提供、部分來自區塊哈希。鏈下服務提供者使用密鑰 s 監視區塊鏈上的請求,並提交一個鏈上相應值 (y, p)。發布交易檢查證明值 p 以確保 y 是正確的值,然後進行發布。

VRF 的好處是,它比以前的方法改進了信任假設:用戶、驗證者和服務提供者都必須串通起來才能預測隨機數。VRF 的主要關注點是活動性:參與者必須信任服務提供者不會審查交易。服務提供者可以看到生成的隨機數,並選擇是否將其提交到區塊鏈。例如,一種可能的攻擊可能是:用戶提交一個抛硬幣請求,然後與 VRF 提供者勾結,只有在結果是正面時才完成請求。但是,應用程序開發者可以減輕這些攻擊 — — 特別地,只要用戶不能從發布失敗中獲益,他們就沒有動機執行此攻擊。

VRF 的另一個缺點是密碼學相對複雜且計算密集。大多數區塊鏈無法提供內置的所有必要的密碼學基礎協議,因此發布隨機數可能會消耗大量的 gas 或需要多個交易。

交付-發布

VRF 並不是改善隨機數生成信任假設的唯一方法。另一種方法是在互不信任的雙方之間生成隨機數的交付-發布協議。該協議的基本工作原理如下:

  1. 在請求階段,用戶和服務提供者都會生成一個秘密隨機數。他們都將隨機數的哈希值提交給區塊鏈。這個哈希值稱為交付值。
  2. 在發布階段,用戶和服務提供者都將發布他們的隨機數。每個參與者檢查另一個參與者所發布的數字是否與他們的交付值相符。該步驟完成後,最終的隨機數則是這兩個隨機數的哈希值。對於區塊鏈部署來說,來自請求交易的區塊哈希也可以包含在最後的哈希加密步驟中。

與最初的方法相比,交付-發布協議同樣地改進了信任假設:用戶、驗證者和服務提供者必須全部串通才能預測隨機數。此外,這個協議只使用了簡單的加密技術 — — 它只需要一個哈希函數 — — 所以它很容易實現。然而,該協議有一個與 VRF 類似的活動性問題:用戶或服務提供者中的任何一個立即發布其隨機數都可以中止協議。與 VRF 一樣,應用程序開發者可以使用上述針對 VRF 的相同技術來減輕這種攻擊向量。

請注意,該協議的最基礎實現方式都將需要兩個以上的交易,因為用戶和服務提供者都需要在兩個階段中的每個階段分別發送交易。這個缺點可以通過更複雜的部署方式來解決,這樣的部署方式允許服務提供者預先提交多個隨機數字。Pyth Entropy 就是交付-發布協議的複雜實現。

VRF 和交付-發布協議都允許應用程序開發者以牺牲活動性為代價獲得不可預測性。如果開發者擔心只信任一個服務提供者的風險,他們可以簡單地向。N 個服務提供者請求隨機數,並將結果組合起來。這種方法提高了不可預測性 — — 所有的 N 個提供者都需要協作才能影響結果 — — 但是降低了活動性 — — N 個提供者中的任何一個都可以中止隨機數的發布。但是,請注意,N 個服務提供者中沒有任何單獨的一個知道最終隨機數是什麼,因此它們不能使用該知識來決定什麼時候中止協議。

其他方法

還有其他更高級的方法來生成安全的隨機數。這些方法旨在從上層改進不可預測性/活動性的權衡,這樣就需要 >1 個提供者才能中止協議。其中一種方法是閾值 VRF,其中 VRF 的秘鑰 s 在多個參與者之間進行分片存儲。另一種方法是隨機信標。雖然這些方法確實比上面的方法具有更好的安全性權衡,但對於大多數應用程序來說,它們有些矯枉過正,因為活動性問題可以通過應用程序設計來改善。

結論

本文介紹了幾種在區塊鏈上生成隨機數的方法,并分析了它們的優缺點。如果你正在開發需要安全隨機數生成器的應用,你可以查看 Pyth Entropy 的官方文件

最後,歡迎加入 SATS TG群 討論各種公鏈跟生態!
另外,SATS twitter 也開張了,現在就立即追蹤起來吧!

--

--

maz3r.sol
SATS Community 多鏈社群

Co-Founder of SATS community, SRE engineer @frigatebird-studio