# Confidential Transfer

XRP LedgerのConfidential Transferは、[EC-ElGamal暗号](https://en.wikipedia.org/wiki/ElGamal_encryption)と[ゼロ知識証明(ZKP)](https://en.wikipedia.org/wiki/Zero-knowledge_proof)を使用し、Multi-Purpose Token(MPT)の保有者が自分の残高と送金額を非公開に保てるようにする機能です。個々の残高と送金額は公開レジャーから遮蔽される一方で、発行者と規制当局が総供給量を検証し規制上の義務を果たせるよう、コンプライアンスの仕組みは維持されます。監査可能性を保ちながら、金融アプリケーションに求められる機関水準のプライバシーに応える設計です。

同じトークンについて公開残高と機密残高は共存でき、1つのMPTの中に、公開で保有される残高と非公開で保有される残高が混在しても構いません。トークン保有者は、必要に応じて公開残高を機密形式へ変換することも、元の形式へ戻すこともできます。

注記
Confidential Transferが使えるのは、アカウント間の直接の支払いだけです。XRP LedgerのDEX、エスクロー、チェックなど、他のトランザクションタイプでは動作しません。

_Requires the [ConfidentialTransfer amendment](/resources/known-amendments#confidentialtransfer). (Open for Voting: 5.71%)_

## Confidential Transferの主な機能

Confidential Transferは、発行者のセカンドアカウントモデル、プライバシーとコンプライアンスを両立するマルチ暗号文アーキテクチャ、送金の確実性を支える残高分割モデルという3つの設計原則の上に成り立っています。

### 発行者のセカンドアカウントモデル

発行者は、主となる発行アカウントではなく専用の **セカンドアカウント** を通じて機密トークンを流通させます。発行者の主アカウントは機密残高を保有できません。その残高が流通トークン数に算入されないためです。

機密トークンを発行するには、まずセカンドアカウントに公開残高を用意し、そのセカンドアカウントから[ConfidentialMPTConvertトランザクション](/ja/docs/references/protocol/transactions/types/confidentialmptconvert)で公開残高を機密形式へ変換します。

機密トークン発行の流れは以下のとおりです。

1. 発行者がMPT発行を作成します。
2. 発行者が専用の *セカンドアカウント* を作成します。
3. 発行者が専用の *セカンドアカウント* へ公開のMPTを送信します。
4. 専用の *セカンドアカウント* が公開残高を機密残高へ変換します。


XRP Ledgerはセカンドアカウントを通常の *保有者* として扱うため、その残高は流通トークン数に算入されます。そのため、バリデータは、機密残高を復号することなく[供給上限](/ja/docs/concepts/tokens/fungible-tokens/multi-purpose-tokens#%E4%BE%9B%E7%B5%A6%E4%B8%8A%E9%99%90)を強制できます。

この方式により、機密での配布が可能になります。各保有者に公開から非公開への変換をさせるのではなく、発行者がセカンドアカウント上で一度だけ変換し、そこからユーザへ直接配布できるからです。ただし、受取人は、機密送金を受け取る前に[暗号鍵の登録](#%E9%8D%B5%E3%81%AE%E7%99%BB%E9%8C%B2)を完了しておく必要があります。

### マルチ暗号文アーキテクチャ

1つの機密残高は、それぞれ別の目的を持つ複数の暗号文で並行して表現されます。

- **保有者による暗号化:** 保有者の残高は保有者自身の公開鍵で暗号化され、排他的な支払権限を与えます。
- **発行者による暗号化:** 保有者の残高は発行者の公開鍵でも暗号化され、支払権限を与えることなく、供給量の検証とコンプライアンスのための暗号化されたミラーが作られます。
- **監査人による暗号化（任意）:** 設定した場合、保有者の残高は監査人の公開鍵でも暗号化され、独立した検証と[オンチェーンの選択的開示](#%E3%82%AA%E3%83%B3%E3%83%81%E3%82%A7%E3%83%BC%E3%83%B3%E3%81%AE%E9%81%B8%E6%8A%9E%E7%9A%84%E9%96%8B%E7%A4%BA)が可能になります。


公開鍵は、secp256k1上のEC-ElGamal暗号を使用して、オフチェーンで生成する必要があります。

注記
この暗号方式は耐量子性を持つとはみなされていません。将来的にXRP Ledgerは、格子暗号にもとづく方式など、ポスト量子に適した方式へ移行する可能性があります。耐量子性を実現するための具体的な移行経路と時期は、現在も研究の途上にあります。

#### 鍵の登録

Confidential Transferに参加するには、保有者はまず[ConfidentialMPTConvertトランザクション](/ja/docs/references/protocol/transactions/types/confidentialmptconvert)で公開残高を機密形式へ変換する必要があります。この最初の変換がオプトインの手続きを兼ね、保有者のElGamal公開鍵をレジャーへ登録することで、機密残高の受け取りと[管理](#%E6%A9%9F%E5%AF%86%E6%AE%8B%E9%AB%98%E3%81%AE%E7%AE%A1%E7%90%86)ができるようになります。変換額は0でも構わないため、トークンを1つも変換せずに鍵だけ登録することも可能です。

発行者と監査人は、MPT発行で[Confidential Transferを有効にする](#%E3%83%97%E3%83%A9%E3%82%A4%E3%83%90%E3%82%B7%E3%83%BC%E3%81%AE%E5%88%B6%E5%BE%A1)際に自分の鍵を登録します。

警告
**保有者が秘密鍵を失うと、その機密資金は永久に失われます。**
発行者と監査人の鍵も、一度登録すると変更も削除もできません。

#### ゼロ知識証明

XRP Ledgerは一連のZKP（ゼロ知識証明）を使用し、残高や送金額を明かさずに機密トランザクションを検証します。使用される証明は以下の種類です。

- **Schnorrの知識証明:** ElGamal公開鍵に対応する秘密鍵を所有していることを証明します。保有者が最初に暗号鍵を登録する際に必要です。
- **コンパクトシグマ証明:** *AND合成コンパクトシグマ証明* とも呼ばれる暗号学的証明で、複数のゼロ知識ステートメントを1つの固定長の証明にまとめ、一度の検証で確かめます。機密トランザクションの各タイプは、暗号化された値が整合し正しく結び付いていることを確かめるための専用のコンパクトシグマ証明を持ちます。
- **範囲証明(Bulletproofs):** 機密の金額と送金後の残高が負の値でなく、有効な範囲に収まっていることを証明し、過剰な支払いを防ぎます。


バリデータはこれらの暗号学的証明を確かめることで、背後にある金額を一切知らないまま機密トランザクションを検証できます。たとえば保有者がトークンを機密で送る際は、トランザクションには暗号化された値と、以下の点を数学的に示す証明が含まれます。

- 送金者に十分な残高があること
- 金額が負の値でないこと
- 送金額の暗号化されたコピーが、送金者、受取人、発行者、任意の監査人の間ですべて整合していること


バリデータは、トランザクションが有効であることを確かめるために、これらの証明の数学的な正しさを検証できるだけで、実際の金額を見ることはできません。

### 残高分割モデル

*古くなった証明* の問題、つまり保有者が送金のために生成したばかりの証明を、受け取った送金が無効にしうる問題を防ぐため、各アカウントの機密残高は2つに分かれています。

- **支払残高(Spending Balance):** 送金トランザクションの証明を生成するために使用する、安定した残高です。
- **受信残高(Inbox Balance):** 受け取った機密送金がすべて入ります。


保有者が機密送金を受け取ると、その金額は受信残高に入ります。使えるようにするには、[ConfidentialMPTMergeInboxトランザクション](/ja/docs/references/protocol/transactions/types/confidentialmptmergeinbox)で支払残高へ統合する必要があります。統合を明示的に行わない限り、受け取った資金は受信残高に蓄積され、安全ではあるものの、支払残高へまとめるまでは使えません。

統合すると、受信残高は決定論的な「暗号化されたゼロ」の値にリセットされます。このゼロ値はゼロを表す有効なElGamal暗号文ですが、秘密鍵を持たない観測者には他の暗号文と区別がつきません。

#### バージョンカウンタ

支払残高が変わるたびに **バージョンカウンタ** が1つ増加し、新たに生成される証明に結び付けられます。[リプレイ攻撃](https://en.wikipedia.org/wiki/Replay_attack)を防ぐためです。機密での送金、受信残高の統合、公開形式への変換、残高の回収は、いずれもカウンタを増加させます。したがって、これらの変更より前に生成された証明はもはや有効ではありません。

## プライバシーの性質

Confidential Transferは取引額と残高を非公開に保ちますが、一部の情報はレジャー上で公開されたままです。

非公開
- 取引額は暗号化されます。
- アカウント残高は暗号化され、保有者、発行者、設定された監査人だけが参照できます。バリデータやネットワークの観測者に見えるのは暗号文と暗号学的証明だけで、背後の金額は決して見えません。
- 保有者間での機密供給量の分布。どのアカウントが機密供給量のうちどれだけを保有しているかを、レジャーは公開しません。


公開
- 送金者と受取人のアドレス
- 送信されたトランザクションの種類
- トークンの総供給量。レジャーは2つの平文の値を公開で追跡します。`OutstandingAmount`（流通しているトークンの総数）と `ConfidentialOutstandingAmount`（そのうち機密で保有されている量）です。バリデータはこれらの値を使用し、残高を復号せずに供給上限を強制します。
- 公開形式と機密形式を相互に変換する際の変換額


取引量が少ない状況では、公開されている要素からパターンが読み取れる点に注意してください。たとえばあるアカウントが1,000,000トークンを機密形式へ変換し、後から800,000トークンを公開形式へ戻したなら、観測者は200,000トークンが機密形式のまま残っていると分かります。ただし、そのトークンが他のアカウントへ送金されたのか、元のアカウントが保有し続けているのかまでは判別できません。ゼロを表す暗号化された残高は、ゼロでない残高と区別がつかないからです。

機密トランザクションを行う参加者が多いほどプライバシーは強くなる点を、念頭に置いてください。

## 監査可能性とコンプライアンス

XRP Ledgerは、隠された残高を監査する方法として、オンチェーンの選択的開示と、発行者を介した監査の2つを用意しています。加えて、コンプライアンス執行のための専用の回収の仕組みも備えています。

### オンチェーンの選択的開示

発行者は[MPTokenIssuanceSetトランザクション](/ja/docs/references/protocol/transactions/types/mptokenissuanceset)で監査人のElGamal公開鍵をMPT発行に登録し、監査人を設定できます。これによって各保有者の機密残高が監査人の公開鍵でも暗号化され、監査人は発行者や保有者の協力を得ずに、オフチェーンで独立して残高を復号して検証できます。たとえば監査人に指定された規制当局は、自分の秘密鍵を使用してレジャー上の保有者の機密残高を復号し、独立した検証を行えます。

### 発行者を介した監査

もう1つの方法として、発行者が自分のElGamal秘密鍵を監査人と共有し、監査のアクセスを提供することもできます。発行者はすべての保有者残高について暗号化されたミラーを保持しているため、その鍵はすべての機密残高と取引額への読み取り専用アクセスをもたらします。たとえば規制当局があるユーザの取引履歴へのアクセスを求めた場合、発行者は自分のElGamal秘密鍵を規制当局に提供できます。規制当局はその鍵で、該当する機密残高と取引額をレジャーから直接復号できます。

この方法は運用が簡単な反面、発行者が完全で正確な情報を提供していると監査人が信頼する必要があり、また監査人には発行者と同じ復号能力が渡ります。

### 機密残高の回収

発行者は、公開のトランザクションと同じ[コンプライアンス管理](/ja/docs/concepts/tokens/fungible-tokens/multi-purpose-tokens#%E3%82%B3%E3%83%B3%E3%83%97%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%82%B9%E7%AE%A1%E7%90%86)を引き続き利用できますが、機密残高に対する回収の動作は異なります。

[ConfidentialMPTClawbackトランザクション](/ja/docs/references/protocol/transactions/types/confidentialmptclawback)を使用すると、発行者は保有者の機密残高を **全額** 回収できます。発行者はオフチェーンで、自分が持つ保有者残高のミラーコピーを復号し、その平文の金額を裏づける暗号学的証明を生成します。そのうえで、平文の金額と証明を添えてトランザクションを送信します。

注意
証明の生成から検証までの間に保有者の機密残高が変わると、回収の証明は古くなる場合があります。証明の正しさと状態の整合性を保ち、トランザクションがレジャー上で失敗しないようにするため、発行者は機密残高の回収について以下の流れに従ってください。

1. `tfMPTLock` フラグを有効にした[MPTokenIssuanceSetトランザクション](/ja/docs/references/protocol/transactions/types/mptokenissuanceset)を送信し、その保有者に対してMPT発行を[ロック](/ja/docs/concepts/tokens/fungible-tokens/deep-freeze)します。
2. ConfidentialMPTClawbackトランザクションを送信します。


バリデータが証明を検証すると、平文の金額が暗号化された残高と一致することが暗号学的に確定します。有効であれば、保有者の支払残高と受信残高はどちらも暗号化されたゼロに設定され、バージョンカウンタが増加し、回収されたトークンは流通から取り除かれます。

## プライバシーの制御

発行者は、MPT発行に **Can Hold Confidential Balance** フラグを設定することで機密機能を有効にできます。設定は、最初の[MPTokenIssuanceCreateトランザクション](/ja/docs/references/protocol/transactions/types/mptokenissuancecreate)で行うことも、後から[MPTokenIssuanceSetトランザクション](/ja/docs/references/protocol/transactions/types/mptokenissuanceset)で行うこともできます。

他の[MPT発行フラグ](/ja/docs/references/protocol/ledger-data/ledger-entry-types/mptokenissuance#mptokenissuance%E3%81%AE%E3%83%95%E3%83%A9%E3%82%B0)と同じく、**Can Hold Confidential Balance** フラグを有効にする操作は **一方向** です。後続のどのトランザクションでも無効に戻せません。

Confidential Transferを有効にする際、発行者は自分のElGamal公開鍵も登録する必要があり、任意で監査人の鍵も登録できます。鍵を登録できるのはMPTokenIssuanceSetトランザクションだけであるため、作成時にフラグを設定した発行者は、保有者が変換を始める前に別途このトランザクションを送信する必要があります。機密残高が一度流通し始めると、鍵は登録できなくなります。

MPT発行の送金手数料は **0** でなければなりません。暗号化された金額には送金手数料を適用できないためです。手数料がゼロでない発行については、Confidential Transferを有効にする前に発行者が手数料を0に戻す必要があります。

注意
**Can Hold Confidential Balance** フラグを有効にしないまま[変更不可](/ja/docs/concepts/tokens/fungible-tokens/mutable-mpts#mpt%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%81%AE%E5%A4%89%E6%9B%B4%E4%B8%8D%E5%8F%AF%E5%8C%96)と宣言すると、そのMPT発行はConfidential Transferに対応できなくなります。

## 機密残高の管理

トークン保有者は、4つの操作で機密残高を管理します。

- **機密形式へ変換する:** [ConfidentialMPTConvertトランザクション](/ja/docs/references/protocol/transactions/types/confidentialmptconvert)は公開トークンを機密形式へ変換します。変換額は平文で見え、保有者の公開鍵は最初の変換の際に登録されます。
- **機密で送信する:** [ConfidentialMPTSendトランザクション](/ja/docs/references/protocol/transactions/types/confidentialmptsend)は保有者間で機密トークンを送金します。送金額は暗号化されたまま公開されず、ZKPがトランザクションの妥当性を保証します。このトランザクションは、[Deposit Authorization](/ja/docs/concepts/accounts/depositauth)や[クレデンシャル](/ja/docs/concepts/decentralized-storage/credentials)を含め、標準的なMPTの支払いと同じ認可要件に対応します。
- **受け取った送金を統合する:** [ConfidentialMPTMergeInboxトランザクション](/ja/docs/references/protocol/transactions/types/confidentialmptmergeinbox)は受け取ったトークンを支払残高へまとめ、送金に使える状態にします。
- **公開形式へ戻す:** [ConfidentialMPTConvertBackトランザクション](/ja/docs/references/protocol/transactions/types/confidentialmptconvertback)は機密トークンを公開形式へ戻し、金額を再びレジャー上で見えるようにします。


## 関連項目

- **コンセプト:**
  - [Multi-Purpose Token](/ja/docs/concepts/tokens/fungible-tokens/multi-purpose-tokens)
- **チュートリアル:**
  - [Confidential Transfer向けMPTの発行](/ja/docs/tutorials/tokens/mpts/issue-mpt-for-confidential-transfers)
  - [機密MPT支払いの送信](/ja/docs/tutorials/payments/send-confidential-payments)
  - [機密残高の回収](/ja/docs/tutorials/tokens/mpts/claw-back-confidential-balances)
- **リファレンス:**
  - [MPTokenエントリ](/ja/docs/references/protocol/ledger-data/ledger-entry-types/mptoken)
  - [MPTokenIssuanceエントリ](/ja/docs/references/protocol/ledger-data/ledger-entry-types/mptokenissuance)
  - [ConfidentialMPTClawbackトランザクション](/ja/docs/references/protocol/transactions/types/confidentialmptclawback)
  - [ConfidentialMPTConvertトランザクション](/ja/docs/references/protocol/transactions/types/confidentialmptconvert)
  - [ConfidentialMPTConvertBackトランザクション](/ja/docs/references/protocol/transactions/types/confidentialmptconvertback)
  - [ConfidentialMPTMergeInboxトランザクション](/ja/docs/references/protocol/transactions/types/confidentialmptmergeinbox)
  - [ConfidentialMPTSendトランザクション](/ja/docs/references/protocol/transactions/types/confidentialmptsend)
  - [MPTokenIssuanceCreateトランザクション](/ja/docs/references/protocol/transactions/types/mptokenissuancecreate)
  - [MPTokenIssuanceSetトランザクション](/ja/docs/references/protocol/transactions/types/mptokenissuanceset)