通過保護性資金池追蹤不良資金

本文為機器翻譯
展示原文

通過保護性資金池追蹤不良資金

我想解釋一個看似瘋狂的想法,即通過一個受保護的資金池來追蹤不良資金,同時儘可能地保護隱私。

劇情梗概

邪惡博士竊取了1000億美元,並將其投入到一個隱私協議中。

不知何故,盜竊和存款事件竟然瞞過了一段時間,存款的延遲期限也已過去。錢已經進入系統。私下轉賬隨即展開。沒人能分辨真假鈔票。時局艱難。

最終,有人發現了盜竊行為並拉響了警報。

用戶如何識別餘額中的受汙染票據?我們如何最大限度地保護用戶隱私?我們如何識別受汙染的取款(以及是否應該識別)?

首要目標:使票據持有人能夠確定其票據中有多少來自“不良”存款,而不會向任何人洩露任何其他信息

超高水平

用戶有一張便條。便條中包含用戶無法解密的加密信息,內容是關於構成這張便條的存款信息。

notes[i][j] = {owner,amount,randomness,deposits: [{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},...],}

一切都很舒適私密。

如果過一段時間後,某筆存款被列入黑名單,而這張票據又是該筆“不良”存款的後續存款,那麼用戶就會突然得知這一信息:

notes[i][j] = {owner,amount,randomness,deposits: [{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},{The bad deposit_id,Some fraction to deduce how much of that 'bad' depositis contained within this note,},{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},...],}

然後,用戶可以執行一個名稱頗為引人注目的“淨化電路”,以創建一個不包含此錯誤 deposit_id 的新票據。

注意事項

目前還沒有人讀過這篇文章。

我並不是真的提倡這種方法,但這確實是一個有趣的設計,它試圖解決一個我以前從未見過有人解決的問題。

我可以想到一些強烈的批評意見,這些批評意見貫穿了整部紀錄片(並在結尾處進行了總結)。

它或許可以作為後世的參考資料。

希望您會覺得這本書有趣。 :slight_smile:

引言

如果你想對這個主題有一個非常精彩的介紹,請閱讀Privacy Pools 論文的第一部分和第二部分。

我的總結如下:

有些人希望在區塊鏈上進行交易時注重隱私,因此各個團隊正在探索如何實現私密區塊鏈交易。一種常見的模式如下:

用戶可以將代幣存入所謂的“屏蔽代幣池”。一段時間後,他們可以將代幣提取到另一個地址。此類協議旨在打破存款地址和取款地址之間的可觀測聯繫。

有些協議還支持對存入資金池的代幣進行私密轉賬,這樣一來,旁觀者就無法推斷出是誰向誰發送了什麼。我對這些充值-轉賬-提現協議最感興趣。

所有這些資金池都存在一個問題,那就是不法分子也可以利用它們,事實上,已經發生過不法分子將非法所得資金存入此類資金池的案例。一旦資金存入,追蹤非法存款就變得更加困難,區分合法提款和非法提款也變得更加困難。

因此,各種項目都試圖解決這個問題。

方法包括:

  • 通過引入存款延遲機制,在不良存款進入資金池之前將其識別出來。
  • 限制在一定時期內可以存入資金池的金額。
  • 只接受信譽良好的演員的存款。
  • 允許用戶提供與不良行為者無關的證明,或僅與良好行為者相關的證明。
  • 將每筆交易的詳細信息加密後提供給第三方(例如監管機構、審計師或會計師),或者與第三方共享查看密鑰。
  • 放寬部分隱私保障,以便對資金池中的所有資金進行一定程度的追蹤。

這些方法都有各自的優缺點,我們將在下文中討論。

我一直在琢磨的想法如下:

當向用戶發送一條消息時,該消息將包含一個重新隨機加密的列表,其中包含所有對該消息做出任何貢獻的上游 deposit_ids 的值,以及每個存款對該消息貢獻了多少價值的加密值。

在理想情況下,用戶的筆記不會是任何“不良”存款的後代,在這種情況下,他們的隱私應該與 Zcash 相當:用戶將無法知道哪些存款促成了他們的筆記。

然而,如果一筆存款被公開認定為“不良存款”,則該設計允許所有下游票據持有人瞭解有多少不良存款流入了他們的票據。至關重要的是,除了“我的票據中有 X 筆款項被認為源自這筆不良存款”之外,不會向票據持有人洩露任何其他信息。資金池的觀察者不應獲知任何信息。

理想情況下,不良存款會在進入系統之前就被識別並標記為“不良”,例如通過一定的延遲期。這樣,它就不會有機會“侵蝕”誠實用戶的資金。但如果延遲時間不夠長呢?或者如果盡職調查有所遺漏呢?我認為,探討如何在不洩露用戶交易記錄的情況下,識別那些僥倖通過存款延遲機制的不良資金會很有意思。

補充說明:Railgun 最近確實遇到了這個問題: https://x.com/dethective/status/1994397800847589736?s =20

我們在此過程中會遇到一些可擴展性問題,並探討如何緩解這些問題。


背景

這裡快速回顧一下基於 utxo 的隱私協議,以便統一術語。

如果您願意,可以跳到下一節“現有技術”。

存款

從概念上講,存款看起來大致如下:

圖像
圖片尺寸:3716×1254,114 KB

用戶向系統中存入一些公共代幣,系統會創建一個包含存入數量和所有者(地址或公鑰)信息的憑證。該憑證代表用戶對這些底層代幣的所有權,這些代幣由系統持有在一個資金池中,直到最終所有者選擇提取或轉移部分餘額。

如果您想了解更多細節,這裡有一張更詳細的圖表,展示了存款流程。不同的實現方式在很多細節上有所不同,但核心在於此。

圖像
圖片4158×2906 382 KB

轉賬

從概念上講,轉賬過程大致如下:

圖像
圖片尺寸:3538×1870,大小:206 KB

發送方花費(或“作廢”)兩張票據,為轉賬接收方創建一張票據,併為自己創建一張找零票據。兩張票據被銷燬,兩個作廢票據被髮出,同時創建併發出兩張新票據。

我敢不解釋什麼是無效化項嗎?我想我可以!

啊,實際上,我需要就無效化符說以下幾點,因為這將有助於我在下一節中對一種方法進行批判:

在私密支付協議中,使用無效化符來斷開創建票據的交易與之後花費該票據的交易之間的關聯。如果沒有無效化符提供的這種“交易不可關聯性”,整個交易圖對觀察者都是可見的,用戶可以獲取不應洩露的信息。

本文檔的其餘部分將忽略電路圖中的無效化符,因為它們只會造成混亂。如果您看到某個音符被輸入到電路中,請假定它已被無效化。
另外,為了減少圖表中的混亂,我將忽略圖表中的變更說明:

圖像
圖片尺寸:3164×1662,大小:160 KB

已簡化:不顯示無效符;不顯示變更說明。

提款

從概念上講,提款過程大致如下:

圖像
圖片尺寸:2724×772,大小:63.2 KB

用戶燒燬一張包含一定金額的紙幣,系統(負責保管所有公開存入的資金,用戶在系統內進行私密交易)會將該金額轉移到用戶指定的地址。


現有技術

按照論文的慣例,在深入探討新思想的細節之前,我們必須對所有現有思想進行無情的批判,以證明這份文件的存在是合理的。

但我會溫柔對待你,因為:

  • 現有的想法其實相當不錯,而且已經轉化為具有實際性能指標(PMF)的實際產品。這太棒了。
  • 你永遠無法預知將來是否會和某人共事;
  • 我的想法可能存在缺陷;
  • 即使這個想法沒有缺陷,我也可以想到一些尖銳的批評意見,我會在討論過程中一一提出,而這些批評意見你可能已經在考慮了。

留在我身邊。

所有產品都尋求某種形式的合規私有代幣。有些是簡單的充值提現方案,有些是充值轉賬提現方案。它們本質上都遵循“背景”部分概述的方法,但在應對惡意行為者方面採取了不同的策略。

佩伊

當你口頭說出這個產品的名字時,你必須說“Pay with two y”,否則別人會一臉茫然。或者你必須說“Payyyyyyy”,並且要非常強調發音。

Payy 是一種存款-轉賬-取款協議。

Payy採取了一種非常務實和簡單的方法來應對不良行為者:他們從協議中移除了無效化器

圖像
圖片尺寸:1910×410,44.8 KB

來源

回顧屏蔽協議的基本原理,無效化器提供了“交易不可鏈接性”。如果沒有無效化器,轉賬交易的輸入備註將公開可見。也就是說,每筆交易的輸出備註都可能被其他交易的輸入備註所取代。這意味著在 Payy 上,整個交易圖都是可觀測的。

圖像
圖片尺寸:1768×940,大小:182 KB

如果系統中出現一筆不良存款,您可以精確追蹤這筆資金的流向,並查看系統中哪些提款源於這筆不良存款。票據的接收者可以立即識別出該票據源於一筆不良存款,儘管他們無法得知該不良存款中有多少資金最終流入了他們的票據。

所以,Payy犧牲了一些隱私來追蹤不法分子。我們來談談這種隱私犧牲的程度。

我能想到的,Payy 的設計會帶來以下幾項隱私洩露問題:

存款後的第一筆轉賬可以被公開識別為來自存款人本人。也就是說,匯款人身份會被洩露。

提款前的最後一筆轉賬是公開可識別的,收款人信息會被洩露。

如果 A 存款,則 A → B(即“A 轉賬給 B”),然後 B 取款,那麼外界就能看到 A 與 B 進行了交易。如果該子圖中沒有其他交易,外界甚至可以得知 A 轉賬給 B 的確切金額。

如果 E → B → C → E,那麼 E 就會得知 B 和 C 有過交易。E 還會得知 B認識C。這洩露的信息量相當大。這種程度的信息洩露,恐怕連婚外情都會曝光。

如果E是一個大型實體,例如交易所,他們或許能夠從這種洩露的信息中推斷出大量的交易圖譜。他們可以拼湊出參與者之間的關係,並有可能推斷出參與者之間的支付金額。

這些是我思考五分鐘後發現的一些蛛絲馬跡。一些技術高超的團隊或許能推斷出更多。

電磁炮

Railgun是一個存款-轉賬-取款協議。非常棒。

所有存款進入系統都有一小時的延遲,以便拒絕“不良”存款。

一旦資金進入系統,用戶之間就可以進行私密轉賬。

問題在於——這也是促使我深入研究並撰寫這篇文章的主要原因——一個小時的時間並不長,理論上來說,不法分子有可能“鑽空子”,將“贓款”存入資金池。一旦資金進入資金池,就很難再抓到他們了。

寫完這些之後補充:事情真的發生了!!!
https://x.com/dethective/status/1994397800847589736?s=20
如果我能在事情發生之前完成這份紀錄片就好了。那樣我就會被認為很有先見之明瞭。

總之,我著手解決通過資金池追蹤“不良”資金的問題,該資金池支持私密轉賬,即使我們在資金進入資金池時並不知道這些資金是否“不良”,同時儘可能地保護所有用戶的隱私。在介紹完其他幾個項目之後,我會更詳細地說明具體要求。

EY區塊鏈

早在 2019 年,我所在的那個小型研究團隊就探索了這個問題:如何設計一個隱私池,既能追蹤不良存款,又能確保良好的隱私。

我記得有一段時間,我們走上了一條顯而易見——現在也眾所周知——的死路:給每張新存入的票據都分配一個 deposit_id。這樣一來,每次轉賬,輸出票據就會包含所有輸入票據的 deposit_id 的並集。這會導致列表呈指數級增長,每次轉賬後列表大小都會翻倍。這種方法不可持續。我想我們當時並沒有公開討論過這個問題。

實際上,我在2019年做過一些公開演講,解決了通過一個受保護的NFT池追蹤被盜NFT這個相對容易的問題。NFT交易的非同質性意味著不會出現列表呈指數級增長的問題。

那支小團隊做了很多超前於時代的研究,但我們沒有發表那些不成熟的想法,現在回想起來真是可惜。

但是……請參閱本文檔後面的內容,我們將嘗試通過偶爾啟動(重置)該列表來解決該問題。

任何追蹤存款ID的方法都普遍受到批評,因為這樣一來,紙幣就失去了可替代性:存款ID變成了紙幣上的標記。人們能夠從他們發送和接收的紙幣中看出規律。

一個簡單的洩露路徑是 Eve->Bob->Eve,或者 Eve->Bob->Charlie->Eve,甚至是 Eve->…->Eve。Eve 能夠發現她發送和接收的筆記中共同的 deposit_id,並可能從中推斷出信息。例如,在 E->B->C->E 的情況下,Eve 可以推斷出 Bob 認識 Charlie,並且 Bob 給 Charlie 匯過款。

這份文檔試圖通過每次轉賬時重新隨機生成 deposit_ids 列表來解決 deposit_ids 作為標記的問題。這樣一來,Eve 就無法識別她發送的筆記和她之後收到的筆記之間的任何共同點。

隱私泳池

Privacy Pools 產品是一種存款取款協議。

我的第一個批評是“它不支持轉賬”,但 Privacy Pools 的論文確實討論了一種可以實現私密轉賬的方法。

在與開發者大會上交流後更新:隱私池 v2 版本似乎支持私密轉賬,但這與隱私池論文中解釋的方法有所不同。以下是我對 v2 版本功能的理解:

每次存款,生成的票據都會包含一個 deposit_id。轉賬可以在系統內進行,但所有輸入的票據必須具有相同的 deposit_id ,並且所有輸出的票據都會被賦予相同的 deposit_id。

這無疑是避免“列表呈指數級增長”問題的巧妙方法:一條筆記始終包含 1 個 deposit_id。

這種方法可能存在以下問題。如果用戶需要發送 100 ETH,他們需要兩張 deposit_id 相同的票據,且兩張票據的金額總和必須大於等於 100。但如果他們沒有兩張 deposit_id 相同的票據怎麼辦?他們需要發送多筆交易,每張票據對應一個不同的 deposit_id。

我懷疑,隨著存款活動的增加,用戶收到包含相同 deposit_id 的票據的情況會變得非常罕見。如果真是如此,用戶將兩張票據合併的情況也會變得非常罕見(因為它們必須具有相同的 deposit_id)。而且我懷疑,這可能會導致系統趨於“臃腫”,票據中的金額會變得非常小且不實用,因為“拆分”操作的次數將遠遠超過“合併”操作的次數。
或許用戶可以互動:潛在的收款人可以向發件人請求包含特定 deposit_id 的便條;有點像紙牌遊戲“釣魚”:“有 deposit_id = 1234 的嗎?”

本文提出的方案旨在實現 deposit_ids 的混合使用。

對 v2 版本方案的另一個批評是——正如前一小節所述——deposit_ids 作為標記會破壞資金的可互換性。本文檔旨在通過在每次轉賬時重新隨機化 deposit_ids 來解決這個問題。

我對隱私資金池的第二個(也是較弱的)批評是,資金存入池子前存在一段不確定的延遲。也許這沒什麼問題,但因為我想探究的是,如果不良資金進入資金池會發生什麼,我不希望答案是“只需等待更長時間進行盡職調查”。我認為盡職調查過程可能會出錯,因此我們希望能夠追溯性地將不良資金標記為不良資金,即使它們是被意外放入的。

隱私池論文中描述的方法如下:

圖像
圖片尺寸:1516×3296 大小:422 KB

一種批評意見認為,這種模式存在過多的信息洩露;而這些信息通常是受保護資金池所希望保密的。在存款最終被列入白名單之前,用戶之間會共享大量私人數據。

空白方格

你可能不相信,但我早在九十月份就開始構思這篇文章了。只是後來忙於其他事情,比如我的日常工作、愉快的家庭旅行以及開發者大會。

然後,在11月下旬的某個星期六,我作為伴侶參加婚禮時,在一個Signal群組裡收到了這個鏈接:

它建議對 deposit_ids 進行加密——這個想法也出現在這份文檔中。英雄所見略同!
總之,我沒有抄襲;它們是對同一事物的獨立詮釋。我有帶時間戳的收據!

這份文檔對這個觀點進行了更深入的闡述,希望您會覺得有趣。它還反駁了對這個觀點的一些批評,我們接下來會談到這些批評。

簡而言之,其思路是讓某個實體為系統中的每一筆存款生成一個新的密鑰對。然後,每個 deposit_id 都可以用其對應的公鑰進行加密。之後,任何相應的提款都會被強制發送相同的加密 deposit_id(該加密後的 deposit_id 會進行加鹽處理,使提款信號看起來與存款無關)。在理想情況下,觀察者永遠不會知道提款與存款有關。但如果之後某筆存款被判定為“不良”,持有解密密鑰的人就可以洩露私鑰,這將使所有觀察者都能解密存款和提款交易的加密 deposit_id,並最終將提款與存款關聯起來。

這種方法存在的問題:

解密密鑰的持有者是系統的一個故障點。如果密鑰洩露(無論是有意還是無意),那麼任何人都能關聯所有用戶的存款和取款記錄。有人建議使用TEE(目標執行環境)或通過MPC(多方計算)節點集合來秘密共享解密密鑰。當然,秘密共享解密密鑰(以及其他秘密)是FHE(全同態加密)和CoSnark(CoSnark加密)中常見的做法,因此有些人可能認為這種做法是可以接受的。

維塔利克顯然不喜歡“剝奪隱私”這種說法:

我在這篇文章中提出的方法仍然需要有爭議的 MPC 集體來生成密鑰,但我試圖大大減少最壞情況下所有解密密鑰洩露造成的損失。

採用 Blanksquare 方法:

  • 最糟糕的情況下,會洩露什麼內容?
    • 每一筆提款都與每一筆存款相關聯。
  • 洩露給了誰?
    • 全世界每個人(每個區塊鏈觀察者)。

本文檔中介紹的方法:

  • 最糟糕的情況下,會洩露什麼內容?
    • 為特定用戶的筆記做出貢獻的 deposit_ids。
    • 每個 deposit_id 對該票據“做出貢獻”的金額。
  • 洩露給了誰?
    • 僅限紙條持有人本人。

洩漏點位於局部地區。

還不錯,對吧?

至少我們還沒有剝奪隱私到讓維塔利克傷心的地步(我希望如此)。

最壞的情況下,本文檔中的協議會簡化為票據所有者可以看到所有參與其票據的 deposit_ids。這並非理想方案(參見前面章節,其中抱怨 deposit_ids 會成為票據上不可互換的“標記”),但我覺得這是一個值得向大家介紹的進步。

在理想情況下,隱私其實相當不錯。

這個想法

最後我們可以討論這個想法了。

要求

它需要哪些功能?

  • 支持私密轉賬的保護資金池。
  • 在正常情況下,存款 ID(在票據中)是隨機化的,以防止高級票據持有者將其用作“標記”來發現活動模式。
  • 如果意外地允許不良存款進入資金池,之後可以將其標記為“不良”,資金池的所有用戶都可以識別:他們的票據是否包含任何“不良”價值,以及他們的票據價值中有多少被認為是“不良”的。
  • 即使在最壞的情況下(即該協議的解密密鑰洩露),區塊鏈觀察者也無法得知哪些票據包含“壞”值。
  • 避免對歷史提款進行追溯性隱私洩露:即使在系統解密密鑰洩露的最壞情況下,該系統也可以設計成不會洩露已發生的提款信息。
  • 在進行轉賬或取款時,用戶可以證明其輸入的票據並非源自“不良”存款。
  • 如果用戶的筆記源自不良存款,用戶可以通過將筆記拆分為“好”筆記和“壞”筆記來“淨化”筆記。
  • 我不保證約束數量。 :slight_smile:

高級

接下來是低層部分。

其基礎是一個簡單的存款-轉賬-取款協議。

某個黑名單維護者維護著一份不良 deposit_ids 黑名單。

存款進入系統可能需要一段時間,但我們感興趣的是能夠捕捉到那些錯過這段延遲期的存款的機制。

在一個龐大的預處理步驟中,生成了一個很長的 deposit_id 密鑰對列表:每個密鑰對對應協議中未來的每一次存款。

[(x_1, Y_1), (x_2, Y_2), ..., (x_{1000000}, Y_{1000000})] [ ( x 1 , Y 1 ) , ( x 2 , Y 2 ) , . , ( x 1000000 , Y 1000000 ) ]

其中x_i私鑰 Y_i公鑰

清單內容不足時,可以定期補充。

這份名單可能由單個參與者生成,但你大概不太喜歡這種說法,所以我們假設這份名單是由一個大型MPC(多方控制)組織生成的。我們稱他們為密鑰持有者。密鑰持有者可能與黑名單維護者是同一人,也可能是不同的實體。我們稍後會再討論這個令人擔憂的問題。

當進行新的存款i i時,它將與公鑰Y_i Y i公開關聯。

預先生成的列表使用戶能夠以非交互方式向協議中存入密鑰,而無需等待密鑰持有者生成和發佈新的公鑰。

我們將使用此公鑰Y_i Y i對信息進行加密。具體來說,此存款“下游”的每一張票據都將包含:

  • deposit_id i i的加密,加密為Y_i Y i ;
  • 對用於支付此票據的存款比例進行加密,加密為Y_i Y i

我們將在後面的章節中慢慢講解技術細節。

由於該系統支持轉賬,一張票據可能源自多筆存款。這沒關係:票據將包含所有上游存款的列表。細心的讀者會注意到,這樣的列表會呈指數級增長,而且是不可持續的——每次轉賬都會使列表翻倍。我們稍後會再討論這個問題。

正常情況下,下游票據的持有者無法解密其票據中包含的加密存款信息,因為沒有人(希望甚至連密鑰持有者集體也不知道)知道解密密鑰x_i 因此他們無法得知哪些存款流入了他們的票據。該系統的目標是儘可能地實現接近 Zcash 的隱私性,即觀察者無法瞭解資金池內部的運作情況,交易圖不可見,價值可互換,票據持有者也無法追蹤其票據的來源。

如果存款i i之後被判定為“不良”,則黑名單維護者會在鏈上標記存款i i 。一旦i i被列入黑名單,密鑰持有者(們)就需要披露對應的鏈上私鑰x_i x i 。如果密鑰持有者是一個 MPC 集體,他們需要共同協作才能瞭解x_i x i 的實際內容,例如通過某種閾值機制。

此次公佈i ix_i x i將引發一系列活動:整個系統中所有紙幣持有者都可以嘗試解密其紙幣中包含的所有加密 deposit_ids。如果他們的紙幣deposit i i的後代,那麼他們將成功解密其紙幣的某個加密 deposit_id 字段,從而得到i i

假設他們的票據確實包含來自存款i 的不良”資金。糟糕!為了瞭解具體金額,還可以使用已揭示的x_i x i來解密票據中相應的“加密部分”。這將揭示票據中包含的原始存款的百分比。

一種名為“淨化電路”的全新功能,將使用戶能夠從票據中“剔除”不良資金。

需要注意的是,票據持有人將無法解密票據中任何其他加密的 deposit_id 字段。票據持有人唯一能獲取到的信息是:

“我的票據是存款i i的‘下游’;協議認為我的票據包含來自該不良存款的 X 金額”。

或者更簡潔地說:

“我的票據中有 X 金額被認為是源自不良存款i i ”。

票據持有人不會了解到票據的任何其他來源信息,包括票據價值在到達他們手中之前經過了哪些人。

外部觀察者不會知道哪些音符被汙染了,也不會了解有關 tx 圖的有意義的信息。

此時此刻,你腦海中可能已經湧現出許多尖銳的批評意見。我們不妨列舉一些:

  • 如果密鑰持有者串通起來,他們就能知道x_i x i的值。
  • 黑名單維護者可能會心懷惡意,通過將人們添加到黑名單中來審查他們。
  • 一旦i i被列入黑名單,密鑰持有者可能不會履行其披露x_i x i的職責。
  • 對於誠實的用戶來說,收到一張無法查看哪些存款構成了這張票據的通知,之後卻發現(在被列入黑名單後)這張票據實際上被一些“不良”價值汙染了,這似乎很不公平。
  • 該協議如何確定每張鈔票中存款的比例?
  • 如果你追蹤存款清單,那麼每次“轉賬”交易都會使存款金額翻倍。這不可持續。

我們稍後會詳細討論這些問題。

步步

設置

在一個龐大的預處理步驟中,生成了一個很長的 deposit_id 密鑰對列表:每個密鑰對對應協議中未來的每一次存款。

[(x_1, Y_1), (x_2, Y_2), ..., (x_{1000000}, Y_{1000000})] [ ( x 1 , Y 1 ) , ( x 2 , Y 2 ) , . , ( x 1000000 , Y 1000000 ) ]

其中x_i私鑰 Y_i公鑰

清單內容不足時,可以定期補充。

稍微正式一點(但符號仍然比較隨意):

G \in \mathbb{G} G G生成點。

x_i \in \mathbb{F} x i F是 deposit_id i i的密鑰,在群\mathbb{G} G的標量域中。

Y_i := x_i \cdot G Y i : = x i G deposit_id i i對應的公鑰。

訂金

用戶存入一定金額作為存款i i的一部分。該存款與公鑰Y_i Y i相關聯。

系統會創建一個新筆記,其中包含以下數據:

notes[i][1] = {owner,amount,randomness,deposits: [{encrypted_deposit_id = "i" ,encrypted_fraction = "1" ,},{},...{}],}

在哪裡:

我們有時會使用符號"x"來表示“值x的加密”。

encrypted_deposit_id = "i" = \text{enc}_{Y_i}(i) enc Y i ( i ) ,是 deposit_id i i的加密,使用公鑰Y_i Y i進行加密。
該加密方案必須支持密文的重新隨機化。Elgamal 是一個不錯的選擇(參見附錄)。

encrypted_fraction = "1" = \text{enc}_{Y_i}(1) enc Y i ( 1 ) ,表示流入此票據的存款部分的加密,最初是1 1的加密。
這種加密方案必須支持密文與已知標量進行標量乘法運算。稍後我們會解釋原因。Paillier 加密是一個不錯的選擇,但在 Snark 電路中效率很低(參見附錄)。

圖表時間到!

圖像
圖片尺寸:2976×1824,133 KB

enc_dep_id_i_j是存款i經過jth跳轉(轉賬)後的“加密 deposit_id”。
enc_frac_i_j是存款i的價值中對本票據做出貢獻的“加密分數”(從存款經過jth轉賬後)。
用戶實際上看不到j ;這只是為了幫助圖表閱讀者。
Paillier 加密並非一成不變;顯然,對於密文與已知標量的乘法運算,還有效率更高的替代方案。
請注意,我使用引號是為了便於閱讀和偷懶: "x"表示“ x的加密”。

轉移

例子

私人轉賬會銷燬兩條備註,併為收款人創建一條備註,為付款人創建一條找零備註。(為簡潔起見,我們忽略找零備註。)

假設我們最初存入 5 個 ETH 的存款人想要向某人發送 1.5 個 ETH。

假設他們除了5 ETH紙幣外,還有一張10 ETH紙幣。

他們可以作廢這兩張價值共計 15 ETH 的票據,並創建一張價值 1.5 ETH 的新票據。

5 ETH 的存款中有多少最終進入了新的 1.5 ETH 紙幣中?10 ETH 的存款中又有多少最終進入了新的 1.5 ETH 紙幣中?

考慮到貨幣的流動性,實際上很難說一筆存款對後續票據的貢獻有多大。這就像試圖弄清楚一勺湯裡有多少番茄一樣。

但是,我們可以採取一種數學上自然的方法,那就是將貢獻視為與輸入的音符成比例。

在我們的例子中,我們可以認為5 * \frac{1.5}{15} = 0.5 5 1.5 15 = 0.5來自 5 ETH 存款, 10 * \frac{1.5}{15} = 1 10 1.5 15 = 1來自 10 ETH 的存款。換句話說,我們可以應用\frac{15}{150} 15 150的一部分。 對兩個輸入存款。

理論上,用戶可以對捐款進行不同的分配:例如,將某個 deposit_id 的所有金額分配到自己的找零中,而完全不分配到預期收款人的找零中。但由於我們的協議會隱藏每張找零中包含哪些 deposit_id(如果 deposit_id 是“有效的”),因此這樣做實際上毫無意義;用戶甚至不知道自己分配了哪些 deposit_id!而且,如果檢測到某個 deposit_id 是“無效的”,還有一個獨立的去汙電路可以將其分離出來。

此圖說明了如何將分數應用於構成特定票據的 deposit_ids:

圖像
圖片4308×3134 337 KB

請注意,我使用引號是為了便於閱讀和偷懶: "x"表示“ x的加密”。

我們可以考慮後續的轉賬,這次轉賬的輸入是這張面值 1.5 ETH 的紙幣。假設我們要轉賬 20 ETH,而另一張輸入的紙幣價值 100 ETH。

接下來,適用於所有為 20 ETH 輸出票據做出貢獻的存款的下一個分數是: \frac{200}{1015} 200 1015

圖像
圖片尺寸:5082×3136,大小:430 KB

圖表中的符號總是很繁瑣。

你可以看到我在那張價值 100 ETH 的紙條裡偷懶用了些符號。例如, enc_frac_3_j = "prod(f_3_j)"表示“對用於生成這張紙條的存款 3 的那部分進行加密”。我們姑且認為,從存款 3 到生成這張紙條,一共進行了j轉賬。

如果你查看 20 ETH 的票據,它應該會開始顯示我們正在跟蹤的存款數據模式。

正在追蹤的 5 ETH 存款數據如下:

deposits: [(enc_dep_id = "1" enc_frac_1_3 = "1 * (15/150) * (200/1015)" ,),

現在,這張 20 ETH 紙幣的持有者實際上無法解密這些密文enc_dep_id_1_3enc_frac_1_3 ,因為他們不知道解密密鑰x_1 x 1

但如果黑名單維護者突然將存款1 1列入黑名單,並且密鑰持有者履行了其職責,導出併發布了x_1 x 1 ,那麼這張 20 ETH 紙幣的持有者將能夠解密密文enc_dep_id_1_3enc_frac_1_3 。(注意:他們仍然無法解密存儲在紙幣中的其他密文,因為每個密文都使用不同的公鑰加密。)

筆記持有者會發現:“哦,我可以用新發布的x_1 x 1解密enc_dep_id_1_3 ,得到1 1 ,這意味著我的筆記被存款1 1中的某些值‘汙染’了。我現在解密enc_frac_1_3 ,得到分數1 * (15/150) * (200/1015) 。我知道存款 1 的金額是多少(因為存款金額是公開的):是 5 ETH。所以我計算5 * (1 * (15/150) * (200/1015)) = 0.098522 ETH 。因此,協議認為我的筆記中有0.098522 ETH來自‘不良’存款1 1。

先別管你腦子裡那些批評的聲音:這很酷,對吧?網絡中數百張票據裡可以存在大量亂碼、難以理解的加密數據,而不會洩露交易圖,然後突然間,一筆存款被列入黑名單,卻能揭示出一小部分有用的信息,而且只有下游票據的持有者才能看到。

帕利耶

我們可以使用 Paillier 加密對分數進行加密,這樣我們就可以在每次未來的轉賬交易中將生成的密文重複乘以一個新的分數,而無需知道生成的分數是多少。

也就是說,如果我給你enc(m) e n c ( m ) ,你可以計算出已知標量k k 的enc(km) e n c ( k m ) ,而無需知道m m是什麼。

請參閱附錄,其中對 Paillier 加密進行了詳盡的解釋。即使不考慮本文檔的其他內容,它本身也非常出色。顯然,使用全同態加密方案在 snark 中實現這種“標量乘法”特性還有更高效的方法。感興趣的讀者可以探索這些方法。 :slight_smile:

回顧我們之前的例子,我們從以下幾點開始:

enc( 1 ) enc ( 1 )

下一個傳輸電路將此密文與一個已知的標量15/150進行標量乘法運算(表示為四捨五入到小數點後 6 位的整數15/150 * 10^6 = 100,000 如果使用Paillier算法運算結果enc(1)^{100000} = enc(1 * 100000) enc ( 1 ) 100000 = enc ( 1 * 100000 ) 紙條的接收者不會知道哪些 deposit_id 流入了紙條,也不會知道每個 deposit_id 分別貢獻了多少比例的金額:他們只會看到新計算出的密文。

下一個傳輸電路將此密文與已知標量200/1015進行標量乘法運算。200 / 1015 (表示為四捨五入到小數點後 6 位的整數,如200/1015 * 10^6 = 197,044 如果使用Paillier算法運算enc(1 * 100000)^{197044} = enc(1 * 100000 * 197044 ) enc ( 1 * 100000 ) 197044 = enc ( 1 * 100000 * 197044 )

解密後,真實分數可推導為1 * 100000 * 197044 / (10^6)^2 = 0.0197044 1 100000 197044 / ( 10 6 ) 2 = 0.0197044

如果解密密鑰被洩露,用戶將能夠解密這個分數並將其應用於原始存款金額(在我們的示例中為 5 ETH),從而發現他們的票據被認為包含0.0197044 * 5 = 0.098522 0.0197044 5 = 0.098522 ETH。

關於示例的一些評論

在我們繼續之前,先提幾點。

分數 → 小數

在圖表中,我們追蹤的是加密分數,但實際上我們並不想這樣做,原因有二:

對分數進行加密,並迭代地乘以新的分數,需要分別對分子和分母進行加密(至少在我熟悉的加密方案中是這樣),這浪費了約束條件。

分數的分子和分母是會漏分的:
分子可以分解,從而推斷出自存款以來每次“轉賬”交易可能轉移的金額。分母可以分解,從而推斷出自存款以來每位中間票據持有人所持有的票據規模。

相反,我們可以將每個分數轉換為小數,然後(至關重要且必要地)將其四捨五入到一定的小數位數。四捨五入會減少通過因式分解可以推斷出的值(尤其是在用戶選擇轉賬金額時,因為由此產生的分數確實需要四捨五入)。

為什麼要對 deposit_ids 進行加密?

假設 Eve 向 Bob 發送消息,Bob 又向 Eve 發送消息(E → B → E)。如果 deposit_ids 沒有加密,那麼 Eve 就會注意到她發送的消息和她收到的消息之間存在相同的 deposit_ids。

更糟糕的是,假設Eve給Bob匯款,Bob再匯給Charlie,Charlie再匯給Eve(E → B → C → E)。如果deposit_ids沒有加密,Eve就會注意到她發給Bob的那張紙條和Charlie發給她的那張紙條的deposit_ids是相同的。Eve可能會推斷出“Bob認識Charlie”和“Bob給Charlie匯過款”之類的信息,甚至可能推斷出他們彼此匯款的金額。這種信息洩露可以通過重新加密deposit_ids來避免。

但是,如果加密的 deposit_ids 在轉賬之間沒有改變,那麼這些密文實際上就成了存款的替代標識符。

這就是為什麼我們每次轉賬都會重新隨機化加密後的 deposit_ids。這樣,每張票據中的 deposit_ids 列表都是一個不同的、看似隨機的數字列表!這也是為什麼 Elgamal 是一種不錯的加密方案選擇。請參閱 Appx 文件,瞭解 Elgamal 和重新隨機化的工作原理。

為什麼要對分數(或小數)進行加密?

這與 deposit_ids 加密的原因類似。

在 tx 圖中多次出現的實體可能會發現其筆記中包含的分數模式,並將 tx 圖拼湊起來,或者做出類似於上述部分的推斷。

糟糕的是,在這個例子中,用戶損失了 0.098522 ETH。

在這個例子中,用戶收到一張紙幣後,其中 0.098522 ETH 的部分被判定為“無效”。該用戶誠實守信,在收到紙幣時並不知道它“無效”。

理想情況下,黑名單的建立應該在系統進行任何轉賬之前完成,例如在存款延遲期間。在這種情況下,所有用戶在任何轉賬發生之前就已經知道惡意存款密鑰x_i 如果惡意用戶試圖將資金轉給誠實用戶,該用戶能夠立即識別出來。

此外,還有一個有趣的值得探討的問題,那就是在現實世界的類似情況下應該發生什麼。

來源
免責聲明:以上內容僅為作者觀點,不代表Followin的任何立場,不構成與Followin相關的任何投資建議。
喜歡
收藏
評論