ステルスアドレスを使うと、アドレスを 1 つ公開しておくだけで、自分宛てのすべての支払いがチェーン上の毎回新しい場所に届きます。このガイドでは、その仕組み、ビューキーとスペンドキーそれぞれの役割、そしてウォレットが自分宛ての支払いを見つける方法を、Blocknet を具体例として説明します。
ステルスアドレスとは何ですか?
ステルスアドレスとは、ブロックチェーン上に決して現れない公開アドレスです。スペンドキーとビューキーという 2 つの公開鍵を持っています。支払いのたびに、送信者のウォレットがそれらを新しい乱数と組み合わせてワンタイムアドレスを作り、そのアドレスを認識して使えるのは受信者だけです。
公開台帳では、通常のアドレスは受け取るすべての支払いに現れます。標準的な Bitcoin アドレスはこのように動作し、アドレスを知っている人なら誰でも各支払いを調べ、合計を出せます。多くの Bitcoin ウォレットが支払いごとに新しいアドレスを発行するのはそのためです。
ステルスアドレスは、その作業を代わりに行ってくれます。Web サイト、プロフィール、または @name としてアドレスを 1 つ共有すれば、送信者はそれぞれそこから異なるワンタイムアドレスを導出します。自分宛ての 10 回の支払いは、互いにも共有したアドレスとも目に見える共通点のない 10 個のアウトプットになります。やり取りは必要ありません。送信者は、公開アドレスと乱数から、単独でワンタイムアドレスを求めます。
ステルスアドレスはどこから生まれたのですか?
Monero、Blocknet などのコインで使われているワンタイムアドレスの設計は、Nicolas van Saberhagen による 2013 年 10 月 17 日付の CryptoNote v2.0 ホワイトペーパーにさかのぼります。この論文はこの考え方を「リンク不可能な支払い」と呼び、送信者が受信者のアドレスから「ワンタイム公開鍵」を生成する方法を説明しています。Monero のドキュメントは、ステルスアドレスによって送信者が「受信者に代わって、トランザクションごとにランダムなワンタイムアドレス」を作れると説明しています。
この考え方はプライバシーコイン以外にも広がっています。Bitcoin の BIP 352「Silent Payments」は、固定の Bitcoin アドレスでチェーン上で結び付けられない支払いを受け取れるようにするもので、2022 年に作られた Ethereum の ERC-5564 は、Ethereum アカウント向けのステルスアドレスを標準化しています。どちらも、それぞれのチェーンでは任意で使う機能です。Blocknet では、すべての支払いがワンタイムアドレスを使います。
ステルスアドレスはどのように機能しますか?
送信者は乱数 r を選び、R = r·G をトランザクションに公開し、r と受信者の公開ビューキーを組み合わせて共有秘密を作ります。その秘密を公開スペンドキーに加えたものがワンタイムの鍵です。受信者は R と自分の秘密ビューキーから同じ秘密を再現できるので、支払いを見つけられるのは受信者だけです。
ウォレットは 2 つの鍵ペアを持っています。それぞれの秘密鍵は秘密の数(スペンド用の s とビュー用の v)で、公開鍵はその数に曲線上の固定点 G を掛けたものです。アドレスは 2 つの公開鍵 S と V だけでできています。やり取りの全体は次のとおりです。
Receiver publishes: S = s·G and V = v·G
Sender picks r: R = r·G (stored in the transaction)
One-time key: P = H(r·V)·G + S
Receiver checks: H(v·R)·G + S == P (true because r·V = v·R)
Key to spend it: x = H(v·R) + s (so P = x·G)
ポイントはディフィー・ヘルマン鍵交換です。送信者は r·V を計算し、受信者は v·R を計算します。どちらも r·v·G なので、両者は同じ点にたどり着きます。r と v はほかの誰も知らないので、ほかの誰もそれを計算できません。その点をハッシュ化(H)すると共有秘密が得られ、ワンタイムの鍵 P は、その秘密を点として公開スペンドキーに加えたものです。
スキャンするときは、R と自分の秘密ビューキーから秘密を計算し直し、それが P と一致するかを確認します。一致すれば、そのアウトプットは自分のものです。それを使うときは、ウォレットが同じ秘密を秘密スペンドキーに加え、そのアウトプット専用の秘密鍵 x を得ます。
Blocknet は Curve25519 上の Ristretto グループでこの設計に従い、Blocknet 固有のドメインタグを付けて SHA-256 でハッシュ化します。また、トランザクション内での各アウトプットの位置もハッシュに混ぜるので、1 つのトランザクションで同じ人に送る 2 つのアウトプットでも、互いに無関係な鍵になります。同じ共有秘密から、アウトプットの金額を隠すブラインディングファクターと、メモを暗号化する鍵も導出されるので、受信者は両方を読めます。
ビューキーとスペンドキーは何をしますか?
鍵を分けることで、2 段階のアクセスが可能になります。
- 秘密ビューキーは支払いを見つけます。 v と公開スペンドキーがあれば、ウォレットはあなた宛てのすべてのアウトプットを認識し、金額を復号し、メモを読めます。
- 秘密スペンドキーはそれを使います。 見つけたアウトプットを、支払いに署名できる秘密鍵 x に変えられるのは s だけです。
この分割によって、閲覧専用ウォレットが可能になります。Blocknet のコマンドライン版ウォレットでは、viewkeys でビューキーから別のウォレットファイルを作ります。ウォレットのヘルプは、これを「監視はできるが支払いはできない」ファイルで、「別のマシンで閲覧専用のアクセスがほしい」ときに便利だと説明しています。実行すると、ウォレットは何を作るのかを説明します。
# View Keys
This will create a view-only wallet that can monitor incoming
funds but CANNOT spend. Anyone with this file can see your
balance and transaction history.
閲覧専用ウォレットは、会計士など履歴を見せてもよい人にだけ渡すか、自分の 2 台目のコンピューターに置いてください。どちらの場合も、スペンドキーは信頼できるマシンに置いたまま、資金の到着を確認できます。
ウォレットはどのように支払いを見つけますか?
ワンタイムの鍵はアドレスと無関係に見えるので、チェーン上にはどのアウトプットが自分のものかを示すラベルはありません。ウォレットが自分で確認します。新しいブロックのすべてのトランザクションについて、R を取り出し、秘密ビューキーで共有秘密を計算し、各アウトプットを上の式で確かめます。ウォレットの同期中に行われているのはこの処理です。
Blocknet のスキャナーはこれを素早く行います。コストのかかる処理である R とビューキーの掛け算はトランザクションごとに 1 回だけ実行し、そのトランザクションのすべてのアウトプットをその結果と照合します。アウトプットが一致すると、ウォレットは金額を復号し、アウトプットのペダーセンコミットメントと照合して確認してから残高に加えます。
スキャンのおかげで復元も簡単です。Blocknet の 2 つの鍵ペアはどちらも 12 単語のリカバリーシードから生成されるので、新しいコンピューターでシードを復元すると鍵が再現され、ウォレットがチェーンを再スキャンして自分のアウトプットをすべて見つけます。シードのバックアップと復元の方法は、Blocknet ウォレットガイドで紹介しています。
Blocknet のステルスアドレス
Blocknet では、ステルスアドレスとは単にあなたのアドレスのことです。公開スペンドキー、公開ビューキー、4 バイトのチェックサムを base58 でエンコードしたもので、長さは 92 文字または 93 文字です。トランザクション形式に公開モードがないので、自分宛てのすべての支払いがこれを使います。ブロック報酬もワンタイムの鍵に送られるので、ソロマイナーのコインベースアウトプットも同じスキャンで見つかります。
ステルスアドレスは、Blocknet のほかのプライバシー機能と組み合わさっています。16 のリングは支払いがどのアウトプットから来たかを隠し、コミットメントは金額を隠し、Dandelion++ はトランザクションがどこからネットワークに入ったかを隠します。Blocknet のプライバシーガイドで各層を順に説明しています。
ステルスアドレスは名前とも連携します。@yourname のような Blocknet ID のショートネームは公開の形でアドレスに対応付けられるので、送信者は blocknet.id で調べられます。それでも支払い自体は新しいワンタイムの鍵に送られるので、名前からあなたが何を受け取ったかは何もわかりません。
そのためショートネームは、マイニングの受け取りアドレスとして便利です。seine を起動し、プロンプトでアドレスまたは @yourname を入力し、デフォルトのプール bntpool.com を選びます。残りはマイニングガイドで説明しており、獲得した BNT はウォレットが上で説明したビューキーによるスキャンで見つけます。
よくある質問
ステルスアドレスとワンタイムアドレスは同じものですか?
1 つの仕組みの 2 つの側面です。ステルスアドレスは公開するアドレスで、公開スペンドキーと公開ビューキーからできています。ワンタイムアドレスは、送信者がそこから 1 回の支払いのために導出する新しい鍵です。チェーン上に現れるのはワンタイムアドレスだけで、公開したアドレスは決して現れません。
ステルスアドレスを知られたら残高を見られますか?
いいえ。公開したアドレスを知っていても、誰も支払いを見つけることはできません。それぞれの支払いは、アドレスとは無関係に見えるワンタイムの鍵に届くからです。支払いを見つけるには秘密ビューキーが必要なので、受け取ったものを一覧できるのは自分のウォレットだけです。Blocknet では金額も隠されているので、アウトプット自体にも金額は表示されません。
秘密ビューキーで何ができますか?
秘密ビューキーを持っている人は、あなた宛ての支払いを見つけ、その金額とメモを読めます。支払いには秘密スペンドキーが必要なので、何かを送金することはできません。Blocknet では、viewkeys コマンドでビューキーから閲覧専用ウォレットを作れるので、2 台目のコンピューターで資金を確認するのに便利です。信頼できる人にだけ渡してください。
Blocknet ではステルスアドレスを有効にする必要がありますか?
いいえ。トランザクション形式に公開モードがないので、Blocknet のすべての支払いは自動的にワンタイムのステルスアドレスに送られます。ウォレットは送金時にワンタイムの鍵を作り、同期時にビューキーで入金を見つけます。アドレス宛てでも @name 宛てでも、設定することは何もありません。