コンテンツにスキップ

条件付きトークンのアトミックスワップ

条件付きトークンのアトミックスワップ

Section titled “条件付きトークンのアトミックスワップ”

本ドキュメントは、ECDH鍵合意とSchnorrアダプター署名を使用したCashu条件付きトークン(NUT-CTF)のピアツーピア取引プロトコルを規定します。このプロトコルにより、カストディアル仲介者なしにトラストレスなアトミック交換(例:YESアウトカムトークンとsatsの交換)が可能になります。

NUT-CTFは将来の結果に依存する条件付きトークンを定義しますが、ユーザーがそれらをどのように取引するかは規定していません。予測市場には2つのコンポーネントが必要です:(1) 買い手と売り手をペアリングするマッチングエンジン、(2) どちらの当事者も不正ができないようにトークンをアトミックに交換する決済メカニズム。

このプロトコルは、NUT-11 P2PK支出条件、ECDH導出共有シークレット、Schnorrアダプター署名からアトミックスワップを構築することで(2)に対処します。マッチングエンジン(1)は公開鍵交換と暗号化メッセージパッシングを促進する非カストディアルリレーです。

アダプター署名スキームは、標準的な署名スキームを4つの操作で拡張します:

  • PreSign(sk, m, T) → s’: シークレットキーskとアダプターポイントT = t·Gを使用して、メッセージmの_プリ署名_s'を生成します。プリ署名は有効な署名ではありませんが、シークレットtにコミットします。
  • PreVerify(pk, m, s’, T) → bool: s'が公開鍵pk、メッセージm、アダプターポイントTに対して有効なプリ署名であることを検証します。
  • Adapt(s’, t) → s: アダプターシークレットtを与えて、プリ署名を有効なSchnorr署名s = s' + tに完成させます。
  • Extract(s, s’) → t: 有効な署名sと対応するプリ署名s'から、アダプターシークレットt = s - s'を復元します。

重要な特性は:プリ署名s'が公開され、後に完成した署名sが現れた場合(誰かがproofを使用したため)、s'を知っている人はtを抽出できることです。これにより、2つの独立した支出イベント間に暗号学的リンクが作成されます。

secp256k1上のSchnorr署名(NUT-11で使用)の場合、アダプター署名は簡単です:

標準Schnorr: s = r + e·x (where e = H(R, P, m))
アダプタープリ署名: s' = r + e·x (but R' = R + T, so e = H(R+T, P, m))
s = s' + t (valid sig with nonce point R = R' - T)

アダプター署名がP2PK層で動作しなければならない理由

Section titled “アダプター署名がP2PK層で動作しなければならない理由”

Cashuのブラインド署名(BDHKE)は乗法構造を使用します:C_ = k · B_。アダプター署名は加法構造を必要とします(Schnorr: s = r + e·x + t)。ミント検証を壊したりNUT-12 DLEQ proofを無効にしたりせずに、乗法ブラインド署名にアダプターシークレットを埋め込むことはできません。

NUT-11 P2PK支出条件は既にsecp256k1上のSchnorr署名を使用しており、アダプター署名と完全に互換性があります。したがって、プロトコルはブラインド署名層ではなく、完全に支出条件層で動作します。

キーペア(a, A = a·G)(b, B = b·G)を持つ2つの当事者は、どちらも秘密鍵を明かさずに共有シークレットS = a·B = b·Aを計算できます。この共有シークレットは、信頼できないマッチングエンジンを介して通信が中継される場合でも、アダプターポイントとプリ署名を交換するための暗号化チャネルを確立します。

  • Alice: YESトークンを売却(satsと交換したい条件付きトークンproofを保有)
  • Bob: YESトークンを購入(条件付きトークンと交換したいsat proofを保有)
  • マッチングエンジン(ME): 注文をペアリングし暗号化メッセージを転送する非カストディアルリレー
  • ミント(M): P2PK支出条件を強制するCashuミント
  • AliceとBobの両方が有効なDLEQ proof(NUT-12)を持つCashu proofを保有
  • ミントがNUT-07(witness取得付きトークン状態チェック)、NUT-11(P2PK)、NUT-12(DLEQ)をサポート
  • AliceのYESトークンproofとBobのsat proofが合意された取引に対して互換性のある額面を持つ

AliceとBobはそれぞれこの取引用のエフェメラルキーペアを生成し、マッチングエンジンに注文を登録します。

Alice: (a, A = a·G)を生成、公開鍵Aで売り注文を登録
Bob: (b, B = b·G)を生成、公開鍵Bで買い注文を登録

マッチングエンジンは注文板に注文を保存します。エフェメラルキーにより取引間の非リンク性が保証されます。

エンジンは価格と数量に基づいてAliceの売り注文とBobの買い注文をマッチングします。送信内容:

  • AliceはBobの公開鍵Bを受信
  • BobはAliceの公開鍵Aを受信

ステップ3:ECDH共有シークレット

Section titled “ステップ3:ECDH共有シークレット”

両当事者が独立して共有シークレットを計算します:

Alice: S = a · B
Bob: S = b · A

Sから対称暗号化鍵を導出し(例:key = SHA256(S))、エンジンを介した暗号化通信に使用します。エンジンは暗号文を中継しますが、復号はできません。

ステップ4:アダプターポイント生成

Section titled “ステップ4:アダプターポイント生成”

Aliceがランダムなアダプターシークレットtを生成し、アダプターポイントTを計算します:

Alice: t ← ランダムスカラー
T = t · G

AliceはECDH暗号化チャネルを介してTをBobに送信します(エンジンが中継)。

ステップ5:AliceがYES Proofをロック

Section titled “ステップ5:AliceがYES Proofをロック”

AliceはNUT-11 P2PKを使用してBobの公開鍵にロックされたYESトークンproofを作成します:

[
"P2PK",
{
"nonce": "<random>",
"data": "<Bobの公開鍵B>",
"tags": [
["sigflag", "SIG_INPUTS"],
["locktime", "<unix_timestamp>"],
["refund", "<Aliceの公開鍵A>"]
]
}
]

locktimerefundタグにより、Bobがスワップを完了しない場合にAliceがトークンを回収できます。

次に、各proofのsecretに対するアダプタープリ署名を作成します:

各proofのsecret x_iに対して:
s'_A_i = PreSign(a, x_i, T)

注記: プリ署名はBobが検証に使用するエフェメラルキーで作成され、アダプターポイントTを使用します。tで適応されるまで有効なSchnorr署名では_ありません_。

Aliceは暗号化チャネルを介して{proofs, s'_A, T}をBobに送信します。

ステップ6:BobがSat Proofをロック

Section titled “ステップ6:BobがSat Proofをロック”

BobはAliceのロックされたproofを受信し、検証します:

  1. DLEQ検証(NUT-12):各proofが有効なミント署名を持つことを確認
  2. P2PK検証:proofが適切なlocktimeとAへの返金で公開鍵Bにロックされていることを確認
  3. PreVerify:各s'_A_iがアダプターポイントTを持つ有効なアダプタープリ署名であることを確認

すべてのチェックに合格した場合、BobはAliceの公開鍵Aにロックされたsat proofを作成します:

[
"P2PK",
{
"nonce": "<random>",
"data": "<Aliceの公開鍵A>",
"tags": [
["sigflag", "SIG_INPUTS"],
["locktime", "<unix_timestamp>"],
["refund", "<Bobの公開鍵B>"]
]
}
]

Bobは同じアダプターポイントTを使用してproofのアダプタープリ署名を作成します:

各proofのsecret y_jに対して:
s'_B_j = PreSign(b, y_j, T)

Bobは暗号化チャネルを介して{proofs, s'_B}をAliceに送信します。

ステップ7:Aliceが請求(Adapt + Swap)

Section titled “ステップ7:Aliceが請求(Adapt + Swap)”

AliceはBobのproofを検証します(DLEQ、AへのP2PKロック、s'_BのPreVerify)。

Aliceはtを知っているため、Bobのプリ署名を有効なSchnorr署名に適応できます:

Bobの各proofに対して:
s_B_j = Adapt(s'_B_j, t) = s'_B_j + t

Aliceはs_B_jをNUT-11 witness署名として使用し、ミントにスワップリクエストを送信します:

POST /v1/swap
{
"inputs": [<witness s_B_j付きBobのsat proof>],
"outputs": [<新しいトークン用Aliceのブラインドメッセージ>]
}

ミントはP2PK署名を検証し、スワップを処理します。Aliceは新しいsatトークンを保有しています。

ステップ8:Bobがアダプターシークレットを抽出

Section titled “ステップ8:Bobがアダプターシークレットを抽出”

BobはミントのNUT-07トークン状態チェックエンドポイントで使用済みsat proofを照会します:

POST /v1/checkstate
{
"Ys": ["<Bobの使用済みsat proofのY値>"]
}

ミントはAliceが使用した有効なSchnorr署名s_B_jを含むwitnessデータを返します:

{
"states": [
{
"Y": "...",
"state": "SPENT",
"witness": "{\"signatures\": [\"<s_B_j>\"]}"
}
]
}

Bobは任意の署名ペアからアダプターシークレットを抽出します:

t = Extract(s_B_j, s'_B_j) = s_B_j - s'_B_j

ステップ9:Bobが請求(Adapt + Swap)

Section titled “ステップ9:Bobが請求(Adapt + Swap)”

tを復元したBobは、Aliceのプリ署名を有効なSchnorr署名に適応します:

Aliceの各proofに対して:
s_A_i = Adapt(s'_A_i, t) = s'_A_i + t

BobはAliceのYES proofに対するスワップリクエストを送信します:

POST /v1/swap
{
"inputs": [<witness s_A_i付きAliceのYES proof>],
"outputs": [<新しい条件付きトークン用Bobのブラインドメッセージ>]
}

ミントが検証してスワップを処理します。Bobは新しいYES条件付きトークンを保有しています。

プロトコルはアダプター署名構造を通じて原子性を達成します:

  • Aliceが請求した場合(ステップ7):適応された署名s_B = s'_B + tがミントに公開されます。BobはNUT-07を介してそれを取得しtを抽出でき、Aliceのproofを請求できます。両当事者がスワップを完了します。
  • Aliceが請求しない場合:どちらの当事者のトークンも使用されません。locktime期限後、両当事者は返金パスを介して自分のトークンを回収します。
  • Bobが先に請求することはできない:Bobはtを知らないため、Aliceのプリ署名を適応できません。Aliceが使用してtを明らかにするまで待つ必要があります。

locktimeは慎重に選択する必要があります:

  • 短すぎる場合:Aliceの返金ウィンドウが開く前にBobがNUT-07に問い合わせてスワップを送信する時間がなく、競合状態が発生する可能性があります。
  • 長すぎる場合:カウンターパーティが消えた場合、トークンが長期間ロックされます。

このプロトコルはecashスワップのみを含むため(Lightningルーティング遅延なし)、locktimeは非常に短く(分ではなく秒のオーダー)設定できます。両当事者は注文マッチングフェーズ中にlocktimeに合意する必要があります。

重要:Bobのsat proof locktimeはAliceのYES proof locktimeより_長く_する必要があります。これにより、Aliceが返金する前にBobがtを抽出してAliceのYES proofを請求する時間が確保されます。

このプロトコルはミントがNUT-07 witness取得をサポートすることを必要とします。いくつかの考慮事項があります:

  • 可用性:ステップ7と8の間にミントがオフラインになった場合、Bobはwitnessを取得できません。locktime返金によりBobの元のsat proofは保護されますが、YES proofを請求する機会は失われます。
  • プライバシー:NUT-07への問い合わせにより、Bobが特定の使用済みproofに関心を持っていることがミントに明らかになり、取引当事者の相関に役立つ可能性があります。
  • 検閲:悪意のあるミントがwitnessデータの返却を拒否し、Bobがtを抽出できなくする可能性があります。locktime返金によりBobの資金は保護されますが、原子性が壊れます。
  • 競合状態:Aliceの使用(ステップ7)とBobの問い合わせ(ステップ8)の間に、ミントがオフラインまたは応答不能になる可能性のあるウィンドウがあります。

これらの制限はP2PK + NUT-07アプローチに固有のものです。より強い原子性保証のためには、アトミック決済エンドポイントバリアント(代替案を参照)を検討してください。

エンティティ信頼要件
マッチングエンジン非カストディアル。暗号化メッセージを中継。復号不可(ECDH)。資金窃取不可。サービス拒否は可能(中継拒否)。
ミントP2PK条件を正直に実行し、NUT-07 witnessデータを返す必要がある。トークン発行で既に信頼済み。
カウンターパーティトラストレス。窃取不可 — 完了しないことによるグリーフのみ可能(locktime返金で保護)。

NUT-14はCashu用のHash Time-Locked Contracts(HTLC)を定義しています。HTLCは理論的にアトミックスワップを可能にしますが、条件付きトークン取引には重大なデメリットがあります:

プロパティHTLC(NUT-14)アダプター署名(本プロトコル)
ロックタイプハッシュプリイメージH(x)ECポイントT = t·G
プリイメージ伝播NUT-07が必要(同じ依存性)NUT-07が必要(同じ依存性)
ミントが知る情報プリイメージ値(両スワップレグを相関可能)通常のP2PK署名(2つのスワップをリンク不可)
プライバシー同じハッシュH(x)が両レグに現れる — 自明にリンク可能異なる署名、オンチェーンリンクなし
追加NUTNUT-14(HTLCサポート)NUT-11(P2PK)以外不要
暗号学的複雑性低い(ハッシュ + プリイメージ)高い(アダプター署名数学)

プライバシーの利点が主要な差別化要因です。HTLCでは、ミントは両スワップレグで同じハッシュロックを見るため、同じ取引の一部であることを自明に判断できます。アダプター署名では、ミントは無関係な署名を持つ2つの独立したP2PK使用を見ます。

Cashuは2のべき乗の額面を使用します。37 YESトークンを0.6 sats/枚で取引 = 22.2 satsは正確に表現できません。実装は表現可能な金額に合わせた最小取引サイズを定義するか、より高い精度の単位を使用する必要があります。

マッチングエンジンは注文フローを見ることができ、ユーザーより先に取引する可能性があります。緩和策:頻繁なバッチオークションを使用し、時間ウィンドウ内のすべての注文を単一のクリアリング価格でマッチングし、フロントランニングの優位性を排除します。

攻撃者が注文を出し、マッチングされ、完了しないことで、カウンターパーティのトークンをlocktime期限までロックする可能性があります。緩和策:

  • 短いlocktime(30秒未満 — このプロトコルはLightningルーティング遅延のないecashスワップのみを含むため、locktimeを非常に積極的に設定可能)
  • マッチングエンジンによるレピュテーション追跡
  • 少額のアンチスパムデポジット(例:エンジンへのLightningインボイス支払い)

このプロトコルは各マッチングペアの完全約定を要求します。部分約定は複数のアトミックスワップへの分割が必要です。ミント運営の注文板は部分約定をより自然に処理でき、このプロトコルを補完する可能性があります。

異なるミントからの条件付きトークンはファンジブルではありません。取引は同じミントのトークンに限定されます。