# [ERC7627] ユーザー間のメッセージ送信を安全に暗号化する仕組みを理解しよう！

> この提案は、ブロックチェーン上で暗号化されたメッセージを安全に交換する機能を実装することを目指しています。

- URL: https://cardene.dev/articles/00371797fd85ae1cd9b9
- 公開日: 2024-04-01
- 更新日: 2024-04-01
- トピック: Blockchain
- タグ: ethereum, solidity, smartcontract, ブロックチェーン

## はじめに

初めまして。
**CryptoGames**というブロックチェーンゲーム企業でエンジニアをしている **cardene（かるでね）** です！
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

https://cryptogames.co.jp/

代表的なゲームは**クリプトスペルズ**というブロックチェーンゲームです。

https://cryptospells.jp/

今回は、ブロックチェーンでの署名に使用される暗号化アルゴリズムについて、様々なアルゴリズムの使用や安全なメッセージ送信をサポートする仕組みを提案している**ERC7627**についてまとめていきます！

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

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

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

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

## 概要

この提案は、ブロックチェーン上で暗号化されたメッセージを安全に交換する機能を実装することを目指しています。
ユーザーは自分の公開鍵と使用する暗号化アルゴリズムを登録することができ、その後、他のユーザーのアドレスを使って暗号化されたメッセージを送信することができます。
公開鍵アルゴリズムの種類とユーザー情報を管理するための構造体を含むインターフェースも提供されます。
これにより、さまざまな暗号化アルゴリズムやユーザー情報の管理がサポートされます。

ここでのキーポイントは以下の通りです。

#### 公開鍵と暗号化アルゴリズムの登録
ユーザーは、自分の公開鍵と選択した暗号化アルゴリズムをシステムに登録します。
公開鍵は、メッセージを暗号化する時に使用され、そのメッセージは特定の受信者だけが復号できるようになります。

#### 暗号化されたメッセージの送信
ユーザーは登録された公開鍵を使用して、他のユーザーに安全にメッセージを送ることができます。
このプロセスは、送信者が受信者の公開鍵を使用してメッセージを暗号化し、その後、受信者が自分の秘密鍵を使用してメッセージを復号することによって行われます。

#### 暗号化アルゴリズムとユーザー情報の管理
システムは、さまざまな暗号化アルゴリズムとユーザー情報を管理するためのインターフェースを提供します。
これにより、ユーザーは自分に最適なセキュリティレベルを選択できるようになります。

#### 拡張性と柔軟性
提案されたシステムは、新しい暗号化アルゴリズムや追加のユーザー情報フィールドを簡単に統合できるように設計されています。
これにより、将来の技術的進歩に対応しやすくなります。

:::message
この提案はブロックチェーン技術を利用して、ユーザー間で安全に情報を交換するための新しい方法を提供します。
公開鍵暗号化という技術を使用して、送信されるメッセージの機密性と安全性を確保することが目的です。
:::

## 動機

レイヤー2チェーンとアカウント抽象化の進展が、リアルタイム通信やオンラインチャットの分散型アプリケーション（dApps）の普及にどのように貢献しているかを説明しています。

#### レイヤー2チェーンの進展
レイヤー2チェーンは、ブロックチェーンの拡張性問題を解決するために開発されました。
これらは元のブロックチェーン（レイヤー1と呼ばれる）の上に構築され、トランザクションの速度と効率を向上させます。
レイヤー2チェーンの特徴の1つは、非常に短いブロック時間を持つことです。
つまり、トランザクションを承認してブロックチェーンに追加するのにかかる時間が非常に短くなります。
これにより、リアルタイムでの通信が可能になります。

#### アカウント抽象化の導入
アカウント抽象化は、ユーザーが複数のサインイン方法やトランザクション承認方法を使えるようにする概念です。
これにより、ユーザーはブロックチェーン上でより簡単に、そして柔軟に操作できるようになります。

#### 端から端までの暗号化通信の使用
端から端までの暗号化は、メッセージが送信者から受信者へ直接、安全に送信されることを意味します。
この通信は途中で読み取られることがなく、プライバシーとセキュリティを確保します。

#### 非対称暗号化の活用
非対称暗号化は、一方のキーでメッセージを暗号化し、もう一方のキーで復号する暗号化方式です。
この技術を使用することで、ユーザー間で安全な通信チャネルを確立できます。

#### 分散型、端から端まで相互運用可能なメッセージングプロトコルの標準化
この文脈での「**標準化**」は、開発者がリアルタイム通信とオンラインチャットのdAppsを作る時に、一貫した方法で安全な通信を確立できるようにすることを意味します。
分散型で相互運用可能なメッセージングプロトコルを使用することで、異なるアプリケーションやプラットフォーム間でのメッセージ交換が可能になり、ユーザー体験が向上します。

:::message
これらの技術の進歩は、ブロックチェーンを基盤としたリアルタイム通信アプリの普及を促進し、ユーザーがより速く、安全に、そして柔軟に通信できるようにすることを可能にしています。
:::

## 仕様

### 目的

このテキストは、スマートコントラクト内でメッセージングシステムを実装するための標準化されたインターフェースを提供することを目的としています。
ユーザー登録やメッセージ送信機能を含むメッセージングシステムの柔軟性と拡張性を高め、そのプロセスの監視と監査を容易にするための複数の目標が設定されています。

#### 標準化されたインターフェースの提供
スマートコントラクトでメッセージングシステムを実装するための一貫した方法を提供します。
これにより、開発者はユーザーが新規登録を行い、メッセージを送信できる基本的な機能を簡単に組み込むことができます。

#### 柔軟性と拡張性の強化
公開鍵アルゴリズムの種類を定義する列挙型とユーザー情報の構造を定義することで、様々な暗号化手法やユーザーデータをサポートします。
これにより、将来の技術進歩にも柔軟に対応できるようになります。

#### メッセージ送信の追跡イベントの定義
スマートコントラクトがメッセージを送信する時にイベントを発行することで、そのプロセスの可観測性と監査可能性を向上させます。
これは、メッセージの送受信を追跡し、システムの透明性を高めるために重要です。

#### カスタムsessionIdの使用
メッセージを会話に組織するためにカスタムsessionIdを使用します。
これにより、関連するメッセージをグループ化し、会話スレッドを簡単に管理できます。

#### 受信者の公開鍵を使用したメッセージ内容の暗号化
メッセージの送信時には、受信者の公開鍵を使用してメッセージ内容を暗号化します。
これにより、送信されたメッセージが受信者以外によって読まれるリスクを最小限に抑え、通信のプライバシーとセキュリティを保証します。

:::message
この提案は、スマートコントラクトで使用されるメッセージングシステムを標準化し、拡張しやすくするための一連の目標とガイドラインを設定しています。
これにより、開発者はより安全で、効率的で、ユーザーフレンドリーな通信プラットフォームを構築できるようになります。
:::

### インターフェース

この規格に準拠するコントラクトは、以下のすべての機能を実装する必要があります。

```ts
pragma solidity ^0.8.0;

interface IERC7627 {

    enum PublicKeyAlgorithm { RSA, ECDSA, ED25519, DSA, DH, ECDH, X25519 }
    
    // Events

    /**
     * @dev Event emitted when a message is sent.
     * @param from The address of the sender.
     * @param to The address of the recipient.
     * @param sessionId The session ID of the message.
     * @param encryptedMessage The encrypted message.
     */
    event MessageSent(address indexed from, address indexed to, bytes32 sessionId, bytes encryptedMessage);

    /**
     * @dev Event emitted when a user updates their public key.
     * @param user The address of the user.
     * @param newPublicKey The new public key of the user.
     * @param algorithm The algorithm used for the public key.
     */
    event PublicKeyUpdated(address indexed user, bytes newPublicKey, PublicKeyAlgorithm algorithm);

    // Functions

    /**
     * @dev Function to update a user's public key.
     * @param _publicKey The public key of the user.
     * @param _algorithm The algorithm used for the public key.
     */
    function updatePublicKey(bytes calldata _publicKey, PublicKeyAlgorithm _algorithm) external;

    /**
     * @dev Function to send an encrypted message from one user to another.
     * @param _to The address of the recipient.
     * @param _sessionId The session ID of the message.
     * @param _encryptedMessage The encrypted message.
     */
    function sendMessage(address _to, bytes32 _sessionId, bytes calldata _encryptedMessage) external;

    /**
     * @dev Function to retrieve a user's public key and algorithm.
     * @param _user The address of the user.
     * @return publicKey The public key of the user.
     * @return algorithm The algorithm used for the public key.
     */
    function getUserPublicKey(address _user) external view returns (bytes memory publicKey, PublicKeyAlgorithm algorithm);
}
```

---

#### PublicKeyAlgorithm

```javascript
enum PublicKeyAlgorithm { RSA, ECDSA, ED25519, DSA, DH, ECDH, X25519 }
```

**概要**

これは公開鍵暗号アルゴリズムの種類を定義する列挙体。

**詳細**

`PublicKeyAlgorithm` 列挙体は、スマートコントラクトがサポートするさまざまな公開鍵暗号化アルゴリズムをリストアップしています。
これにより、ユーザーは自分の公開鍵と一致する暗号化アルゴリズムを選択できます。

**パラメータ**

- `RSA`
    - 広く使用されている公開鍵暗号アルゴリズム。
- `ECDSA`
    - 楕円曲線デジタル署名アルゴリズム。
- `ED25519`
    - EdDSA署名スキームに基づく暗号アルゴリズム。
- `DSA`
    - デジタル署名アルゴリズム。
- `DH`
    - ディフィー・ヘルマン鍵交換。
- `ECDH
    - 楕円曲線ディフィー・ヘルマン鍵交換。
- `X25519
    - 楕円曲線を使用した鍵交換アルゴリズム。

---

#### MessageSent

```javascript
event MessageSent(address indexed from, address indexed to, bytes32 sessionId, bytes encryptedMessage);
```

**概要**

メッセージが送信されたときに発行されるイベント。

**詳細**

`MessageSent` イベントは、ユーザーがメッセージを送信するたびに発行されます。
このイベントを通じて、メッセージの送信情報がブロックチェーン上に記録され、追跡や監査が可能になります。
メッセージは暗号化されており、セッションIDを使用して会話に関連付けられます。

**パラメータ**

- `from`
    - メッセージの送信者のアドレス。
- `to`
    - メッセージの受信者のアドレス。
- `sessionId`
    - メッセージが属するセッションのID。
- `encryptedMessage`
    - 暗号化されたメッセージの内容。

---

#### PublicKeyUpdated

```javascript
event PublicKeyUpdated(address indexed user, bytes newPublicKey, PublicKeyAlgorithm algorithm);
```

**概要**

ユーザーが自分の公開鍵を更新したときに発行されるイベント。

**詳細**

`PublicKeyUpdated` イベントは、ユーザーが新しい公開鍵に更新する時に発生します。
このイベントにより、公開鍵の変更がブロックチェーン上に記録され、公開鍵の変更履歴を追跡できます。
公開鍵は特定の暗号化アルゴリズムに基づいています。

**パラメータ**

- `user`
    - 公開鍵を更新したユーザーのアドレス。
- `newPublicKey`
    - 新しい公開鍵。
- `algorithm`
    - 公開鍵の生成に使用された暗号化アルゴリズム。

---

#### `updatePublicKey`

```javascript
function updatePublicKey(bytes calldata _publicKey, PublicKeyAlgorithm _algorithm) external;
```

**概要**

ユーザーの公開鍵を更新する関数。

**詳細**

この関数は、ユーザーが自分の公開鍵とその公開鍵に使用される暗号化アルゴリズムを更新するために使用されます。
更新プロセスは外部から呼び出すことができ、ブロックチェーン上で公開鍵が変更されたことを記録します。

**引数**

- `_publicKey`
    - 更新する新しい公開鍵。
- `_algorithm`
    - 新しい公開鍵に使用される暗号化アルゴリズム。

---

#### `sendMessage`

```javascript
function sendMessage(address _to, bytes32 _sessionId, bytes calldata _encryptedMessage) external;
```

**概要**

一方のユーザーから別のユーザーへ暗号化されたメッセージを送信する関数。

**詳細**

`sendMessage` 関数は、暗号化されたメッセージを受信者に送信するために使用されます。
この関数により、セッションIDを用いてメッセージを会話に関連付けることができ、メッセージのプライバシーが保たれます。

**引数**

- `_to`
    - メッセージの受信者のアドレス。
- `_sessionId`
    - メッセージが属するセッションのID。
- `_encryptedMessage`
    - 送信する暗号化されたメッセージ。

---

#### `getUserPublicKey`

```javascript
function getUserPublicKey(address _user) external view returns (bytes memory publicKey, PublicKeyAlgorithm algorithm);
```

**概要**

指定したユーザーの公開鍵とその公開鍵の暗号化アルゴリズムを取得する関数。

**詳細**

`getUserPublicKey` 関数は、指定されたユーザーの公開鍵とその公開鍵に使用されている暗号化アルゴリズムの両方を返します。
これは読み取り専用の関数であり、外部から情報を取得する際に使用されます。

**引数**

- `_user`
    - 公開鍵と暗号化アルゴリズムを取得したいユーザーのアドレス。

**戻り値**

- `publicKey`
    - 指定されたユーザーの公開鍵。
- `algorithm`
    - 公開鍵に使用される暗号化アルゴリズム。

---

## 補足

ブロックチェーン通信におけるセキュリティと透明性の不足を解決するための暗号化メッセージングシステムの導入に関して説明しています。

#### 非対称暗号化の選択
伝統的なメッセージングシステムではセキュリティと透明性が不足しています。
非対称暗号化の使用により、メッセージの機密性と完整性が保証されます。
この方法では、公開鍵でメッセージを暗号化し、受信者のみが秘密鍵でそれを復号できるため、セキュリティが大幅に強化されます。

#### 統一インターフェースの提供
スマートコントラクトに暗号化された通信を簡単に統合できるようにするために、統一されたインターフェースが提供されます。
これにより、開発者は独自の暗号化通信システムを容易に実装でき、イノベーションが促進されます。

#### 暗号化メッセージングの保証
データセキュリティのベストプラクティスに従うことを保証します。
これにより、ユーザー間の通信が安全に行われ、第三者によるデータの盗聴や改ざんが防がれます。

#### 公開鍵の定期的な更新
セキュリティ上の理由から、公開鍵は定期的に更新する必要があります。
そのため、ユーザーが自らの公開鍵を自律的に更新できる機能が追加されました。

#### 様々な暗号化方法のサポート
インターフェースは、さまざまな暗号化メソッドに対応しており、適応性が向上しています。
これにより、異なるセキュリティ要件を持つ様々なアプリケーションに対応することが可能です。

#### イベント追跡による監視性と監査性の強化
コントラクトの可観測性と監査性を高めるために、イベント追跡が利用されます。
これは、コンプライアンスの取り組みを支援し、システムの透明性を保証します。

#### 標準化による相互運用性の促進
標準化されたインターフェースは、プラットフォーム間のシームレスな通信を容易にし、異なるシステム間での互換性と連携を実現します。

:::message
このシステムはブロックチェーン技術を利用した通信のセキュリティと効率を大幅に向上させることを目指しています。
これにより、安全で信頼性の高いメッセージング環境が提供され、ユーザーは自信を持って情報を交換できるようになります。
:::

## 参考

```ts
pragma solidity ^0.8.0;

contract ERC7627 {

    enum PublicKeyAlgorithm { RSA, ECDSA, ED25519, DSA, DH, ECDH, X25519 }

    struct UserInfo {
        bytes publicKey;
        PublicKeyAlgorithm algorithm;
    }

    mapping(address => UserInfo) public pk;

    event MessageSent(address indexed from, address indexed to, bytes32 sessionId, bytes encryptedMessage);
    event PublicKeyUpdated(address indexed user, bytes newPublicKey, PublicKeyAlgorithm algorithm);

    // Function to register a user with their public key
    function updatePublicKey(bytes calldata _publicKey, PublicKeyAlgorithm _algorithm) public {
        pk[msg.sender].publicKey = _publicKey;
        pk[msg.sender].algorithm = _algorithm;
        emit PublicKeyUpdated(msg.sender, _publicKey, _algorithm);
    }

    // Function to send an encrypted message from one user to another
    function sendMessage(address _to, bytes32 _sessionId, bytes calldata _encryptedMessage) public {
        emit MessageSent(msg.sender, _to, _sessionId, _encryptedMessage);
    }

    // Function to retrieve a user's public key
    function getUserPublicKey(address _user) public view returns (bytes memory, PublicKeyAlgorithm) {
        UserInfo memory userInfo = pk[_user];
        return (userInfo.publicKey, userInfo.algorithm);
    }
}
```

## セキュリティ

ブロックチェーンにおける暗号化メッセージングシステムのセキュリティに関する考慮事項を概説しています。

#### 最新の安全な暗号化アルゴリズムの利用
暗号化アルゴリズムを選択する時は、最新のセキュリティニュースや推奨事項に常に注意を払うことが重要です。
既知の脆弱性がある、または推奨されていない非対称暗号化アルゴリズムの使用を避けることで、メッセージの機密性と完整性を確保します。
進化するセキュリティ脅威に対処するために、定期的に暗号化アルゴリズムを更新します。

#### 公開鍵を使用した厳格な暗号化
メッセージの機密性を維持するために、送信されるメッセージの内容は受信者の公開鍵を使用して厳密に暗号化する必要があります。
平文での情報の送信は情報漏洩やセキュリティリスクにつながるため、送信および保管中のメッセージ内容は常に暗号化してください。

#### キーマネジメントと保護
ユーザーの公開鍵と秘密鍵の両方に対して、堅牢なキーマネジメントと保護措置が必要です。
キーの安全な保管と伝送を保証し、漏洩や改ざんを防ぐために、多要素認証やキーローテーション戦略を採用します。
潜在的なセキュリティリスクを軽減するために、定期的にキーマネジメントプロセスを評価します。

#### 監査とモニタリング
メッセージの送受信やキーの使用を追跡するための監査およびモニタリング機構を実装します。
異常な活動や潜在的なセキュリティ脅威を迅速に特定し、適切な対応措置を講じます。
セキュリティインシデントの調査および追跡目的で、重要な操作とイベントを記録します。

これらのセキュリティ考慮事項は、ブロックチェーン上で安全な暗号化メッセージングシステムを実装および運用する際に、機密情報の不正アクセスや漏洩を防ぐために不可欠です。

## 引用

Chen Liaoyuan (@chenly) <cly@kip.pro>, "ERC-7627: Secure Messaging Protocol [DRAFT]," Ethereum Improvement Proposals, no. 7627, February 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7627.

## 最後に

今回は「ブロックチェーンでの署名に使用される暗号化アルゴリズムについて、様々なアルゴリズムの使用や安全なメッセージ送信をサポートする仕組みを提案している**ERC7627**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下の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
