Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OP_CAT and Schnorr Trick

OP_CAT and Schnorr Trick

shigeyuki azuchi

January 27, 2025
Tweet

More Decks by shigeyuki azuchi

Other Decks in Technology

Transcript

  1. 1 OP_CAT
 スタック上の2つの要素を連結するシンプルなopcode 
 Bitcoinの初期に存在したものの、2010年に 
 実行時に大量のメモリ消費をさせる攻撃が可能なことから無効化 
 <1 byte>

    OP_DUP OP_CAT OP_DUP OP_CAT …
 【BIP347】
 TapscriptのOP_SUCCESS系 opcodeにOP_CATを割り当てるソフトフォークの提案 
 Tapscriptの制限により、連結したデータのサイズが520 byteに制限されるため、メモリDoSも回避 
 https://github.com/bitcoin/bips/blob/master/bip-0347.mediawiki

  2. 2 Schnorrトリック
 【Schnorr署名のスキーム】
 • 秘密鍵:x、公開鍵:P = xG(Gは楕円曲線のベースポイント) 
 • メッセージ:m


    
 1. ランダムなnonce kを選択し、
 2. R = kGを計算
 3. e = H(P || R || m) を計算
 4. s = k + exを計算
 5. (R, s)がSchnorr署名
 
 
 https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-i.html 
 【Schnorrトリック】
 P = R = G に固定する、つまりx = k = 1 
 生成されるSchnorr署名はs = 1 + e 
 (G, 1 + e) 
 sの値が署名対象のメッセージダイジェストに 1を加算した値になる 
 
 このSchnorr署名の検証をパスするためには、 
 トランザクションが指定された形式( m)になっている必要がある 
 つまり、コベナンツが可能になる! 

  3. 3 OP_CAT × Schnorrトリック
 Lock Script Spending Tx In コベナンツUTXO

    Out 規定の宛先、規定の金額 witness • 適用するアウトプットのデータ 
 ◦ ロックスクリプト
 ◦ 金額
 • コベナンツスクリプト 
 
 <G> OP_2DUP OP_SWAP OP_CAT OP_SWAP OP_CHECKSIG 
 • コベナンツUTXOの参照情報 
 ◦ OutPoint
 ◦ nSequence
 • nLocktime
 1. ロックスクリプトとwitnessのデータから OP_CAT を利用してスタック上で Txを組み立て
 2. OP_SHA256 でハッシュH(P || R || m) を計算し、
 3. コベナンツスクリプトによりSchnorrトリックを使って 
 Spending Tx がTxと同じになることを検証 

  4. 4 OP_CAT × Schnorrトリック
 <G> OP_2DUP OP_SWAP OP_CAT OP_SWAP OP_CHECKSIG

    
 <s>
 Schnorr署名のデータの一部となる Txをハッシュしたデータ sが提供された際のスタックの動作 
 s
 G
 s
 G
 s
 G
 s
 G
 s
 s
 G
 G
 s
 Gs
 Gs
 s
 G
 <G>
 OP_2DUP
 OP_SWAP
 OP_CAT
 OP_SWAP
 OP_CHECKSIG 
 s
 G = P→公開鍵
 Gs = (R, s)→ Schnorr署名
 Schnorrトリックによる署名検証 
 

  5. 5 +1対応
 実際にはsの値はTxのハッシュ+1の値である必要がある 
 
 
 1. witnessで提供する値(nSequenceやnLocktimeなど)を変更しながら 
 H(P

    || R || m) の最下位byteが0x01 で終わるようなTxを見つける(平均256回の試行) 
 ※ 最下位byteが0x01 であれば、sの値の最下位byteは 0x02 になる
 2. witnessに追加で、H(P || R || m) の上位31byteを提供させ(仮に σとする)
 3. OP_CAT を使用して、
 a. σ || 01 がTxのハッシュと一致するか OP_EQUALVERIFY で検証し、
 b. σ || 02 を使ってSchnorrトリックの署名を検証させる 

  6. 6 ECDSAトリック
 【ECDSA署名のスキーム】 
 • 秘密鍵:x、公開鍵:P = xG (Gは楕円曲線のベースポイント) 


    • メッセージ:m
 
 1. ランダムなnonce kを選択し、
 2. R = kG を計算し、
 3. RのX座標をrとする
 4. s = (H(m) + r × x)/k 
 5. (r, s) がECDSA署名 
 
 
 https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85 
 https://techmedia-think.hatenablog.com/entry/2024/12/03/142109 
 【ECDSAトリック】
 k = 1, R = G、x = 1/r, P = (1/r)G と固定する
 生成されるECDSA署名はs = H(m) + 1 
 (G, H(m) + 1) 
 sの値が署名対象のメッセージダイジェストに 1を加算した値になる 
 
 このECDSA署名の検証をパスするためには、 
 トランザクションが指定された形式( m)になっている必要がある 
 つまり、コベナンツが可能になる!