[EIP2334] BLS鍵における用途別パス構造の仕組みを理解しよう！

# はじめに

『DApps開発入門』という本や色々記事を書いているかるでねです。

https://amzn.asia/d/gxvJ0Pw

今回は、BLS12-381署名方式を使うEthereum 2.0や他のプロジェクト向けに、**EIP2333**によって導出された鍵に「用途ごとのパス（path）」を割り当てる仕組みを提案している**EIP2334**についてまとめていきます！

:::note info
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-2334

他にも様々なEIPについてまとめています。

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

# 概要

**EIP2334**は、**EIP2333**で生成される鍵に「目的」を割り当てるための標準を定義しています。
**EIP2333**ではBLS12-381署名方式に基づく鍵のツリー構造を提案していますが、**EIP2334**ではそのツリー内のどの鍵を使うべきかを文字列として表される「パス」によって指定します。

つまり、「シード」と「その鍵の用途（パス）」を指定することで、必要な鍵ペアを一意に導出できるようになります。
この仕組みにより、複数の目的に応じた鍵管理が効率的かつ標準化されます。

なお、この仕様はEthereum 2.0だけにとどまらず、BLS署名を採用している他のプロジェクトでも利用されることを意図しており、将来的にはより中立的なリポジトリへの移行も視野に入れられています。

:::note iofo
**EIP2333**については以下の記事を参考にしてください。
:::

https://qiita.com/cardene/items/99a51a2a78f3b774b400

# 動機

Ethereum 2.0やその他の多くのプロジェクトでは、BLS12-381に基づくBLS署名が使われます。
この方式には、**EIP2333**による新しい鍵導出スキームが必要です。
しかし、この新スキームは、従来使われていたBIP44とは互換性がありません。

BIP44では、UTXO（未使用トランザクション出力）ベースの設計や通常の鍵導出（BIP32）を前提としているため、以下の点でマッチしません。

:::note info
### BIP44とは？

BIP44（Bitcoin Improvement Proposal 44）は、階層的決定性ウォレット（HD Wallet）のためのアドレス設計ルールを定めた標準仕様です。
これは、1つのシード（秘密の文字列）から複数の鍵やアドレスを体系的に生成できるようにすることで、ウォレットの管理を容易にするために作られました。

#### 背景と目的

**BIP44**は、**BIP32**（HD Walletの基本仕様）および**BIP43**（目的フィールドの導入）を拡張する形で作られた提案です。
この規格の目的は、複数のコインやアカウントを1つのシードから安全かつ効率的に管理できるようにすることです。

#### パス構造

BIP44は、以下のような固定のパス構造を持っています。

```
m / purpose' / coin_type' / account' / change / address_index
```

それぞれの意味は以下のとおりです。

* `purpose`
    * 使用する仕様（**BIP44**なら44）を示す固定値（常に44’）
* `coin_type`
    * 使う仮装通貨（Bitcoinなら0、Ethereumなら60など）
* `account`
    * ユーザーが複数のアカウントを使いたいときに区別する単位
* `change`
    * 0なら外部アドレス、1なら内部アドレス（お釣り用など）
* `address_index`
    * 実際に使うアドレスをこのインデックスで順番に生成する

例えば、Ethereumで最初のアドレスを使いたい場合、以下のようなパスになります。

```
m/44'/60'/0'/0/0
```

#### 特徴

* **階層構造**により、多数のアドレスを一元的に管理可能
* アドレスを体系的に生成できるため、バックアップは1つのシードだけで済む
* 複数通貨やアカウントの分離が可能

#### Ethereumにおける扱い

EthereumではこのBIP44を元にして、ウォレットアプリ（MetaMaskなど）がアドレスを導出しています。
一般的に `m/44'/60'/0'/0/x` 形式のパスが使われています（60はEthereumのcoin\_typeです）。
:::

* 鍵導出に「ハード化された鍵（hardened key）」しか使えない
* 各レベルで生成可能な鍵の数が異なる
* パス構造がUTXOに特化している

そのため、**EIP2333**の鍵ツリーを利用するためには、新しい用途指向のパス構造を定義する必要があります。
**EIP2334**はその標準化を目指しており、Ethereum 1.0時代に乱立していた複数のウォレットパス（**ERC600**や**ERC601**のような）を解消する狙いもあります。

:::note info
**ERC600**については以下の記事を参考にしてください。
:::

https://qiita.com/cardene/items/1a0a0e50c77c7c3be091

:::note info
**ERC601**については以下の記事を参考にしてください。
:::

https://qiita.com/cardene/items/a29e84d0c12815d2ef9d

# 仕様

### パス構造の仕様

**EIP2334**では、**EIP2333**によって生成される鍵のツリーをたどるための「パス」を定義しています。
パスは整数の並びで構成され、`/`で階層構造を表現します。
必ず5階層（マスターノードを含めて）が使われます。

基本構造は以下のとおりです。

```
m / purpose / coin_type / account / use
```

### パス記法のルール

* `m`
    * ツリーの最上位（ルート）ノードを示します。
* `/`
    * 階層の区切りを表します。
    * 例えば `i/j` は「`j` は `i` の子ノード」であることを示します。
* `purpose`
    * このフィールドは `12381` に固定されています。
    * これは、BLS12-381という楕円曲線（暗号技術）を用いることを示しています。
    * ただし、この値を使うには**EIP2333**の鍵導出スキーム（KDF）を実装している必要があります。
* `coin_type`
    * どのブロックチェーン（コイン）で使う鍵かを区別するためのフィールドです。
    * 各コインに固有の番号が割り当てられており、異なるチェーン間で鍵が混ざらないようにします。
* `account`
    * ユーザーが用途ごとに鍵を分けたい場合に使う階層です。
    * 例えば、複数のアカウントを持つウォレットアプリではこのフィールドでそれらを区別します。
* `use`
    * 1つのアカウント内でさらに細かい用途に応じて鍵を分けたい場合に使用します。
    * 通常は `0` が使われますが、アプリケーションによっては他の値を用いることもあります。
    * セキュリティ上、同じアカウント内でも異なる操作に異なる鍵を使うことが推奨されます。

### Ethereum 2.0における特定のパス

#### `coin_type`（Ethereum 2.0）

* Ethereum 2.0では、BLS12-381用の `coin_type` として `3600` が使われます。

#### バリデーター用鍵の構造

Ethereum 2.0のバリデーターは、2種類の鍵を持ちます。

* **引き出し用鍵（withdrawal key）**
    * ステーキング解除や資金移動に使用される鍵
    * パス：`m/12381/3600/i/0`
    * ここで `i` は第 `i` 番目のバリデーターを意味します。
* **署名用鍵（signing key）**：バリデーターとしてブロック提案などの動作をするための鍵
    * パス：`m/12381/3600/i/0/0`
    * これは、上記の引き出し鍵の子ノード（0番目の子）として位置づけられます。

この構造によって、引き出し鍵と署名鍵の関係が明確になり、安全かつ体系的な鍵管理が可能になります。

#### 特殊なケースへの対応

秘密分散（secret-sharing）やカストディ型（custodial）バリデーターのように、このパス構造を使えない場合もあります。
その場合でも、可能な限りこの仕様に準拠するようするべきです。
例えば、引き出し鍵はユーザー自身がこのパスで生成し、署名鍵についてはサービスプロバイダーが別の方法で管理しても問題ありません。

# 補足

### 用語選定の背景と理由

**EIP2334**では、`purpose`、`coin_type`、`account` といったフィールド名が使われています。
これらはすでにBIP43およびBIP44で広く採用されているため、既存の概念との互換性やユーザーの理解しやすさを考慮して、同じ用語が再利用されています。

ただし、`purpose` の値自体は `12381` として新たに定義されています。
これは、鍵導出の仕組み（KDF）やパスの構造がBIP44とは非互換であるため、明確に区別する必要があるためです。
`12381` という値は、使用する暗号曲線である「BLS12-381」に由来しています。

また、`account` は、ユーザーが鍵の利用目的ごとにアカウントを分けたい場合に便利な区切りとなります。
`use` フィールドは、アプリケーション側で用途ごとに独立した鍵を割り当てたい場合に利用される想定です。例えば、同じアカウントでも署名用・支払い用など異なる場面で使い分けが可能です。

### Ethereum 2.0における特別な設計意図

#### Eth2の新しい`coin_type`（3600）

Ethereum 2.0用に新しく `coin_type = 3600` が導入されました。
これはEthereum 1.0の `coin_type = 60` と区別するためのもので、サービス（例：ENSのマルチチェーンアドレス解決機能）がコインごとに異なる識別子を必要とする場面において混同を防ぐためです。
また、3600は60の2乗（60²）であり、Ethereum 2.0がEthereum 1.0の次世代であることを象徴する設計でもあります。

#### 署名鍵と引き出し鍵の分離理由

Ethereum 2.0のバリデーターは、以下の2種類の鍵を使い分けます。

* **署名鍵（signing key）**
    * ブロックの提案や投票など、バリデーターとしての活動に使われる鍵。
    * クライアントがオンライン状態で保持する「ホットキー」であり、万が一流出した場合はスラッシュ（罰則）のリスクがあります。
* **引き出し鍵（withdrawal key）**
    * ステーキング解除や資金の移動に使われる鍵。
    * オフラインで安全に保管される「コールドキー」であり、資金への直接アクセス権限を持つため、より強いセキュリティが必要です。

この2つを分離することで、バリデーターのセキュリティリスクを最小限に抑える設計となっています。
さらに、署名鍵は引き出し鍵の子ノードとして派生されているため、万が一署名鍵が失われた場合でも、引き出し鍵があれば復元可能です。
これは安全性とリカバリー性の両立を意識した構造です。

# 互換性

Ethereum 1.0では、鍵の管理にBIP43およびBIP44が広く使われてきました。
これらはHDウォレット（階層的決定性ウォレット）におけるパス構造を定義する規格ですが、実は正式に「標準」として採択されたものではありません。

一方、Ethereum 2.0では、BLS12-381署名方式を採用しており、その鍵導出の仕組みとして**EIP2333**が導入されました。
**EIP2333**では、従来のBIP32で使われていたKDF（鍵導出関数）とは異なる方式が使われているため、BIP44などの旧方式とは互換性がありません。

そのため、**EIP2334**では、**EIP2333**に適した新しいパス構造を定義しています。
ただし、用語や階層構造はBIP44に近いため、ユーザーにとっては理解しやすいものとなっています。

また、重要な点として、`purpose = 12381` を使ったこの新しいパス構造では、「ハード化された鍵（hardened key）」をサポートしていません。
BIP44ではハード化された鍵を表すために `'`（アポストロフィ）が使われますが、**EIP2334**ではこの `'` 記号は無効となります。
これは、**EIP2333**で定義されているBLS鍵導出方式では、全ての子鍵の生成に親の秘密鍵が必ず必要になる仕組みになっているためです。
つまり、BIP44で使われているような「ハード化された鍵（秘密鍵がなければ導出できない鍵）」と同等の安全性が標準で確保されているため、あえて `'` を使ってハード化を指定する必要がありません。

その結果として、この方式では `'` を使うパス指定は無効とされており、すべての鍵導出は自動的にハード化された状態で行われます。

# 引用

Carl Beekhuizen (@CarlBeek) <carl@ethereum.org>, "ERC-2334: BLS12-381 Deterministic Account Hierarchy [DRAFT]," Ethereum Improvement Proposals, no. 2334, September 2019. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2334.

# 最後に

今回は「BLS12-381署名方式を使うEthereum 2.0や他のプロジェクト向けに、**EIP2333**によって導出された鍵に「用途ごとのパス（path）」を割り当てる仕組みを提案している**EIP2334**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

他の媒体でも情報発信しているのでぜひ他も見ていってください！

https://chaldene.net/

https://zenn.dev/heku

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4