PoDLE

# はじめに（Introduction）

2020年02月05日のBitcoin OptechにLightningのファンドを作成に関する論議が掲載されていました。
ここでは、ここに掲載されているPoDLEについて解説します。
（注：SSL3.0 の脆弱性「POODLE [CVE-2014-3566](https://nvd.nist.gov/vuln/detail/CVE-2014-3566)」**とは異なります**。）

# 問題（Problem）

Bitcoin Optechでは、ファンド作成など多数のプロトコルにおいて、使用予定のUTXOがプロトコル内において
他で使われていない事を証明する必要があります。
単純にUTXOを送った場合、相手ユーザはコスト無しでUTXOを知る事が出来てしまいます。

暗号では、秘密を教える前に秘密を所有しているというコミットメントを使う方式をとる事があります。
これにより、**相手ユーザ**や**プロトコル内の他ユーザ**に対して、コミットすることができます。

通常のコミットメントでは以下のような手順で行います。

- Aliceは $h=\text{hash}(\text{secret},\text{nonce})$ を作成し、Bobに $h$ を送信します。
- *プロトコルでなんらかの処理を行います。*
- Aliceは、Bobに $\text{secret}$ と $\text{nonce}$ を送信します。
- Bobは、$h\overset{?}{=}\text{hash}(\text{secret},\text{nonce})$ を検証します。

この場合、プロトコルの**相手ユーザ**に対してはコミットメントとなり得るかもしれませんが、
**プロトコル内の他ユーザ**に対しては、ナンス（nonce）が不明な為コミットメントとはなりません。

では単純に秘密（secret）をハッシュ（$\text{hash}(\text{secret})$）した場合はどうでしょうか？
秘密（secret）が、十分に大きい集合である場合は有効です。
ここで扱うのはUTXOで、UTXOは小さい集合なので、予測出来てしまいます。
したがって、ナンス（nonce）のような、十分に大きい集合を付加する事により予測不能な状態にしています。

# 解決（Solution）

あるプロトコルにおいて、**相手ユーザ**や**プロトコル内の他ユーザ**にコミットメントする方法です。

楕円曲線（elliptic curve）の生成元を $G$ としたとき、秘密鍵を$x$とすると、公開鍵は $P=xG$ となります。
また、[NUMS](https://en.wikipedia.org/wiki/Nothing-up-my-sleeve_number)の代替生成元 $J$ を利用します。

AliceとBobのプロトコル手順を見てみます。
Aliceは以下のように、$P$と$P_2$を計算します。

```math
\begin{align*}
P &= xG \\
P_2 &= xJ \\
\end{align*}
```

Aliceは、プロトコルのハンドシェイク時に、$\text{H}(P_2)$ をコミットメントとして送信します。
また、Alice（または、Bob）は、コミットメントを**プロトコル内に公開**します。

AliceはBobにプライベートチャンネルメッセージでプライベート情報を要求する場合、以下の値を計算します。

```math
\begin{align*}
K_G &= kG \\
K_J &= kJ \\
e &= \text{H}(K_G||K_J||P||P_2) \\
s &= k + xe \\
\end{align*}
```

AliceはBobに、$P,P_2,e,s$ を承認情報として送信します。
BobはAliceから受信した承認情報を以下の手順で検証します。

1. $\text{H}(P_2)$ を計算しハンドシェイク時に受信した値と同値であるかを確認します。
2. 複数、**プロトコル内に公開**されていない事を確認します。
3. $P$がUTXOとしてBlockchain内にある事を確認します。
4. $K_G = sG - eP$ を計算します。
5. $K_J = sJ − eP_2$ を計算します。
6. $e\overset{?}{=}\text{H}(K_G||K_J||P||P_2)$ を検証します。

検証が正常であれば、Bobはプライベート情報をAliceに送信します。

# 代替生成元 J を使用する理由<br>（Why an alternate generator point J?）

$\text{H}(P_2)$ を公開しても、Aliceが使用したいBitcoin公開鍵である $P$ に関する情報は提供されません。
そういった意味では、コミットメントでナンスを使用するのと同じです。
ただし、ナンスのような自由度はAliceに与えられていません。
$x$ を知らなければ、$P_2$ から $P$ を知る事はできません。
しかし、$J=x'G$ となる$x'$ を知っている場合は以下のように計算可能となります。

```math
P_2=xJ=x(x^∗G)=x^∗(xG)=x^∗P
```

この逆演算は可能です。
したがって、代替生成元の秘密（$x'$）はNUMSである必要があります。

***個人的な見解***
要するに、誰もが作成可能な楕円曲線上の点 $J$ ではあるが、誰も $J=x'G$ となる$x'$ を知らないようなものが必要です。
[An investigation into Confidential Transactions](https://github.com/AdamISZ/ConfidentialTransactionsDoc/blob/master/essayonCT.pdf)の**2.2**では、生成元 $G$ をsha256した値を点 $J$ の $x$ 座標としています。
したがって、$J=x'G$ となる$x'$ は誰もわかりません。（離散対数問題により求めるのは非常に困難）

# おわりに（Conclusion）

この方式は、元々[JoinMarket](https://en.bitcoin.it/wiki/JoinMarket)内で論議されてきた内容です。
これをカスタマイズしてLightningなどのファンド生成プロトコルに応用していくアプローチが出てきているようです。
ただ、個人的に気になるのをつらつらと挙げてみます。

- UTXOを公開鍵で特定しているが、同じ公開鍵を使ったUTXOは対象外なのか？（そもそも、同じ公開鍵は使わない方が良いのだが、現実的には同じ公開鍵を使っているケースが多い）
- コミットメントは、プロトコル内で公開するだけなので、プロトコル内での多重利用などは避けられるかもしれないが、他プロトコルでは検知できない。（パブリックブロックチェーンなんかに記載するのか？）

このあたりをどう解決していくのかが気になるとこです。

ただ、ナンスを使わずにコミットメント可能である方式については大変興味深く感じました。


# 参照（Reference）

- Bitcoin Optech #83<br>https://bitcoinops.org/en/newsletters/2020/02/05/

- Bitcoin Optech #83 (日本語版）<br>https://bitcoinops.org/ja/newsletters/2020/02/05/#ln

- P(o)ODLE<br>https://joinmarket.me/blog/blog/poodle/

- Nothing-up-my-sleeve number - Wikipedia<br>https://en.wikipedia.org/wiki/Nothing-up-my-sleeve_number

- An investigation into Confidential Transactions<br>https://github.com/AdamISZ/ConfidentialTransactionsDoc/blob/master/essayonCT.pdf