在過去一週(2026/06/01 - 2026/06/07),區塊鏈生態系統中觀察到多起攻擊事件。本週報告重點關注 Zcash Orchard 隱私池中一個關鍵可靠性漏洞的公開披露,該漏洞可能允許不可偵測地偽造 ZEC。目前尚未確認有任何鏈上利用行為,但此次披露引發了緊急網路升級,且 ZEC 價值損失逾 40%。
| 日期 | 事件 | 類型 | 預估損失 |
|---|---|---|---|
| 2026/06/04 | Zcash Orchard | ZK 可靠性漏洞 | 未確認有任何利用行為 |
Web3 最佳安全審計機構
在上線前驗證設計、程式碼與業務邏輯
本週精選:Zcash Orchard 可靠性漏洞
本事件被選為本週精選,因為它是在生產環境中發現的最嚴重 ZK 漏洞之一。一個缺失的電路約束在歷經多次審計後超過四年未被偵測到,最終透過 AI 輔助安全審查才被發現。此漏洞類別(ZK 電路中約束不足的關係)可能存在於任何基於 ZK 電路構建的協議中。
2026 年 6 月 4 日,Zcash 公開披露了其 Orchard 隱私池電路中的一個關鍵可靠性漏洞 [1]。零知識證明電路中缺少一個約束,破壞了防止雙重花費的密碼學綁定,可能允許同一隱私票據在未被偵測的情況下被多次花費。該漏洞自 2022 年 5 月 Orchard 啟動以來便已存在,並於 2026 年 5 月 29 日由安全研究員 Taylor Hornby 透過 AI 輔助審計發現。緊急網路升級(NU6.2)於 2026 年 6 月 3 日修補了該電路。目前未發現任何被利用的證據。
背景
Zcash 是一條以隱私為重點的第一層區塊鏈,其原生代幣為 ZEC。與比特幣所有交易細節均公開可見不同,Zcash 透過零知識證明支援隱私交易,隱藏發送方地址、接收方地址及交易金額。Zcash 擁有多個隱私池,每個隱私池對應其隱私協議的不同世代。Orchard 是最新一代,於 2022 年 5 月隨 NU5 網路升級啟動,並使用 halo2 零知識證明系統 [2] 來驗證交易。當使用者進行隱私交易時,其作為證明者:使用 Orchard 電路構建零知識證明,證明交易有效——他們擁有該票據、nullifier 已正確推導、金額平衡——而不洩露任何私密細節。網路節點充當驗證者,在不查看底層數據的情況下檢查證明。Orchard 電路定義了每個有效證明必須滿足的約束。該漏洞存在於此電路實作中,涉及 Zcash 的四個核心概念:金鑰、地址、票據與 nullifier。
金鑰。 Zcash 的金鑰層次結構比大多數區塊鏈更為複雜。單一花費金鑰(錢包密鑰)衍生出多個子金鑰:ask(花費授權密鑰)、nk(nullifier 衍生金鑰)和 rivk(隨機化器)。由這些金鑰,系統計算出 ak(授權公鑰)和 ivk(傳入查看金鑰,透過 ivk = Commit(ak, nk, rivk))。金鑰 ivk 用於識別和接收傳入資金。
地址。 要建立 Orchard 地址,使用者選擇一個多樣化器 d(一個 11 位元組的值),其決定了多樣化基點 g_d = DiversifyHash(d)。地址為組合 (d, pk_d),其中多樣化傳輸金鑰 pk_d 透過橢圓曲線純量乘法計算得出:pk_d = [ivk] g_d。這意味著地址與使用者的查看金鑰在密碼學上相互綁定。
票據。 票據(Note)是代表已接收資金的資產記錄。為保護隱私,鏈上儲存的不是票據本身,而是票據承諾 cm(對票據內容的密碼學承諾,包含 pk_d、金額及其他數據)。票據鎖定至接收方地址。
Nullifier。 在花費票據時,花費者揭示一個 nullifier nf,由票據數據和 nullifier 金鑰 nk 計算得出:nf = Extract_P([(F_nk(ρ) + ψ) mod p]G + cm)。關鍵安全屬性是每個票據必須恰好產生一個 nullifier。一旦 nullifier 出現在鏈上,對應的票據即被視為永久花費。如果同一票據可以產生不同的 nullifier,它就可以被多次花費而不被任何人察覺。
綁定鏈。 這些概念透過密碼學綁定鏈相互連接:

紅色高亮節點(pk_d、nk)是漏洞破壞綁定鏈的關鍵點:電路必須強制執行 pk_d = [ivk] g_d,將花費者綁定至正確的 ivk,從而綁定至該票據對應的正確 nk。若此綁定被破壞,花費者可以偽造假的 ivk,從而在每次花費時使用不同的 nk。不同的 nk 值為同一票據產生不同的 nullifier,從而實現雙重花費。
電路如何強制執行此綁定。 關係式 pk_d = [ivk] g_d 是一個橢圓曲線純量乘法(Q = [k]P),使用倍加演算法實作。在零知識電路中,驗證者不直接執行該演算法;相反,電路約束每個中間步驟。一個正確的純量乘法電路必須強制執行,除其他事項外,內部迴圈基點等於預期的輸入基點(P_loop = P_input)。若沒有此約束,電路可能證明執行了有效的純量乘法,但使用了錯誤的基點,使整個綁定鏈變得毫無意義。
漏洞分析
該漏洞存在的 ECC 電路組件用於強制執行 pk_d = [ivk] g_d 的純量乘法關係中,其中 Q = pk_d、k = ivk、P = g_d。漏洞程式碼位於 halo2 儲存庫的變基點純量乘法實作中(incomplete.rs L309-L310):
// incomplete.rs(完整原始碼連結如上)
298 for (row, k) in bits.iter().enumerate() {
299 // z_{i} = 2 * z_{i+1} + k_i
...
305 z = region.assign_advice(|| "z", self.z, row + offset, || z_val)?;
306 zs.push(Z(z.clone()));
307
308 // 賦值 `x_p`, `y_p`
309 region.assign_advice(|| "x_p", self.double_and_add.x_p, row + offset, || x_p)?; // BUG
310 region.assign_advice(|| "y_p", self.y_p, row + offset, || y_p)?; // BUG
311
312 // 若位元已設定,使用 `y`;若位元未設定,使用 `-y`
313 let y_p = y_p
314 .zip(k.as_ref())
315 .map(|(y_p, k)| if !k { -y_p } else { y_p });
316
317 // 計算並賦值 lambda1
318 let lambda1 = y_a.zip(y_p).zip(x_a.value()).zip(x_p)
.map(|(((y_a, y_p), x_a), x_p)| (y_a - y_p) * (x_a - x_p).invert());
...
}
在零知識電路中,證明者填入每個單元格的值;電路本身無法在單元格之間複製或傳遞值——它只能定義驗證者所檢查的約束。標記為 BUG 的兩行使用 assign_advice() 將基點座標 x_p 和 y_p(稱為見證值的私密電路輸入)寫入電路的建議欄(證明者的私密輸入區域)。此函數填入值時不會建立將其綁定至外部基點的約束。一個獨立的約束確保基點值在所有迴圈迭代中保持相等——證明者無法在每次迭代中使用不同的基點。然而,證明者可以在所有迭代中替換為單一任意基點,電路中沒有任何約束會拒絕它,因為沒有任何約束將迴圈的基點值錨定至從外部傳入的實際 g_d。
正確的函數是 copy_advice(),它在填入值的同時添加一個等式約束(複製約束),強制其與實際基點 g_d 匹配。由於 g_d 因地址而異(由每個地址的多樣化器衍生),電路無法對其進行硬編碼——它必須約束迴圈的基點與上游計算的 g_d 相匹配。
因此,電路實際上並未強制執行 pk_d = [ivk] g_d。惡意證明者可以在迴圈內部提供任意基點(而非正確的 g_d),電路仍會接受該證明:內部計算在代數上保持自洽,但不再錨定至協議指定的多樣化基點。這個額外的自由度允許證明者每次選擇不同的 nk,計算對應的 ivk = Commit(ak, nk, rivk),並利用未受約束的純量乘法使偽造的 ivk 通過驗證。由於 nullifier 依賴於 nk,每次花費都會產生一個不同的 nullifier:
同一票據 N + nk_1 → nf_1
同一票據 N + nk_2 → nf_2
其中:nf_1 ≠ nf_2
共識機制僅檢查某個 nullifier 是否已出現在鏈上。由於每次花費都產生一個獨特且看似合法的 nullifier,雙重花費對網路而言是不可見的。
修復方案 [3] 在迴圈的第一次迭代(row == 0)中添加了一個 copy_advice() 呼叫,建立一個複製約束,將迴圈的基點錨定至從外部傳入的實際 base。其餘迭代繼續使用 assign_advice(),但現有的迭代間一致性約束將錨點傳播至所有迭代。
影響與回應
利用場景。 惡意證明者可以利用該漏洞多次花費同一 Orchard 票據,每次生成不同的 nullifier。由於零知識證明隱藏了私密電路輸入,欺詐性 nullifier 與合法 nullifier 無法區分。攻擊在鏈上不留下任何確定性的密碼學證據,使得無法確定它是否曾被利用。
該漏洞自 2022 年 5 月 Orchard 啟動(NU5 升級)以來便已存在,總暴露窗口超過四年。Zcash 的轉換閘門計量機制限制了偽造價值從 Orchard 池流入透明或 Sapling 池的數量,限制了對更廣泛供應量的實際影響。然而,偽造票據可能在隱私池內部不被察覺地存在,且其隱私屬性使得無法從密碼學角度證明該漏洞是否曾被利用。
注意:轉換閘門僅在某個池的總流出量超過總流入量時才會觸發。攻擊者可以隨時間分批少量提取偽造價值,而不觸及此限制。只有當合法使用者集體嘗試提取超過池實際持有量時,差異才會顯現。
發現與回應。 該漏洞於 2026 年 5 月 29 日由安全研究員 Taylor Hornby(受 Shielded Labs 委託)使用前一天發布的 Anthropic Opus 4.8 模型的 AI 輔助審計框架發現。此前使用舊版模型對同一電路進行的審計未能發現該漏洞。Hornby 當天向 ZODL 報告了此問題。6 月 2 日(UTC)的緊急軟分叉暫時停用了 Orchard 交易,6 月 3 日(UTC,區塊 3,364,600)的 NU6.2 網路升級引入了修正後的電路,恢復了 Orchard 功能 [1]。6 月 4 日公開披露後,ZEC 價值損失逾 40%,清算金額超過 1 億美元 [4]。
結論
Zcash Orchard 漏洞由純量乘法電路中缺少等式約束引起,允許證明者繞過基點綁定並偽造 nullifier 以實現雙重花費。與傳統智能合約漏洞通常可透過程式碼審查或測試發現不同,ZK 電路中的可靠性漏洞需要理解電路實際證明的內容與其應當證明的內容之間的差距——這一微妙之處逃過了頂級密碼學家長達四年以上的專業審計。
halo2 函式庫在 ZKP 生態系統中被廣泛使用,類似的約束不足關係可能存在於基於這些密碼學構建塊構建的其他項目中。使用零知識證明的協議應實作餘額完整性檢查(例如轉換閘門計量),以限制未發現的可靠性漏洞的潛在影響:若沒有 Zcash 的轉換閘門機制,在隱私池內部創建的偽造價值本可自由流入更廣泛的供應量中。Shielded Labs 已宣布計劃對 Orchard 電路進行正式數學驗證。
此次發現是人機協作工作流程的典型範例:一位經驗豐富的安全研究員構建了審計框架並主導調查,而 AI 則負責廣泛檢查各個電路約束。兩個組成部分單獨都不足以完成任務:此前僅靠 AI 使用舊版模型的運行未能發現該漏洞,而多年的人類專家審查同樣也未能發現。Hornby 本人是 Zcash 安全專家——需要領域專業知識來為 AI 設計正確的審計範疇。正如 BlockSec 最近發布的研究所示 [5],AI 模型在安全分析方面正在快速進步,但仍需專家指引將 AI 引導至正確目標並驗證其發現。專家與 AI 之間的互動協作——而非單獨依賴 AI——是最有效的工作模式。
參考資料
- The Orchard counterfeiting vulnerability and next steps(Orchard 偽造漏洞及後續步驟),Zcash 社區論壇,2026 年 6 月 4 日。連結
- halo2:零知識證明系統,GitHub。連結
- 修復:透過複製約束錨定純量乘法基點,halo2 GitHub。連結
- Why ZEC fell 40% even after Zcash patched a shielded pool bug(為何 Zcash 修補隱私池漏洞後 ZEC 仍下跌 40%),CoinTelegraph,2026 年 6 月 5 日。連結
- Re-Evaluating EVMBench: Are AI Agents Ready for Smart Contract Security?(重新評估 EVMBench:AI 代理是否已準備好應對智能合約安全?),arXiv,2026 年。連結
關於 BlockSec
BlockSec 是一家全棧區塊鏈安全及加密貨幣合規服務提供商。我們構建產品和服務,幫助客戶進行程式碼審計(包括智能合約、區塊鏈及錢包)、即時攔截攻擊、分析事件、追蹤非法資金,以及履行反洗錢/打擊恐怖主義融資義務,覆蓋協議和平台的全生命週期。
BlockSec 已在頂級會議上發表多篇區塊鏈安全論文,報告了多個 DeFi 應用程式的零日攻擊,攔截了多起駭客事件並成功救援逾 2,000 萬美元,並已保護數十億美元的加密貨幣資產。
-
官方 Twitter 帳號:https://twitter.com/BlockSecTeam



