作者:Pavol Rusnak
原文為作者在 Advancing Bitcoin 2022 大會上的演講的轉錄稿,由 delcin-raj 通過 review.btctranscripts.com 轉錄。
引言
各位好,我是 Pavol Rusnak,在比特幣社區中人們叫我 Stik 。我是 Satoshi Labs 的聯合創始人,我們開發出了 Trezor 硬件簽名器。今天我準備聊聊在硬件簽名器中籤名 CoinJoin 交易的挑戰。
為何需要隱私性?
我們先來講講隱私性有什麼意義。在許許多多的理由中,我認為這些理由是最重要的。
- 自治:隱私性允許個體控制自己的個人信息,讓他們可以作出獨立的選擇和決定。
- 人身安全:隱私性保護個體免於跟蹤、騷擾和身份盜竊這樣的傷害和威脅。
- 表達自由:隱私性鼓勵自由表達和開放溝通。
- 信任:隱私性是構建個體之間和機構之間的信任的前提。
- 平等:隱私性有助於每個人得到平等對等,不論其種族、性別、宗教,等等。
- 民主:隱私性對於保持民主是極為關鍵的,它讓公民可以彼此自由溝通、跟代表自由溝通。
- 創新:通過為個體和公司提供安全的環境來實驗和發展新的理念和技術、無需盜竊和濫用,隱私性鼓勵了創新。
總結一下,隱私性是一種基本的人權,保護著個體的自治、人身安全和自由,同時鼓勵信任、平等、民主和創新。
比特幣中的隱私性
比特幣隱私性的現狀
在比特幣中,交易會被記錄在一條公開的區塊鏈上,可以被任何人跟蹤和分析,甚至可以溯及既往。交易參與者的真實身份並不必然是已知的,但這些身份常常被多種手段關聯起來,比如 IP 地址跟蹤、公開的信息洩露。交易跟身份發生關聯的例子還包括在 Twitter 或 Nostr 的個人簡介裡發佈接收捐贈的地址 地址;如果當事人還重複使用地址,那更是雪上加霜。但這都比不上交易所和他們對客戶的做法危害這麼大。
相關的隱私保護技術有哪些?
- “機密交易” 是其中一種,它會遮掩交易的金額。但我們需要驗證在此過程中比特幣沒有增發(也沒有銷燬)。通常會部署在側鏈上。在比特幣基礎層上,我們還沒有機密交易技術。
- 閃電網絡同樣有助於隱私性,因為區塊鏈只展示開啟通道和關閉通道的交易,不會展示用戶在其中的每一筆交易。
- 有一些服務,比如 Tor 和私人虛擬網絡,可以幫助你隱藏 IP 地址(從而隱藏你的地理位置)。並且將眾多交易關聯起來會變得更難。比如說,在 Tor 上,你可以在發送不同交易時切換不同身份,那麼他們在網絡上會被當成不同的人。
- 當然,CoinJoin 也是其中之一。
CoinJoin
好,那麼什麼是 “CoinJoin”?它是一種加強隱私性、提高比特幣交易匿名性的技術。多個參與者將他們的交易合併在一起(也就是彙集各自的輸入和輸出),然後簽名一筆體積更大的交易。最終的交易讓人更難將輸入和輸出關聯到其各自的主人。CoinJoin 可以比我這裡展示的規模大得多,不過這個例子也足夠形象了。
案例
假設有三個參與者,同意加入同一筆交易,他們有 5 + 3 個輸出(多出來的 3 個是因為要考慮找零輸出)。假設輸入有 3 個。你也許能猜到這些找零輸出分別屬於哪個人。但其它輸出,你就無法斷定了。搞不清楚哪個輸出是這個人的還是那個人的。這裡的關鍵是,創造出同樣面額的輸出。而這些同樣面額的輸出的集群,獲得了我們稱之為 “k-匿名集” 的東西。在這個案例中,這組輸出屬於同一個 k-匿名集,k 是 5 。還是那句話,你猜不出來哪個人擁有哪個輸出。
一次 CoinJoin 的階段
- 輸入登記:每個參與者都在一個協調員處登記自己的輸入。這通常是通過 Tor 往裡來進行的,每個輸入都來自一個 Tor 身份。成功登記輸入之後,協調員會給這個參與者一些東西(我稱之為 “token”),不過它不是密碼貨幣 token 。它可能是,比如說,在 Wasabi 1中是一個盲簽名,在 Wasabi 2 中是一個使用密鑰可以驗證的匿名證書。我不會再講更多細節,重點知識,你得到的這個 token 可以用在第二個階段,也就是輸出登記中。
- 輸出登記:每個參與者都在協調員處登記自己的輸出(又要使用另一個 Tor 身份)。這裡的重點是因為參與者使用的身份不同於他們在輸入登記中使用的身份,所以不會被發現關聯。每一次輸出登記都要消耗一個 token,它是你有權登記特定大小的一個輸出的證據。這個 token 會被 “燒掉”,也就是協調員會將它標記為已經使用。通常,這個 token 也是跟一個 CoinJoin 回合綁定的,不能用在另一個 CoinJoin 回合中。這個設計也很好,因為這個標記清單在本輪 CoinJoin 結束後就可以丟棄,而不會隨時間無限增長。在一些技術中,這些 token 是可以無限期使用的,但那通常是各種 e-cash 實現,比如 Cashu 和 Fedimint 。回到 CoinJoin,這些 token 只能用在本回閤中。
- 簽名:在輸入和輸出都登記完成之後,我們組合出一筆交易、將它發送給每一個參與者,讓他們簽名。我們可以使用不同的身份,但這不是重點。甚至可以使用在第一階段中用過的身份,因為只要你在第一階段登記了輸入,就 100% 確定你會在這個階段簽名同一個輸入。所有參與者都要提供簽名。如果最終組合出來的交易是有效的,那麼這次 CoinJoin 就算成功,而這筆交易會被廣播到網絡中。
在硬件簽名器中籤名 CoinJoin
現狀
那,這關硬件簽名器什麼事呢? 通常來說,如果你要簽名一筆常規交易(不是 CoinJoin),那麼硬件簽名器會在用戶介入下完成簽名。這意味著用戶會確認輸出的地址(也就是輸出的腳本);然後確認輸出的金額和挖礦手續費(通常就是輸入的和減去輸出的和)。這裡有一個星號,是因為,通常,如果硬件簽名器沒有檢測到極高的手續費,就不會詢問用戶。我後面還會再講這一點。
挑戰
對 CoinJoin 交易,我們需要在用戶不介入的前提下完成交易簽名。為什麼呢?
因為我們並不知道什麼時候其他人準備好了簽名、什麼時候我們能進入簽名階段。通常來說,我們都需要參與多輪 CoinJoin 才能成功一次。而我們不想讓用戶坐在電腦前乾等(等上兩天或者更久)。因此,硬件簽名器需要做到多件事。它需要檢查輸入之和是否等於輸出之和再加上一點差額(也就是挖礦手續費、協調員手續費,等等)。困難在於,如何正確地識別哪個輸入是我的、哪個輸出是我的,以及它們的數額。
隔離見證以前的手續費攻擊(偽造輸入金額)
輸入金額之和減去輸出金額之和就是挖礦手續費。但是交易的輸入並不包含任何金額信息。它們包含的僅僅是前序交易的哈希值和輸出的索引號。所以,如果一個攻擊者在輸入的金額上撒謊,那會怎麼樣?比如說,輸入的面額是 10 BTC,卻被謊稱是 1 BTC 。請居住,這是在硬件簽名器上,你只能確認輸出的面額,不能確認輸入的面額。那麼這名用戶會讓 9 BTC 變成交易手續費。
(譯者注:作者這裡的假設是攻擊者篡改了用戶的錢包軟件 —— 在硬件簽名器的語境下,“錢包軟件不可信任” 是一種常見的假設。)
Trezor 如何緩解這種攻擊
所以,在 Trezor 上,我們總是要傳入完整的前序交易,從而,硬件簽名器可以計算被花費的輸入的真實面額。 這有時候會遇到一點小麻煩 —— 你要花費的交易的體積非常大。並且,我說過了,當手續費非常高的時候,Trezor 會顯示一個警告。手續費非常非常高的時候,我們會直接表示出錯。只要手續費低於這個門檻,我們就會讓它通過。
隔離見證 v0 解決這個問題了嗎?
- BIP-143 的簽名也承諾被花費的輸入的金額,這是好事。
- 如果攻擊者在 UTXO 數額上撒了謊,那麼這個簽名直接就是個無效簽名,不會被比特幣網絡認可。
這種解決方案的問題
所以我們這就解決了?並沒有。隔離見證 v0 並沒有完全修復這個問題。為什麼這麼說呢?
假設一個受害者有兩個 BIP-143(隔離見證 v0)UTXO,面額分別為 15 BTC 和 20 BTC。惡意軟件要求用戶確認交易, 這筆交易的第一個輸入是價值 15 BTC 的 UTXO,而其第二個輸入的價值被設定為 5 BTC 加 1 聰;然後用戶選擇輸出和找零輸出(如果有必要的話)。於是用戶確認了交易。但是 TA 之確認了輸出。他們以為自己在花費 20 BTC 加 1 聰。
然後,惡意軟件表示出錯,讓用戶再次確認交易。但這一回,惡意軟件在第一個輸入中使用 1 聰的面額、在第二個輸入中使用 20 BTC 的 UTXO;並傳給硬件簽名器。從用戶的角度看,他們看不到交易的輸入,只能看到輸出。他們以為這跟自己簽名的上一筆交易是同一筆。所以用戶再次確認花費 20 BTC 加 1 聰。
但是實際上,他們花掉了 15 + 20 BTC,因為惡意軟件可以結合這兩個簽名、創造出一筆把兩個 UTXO 都花掉的交易。這意味著 15 BTC 又在不明不白中成了交易手續費。
隔離見證 v1 解決這個問題了嗎?
現在,BIP341(Taproot)的簽名承諾所有輸入的面額。這就很好。所以,交易中的所有簽名的承諾所有輸入的面額。它們也承諾了輸入的腳本。這也很好。這樣攻擊者就無法修改輸入腳本了。那這算是徹底解決了嗎?
問題
你怎麼看呢?不,還沒有。攻擊者依然可以在輸入腳本上撒謊,說這個輸入不屬於這個錢包。然後欺騙硬件簽名器不要將這個輸入考慮在內。然後,你可以執行同樣的兩次簽名、抽取和收集這兩個簽名、然後結合它們。攻擊手法完全一樣。
解決辦法
這個問題是我的同事 Andrew Kozlik 在 2020 年開發 CoinJoin 簽名的時候發現的。他立即提議,BIP341簽名應該承諾所有輸入的腳本,而不僅僅被簽名的這個輸入的腳本。幸運的是,討論發展得很快,所有人都同意應該這樣做。沒有理由不這樣做。所以隔離見證 v1 確實修復了這個問題。隔離見證 v 1 輸入的簽名承諾了前序交易的哈希值、被花費的輸出的索引號、被簽名的數額、交易的所有數額、被簽名的輸入腳本,以及所有的輸入腳本。這就是 CoinJoin 真正受益於 Taproot 的地方。
Taproot 與 CoinJoin
讓簽名承諾所有東西,對於包含外部輸入的自動化交易非常好。比如說,在 CoinJoin 中,攻擊者無法改變輸入的面額和腳本,因為一旦這樣做,整個交易都會因為這個錯誤的簽名而作廢。
所有權證明
不過,我們要澄清的另外一個事情是,攻擊者依然可以扣住一些信息。比如說,一個輸入是否屬於這個錢包。也許攻擊者不想告訴硬件簽名器用到的是哪一條 BIP32 路徑,而硬件簽名器光憑自己也無法搞清楚。然後這個輸入就不會進入求值。因此,我們需要某種方式來探明所有輸入的所有權。那麼該怎麼做呢?這對所有帶有外部輸入的交易都很重要。不僅僅是 CoinJoin 交易,還有雙向注資的閃電通道,等等。所以我們需要一種機制,可靠地確定哪個輸入是否屬於本錢包。該怎麼做呢?
SLIP 19 所有權證據
這個叫做 “SLIP 19”。SLIP 對於Satoshi Labs 就像 BIP 對於比特幣。SLIP 19 的名稱是 “所有權證據”,顧名思義,本質上就是得到簽名的三段信息。
- 第一段信息是 “所有權標識符”,讓我們可以高效地確定本錢包是否可以花費具有給定一個腳本公鑰的 UTXO 。這是一種非常簡單的構造,基本上就是從種子派生一個對稱密鑰,然後使用 HMAC(基於哈希函數的消息認證碼)來處理這個密鑰,將腳本公鑰作為它的消息。
HMAC-SHA256(key = 對稱密鑰; message = 腳本公鑰)
另一段信息是腳本公鑰本身。
我們也有額外的不限定的承諾數據。如果你不想用,也可以不用。但基本上,它就是一個隨機的 256 比特的數值;在 CoinJoin 交易中,我們使用 192 比特的 CoinJoin 協調員 ID 以及 64 比特的 CoinJoin 回合 ID 。但它可以是任何數值,只取決於你要開發什麼樣的應用。
所有東西都會得到簽名,通過一種在 BIP322 “通用簽名消息格式” 的 2020 年 3 月版本中描述的方法。
為什麼人們不大使用 CoinJoin 呢?
首先,我認為真正的問題是缺乏意識,希望我們能逐步改變這個局面。
- 人們不知道 CoinJoin 存在。
- 人們完全不理解為什麼需要隱私性。
- 人們完全不在乎隱私性。我覺得我們生活在一個泡沫裡,可能有 99% 的人都不在乎這件事。
複雜性。我的意思是,可能會有幾千種新信息要你在幾分鐘內處理完,而你都不知道這是在幹什麼。
缺乏硬件簽名器集成。因為 CoinJoin 錢包通常都是聯網錢包,那麼你就不想把你所有的聰都放在聯網錢包裡面。
最後,並非無足輕重的是,可能有法律上的後果。
結論
所以,我希望 Trezor 和 Wasabi 協調器的集成可以解決上述四個問題,這會在本月晚些時候發佈。這就是我的演講的全部。我們應該還有五分鐘來回答一些問題。
問答
【聽眾】:我知道去年 Adam Gibson 開了一個關於 CoinJoin 的研討會,他好像還提到另一個問題,就是我們不知道其他參與者是誰。因此,似乎有另一種恐懼是,也許所有其他參與者都來自一個嘗試針對你的實體。你怎麼看呢?
【Pavol Rusnak】:我認為 Max 也許能夠給出一個更加詳盡的回答。但我想的是,我們應該努力讓 CoinJoin 變得儘可能大。我不知道當前在 Wasabi 協調器那裡一次 CoinJoin 的參與者數量上限是多少,我想起碼允許 150 個輸入。如果只有 5 個輸入,那攻擊你當然容易得多得多,但如果有 …… 我就是說,希望這個集成會吸引更多人參加 CoinJoin ,而我認為我們可以開始提高限額了。大概就是這樣。
【聽眾】:(無法辨識)比如說,如果我想往交易所充值,他們可以拒絕 CoinJoin 交易的輸出嗎?
【Pavol Rusnak】:所以,問題在於,交易所跟 CoinJoin 交易的關係是什麼、或者說他們怎麼看待 CoinJoin 交易?我猜這是他們的問題,不是我的問題。但我認為,不是所有交易所都會採取同樣的行為模式。其中有一些會將所有 CoinJoin 輸出都標記為非法的,他們不想接受 CoinJoin 交易的輸出。我知道還有一些交易所甚至更瘋狂,會在你取款之後跟蹤你的交易。他們會說你從交易所取款的幾天之後似乎參加了 CoinJoin,我們不喜歡你這樣做。我認為這就過分了。但我也認為,我們現在做的事情正在為 CoinJoin 吸引更多的用戶。以前,交易所很容易貫徹將 CoinJoin 看作非法交易的做法,但是,如果有成千上萬個守法的用戶都這樣做,那麼也許他們就會改變做法。如果他們不改變,我猜他們也會遇上問題。所以,這就像是在玩一種博弈遊戲,或者四維象棋。
【聽眾】:嗨,我叫 Robert,我運行了一個 Start9 節點。在法律上為使用 CoinJoin 辯護的最重要理由是什麼?他們正在逮捕開發者不是嗎?你怎麼為之辯護呢?
【Pavol Rusnak】:我怎麼辯護?舉個例子,捷克共和國有一家非常大的連鎖店,出售電子產品。我喜歡用比特幣從那家店買電子產品。但我一點也不像告訴他們我有多少聰。但如果我不使用 CoinJoin 的話,這是很容易曝光的,你只需要觀察區塊鏈上的交易,馬上就能看出這個人買了電子產品。你可以說我已經在這家商店登記了 KYC,因為我會讓他們把貨發到我的住處。他們可能不會這樣做,但只要他們想,他們就能做到。所以我使用 CoinJoin ,基本上就是在錢幣 —— 我花費掉的錢幣與還在我錢包中的錢幣 —— 之間建立防火牆。
(完)





