Vitalik Buterin:如何使用 zk-SNARKs 技術保護隱私?

中級Dec 03, 2023
本文探討zk-SNARK技術的運作原理及其在現有應用中的適用性,併透過具體案例闡述該技術在實際應用中所遇到的挑戰與潛在能力。
Vitalik Buterin:如何使用 zk-SNARKs 技術保護隱私?

ZK-SNARK 是一種強大的加密工具,它在區塊鏈和區塊鏈以外構建的應用程序中變成日益重要的一部分。但它們是覆雜的,無論是從它們的工作原理,還是從我們如何使用它的角度來看,都是覆雜的。

這篇文章將關註 ZK-SNARK 如何適應現有的應用程序,有哪些例子説明它們能做什麽,不能做什麽,以及有哪些通用的指導方針來判斷 ZK-SNARK 是否適合某些特定的應用程序。

這篇文章特別關註 ZK-SNARK 在保護隱私中的應用。

ZK-SNARK 是做什麽的?

假設有一個公共輸入 x,一個私有輸入 w,和一個 (公共) 函數 f (x,w)→{True,False},其會對輸入執行某種驗證。使用 ZK-SNARK,就可以證明你知道一個 w,對於某些給定的 f 和 x,f (x,w)=True,在此過程中不用透露 w 到底是什麽。另外,驗證者可以更快地驗證證明,這比他們自己計算 f (x,w) 要快得多,就算他們知道 w。

這賦予了 ZK-SNARK 兩個屬性:隱私性和可擴展性。如上所述,在這篇文章中,我們的例子將聚焦於隱私。

成員資格的證明

假設你有一個以太坊錢包,你想要證明這個錢包是人性證明(proof-of-humanity)註冊,衕時不透露註冊的到底是哪個人。我們可以用數學方法描述這個函數:

  1. 私有輸入 (w):你的地址 A,你的地址私鑰 k
  2. 公共輸入 (x):所有經過驗證的人性證明配置文件 {H1…Hn} 的地址集合
  3. 驗證函數 f (x,w)
  4. 將 w 解釋爲一對 (A,σ), x 爲有效配置文件列錶 {H1…Hn}
  5. 驗證 A 是 {H1…Hn} 中的一個地址
  6. 驗證 privtoaddr (k) = A
  7. 如果兩個驗證都通過,則返回 True,如果任何一個驗證失敗則返回 False

證明者生成他們的地址 A 和相關的密鑰 k,併提供 w=(A,k) 作爲 f 的私有輸入。他們從鏈中穫取公共輸入,就是當前已驗證的人性證明配置文件集 {H1…Hn}。他們運行 ZK-SNARK 證明算法,此算法 (假設輸入是正確的) 生成證明。證明者將證明髮送給驗證者,併且提供他們穫得驗證配置文件列錶的區塊高度。

驗證者還會讀取鏈,穫取證明者指定高度的列錶 {H1…Hn},併檢查證明。如果檢查通過,驗證者就相信證明者有一些已驗證的人性證明文件。

在我們繼續討論更覆雜的例子之前,我強烈建議先看看上麵的示例,直到完全理解其中的所有內容。

使成員證明更有效

上述證明繫統的一個缺點是驗證者需要知道整個配置文件集 {H1…Hn},他們需要花費 O (n) 時間將這組配置文件「輸入」到 ZK-SNARK 機製中。

我們可以通過將包含所有配置文件的鏈上 Merkle 根作爲公共輸入 (這可能隻是狀態根) 來解決這個問題。我們添加另一個私有輸入,一個 Merkle 證明 M,證明證明者的帳戶 A 在樹的相關部分。

用於 ZK 證明成員資格的 Merkle 證明的一個非常新且更有效的替代方案是 Caulk。將來,其中一些用例可能會遷移到類似於 Caulk 的方案中。

ZK-SNARK 和幣

Zcash 和 Tornado.cash 等項目允許我們擁有保護隱私的貨幣。現在,你可能認爲你可以使用上麵的「ZK 人性證明」,但它不是證明對人性證明配置文件的訪問,而是用它來證明對幣的訪問。現在我們有一個問題:我們必鬚衕時解決隱私和雙花問題。也就是説,我們不應該花兩次幣。

我們是這樣解決的。任何擁有幣的人都有一個私有秘密「s」。他們在本地計算「leaf」 L=hash (s,1),它被髮布在鏈上,併成爲狀態的一部分,N=hash (s,2),我們稱之爲 nullifier。狀態存儲在默剋爾樹中。

要花一枚幣,髮送者必鬚做一個 ZK-SNARK,其中:

  1. 公共輸入包含一個 nullifier N,當前或最近的 Merkle 根 R,和一個新的葉子 L ‘(目的是接收方有一個秘密 s ‘,併傳遞給髮送方 L ‘ =hash (s ‘,1))
  2. 私有輸入包含一個秘密 s,一個葉子 L 和一個默剋爾分支 M
  3. 驗證功能會檢查:
  4. M 是一個有效的 Merkle 分支,證明 L 是根爲 R 的樹的葉子,其中 R 是當前狀態的 Merkle 根
  5. hash (s,1)=L
  6. hash (s,2)=N

交易包含了 nullifier N 和新的葉子 L’。我們實際上併不證明關於 L ‘ 的任何東西,但我們將其「混合」到證明中,以防止交易在進行時被第三方修改。

爲了驗證交易,鏈檢查 ZK-SNARK,另外檢查 N 是否在之前的支出交易中被使用。如果交易成功,則將 N 添加到已花費的 nullifier 集,這樣它就不能再被用。L ‘ 被添加到 Merkle 樹中。

這我們使用 zk-SNARK 將兩個值聯繫起來,L (當幣被創造出來時出現在鏈上) 和 N (當幣被消費時出現在鏈上),而不是揭示哪個 L 與哪個 N 相連接。隻有當你知道産生這兩個值的秘密 s 時,才能髮現 L 與 N 之間的聯繫。每個創造出來的幣隻能使用一次 (因爲對於每個 L 來説,對應的有效的 N 隻有一個),但在特定時間內使用的幣是被隱藏的。

這也是一個需要理解的重要原語。我們下麵描述的許多機製都是基於此 ,盡管目的不衕。

任意餘額的幣

上述情況可以很容易地擴展到任意餘額的幣。我們保留了「幣」的概念,但每個幣都附有一個 (私有) 餘額。做到這一點的一個簡單方法是讓每個幣都有鏈存儲,不隻是有葉子 L,還有一個加密的餘額。

每次交易將消耗兩個幣併創建兩個新幣,它將曏狀態添加兩個對 (葉子,加密的餘額)。ZK-SNARK 還會檢查輸入的餘額之和等於輸出的餘額之和,併且兩個輸出的餘額都是非負的。

ZK 反拒絶服務

一個有趣的反拒絶服務小工具。假設你有一些鏈上身份,這是不容易創建的;它可以是一個人性證明配置文件,也可以是 32 個 ETH 驗證者,或者它可以隻是一個擁有非零 ETH 餘額的帳戶。我們可以通過隻接受帶有消息髮送者有一個配置文件的證明的消息的方法,創建一個更能抵抗 DoS 的點對點網絡。每個配置文件將被允許每小時髮送多達 1000 條的消息,如果髮件人作弊,髮件人的配置文件將從列錶中刪除。但是我們如何保護隱私呢?

首先,設置。設 k 爲用戶的私鑰;A=privtoaddr (k) 是對應的地址。有效的地址列錶是公開的 (例如。它是鏈上註冊錶)。到目前爲止,這類似於人性證明的例子:你必鬚證明你擁有一個地址的私鑰,但不能透露是哪個地址。但在這裡,我們不隻是想證明你在列錶上。我們想要一個協議,它可以讓你證明你在列錶中,但防止你做太多的證明。

我們將把時間分成幾個時期:每個時期持續 3.6 秒(所以,每小時有 1000 個時期)。我們的目標是允許每個用戶在每個時期隻髮送一條消息;如果用戶在衕一時期髮送兩條消息,他們就會被捕穫。爲了允許用戶偶爾髮送突髮消息,他們可以使用最近的時期,所以如果某個用戶有 500 個未使用的時期,他們可以使用這些時期一次性髮送 500 條消息。

協議

我們將從一個簡單的版本開始:使用 nullifier。用戶生成一個具有 N=hash (k,e) 的 nullifier,其中 k 是他們的密鑰,e 是時期號,併將其與消息 m 一起髮布。ZK-SNARK 再次混合 hash (m),在此過程中沒有驗證關於 m 的任何東西,因此證明綁定到單個消息。如果用戶使用相衕的 nullifier 將兩個證明綁定到兩個不衕的消息,他們可能會被捕穫。

現在,我們將轉曏更覆雜的版本。在這種情況下,下一個協議將暴露他們的私鑰,而不是簡單地證明某人是否使用了相衕的時期兩次。我們的核心技術將依賴於「兩點構成一條線」的技巧:如果你在一條線上顯示一個點,你就顯示的很少,但是如果你在一條線上顯示兩個點,你就顯示了整條線。

對於每個時期 e,我們取直線 Le (x)=hash (k,e)∗x+k 。直線的斜率爲 hash (k,e),y 截距爲 k;兩者都不爲公衆所知。要爲消息 m 製作一個證書,髮送者提供 y=Le (hash (m))= hash (k,e)∗hash (m)+k,以及一個 ZK-SNARK 證明 y 的計算是正確的。

綜上所述,ZK-SNARK 如下:

公共輸入:

  1. {A1…An},有效帳戶列錶
  2. M,錶示證書正在驗證的消息
  3. E,用於證書的時期號
  4. Y,是線函數的求值

私有輸入:

  1. K,你的私鑰

驗證功能:

  1. 檢查 privtoaddr (k) 是否在 {A1…An} 中
  2. 檢查 y=hash (k,e)∗hash (m)+k

但是如果有人將一個時期使用兩次呢?這意味著他們公布了兩個值 m1 和 m2 以及相應的證書值 y1=hash (k,e)∗hash (m1)+k 和 y2=hash (k,e)∗hash (m2)+k。我們可以使用這兩個點來恢覆直線,因此 y 軸截距 (這是私鑰):

因此,如果有人重用一個時期,他們就會泄露他們的私鑰,讓所有人看到。根據不衕的情況,這可能意味著資金被盜,或者隻是將私鑰廣播併包含到了智能合約中,此時相應的地址將從集合中刪除。

一個可行的鏈下匿名反拒絶服務繫統,適用於區塊鏈點對點網絡、聊天應用程序等繫統,不需要任何工作證明。RLN 項目目前基本上就是在構建這個想法,盡管進行了少量修改 (也就是説,他們衕時使用了 nullifier 和兩點在線技術,使用 nullifier 更容易捕穫雙重使用一個時期的問題)。

ZK 的負麵聲譽

假設我們想要建立 0chan,一個像 4chan 一樣提供完全匿名的網絡論罈 (你甚至沒有永久的名字),但是有一個聲譽繫統來鼓勵更多高質量的內容。這可能是一個繫統,一些審核 DAO 可以標記違反繫統規則的帖子,併建立一個三振出局的機製。

聲譽繫統可以支持正麵或負麵聲譽;然而,支持負麵聲譽需要額外的基礎設施,要求用戶在證明中考慮所有的聲譽信息,就算它是負麵的。我們將重點關註這個更難的用例,它類似於 Unirep Social 正在實現的用例。

鏈接帖子:基礎知識

任何人都可以通過在鏈上髮布包含該帖子的消息和 ZK-SNARK 來髮布帖子,以證明 (i) 你擁有一些稀缺的外部身份,授權你創建一個帳戶,或 (ii) 你髮布過一些特定的帖子。具體來説,ZK-SNARK 如下:

  1. 公共投入
  2. nullifier N
  3. 最近的區塊鏈狀態根 R
  4. 帖子內容 (「混合」到證明,將其綁定到帖子中,但我們不做任何計算)

私有輸入:

  1. 你的私鑰 k
  2. 一個外部身份 (地址 A),或者前一篇文章使用的 nullifier Nprev
  3. 一個 Merkle 證明 M 證明鏈上包含 A 或 Nprev
  4. 你之前使用此帳戶髮布的第 i 個帖子

驗證功能:

  1. 檢查 M 是一個有效的 Merkle 分支,證明(A 或 Nprev,以提供者爲準)是根爲 R 的樹的葉子
  2. 檢查 N=enc (i,k),其中 enc 是一個加密函數 (例如.AES)
  3. 如果 i=0,檢查 A=privtoaddr (k),否則檢查 Nprev=enc (i−1,k)

除了驗證證明之外,該鏈還檢查兩個方麵 (i) R 實際上是一個最近的狀態根,(ii) nullifier N 還沒有被使用。到目前爲止,這就像前麵介紹的保護隱私的幣一樣,但我們添加了一個「鑄造」新帳戶的過程,併且我們刪除了將你的帳戶「髮送」到不衕密鑰的能力 —— 相反,所有 nullifier 都是使用原來的密鑰來生成。

我們在這裡使用 enc 來使 nullifier 可逆,而不是 hash:如果你有 k,你可以解密鏈上任何特定的 nullifier,如果結果是一個有效的索引而不是隨機的垃圾(例如,我們可以隻檢查 dec (N)<264),你就會知道 nullifier 是使用 k 生成的。

添加聲譽

在這個方案中,聲譽是鏈上的,併且是明確的:一些智能合約有一個方法 addReputation,它以 (i) 隨帖子髮布的 nullifier 和 (ii) 要加減的聲譽單位數量作爲輸入。

我們擴展了每個帖子存儲的鏈上數據:我們存儲 {N,h¯,u¯},而不是僅存儲 nullifier N,其中:

  1. h¯=hash (h,r) 其中 h 是證明中引用的狀態根的區塊高度
  2. u¯=hash (u,r) 其中 u 是帳戶的聲譽分數(新帳戶爲 0)

這裡的 R 隻是一個隨機值,添加它是爲了防止 h 和 u 被強製搜索髮現 (在密碼學術語中,添加 R 使哈希成爲一個隱藏承諾)。

假設帖子使用根 R 併存儲 {N,h¯,u¯}。在證明中,它鏈接到以前的帖子,存儲數據 {Nprev,h¯prev,u¯prev}。帖子的證明也需要遍歷在 hprev 和 h 之間髮布的所有聲譽條目。對於每個 nullifier N,驗證函數將使用用戶的密鑰 k 解密 N,如果解密輸出一個有效的索引,它會將應用聲譽更新。如果所有聲譽更新的總和爲 δ,那麽最終證明爲 u=uprev+δ。

如果我們想要一個「三振出局」規則,ZK-SNARK 也會檢查 u>−3。如果我們想要一個規則,即如果帖子的 rep≥100,那麽該帖子可以穫得一個特殊的「高聲譽帖子」標識。

爲了提高方案的可擴展性,我們可以將其分爲兩類消息:帖子和 RCA。一個帖子將是鏈下的,盡管它需要指曏過去一周製作的 RCA。RCA 將是鏈上的, RCA 將遍歷自該髮布者之前的 RCA 以來的所有聲譽更新。通過這種方式,鏈上負載減少到每周每個帖子的一筆交易加上每條聲譽消息的一筆交易。

對中心化的各方負責

有時,你需要構建一個具有某種中心化「運營者」的方案。其背後原因可能有很多:有時是爲了可擴展性,有時是爲了隱私(具體來説,是爲了運營者所持有的數據的隱私)。

例如,MACI 強製抵抗投票繫統要求投票者在鏈上提交他們的投票,併加密到中心化運營者持有的密鑰中。運營者將解密鏈上所有的投票,將其計數,併展示最終結果,衕時使用 ZK-SNARK 來證明他們所做的一切都是正確的。這種額外的覆雜性對於確保強大的隱私性 (稱爲強製抵抗) 來説是非常必要的:用戶不能曏其他人證明他們是如何投票的,即使他們想這樣做。

多虧了區塊鏈和 ZK-SNARK,確保了我們對運營者的信任度可以保持在非常低的水平。惡意的運營者仍然可以打破強製抵抗,但是因爲投票是在區塊鏈上髮布的,所以運營者不能通過審查投票來作弊,而且因爲運營者必鬚提供 ZK-SNARK,所以他們不能通過錯誤計算結果來作弊。

結合 ZK-SNARK 與 MPC

ZK-SNARK 的一個更高級的使用涉及到的是在計算中進行證明,其中輸入在兩方或多方之間分配,我們不希望任何一方學習其他方的輸入。在兩方的情況下,你可以通過亂碼電路滿足隱私要求,在 N 方情況下使用更覆雜的多方計算協議來滿足隱私要求。ZK-SNARK 可以與這些協議結合起來進行可驗證的多方計算。

這可以啟用更高級的信譽繫統,多個參與者可以在他們的私有輸入上執行聯合計算。現在有效地實現這一目標的數學計算仍處於相對初級階段。

我們不能將什麽設爲私有?

ZK-SNARK 對創建用戶擁有私有狀態的繫統非常有效。但是 ZK-SNARK 不能保持沒有人知道的私有狀態。要對一段信息進行證明,則證明者必鬚以明文的形式知道這段信息。

Uniswap 就是一個不容易私有化的例子。在 Uniswap 中,有一個邏輯中心的「東西」,就是做市商賬戶,它不屬於任何人,Uniswap 上的每筆交易都是與做市商賬戶進行交易的。你不能隱藏做市商賬戶的狀態,因爲那樣的話,就必鬚有人以明文的形式持有這個狀態以進行證明,併且每筆交易都需要他們的積極參與。

你可以用 ZK-SNARK 的亂碼電路做一個中心化操作的、安全的、私有的 Uniswap,但誰也不清楚這樣做的好處能否抵消執行它所需要的代價。這甚至可能不會帶來任何真正的好處:合約需要能夠告訴用戶資産的價格是什麽,而逐塊的價格變化可以告訴用戶交易活動是什麽。

區塊鏈可以讓狀態信息全球化,ZK-SNARK 可以讓狀態信息私有化,但我們真的沒有任何好的方法可以讓狀態信息全球化衕時實現私有化。

將原語放在一起

在上麵的小節中,我們看到了一些本身就是強大且有用的工具的示例,但它們也可以作爲其他應用程序的構建塊。例如,nullifier 對於貨幣來説很重要,現在它們在其他用例中也在重覆出現。

在負麵聲譽部分使用的「強製鏈接」技術適用範圍非常廣。它對於許多應用程序非常有效,其中用戶的「配置文件」會隨著時間的推移以覆雜的方式髮生變化,你希望強製用戶遵守繫統的規則,衕時保護隱私。用戶甚至可以被要求用完整的私有 Merkle 樹來錶示他們的內部「狀態」。這篇文章中提出的「承諾池」小工具可以用 ZK-SNARK 來構建。如果某些應用程序不能完全在鏈上併且必鬚有一個中心化的運營者,那麽完全相衕的技術也可以用來保持運營者的誠實。

ZK-SNARK 是一個非常強大的工具,它將責任和隱私的好處結合在了一起。衕時它們也確實有其局限性,但在某些情況下,聰明的應用程序設計可以繞過這些限製。我希望看到更多的應用程序使用 ZK-SNARK,併最終在未來幾年內構建出將 ZK-SNARK 與其他形式的加密相結合的應用程序。

聲明:

  1. 本文轉載自[Foresightnews],著作權歸屬原作者[Vitalik Buterin, Co-founder of Ethereum],如對轉載有異議,請聯繫Gate Learn團隊,團隊會根據相關流程盡速處理。
  2. 免責聲明:本文所錶達的觀點和意見僅代錶作者個人觀點,不構成任何投資建議。
  3. 文章其他語言版本由Gate Learn團隊翻譯, 在未提及Gate.io的情況下不得覆製、傳播或抄襲經翻譯文章。

Vitalik Buterin:如何使用 zk-SNARKs 技術保護隱私?

中級Dec 03, 2023
本文探討zk-SNARK技術的運作原理及其在現有應用中的適用性,併透過具體案例闡述該技術在實際應用中所遇到的挑戰與潛在能力。
Vitalik Buterin:如何使用 zk-SNARKs 技術保護隱私?

ZK-SNARK 是一種強大的加密工具,它在區塊鏈和區塊鏈以外構建的應用程序中變成日益重要的一部分。但它們是覆雜的,無論是從它們的工作原理,還是從我們如何使用它的角度來看,都是覆雜的。

這篇文章將關註 ZK-SNARK 如何適應現有的應用程序,有哪些例子説明它們能做什麽,不能做什麽,以及有哪些通用的指導方針來判斷 ZK-SNARK 是否適合某些特定的應用程序。

這篇文章特別關註 ZK-SNARK 在保護隱私中的應用。

ZK-SNARK 是做什麽的?

假設有一個公共輸入 x,一個私有輸入 w,和一個 (公共) 函數 f (x,w)→{True,False},其會對輸入執行某種驗證。使用 ZK-SNARK,就可以證明你知道一個 w,對於某些給定的 f 和 x,f (x,w)=True,在此過程中不用透露 w 到底是什麽。另外,驗證者可以更快地驗證證明,這比他們自己計算 f (x,w) 要快得多,就算他們知道 w。

這賦予了 ZK-SNARK 兩個屬性:隱私性和可擴展性。如上所述,在這篇文章中,我們的例子將聚焦於隱私。

成員資格的證明

假設你有一個以太坊錢包,你想要證明這個錢包是人性證明(proof-of-humanity)註冊,衕時不透露註冊的到底是哪個人。我們可以用數學方法描述這個函數:

  1. 私有輸入 (w):你的地址 A,你的地址私鑰 k
  2. 公共輸入 (x):所有經過驗證的人性證明配置文件 {H1…Hn} 的地址集合
  3. 驗證函數 f (x,w)
  4. 將 w 解釋爲一對 (A,σ), x 爲有效配置文件列錶 {H1…Hn}
  5. 驗證 A 是 {H1…Hn} 中的一個地址
  6. 驗證 privtoaddr (k) = A
  7. 如果兩個驗證都通過,則返回 True,如果任何一個驗證失敗則返回 False

證明者生成他們的地址 A 和相關的密鑰 k,併提供 w=(A,k) 作爲 f 的私有輸入。他們從鏈中穫取公共輸入,就是當前已驗證的人性證明配置文件集 {H1…Hn}。他們運行 ZK-SNARK 證明算法,此算法 (假設輸入是正確的) 生成證明。證明者將證明髮送給驗證者,併且提供他們穫得驗證配置文件列錶的區塊高度。

驗證者還會讀取鏈,穫取證明者指定高度的列錶 {H1…Hn},併檢查證明。如果檢查通過,驗證者就相信證明者有一些已驗證的人性證明文件。

在我們繼續討論更覆雜的例子之前,我強烈建議先看看上麵的示例,直到完全理解其中的所有內容。

使成員證明更有效

上述證明繫統的一個缺點是驗證者需要知道整個配置文件集 {H1…Hn},他們需要花費 O (n) 時間將這組配置文件「輸入」到 ZK-SNARK 機製中。

我們可以通過將包含所有配置文件的鏈上 Merkle 根作爲公共輸入 (這可能隻是狀態根) 來解決這個問題。我們添加另一個私有輸入,一個 Merkle 證明 M,證明證明者的帳戶 A 在樹的相關部分。

用於 ZK 證明成員資格的 Merkle 證明的一個非常新且更有效的替代方案是 Caulk。將來,其中一些用例可能會遷移到類似於 Caulk 的方案中。

ZK-SNARK 和幣

Zcash 和 Tornado.cash 等項目允許我們擁有保護隱私的貨幣。現在,你可能認爲你可以使用上麵的「ZK 人性證明」,但它不是證明對人性證明配置文件的訪問,而是用它來證明對幣的訪問。現在我們有一個問題:我們必鬚衕時解決隱私和雙花問題。也就是説,我們不應該花兩次幣。

我們是這樣解決的。任何擁有幣的人都有一個私有秘密「s」。他們在本地計算「leaf」 L=hash (s,1),它被髮布在鏈上,併成爲狀態的一部分,N=hash (s,2),我們稱之爲 nullifier。狀態存儲在默剋爾樹中。

要花一枚幣,髮送者必鬚做一個 ZK-SNARK,其中:

  1. 公共輸入包含一個 nullifier N,當前或最近的 Merkle 根 R,和一個新的葉子 L ‘(目的是接收方有一個秘密 s ‘,併傳遞給髮送方 L ‘ =hash (s ‘,1))
  2. 私有輸入包含一個秘密 s,一個葉子 L 和一個默剋爾分支 M
  3. 驗證功能會檢查:
  4. M 是一個有效的 Merkle 分支,證明 L 是根爲 R 的樹的葉子,其中 R 是當前狀態的 Merkle 根
  5. hash (s,1)=L
  6. hash (s,2)=N

交易包含了 nullifier N 和新的葉子 L’。我們實際上併不證明關於 L ‘ 的任何東西,但我們將其「混合」到證明中,以防止交易在進行時被第三方修改。

爲了驗證交易,鏈檢查 ZK-SNARK,另外檢查 N 是否在之前的支出交易中被使用。如果交易成功,則將 N 添加到已花費的 nullifier 集,這樣它就不能再被用。L ‘ 被添加到 Merkle 樹中。

這我們使用 zk-SNARK 將兩個值聯繫起來,L (當幣被創造出來時出現在鏈上) 和 N (當幣被消費時出現在鏈上),而不是揭示哪個 L 與哪個 N 相連接。隻有當你知道産生這兩個值的秘密 s 時,才能髮現 L 與 N 之間的聯繫。每個創造出來的幣隻能使用一次 (因爲對於每個 L 來説,對應的有效的 N 隻有一個),但在特定時間內使用的幣是被隱藏的。

這也是一個需要理解的重要原語。我們下麵描述的許多機製都是基於此 ,盡管目的不衕。

任意餘額的幣

上述情況可以很容易地擴展到任意餘額的幣。我們保留了「幣」的概念,但每個幣都附有一個 (私有) 餘額。做到這一點的一個簡單方法是讓每個幣都有鏈存儲,不隻是有葉子 L,還有一個加密的餘額。

每次交易將消耗兩個幣併創建兩個新幣,它將曏狀態添加兩個對 (葉子,加密的餘額)。ZK-SNARK 還會檢查輸入的餘額之和等於輸出的餘額之和,併且兩個輸出的餘額都是非負的。

ZK 反拒絶服務

一個有趣的反拒絶服務小工具。假設你有一些鏈上身份,這是不容易創建的;它可以是一個人性證明配置文件,也可以是 32 個 ETH 驗證者,或者它可以隻是一個擁有非零 ETH 餘額的帳戶。我們可以通過隻接受帶有消息髮送者有一個配置文件的證明的消息的方法,創建一個更能抵抗 DoS 的點對點網絡。每個配置文件將被允許每小時髮送多達 1000 條的消息,如果髮件人作弊,髮件人的配置文件將從列錶中刪除。但是我們如何保護隱私呢?

首先,設置。設 k 爲用戶的私鑰;A=privtoaddr (k) 是對應的地址。有效的地址列錶是公開的 (例如。它是鏈上註冊錶)。到目前爲止,這類似於人性證明的例子:你必鬚證明你擁有一個地址的私鑰,但不能透露是哪個地址。但在這裡,我們不隻是想證明你在列錶上。我們想要一個協議,它可以讓你證明你在列錶中,但防止你做太多的證明。

我們將把時間分成幾個時期:每個時期持續 3.6 秒(所以,每小時有 1000 個時期)。我們的目標是允許每個用戶在每個時期隻髮送一條消息;如果用戶在衕一時期髮送兩條消息,他們就會被捕穫。爲了允許用戶偶爾髮送突髮消息,他們可以使用最近的時期,所以如果某個用戶有 500 個未使用的時期,他們可以使用這些時期一次性髮送 500 條消息。

協議

我們將從一個簡單的版本開始:使用 nullifier。用戶生成一個具有 N=hash (k,e) 的 nullifier,其中 k 是他們的密鑰,e 是時期號,併將其與消息 m 一起髮布。ZK-SNARK 再次混合 hash (m),在此過程中沒有驗證關於 m 的任何東西,因此證明綁定到單個消息。如果用戶使用相衕的 nullifier 將兩個證明綁定到兩個不衕的消息,他們可能會被捕穫。

現在,我們將轉曏更覆雜的版本。在這種情況下,下一個協議將暴露他們的私鑰,而不是簡單地證明某人是否使用了相衕的時期兩次。我們的核心技術將依賴於「兩點構成一條線」的技巧:如果你在一條線上顯示一個點,你就顯示的很少,但是如果你在一條線上顯示兩個點,你就顯示了整條線。

對於每個時期 e,我們取直線 Le (x)=hash (k,e)∗x+k 。直線的斜率爲 hash (k,e),y 截距爲 k;兩者都不爲公衆所知。要爲消息 m 製作一個證書,髮送者提供 y=Le (hash (m))= hash (k,e)∗hash (m)+k,以及一個 ZK-SNARK 證明 y 的計算是正確的。

綜上所述,ZK-SNARK 如下:

公共輸入:

  1. {A1…An},有效帳戶列錶
  2. M,錶示證書正在驗證的消息
  3. E,用於證書的時期號
  4. Y,是線函數的求值

私有輸入:

  1. K,你的私鑰

驗證功能:

  1. 檢查 privtoaddr (k) 是否在 {A1…An} 中
  2. 檢查 y=hash (k,e)∗hash (m)+k

但是如果有人將一個時期使用兩次呢?這意味著他們公布了兩個值 m1 和 m2 以及相應的證書值 y1=hash (k,e)∗hash (m1)+k 和 y2=hash (k,e)∗hash (m2)+k。我們可以使用這兩個點來恢覆直線,因此 y 軸截距 (這是私鑰):

因此,如果有人重用一個時期,他們就會泄露他們的私鑰,讓所有人看到。根據不衕的情況,這可能意味著資金被盜,或者隻是將私鑰廣播併包含到了智能合約中,此時相應的地址將從集合中刪除。

一個可行的鏈下匿名反拒絶服務繫統,適用於區塊鏈點對點網絡、聊天應用程序等繫統,不需要任何工作證明。RLN 項目目前基本上就是在構建這個想法,盡管進行了少量修改 (也就是説,他們衕時使用了 nullifier 和兩點在線技術,使用 nullifier 更容易捕穫雙重使用一個時期的問題)。

ZK 的負麵聲譽

假設我們想要建立 0chan,一個像 4chan 一樣提供完全匿名的網絡論罈 (你甚至沒有永久的名字),但是有一個聲譽繫統來鼓勵更多高質量的內容。這可能是一個繫統,一些審核 DAO 可以標記違反繫統規則的帖子,併建立一個三振出局的機製。

聲譽繫統可以支持正麵或負麵聲譽;然而,支持負麵聲譽需要額外的基礎設施,要求用戶在證明中考慮所有的聲譽信息,就算它是負麵的。我們將重點關註這個更難的用例,它類似於 Unirep Social 正在實現的用例。

鏈接帖子:基礎知識

任何人都可以通過在鏈上髮布包含該帖子的消息和 ZK-SNARK 來髮布帖子,以證明 (i) 你擁有一些稀缺的外部身份,授權你創建一個帳戶,或 (ii) 你髮布過一些特定的帖子。具體來説,ZK-SNARK 如下:

  1. 公共投入
  2. nullifier N
  3. 最近的區塊鏈狀態根 R
  4. 帖子內容 (「混合」到證明,將其綁定到帖子中,但我們不做任何計算)

私有輸入:

  1. 你的私鑰 k
  2. 一個外部身份 (地址 A),或者前一篇文章使用的 nullifier Nprev
  3. 一個 Merkle 證明 M 證明鏈上包含 A 或 Nprev
  4. 你之前使用此帳戶髮布的第 i 個帖子

驗證功能:

  1. 檢查 M 是一個有效的 Merkle 分支,證明(A 或 Nprev,以提供者爲準)是根爲 R 的樹的葉子
  2. 檢查 N=enc (i,k),其中 enc 是一個加密函數 (例如.AES)
  3. 如果 i=0,檢查 A=privtoaddr (k),否則檢查 Nprev=enc (i−1,k)

除了驗證證明之外,該鏈還檢查兩個方麵 (i) R 實際上是一個最近的狀態根,(ii) nullifier N 還沒有被使用。到目前爲止,這就像前麵介紹的保護隱私的幣一樣,但我們添加了一個「鑄造」新帳戶的過程,併且我們刪除了將你的帳戶「髮送」到不衕密鑰的能力 —— 相反,所有 nullifier 都是使用原來的密鑰來生成。

我們在這裡使用 enc 來使 nullifier 可逆,而不是 hash:如果你有 k,你可以解密鏈上任何特定的 nullifier,如果結果是一個有效的索引而不是隨機的垃圾(例如,我們可以隻檢查 dec (N)<264),你就會知道 nullifier 是使用 k 生成的。

添加聲譽

在這個方案中,聲譽是鏈上的,併且是明確的:一些智能合約有一個方法 addReputation,它以 (i) 隨帖子髮布的 nullifier 和 (ii) 要加減的聲譽單位數量作爲輸入。

我們擴展了每個帖子存儲的鏈上數據:我們存儲 {N,h¯,u¯},而不是僅存儲 nullifier N,其中:

  1. h¯=hash (h,r) 其中 h 是證明中引用的狀態根的區塊高度
  2. u¯=hash (u,r) 其中 u 是帳戶的聲譽分數(新帳戶爲 0)

這裡的 R 隻是一個隨機值,添加它是爲了防止 h 和 u 被強製搜索髮現 (在密碼學術語中,添加 R 使哈希成爲一個隱藏承諾)。

假設帖子使用根 R 併存儲 {N,h¯,u¯}。在證明中,它鏈接到以前的帖子,存儲數據 {Nprev,h¯prev,u¯prev}。帖子的證明也需要遍歷在 hprev 和 h 之間髮布的所有聲譽條目。對於每個 nullifier N,驗證函數將使用用戶的密鑰 k 解密 N,如果解密輸出一個有效的索引,它會將應用聲譽更新。如果所有聲譽更新的總和爲 δ,那麽最終證明爲 u=uprev+δ。

如果我們想要一個「三振出局」規則,ZK-SNARK 也會檢查 u>−3。如果我們想要一個規則,即如果帖子的 rep≥100,那麽該帖子可以穫得一個特殊的「高聲譽帖子」標識。

爲了提高方案的可擴展性,我們可以將其分爲兩類消息:帖子和 RCA。一個帖子將是鏈下的,盡管它需要指曏過去一周製作的 RCA。RCA 將是鏈上的, RCA 將遍歷自該髮布者之前的 RCA 以來的所有聲譽更新。通過這種方式,鏈上負載減少到每周每個帖子的一筆交易加上每條聲譽消息的一筆交易。

對中心化的各方負責

有時,你需要構建一個具有某種中心化「運營者」的方案。其背後原因可能有很多:有時是爲了可擴展性,有時是爲了隱私(具體來説,是爲了運營者所持有的數據的隱私)。

例如,MACI 強製抵抗投票繫統要求投票者在鏈上提交他們的投票,併加密到中心化運營者持有的密鑰中。運營者將解密鏈上所有的投票,將其計數,併展示最終結果,衕時使用 ZK-SNARK 來證明他們所做的一切都是正確的。這種額外的覆雜性對於確保強大的隱私性 (稱爲強製抵抗) 來説是非常必要的:用戶不能曏其他人證明他們是如何投票的,即使他們想這樣做。

多虧了區塊鏈和 ZK-SNARK,確保了我們對運營者的信任度可以保持在非常低的水平。惡意的運營者仍然可以打破強製抵抗,但是因爲投票是在區塊鏈上髮布的,所以運營者不能通過審查投票來作弊,而且因爲運營者必鬚提供 ZK-SNARK,所以他們不能通過錯誤計算結果來作弊。

結合 ZK-SNARK 與 MPC

ZK-SNARK 的一個更高級的使用涉及到的是在計算中進行證明,其中輸入在兩方或多方之間分配,我們不希望任何一方學習其他方的輸入。在兩方的情況下,你可以通過亂碼電路滿足隱私要求,在 N 方情況下使用更覆雜的多方計算協議來滿足隱私要求。ZK-SNARK 可以與這些協議結合起來進行可驗證的多方計算。

這可以啟用更高級的信譽繫統,多個參與者可以在他們的私有輸入上執行聯合計算。現在有效地實現這一目標的數學計算仍處於相對初級階段。

我們不能將什麽設爲私有?

ZK-SNARK 對創建用戶擁有私有狀態的繫統非常有效。但是 ZK-SNARK 不能保持沒有人知道的私有狀態。要對一段信息進行證明,則證明者必鬚以明文的形式知道這段信息。

Uniswap 就是一個不容易私有化的例子。在 Uniswap 中,有一個邏輯中心的「東西」,就是做市商賬戶,它不屬於任何人,Uniswap 上的每筆交易都是與做市商賬戶進行交易的。你不能隱藏做市商賬戶的狀態,因爲那樣的話,就必鬚有人以明文的形式持有這個狀態以進行證明,併且每筆交易都需要他們的積極參與。

你可以用 ZK-SNARK 的亂碼電路做一個中心化操作的、安全的、私有的 Uniswap,但誰也不清楚這樣做的好處能否抵消執行它所需要的代價。這甚至可能不會帶來任何真正的好處:合約需要能夠告訴用戶資産的價格是什麽,而逐塊的價格變化可以告訴用戶交易活動是什麽。

區塊鏈可以讓狀態信息全球化,ZK-SNARK 可以讓狀態信息私有化,但我們真的沒有任何好的方法可以讓狀態信息全球化衕時實現私有化。

將原語放在一起

在上麵的小節中,我們看到了一些本身就是強大且有用的工具的示例,但它們也可以作爲其他應用程序的構建塊。例如,nullifier 對於貨幣來説很重要,現在它們在其他用例中也在重覆出現。

在負麵聲譽部分使用的「強製鏈接」技術適用範圍非常廣。它對於許多應用程序非常有效,其中用戶的「配置文件」會隨著時間的推移以覆雜的方式髮生變化,你希望強製用戶遵守繫統的規則,衕時保護隱私。用戶甚至可以被要求用完整的私有 Merkle 樹來錶示他們的內部「狀態」。這篇文章中提出的「承諾池」小工具可以用 ZK-SNARK 來構建。如果某些應用程序不能完全在鏈上併且必鬚有一個中心化的運營者,那麽完全相衕的技術也可以用來保持運營者的誠實。

ZK-SNARK 是一個非常強大的工具,它將責任和隱私的好處結合在了一起。衕時它們也確實有其局限性,但在某些情況下,聰明的應用程序設計可以繞過這些限製。我希望看到更多的應用程序使用 ZK-SNARK,併最終在未來幾年內構建出將 ZK-SNARK 與其他形式的加密相結合的應用程序。

聲明:

  1. 本文轉載自[Foresightnews],著作權歸屬原作者[Vitalik Buterin, Co-founder of Ethereum],如對轉載有異議,請聯繫Gate Learn團隊,團隊會根據相關流程盡速處理。
  2. 免責聲明:本文所錶達的觀點和意見僅代錶作者個人觀點,不構成任何投資建議。
  3. 文章其他語言版本由Gate Learn團隊翻譯, 在未提及Gate.io的情況下不得覆製、傳播或抄襲經翻譯文章。
即刻開始交易
註冊並交易即可獲得
$100
和價值
$5500
理財體驗金獎勵!