邁向 k-of-n 多簽名的閃電節點

作者:ZmnSCPxj

來源:https://delvingbitcoin.org/t/towards-a-k-of-n-lightning-network-node/2395

引言

最近,隨著《嵌套的MuSig2》論文的出版,我們開始思考:我們能夠製作出一種集成了閃電網絡的多簽名自主保管錢包嗎?

具體來說,我們希望的是,在 “簡單 Taproot 通道”(PR995)中,我們可以使用 “嵌套的 MuSig2”,製作出天衣無縫的多簽名閃電網絡節點。

但是,先想想:一個終端用戶說的 “我想要一款 k-of-n 的多簽名錢包”,究竟是什麼意思?

我認為,終端用戶的核心需求是這樣的:

關於 “k-of-n 多簽名”,我的願望是,我持有 N 臺設備,只要不到 K 臺被劫持,我的資金就是安全的。即使我不可挽回地弄丟了一些設備,只要不到 (N - K + 1) 臺,我就依然能花費我的資金。

這種願望,我們該如何轉化到(現實場景中的) “閃電網絡錢包” 中?

一個區塊鏈內的錢包可以直接用腳本來表達這種 k-of-n 的要求,相當簡單,但閃電網絡錢包不行。閃電網絡通道有額外的複雜性。這些額外的複雜性,需要閃電網絡 BOLT 協議發生變更,不僅僅是為了 k-of-n 的閃電網絡錢包自身,也是為了其通道對手(可能是,也可能不是 k-of-n 多簽名的)。

這意味著,一個想要使用 k-of-n 多簽名閃電錢包的終端用戶,必須:

  • 等待修改過的閃電網絡 BOLT 協議獲得廣泛採用,或者
  • 接受來自網關節點的服務(他們 “提早” 實現了修改後的閃電網絡 BOLT 協議,代價是損失隱私性,以及更少的轉發費收入。

K-of-n 多簽名的閃電網絡節點的一個主要應用場景,是讓手握大量資金的 HODLer 可以使用自己的儲蓄來給閃電網絡提供流動性,隨時保證自己是安全的、可復原的。

(譯者注:“HODLer” 是一個有文化意味的詞,來自 “holder(囤幣者)”。下文都翻譯為 “囤幣者”。)

然而,在這套修改後的閃電網絡 BOLT 協議得到廣泛採用之前,這樣的大型的 k-of-n 多簽名節點都只能連接到網關,由後者在修改後的協議與尚未升級的網絡之間架起橋樑;可以理解,這樣的網關節點會為此收一筆費用,只是收費方式或此或彼而已。任何不收取費用的網關節點都會發現,其可用流動性會被這樣的重倉囤幣者很快用盡;他們自己是沒有那麼多的流動性的,除非他們自己也是重倉囤幣者;但如果他們是,則(根據我們的假設)他們本身就會想要使用一個多簽名裝置,也就是同樣需要使用支持這套修改後的協議的網關。

因此,為了支持我們說的這個應用場景,協議必須 “提早” 修改,以驅動修改後的協議得到採用,這樣重倉囤幣者才能使用自己的儲蓄來提供流動性。

信任最小化的通道對手

有人可能會反駁:“閃電網絡實際上更加安全,因為必須也攻破通道對手,才能讓受害者弄丟自己的密鑰。”

這種想法也是非常錯誤的。

正確的想法是:“通道對手佔據了坑害你的最佳位置,所以你應該格外擔心你的通道對手。”

具體來說,設想這樣一種情形:如果你是一個重倉囤幣者,希望向閃電網絡提供流動性(換取手續費收入),你希望任何人都能與你開設通道。其他人跟你開設通道,意味著你有更多機會賺取路由手續費!

如果你不允許互聯網上的陌生人跟你的大型路由節點開設通道,只允許少量值得信任的實體跟你開設通道,那麼我打賭:

因為這樣或那樣的原因,這些精挑細選的 “值得信任” 的通道對手以流動性租金的形式,把你賺到的手續費又賺回去;或者,你會發現自己的流動性利用率低下。

事實是,你必須允許互聯網上的陌生人,比如 YaiJBOjA(事先聲明,絕對不是我哈)跟你開設通道,於是這也意味著,你允許潛在的竊賊成為你的通道對手。你允許別人瞄準你。

因此,你必須假設,只有你本地的簽名器(們)是值得信任的,同時免去對通道對手的篩選。你的安全武裝必須足夠強大,即使別人瞄準你的後背也不怕,這樣才能嚇退盜賊,而且不應該依賴通道對手,因為通道對手正是最好的盜賊

你的對手,如果哪怕純用自己的資金與你開設通道,也可以把自己在通道內的餘額都(通過你)發給他們自己控制的另一個節點,然後再偷盜通道中的資金(在他們用盡自己的餘額之後,顯然,通道中的資金都是你的)。如果他們能夠攻破足夠多的簽名器,或者利用你的多簽名方案中的漏洞,就可以盜竊你的資金。

因此,你的 “莫頓叉子” 是這樣的:

  • 如果你不注重簽名器安全性,那麼互聯網上的陌生人就有可能竊取你的財產。
  • 如果你不允許互聯網上的陌生人靠近,那麼你的流動性就得不到網絡的有效利用(首先你也賺不到錢,而且還把自己的錢放在了一個聯網的熱錢包中,卻不能給你或者任何人帶來好處)。

(譯者注:“莫頓叉子” 指的是橫豎都是死的兩難局面。)

因此,需要有比 “在我所有的閃電網絡通道中都使用一個根簽名器” 更好的安全體態。

多簽名是一個額外的維度

你可能會說:“但是我的簽名器是放在一個 ‘受信任的執行環境(TEE)’ 中的;這個執行環境運行在一個 ‘安全芯片(SE)’ 中;而這個安全芯片是用一個 ‘物理不可仿製功能(PUF)’ 來實現的!!!”

首先(也是最重要的),一個 PUF 僅僅是一個安全的擲骰子程序,用來生成一個嵌入其中的私鑰。如果你能夠訪問 SE 的調試(debug)接口 —— 這是每一家芯片製造商都必然預留了的,因為芯片的製造並非一個完美的過程,總會有瑕疵 —— PUF 就沒有任何防護作用。能夠檢測瑕疵的同一個 debug 接口,也可以用來抽取使用嵌入的私鑰運行的計算的中間結果;畢竟,也需要檢查這些中間計算電路以驗證它是正確製造的。出於實用性,你沒法用一條電路計算一切,所以,你需要 “觸發器(flip-flops)” 來保存這些中間結果(不然,你就需要一個巨大的,因此也是昂貴且緩慢的電路,因為觸發器中存儲的中間結果,正是讓同一個通用電路,比如乘法器或者加法器,可以在計算的不同部分重複使用的東西),並且,這些觸發器也被用作調試接口的一部分(叫做 “掃描鏈”,自己搜索一下),在製造商那裡用來檢查製造好的芯片的誤差。

這些存儲中間計算結果的觸發器不可能位於 PUF 中:因為你希望這些觸發器以及寫入其中的電路,跟你的設計完全一模一樣,不然這就是一個不可靠的芯片;而 PUF 是你故意提高其故障率、從而讓人們無法實用地克隆它的區域!

因此,這些中間計算結果,可以用來減少你在抽取嵌入其中的私鑰時不得不猜測的比特的數量。

此外,提醒一句,製造商可以訪問上述 “製造商調試接口/掃描鏈”,不然這個術語中就不會出現 “製造商” 這個詞。你真的相信製造商沒有能力讀取你如此敬畏的 PUF 中嵌入的私鑰嗎?你最好還是使用一款不帶 “安全芯片” 的 Trezor 簽名器,因為置入其中的私鑰是你真的可以用投硬幣、擲骰子來生成的,你可以使用硬幣、骰子以及其它你真的可以控制的硬件,完整那些你真正知道而且理解的操作。

“受信任的執行環境” 只是 “擋住你的小妹妹”,不是 “擋住威權政府”。

(信息來源:我曾經設計過 LCD(液晶面板)顯示驅動 ASIC(專用芯片)。在此之前,我曾經逆向工程過 ASIC,我們曾經磨碎每一層金屬(字面意思)、用顯微鏡拍照來搞清楚電路。你知不知道,臺灣的大牌芯片製造商只接受你使用前三大 verilog 模擬器軟件設計出來的電子邏輯電路(Mentor、Synaptic,第三名是誰你就別管了,你實在要問,我們曾經是一家 Synaptic 的商店);如果你不提供來自其中一家的仿真結果,他們就不會理會你的製造請求。他們完全不信任 Icarus Verilog,只要你提到這個詞,他們甚至都不會回覆你。)

因此,佔有硬件始終等同於佔有私鑰,無論 “受信任執行環境”、“安全芯片”、“物理不可仿製的功能”,都不改變 “十樁訴訟,佔有九勝(possession is 9/10 of the law)”。硬件一脫手,私鑰即脫手。

譯者注:“possession is 9/10 of the law” 直譯過來是 “佔有是法律的 9/10”,講的是在所有權訴訟中,當前佔有者大概率會贏得訴訟。作者在這裡化用它來強調 “佔有硬件(簽名器)” 的重要性:既然實際上沒有機制可以絕對防止敵人在獲得你的簽名器後抽取出其中的私鑰,那麼最重要的就是牢牢把它放在安全的地方,不讓敵手得到。

而且,不論如何:即使你擁有一個 ”完美“ 的電子設備,比如一個用現成的零件湊出來的簡單 Trezor 簽名器(這些零件你真的隨處都可以買到,而且不會引人懷疑,因為它們實在是太常見了,沒人會想著替換你的供應鏈,因為這些老舊無聊的微控制器的供應鏈實在太多了),使用多簽名方案依然對你更好:因為竊賊需要偷盜多個這樣的電子設備才能竊取你的資金。

多簽名給你的裝置加入了額外的維度,不論你的裝置是一個基於 “受信任執行環境” 的 “安全” 裝置(供應商承諾不會盜竊你的私鑰),還是一個完全由你佔用的真實設備。

多簽名,如本文引言的第一部分所說的,意味著 “要讓我的資金不安全,必須攻破 k 個設備” —— 只要我們能實現它。

不那麼多簽名的替代品

除了要求閃電網絡發生廣泛的變更,還有別的辦法可以獲得多簽名的一些好處。

比如說,每一條閃電通道都有一對專門的公鑰,兩端各一個。

閃電網絡協議自身並不指定從 “根” 密鑰(或者從節點 ID)派生出用於各通道的公鑰的具體方案。

因此,有可能做到:準備 N 個簽名器,不論什麼時候,一有通道開啟,就選出其中一個簽名器來指定用在這條通道中的公鑰。因為你用在通道中的公鑰跟你的節點 ID 沒有什麼關係,你可以自由地為各個通道選擇任何一個簽名器。

這跟現在的閃電網絡是完全兼容的,不需要變更協議,甚至不需要等待 PR995 合併。

在這種方案下,如果你有 N 個簽名器,而其中一個被劫持了,只會導致你的通道中的 1/N 條失盜。比起只設一個簽名器(讓所有通道處於風險之中)依然是一項提升。

這裡給出了這一方案的例子:rotating-signer-provider

這種方案在當下就能部署,也很實用,因為至少它分散了風險。它類似於使用多個節點,區別只在於它會讓你形成一個巨大的節點、用多個獨立的簽名器來管理資金。通常來說,大節點在路由效率上有優勢,並且被網絡上許多節點偏愛,因此可以增加你的路由費收益。

BOLT 變更:撤銷密鑰

為了實現真正 k-of-n 多簽名的閃電節點,BOLT 的絕對必要的變更是:取消使用 shachain(哈希鏈條)為遠端(remote side,對方)生成各承諾交易的撤銷密鑰(revocation key)的要求。

為什麼這是必要的呢?

回憶一下你的承諾交易所控制的資金,它的實際鏈內合約是什麼樣的:

  • 二選一:
    • 都滿足:
      • 遮蔽承諾交易已經深度確認(通常是長達兩個星期)
      • 你的簽名
    • 都滿足:
      • 對手的簽名
      • 撤銷密鑰

這裡的第二部分就是重點。

你的承諾交易是你可以追回自己的錢的唯一辦法。比如說,一個竊賊可以用 TA 自己的錢跟你開設一條通道、把通道中的餘額都發送到他們控制的另一個節點,然後關停自己的盜竊節點;這時候,他們已經沒有什麼可以損失了(除了 1% 的保證經,但這可以算作盜竊的成本)。你必須使用你的承諾交易;不然,你的資金就不安全:變得不可花費。

什麼是 “撤銷”?

閃電通道的許多術語可能讓人頭昏眼花:

  • 懲罰 指的是你的對手方使用舊狀態 單方面關閉 通道時你可以作出的反擊。前提是你的對手方廣播了一筆承諾交易並讓它得到了確認,而這筆承諾交易已經被 撤銷 了。
  • 單方面關閉 指的是你廣播一個狀態,並斷言它就是這條通道的最新狀態。如果你以前已經 撤銷 過這個狀態(意思是它實際上並非最新狀態,因此你的斷言是錯的),那麼它可能會被 懲罰
  • 撤銷 指的是你同意一個狀態已經是過時的了。它會交給對手方足夠多的信息,從而,如果你使用一個已經撤銷的狀態來 單方面關閉 通道,對手可以稍後 懲罰 你。

所以,這些事都是什麼時機發生的?

  • 撤銷
    • 每當狀態變更的時候就發生,也即:每當在通道中添加或移除一個 HTLC 的時候
    • 比如說,你們當前的狀態編號為 N。你和對手方都同意移動到 N + 1 。處理方式是 “雙手交替”:
      • 你的對手簽名狀態 N + 1 。
        • 在這時候,狀態 N 和狀態 N + 1 都是有效的,兩者都可以用來單方面關閉通道而不會遭受懲罰。
        • 用 “雙手交替” 這個比喻來說,你現在是兩隻手都抓在繩子上,一隻手在上、一隻手在下,就這樣向上攀爬 —— 在通道內推進狀態也是一樣的。
      • 你撤銷舊狀態 N 。
        • 這個操作將你 不可逆轉地鎖定 到狀態 N + 1,因為現在它是唯一有效的狀態了。
        • 用 “雙手交替” 這個比喻來說,在撤銷過程中你鬆開了下面這隻手。
    • 任何時候,最多隻有兩個未撤銷的狀態;大多數時候,只有一個未撤銷的狀態。
  • 單方面關閉
    • 發生在你決定簽名某一筆承諾交易 —— 讓你自己的簽名加入你的對手方的簽名,那是你在正常的雙手交替狀態推進過程中得到的 —— 並廣播它的時候。
    • 沒有硬性的密碼學機制阻止你使用舊的狀態交易(及其簽名),只有一種經濟激勵:只要你使用了舊的承諾交易(你已經撤銷過的),你會被懲罰:損失在通道中的所有資金。
  • 懲罰
    • 在你注意到你的對手方用一箇舊的(已經撤銷的)狀態來關閉通道的時候。

問題出在 “撤銷” 這個操作上,不是在 “單方面關閉” 或者 “懲罰”上。

撤銷 需要傳遞叫做 “撤銷密鑰” 的東西給你的對手。然後對手才能使用自己的簽名和這個撤銷密鑰來懲罰舊狀態單方面關閉。

K-of-N 撤銷密鑰的問題

現在,想想:

  • 假設你有一個 k-of-n 多簽名裝置。
  • 你如何為每一筆承諾交易生成撤銷密鑰?
    • 你的對手要攻破多少設備,才能偷盜最新的這個撤銷密鑰?

背後的大問題是:撤銷密鑰究竟是如何生成的

答案是:看 BOLT 規範。BOLT 規範指明瞭:要使用 shachian 。

問題在於,顧名思義,shachain 使用的是 SHA2(“sha”)的迭代應用(“chain”)。

不可能創建一種 k-of-n 的 SHA2 函數啊。SHA2 完全不是線性的,所以不可能創造出 k-of-n 的 SHA2,哪怕 k = n 都不可能。

即使有可能通過一些神秘的密碼學魔法創造出一種 k-of-n 的 SHA2 函數(涉及虛擬電路(virtual circuits),將比特 0 和 1 編碼成 “同態承諾”),持有 shachain 的一個中間結果(即迭代過程中的 一次 SHA2 的輸出)也一樣糟糕,因為同樣是 shachian 迭代中的 中間 結果 成了 撤銷密鑰。

這樣的虛擬電路通過使用迭代來實現,從而,讓中間結果可以被參與虛擬電路的多個參與者知曉;這些虛擬電路方案只保護根輸入,不保護中間結果。

問題在於,shachain 的中間結果就是撤銷密鑰!虛擬電路使用 0 和 1 的同態加密來保護撤銷密鑰鏈條的根,這根本無關緊要,因為必須揭曉迭代的中間結果,這些結果 就是 撤銷密鑰序列。作為一個序列,其中一個密鑰就是最新狀態的撤銷密鑰。

為了保護這些中間結果,你需要將整個 shachain 迭代展開並實現為一個巨大的虛擬電路。甚至更壞,每當你必須從 shachain 計算中間結果時,都要展開一個不一樣的虛擬電路;而這樣的計算次數,根據 BOLT 規範,至少 2(2 的 1 次冪)次,可以多達 2 的 48 次冪。

所以,多方計算的虛擬電路方案也許並不可行。

(警告:我並不是密碼學家。關於上述內容請諮詢真正懂得同態密碼學和多方計算的密碼學家。即使栓此,我也不會在 shachain 中使用多方計算,因為我認為那行不通,而且我的密碼學造詣找不出行得通的辦法。)

再次回顧:

關於 “k-of-n 多簽名”,我的願望是,我持有 N 臺設備,只要不到 K 臺被劫持,我的資金就是安全的。

如果 shachain 迭代的根值被所有簽名器知曉,那麼,其中任何一臺被攻破 —— 只要一臺被攻破 —— 通道對手就能直接竊取所有通道資金,從而打破上述期望。

如果 shachain 迭代的根值不被所有簽名器知曉,而是分散在 k 個簽名器之間,那麼:哪個設備來運行重複的 shachain 迭代、給對手提供撤銷密鑰呢?只要這一個持有根密鑰(甚至是一箇中間狀態)的設備被攻陷了,就同樣等價於持有最新的撤銷密鑰,也就允許盜竊資金。

再說一遍,“k-of-n” 的意義在於讓盜賊必須攻陷至少 k 臺設備。即使只有一臺設備持有撤銷密鑰,哪怕只是暫時的,攻破這一臺設備也將允許盜竊。因此,從道德上來說我們不能管這叫 “k-of-n 多簽名”,因為它並不是終端用戶說“k-of-n” 時期待的那種東西。

因此:shachain 必須從 BOLT 規範中移除。

BOLT 修改提議

我提議添加一對 “特性比特”,稱為 “no_more_shachains”,可以是 globalfeatures(全局特性)也可以是 localfeatures(局部特性):

  • 奇數比特:我不會對對手執行 shachain 驗證,但依然會給對手提供 shachain 有效的撤銷密鑰。
    • 這為依然期待傳統 shachain 的不升級節點提供了後向兼容性。
    • 這意味著我會存儲所有的撤銷密鑰,而不是使用 shachain 加速結構將存儲空間壓縮到 O(1) 量級。
    • 這讓不使用 shachain 的節點可以跟我開設通道,也讓我可以橋接他們以及要求 shachain 的節點。
  • 偶數比特:我不會提供 shachian 有效的撤銷密鑰,也不會驗證對手提供的撤銷密鑰的 shachain 有效性。

這個 globalfeatures 比特讓 k-of-n 多簽名節點可以識別出自己可以安全地與之建立通道的其他節點。注意,“創建 BOLT8 連接” 並不意味著 “創建一條通道”,而一個 k-of-n 節點可以建立 BOLT8 連接、下載 gossip 圖,然後搜索 globalfeatures 以尋找 no_more_shachains

然後,一個 k-of-n 閃電節點可以啟用偶數比特,而網關節點可以啟用奇數比特。最終,我們希望所有節點都至少啟用奇數比特並且我們可以之間使用偶數比特,哪怕是 1-of-1 的閃電節點。

以上設計尊重了 “可以保持奇數位” 的哲學,傳統節點依然可以跟啟用了奇數比特但沒有啟用偶數比特的節點互操作。啟用了奇數比特的節點也可以跟需要使用偶數比特的節點互操作。k-of-n 節點需要啟用偶數比特,但可以跟啟用了奇數比特的節點互操作。

請注意,即使僅僅啟用奇數比特,也會讓具有較長曆史的通道的存儲體積變成三倍,雖然通道拼接允許你修剪這些數據。

空間佔用變成三倍的原因是:

  • 使用帶錨點的承諾交易,唯一的狀態變更形式是添加和移除 HTLC 。
    • 因此,每一個 HTLC 都觸發 2 次狀態變更。
  • 每一個歷史 HTLC 都是大約 32 字節的哈希數據。
  • 每一次狀態變更都需要一個額外的撤銷密鑰。
    • shachain 方案只要求常量的存儲空間,但拋棄它之後,我們就需要線性增長的存儲空間。
    • 每一個撤銷密鑰都是大約 32 字節的數據(一開始是公鑰,但在撤銷之後,我們可以用私鑰來替代公鑰)。
  • 因此,一個 HTLC 將需要 32 字節來存儲哈希值、 32 字節為 添加 這個 HTLC 的承諾交易存儲撤銷密鑰,再有 32 字節為 移除 這個 HTLC 的承諾交易存儲撤銷密鑰。
    • 以前,使用 shachain,我們只需要 32 字節來存儲這個哈希值;因此,最終通道歷史的存儲空間會膨脹為 3 倍

並非問題:MuSig2 Nonce 通知

MuSig2 是一套兩輪的協議:

  • 第一輪,交換對 R 的投入。
  • 然後,交換碎片簽名 s

具體到 Taproot 通道,這個 “交換碎片簽名 s ” 的過程實際上只是一方給另一方發送碎片簽名 s;另一方把這個碎片簽名 s 存在硬盤中。如果另一方決定使用這個狀態單方面關閉通道,TA 會生成自己的 s、將兩者加在一起,生成最終的簽名 R, s ,然後將簽名和交易廣播到區塊鏈。

嵌套的 MuSig2 很大程度上也是相同的兩輪協議,嵌套簽名器們在內部完成每一輪、將他們的結果彙總、組合,然後執行在它們之上的層級的信息交換。

因為有兩輪,PR995 指明瞭使用當前交換 s 的時機來發送用在 下一次 簽名會話中的 R 的 nonce 投入。這減少了通信往返的次數,對於我們身在澳大利亞的同事來說,考慮到其中的延遲,這很重要。

K-of-N 的 MuSig2 ?

雖然 MuSig2(以及 “嵌套的 MuSig2”) 都被設計成 n-of-n 的簽名協議,我要指出, “k-of-n” 的 FROST 協議實際上是一套可驗證的 Shamir 秘密分割方案,在實際簽名過程中使用了 MuSig2 簽名協議的許多部分。也就是說,並非使用 MuSig/MuSig2 密鑰組合函數(與 MuSig2 簽名協議不同),FROST 使用自身的多方計算方案來生成一組你必須存儲的 “碎片”,每個碎片對應你的一個聯合簽名人,再加上你自己的密鑰碎片,以及一個集體公鑰。

在簽名的時候,FROST 基本上使用的是跟 MuSig2 非常相似的東西(也正因此,從機制上看,結合 FROST 和 “嵌套 MuSig2” 應該 是有可能的; 然而,還不能保證 “嵌套 MuSig2” 的安全證明可以延申到 FROST-in-MuSig2 !)

在簽名的時候,你要找出在線的簽名器(湊出 k 個聯合簽名器),然後所有在線的簽名器根據 MuSig2 簽名方案,生成第一輪的對 R 的投入、相互交換,然後生成第二輪的碎片簽名 s

問題在於,在 PR995 提議中,每次我們要為本次簽名會話發送第二輪的碎片簽名 s 時,也要 發送為下一次簽名會話準備的對 R 的投入。

所以,比如說,假設:

  • 我們有三臺簽名器,Alice、Bob 和 Carol,組成一個 2-of-3 的閃電節點。
  • 在當前的簽名會話中,Alice 和 Bob 在線,它們生成了對 R 的投入、處理了,然後將組合結果發給了對手方。
  • 然而,在下一次簽名會話以前,Alice 就死在了終於到來的機器人起義的流彈中。
  • Bob 喚醒了 Carol 。
  • Carol 並不知道 Alice 使用的 nonce 秘密值,因此無法使用結合好的 Alice+Bob nonce 來簽名。

幸運的是,雖然 PR995 提議指明瞭對手方應該記住 nonce 投入直至下一次簽名揮發,如果丟失了 BOLT8 連接,這個 nonce 會被丟棄。在重新連接是,發送一條 channel_reestablish 消息,就可以發送新的 nonce 。

所以,在上面這種情形中,Bob 和 Carol 可以不管機器人起義,繼續簽名:直接重新連接對手方,然後強迫使用一個新的組合好的 Bob+Carol nonce 。

因此,nonce 投入輪,對我們的 k-of-n 多簽名也不是一個問題。

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