Lightning-Network

如何使用 CHECKSIGFROMSTACKVERIFY 模擬 SIGHASH_NOINPUT?

  • July 29, 2021

在 bitcoin-dev上讀到 CHECKSIGFROMSTACKVERIFY(BCash 中的 CHECKDATASIG)可用於模擬新的 sighash 標誌。具體來說,這將如何運作?作為範例,請提供基於Eltoo 論文圖 4 的範例更新事務,或aj 的簡化閃電(不適用於瞭望塔)

Eltoo 依賴於原語SIGHASH_ANYPREVOUTSIGHASH_NOINPUT(以下稱為 APO)BPI118,從 APO 建構 Eltoo 將用修改後的腳本替換Eltoo 論文CHECKSIG的圖 4 。

該答案的大部分內容基於此連結中 Russell O’Connor 的部落格文章(該連結也涉及其他盟約結構)。為了完整起見,讓我們看一下事務自省的基礎知識,然後再討論如何構造APO. 答案是隔離見證簽名雜湊和 ECDSA 簽名算法。不幸的是,將其擴展到主根需要額外的操作碼/其他更改,我將在答案末尾解釋。

  1. OP_CHECKSIGFROMSTACK:(此後CSFS)這個操作碼還沒有正式的提議,但很可能它會按如下方式工作:pop 1) a pubkey pk, 2) a message m, and a 3) digital signature sig。該操作將驗證 sig 作為 ECSDA.Verify(pk, sha256(m), sig) 並將結果推送到堆棧頂部。
  2. OP_CAT:從堆棧中彈出兩個項目topnext_top壓入next_top || top堆棧,其中||表示字節字元串連接。我將假設一個SIGHASH_ALL用於以下構造,但該構造可用於 sighash 類型。

OP_CAT首先,我們將使用and來查看基本的事務自省OP_CSFS:考慮以下腳本:

1. OP_OVER OP_SHA256 <pubKey>
2. 2 OP_PICK 1 OP_CAT OP_OVER
3. OP_CHECKSIGVERIFY
4. OP_CHECKSIGFROMSTACKVERIFY

與見證堆棧

<sig>
<sig_msg>

哪裡<fixed_pk>是公開的,每個人都知道其密鑰。比如說,G密鑰為的生成器1<sig_msg>表示正在簽名的轉換摘要。

在步驟 1 結束時,堆棧為

<pubKey>
<sha256(<sig_msg>)>
<signature>
<<sig_msg>>

在第 2 步結束時,堆棧內容為

<pubKey>
<sig;SIGHASH_ALL>
<pubKey>
<sha256(sig_msg)>
<sig>
<sig_msg>

請注意,它1被翻譯為SIGHASH_ALL並 catted 為sig. 這會創建一個正常的比特幣簽名,我們可以使用正常OP_CHECKSIG的 . 步驟 3 之後,堆棧內容為

<pubKey>
<sha256(sig_msg)>
<sig>
<sig_msg>

這會要求OP_CHECKSIGFROMSTACKVERIFY只留&lt;sig_msg&gt;在堆棧上。第 4 步的 OP_CHECKSIGFROMSTACKVERIFY 使用相同的 pubKey 和簽名。此操作執行另一個 SHA-256(segwit sighash 算法需要雙 sha256)並對雙散列 <sig_msg> 進行數字簽名驗證。請注意,因為我們使用的&lt;pubKey&gt;&lt;sig&gt;之前的OP_CHECKSIGVERIFY操作完全相同,所以只有在 <sig_msg> 與步驟 3 的 OP_CHECKSIGVERIFY 操作期間檢查的消息相同時,目前OP_CHECKSIGFROMSTACKVERIFY才能成功。至此,我們可以確定&lt;sig_msg&gt;棧頂上的 和簽名的交易消息是一樣的。

*請注意,*由於私鑰是已知的,任何人都可以創建此簽名,但此腳本只有在如上所述正確指定&lt;fixed_pk&gt;時才會成功。&lt;sig_msg&gt;

到 ANYPREVOUT

Anyprevout 本質上是從正常簽名雜湊消息中替換一些東西,並用 0 替換那些東西。詳細地說,我們現在可以sig_msg按照BIP143中的定義使用OP_SUBSTR. 也可以使用OP_CAT最初提供拆分的消息,然後將其集中在一起。

現在我們在堆棧上有了符合 BIP143 的簽名雜湊消息,我們對其進行操作以使某些欄位為 0。特別是,我們將項目 2-4 設為 0。

2. hashPrevouts (32-byte hash)
3. hashSequence (32-byte hash)
4. outpoint (32-byte hash + 4-byte little endian) 

我們採取 aOP_DUP OP_SUSTR 0 &lt;4&gt;得到第 1 項,版本。到堆棧上。同樣,將項目 5-10 連接到堆棧上。最後,我們通過 <items 5.10> 將它們組合在一起<ver> <[0; (32+ 32 + (32 +4))]>`以獲得一個新的 sighash,我們將其用於 Eltoo 更新密鑰。

introspect_script=

OP_OVER OP_SHA256 &lt;pubKey&gt; 2 OP_PICK 1 OP_CAT OP_OVER OP_CHECKSIGVERIFY OP_CHECKSIGFROMSTACKVERIFY

正如我們上面所討論的。並讓manipulate_txdata_script腳本從 BIP143 sighash 消息中修改堆棧內容以獲取將相應項目設置為的新消息0s。然後我們的最終替代品OP_CHECKSIGANYPREVOUT將是以下腳本。

final_script(eltoo_pk) = &lt;introspect_script&gt; &lt;manipulate_txdata_script&gt; &lt;eltoo_pk&gt; OP_CSFS

滿足這一點需要在初始見證堆棧中添加以下內容。

&lt;sig_from_fixed_key&gt;
&lt;sig_msg&gt;
&lt;sig_from_eltoo_update_priv_key&gt;

最後,eltoo 腳本現在看起來像:

OP_IF
   10 OP_CSV
   2 A(s,i) B(s,i) 2 OP_CHECKMULTISIGVERIFY
OP_ELSE
   &lt;Si + 1&gt; OP_CHECKLOCKTIMEVERIFY
   final_script(Au) final_script(Bu)
OP_ENDIF

注意兩個多重簽名中的兩個是如何分成兩部分的。

Taproot簽名雜湊:

由於標記的雜湊,相同的技術不適用於 Taproot 簽名雜湊算法(請參閱BIP341)和 Schnorr 簽名(請參閱BIP340)。在高層次上,由於標籤,這些消息的大小超過 520 字節,這是目前比特幣網路支持的最大值。可以通過添加 1) 流式SHA256操作碼、2) 通過提高每個堆棧元素限製或 3) 通過新操作碼添加對標記雜湊的支持來克服此限制。

引用自:https://bitcoin.stackexchange.com/questions/89537