# 機能設計書 72-Bun.CryptoHasher

## 概要

本ドキュメントは、Bun.CryptoHasher APIの機能設計を記述する。Bun.CryptoHasherは、SHA、MD5、BLAKE2等の暗号学的ハッシュ関数を提供するAPIである。

### 本機能の処理概要

Bun.CryptoHasherは、入力データに対して暗号学的ハッシュアルゴリズムを適用し、ダイジェスト値を生成する機能である。ストリーミングAPI（update/digest）とワンショットAPI（hash）の両方をサポートし、HMAC（Hash-based Message Authentication Code）にも対応する。

**業務上の目的・背景**：パスワードの検証、ファイル整合性チェック、デジタル署名の作成、メッセージ認証コードの生成など、セキュリティが重要な場面で使用される。Node.js cryptoモジュールとの互換性を提供しつつ、高速な実装を実現している。

**機能の利用シーン**：
- ファイルのチェックサム計算（SHA-256等）
- パスワードハッシュの生成・検証
- APIリクエストの署名（HMAC）
- SSL/TLS証明書の検証
- データの改ざん検知

**主要な処理内容**：
1. アルゴリズム名を指定してハッシャーインスタンスを生成
2. update()メソッドでデータを追加（複数回呼び出し可能）
3. digest()メソッドでハッシュ値を取得
4. hash()静的メソッドでワンショットハッシュを実行
5. HMACキーを指定してメッセージ認証コードを生成

**関連システム・外部連携**：BoringSSL（Google製OpenSSLフォーク）を内部で使用。一部アルゴリズム（SHA-3系、BLAKE2s256）はZig標準ライブラリの実装を使用。

**権限による制御**：特に権限による制御は行われない。すべてのコードから利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | コマンドライン/API経由での利用（画面なし） |

## 機能種別

計算処理（暗号ハッシュ計算）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| algorithm | string | Yes | ハッシュアルゴリズム名 | サポートされるアルゴリズムのみ |
| hmacKey | string / Buffer | No | HMACのキー | 指定時はHMACモードで動作 |
| input | string / Blob / Buffer / ArrayBuffer | Yes (hash) | ハッシュ対象データ | - |
| encoding | string / Buffer | No | 出力エンコーディング | hex, base64, buffer等 |

### 入力データソース

API呼び出し時の引数として直接指定。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| digest | string / Buffer | ハッシュダイジェスト値（エンコーディングに依存） |

### 出力先

API戻り値として返却。

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ アルゴリズム名を解析し、適切なハッシャーを初期化
   └─ HMACキーがあればHMACモードで初期化
2. update()呼び出し（0回以上）
   └─ 入力データをハッシャーに追加
3. digest()呼び出し
   └─ ファイナライズしてダイジェスト値を出力
   └─ エンコーディングに応じて変換
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{HMACキーあり?}
    B -->|Yes| C[HMACモードで初期化]
    B -->|No| D{EVPサポート?}
    D -->|Yes| E[EVPで初期化]
    D -->|No| F[Zigハッシャーで初期化]
    C --> G[update呼び出し]
    E --> G
    F --> G
    G --> H{追加データあり?}
    H -->|Yes| I[データをハッシャーに追加]
    I --> G
    H -->|No| J[digest呼び出し]
    J --> K{エンコーディング指定?}
    K -->|Yes| L[指定形式で出力]
    K -->|No| M[Bufferで出力]
    L --> N[終了]
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-72-01 | アルゴリズム大文字小文字 | アルゴリズム名は大文字小文字を区別しない | 常時 |
| BR-72-02 | HMAC制限 | ripemd160はHMACモードで使用不可 | HMACキー指定時 |
| BR-72-03 | digest後の状態 | digest()呼び出し後、同じインスタンスは再利用不可 | 常時 |
| BR-72-04 | copy機能 | copy()で現在の状態をコピーした新インスタンスを作成可能 | 常時 |

### 計算ロジック

各ハッシュアルゴリズムの実装はBoringSSLまたはZig標準ライブラリに委譲。

## データベース操作仕様

### 操作別データベース影響一覧

なし（データベース操作を行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArguments | TypeError | 未サポートアルゴリズム | サポートされるアルゴリズムを使用 |
| InvalidArguments | TypeError | 不正なHMACキー | string または buffer を指定 |
| InvalidArguments | TypeError | 不正なエンコーディング | hex, base64等を指定 |
| InvalidState | Error | digest済みインスタンスでupdate/digest | 新インスタンスを作成 |
| CryptoError | Error | BoringSSLエラー | エラーメッセージを確認 |

### リトライ仕様

なし（同期処理のため）

## トランザクション仕様

なし（データベース操作を行わない）

## パフォーマンス要件

- BoringSSLの最適化された実装を使用
- SHA-3系はZig標準ライブラリの実装を使用
- ストリーミングAPIで大規模データを効率的に処理

## セキュリティ考慮事項

- 暗号学的に安全なハッシュ関数を提供
- MD4/MD5は脆弱性があるため、セキュリティ目的での使用は非推奨
- パスワードハッシュにはBun.passwordを使用することを推奨

## 備考

サポートされるハッシュアルゴリズム一覧：
- **BoringSSL実装**: md4, md5, sha1, sha224, sha256, sha384, sha512, sha512-224, sha512-256, ripemd160, blake2b256, blake2b512
- **Zig実装**: sha3-224, sha3-256, sha3-384, sha3-512, shake128, shake256, blake2s256

専用クラス（静的ハッシャー）：
- `Bun.SHA1`, `Bun.MD5`, `Bun.MD4`, `Bun.SHA224`, `Bun.SHA256`, `Bun.SHA384`, `Bun.SHA512`, `Bun.SHA512_256`

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

CryptoHasherの内部構造とアルゴリズム定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CryptoHasher.zig | `src/bun.js/api/crypto/CryptoHasher.zig` | CryptoHasher union型の定義（1-8行目） |
| 1-2 | EVP.zig | `src/bun.js/api/crypto/EVP.zig` | Algorithm enumの定義（9-41行目） |
| 1-3 | crypto.classes.ts | `src/bun.js/api/crypto.classes.ts` | JSクラス定義（75-112行目） |

**読解のコツ**: CryptoHasherは`union(enum)`型で、hmac/evp/zigの3つの実装を切り替える。EVP.Algorithmは全サポートアルゴリズムを列挙。

#### Step 2: エントリーポイントを理解する

コンストラクタと静的hashメソッドの実装。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CryptoHasher.zig | `src/bun.js/api/crypto/CryptoHasher.zig` | constructor関数（242-304行目） |
| 2-2 | CryptoHasher.zig | `src/bun.js/api/crypto/CryptoHasher.zig` | hash_静的メソッド（211-239行目） |

**主要処理フロー**:
1. **244-257行目**: 引数検証（アルゴリズム名の取得）
2. **259-271行目**: HMACキーの取得（オプション）
3. **273-303行目**: ハッシャーの初期化（HMAC/EVP/Zigを選択）
4. **217-219行目**: hash_メソッドでEVPまたはZig実装を選択

#### Step 3: update処理を理解する

データ追加処理の実装。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CryptoHasher.zig | `src/bun.js/api/crypto/CryptoHasher.zig` | updateメソッド（313-360行目） |

**主要処理フロー**:
- **316-328行目**: 入力データの取得とバリデーション
- **330-357行目**: 各実装（evp/hmac/zig）に応じたupdate処理

#### Step 4: digest処理を理解する

ファイナライズとダイジェスト出力の実装。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | CryptoHasher.zig | `src/bun.js/api/crypto/CryptoHasher.zig` | digest_メソッド（386-407行目） |
| 4-2 | CryptoHasher.zig | `src/bun.js/api/crypto/CryptoHasher.zig` | final関数（445-458行目） |

**主要処理フロー**:
- **386-407行目**: 出力形式（エンコーディング/バッファ）の判定
- **445-458行目**: 各実装に応じたfinal処理

#### Step 5: Zig実装のアルゴリズムを理解する

SHA-3系等のZig標準ライブラリ実装。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | CryptoHasher.zig | `src/bun.js/api/crypto/CryptoHasher.zig` | CryptoHasherZig構造体（479-655行目） |

**主要処理フロー**:
- **484-492行目**: algo_mapでサポートアルゴリズムを定義
- **592-606行目**: init関数でZigハッシャーを初期化

### プログラム呼び出し階層図

```
Bun.CryptoHasher(algorithm, hmacKey?)
    │
    ├─ constructor()
    │      ├─ HMAC.init() [HMACモード]
    │      ├─ EVP.byName() [BoringSSL]
    │      └─ CryptoHasherZig.constructor() [Zig実装]
    │
    ├─ update(data)
    │      ├─ EVP.update()
    │      ├─ HMAC.update()
    │      └─ CryptoHasherZig.update()
    │
    └─ digest(encoding?)
           ├─ digestToEncoding() / digestToBytes()
           │      └─ final()
           │             ├─ HMAC.final()
           │             ├─ EVP.final()
           │             └─ CryptoHasherZig.final()
           │
           └─ encoding.encodeWithMaxSize() [エンコード変換]

Bun.CryptoHasher.hash(algorithm, input, encoding?)
    │
    ├─ EVP.byName() / CryptoHasherZig.hashByName()
    │
    └─ hashToEncoding() / hashToBytes()
```

### データフロー図

```
[入力]                      [処理]                           [出力]

algorithm        ───▶  constructor()
hmacKey(opt)     ───▶  ├─ HMAC/EVP/Zig選択
                       └─ ハッシャー初期化

data             ───▶  update()
                       └─ 内部状態更新

encoding(opt)    ───▶  digest()                    ───▶   string (hex/base64)
                       ├─ final()                          または
                       └─ エンコード変換                    Buffer
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CryptoHasher.zig | `src/bun.js/api/crypto/CryptoHasher.zig` | ソース | メイン実装（union型、各メソッド） |
| EVP.zig | `src/bun.js/api/crypto/EVP.zig` | ソース | EVP（BoringSSL）ラッパー |
| HMAC.zig | `src/bun.js/api/crypto/HMAC.zig` | ソース | HMACラッパー |
| crypto.classes.ts | `src/bun.js/api/crypto.classes.ts` | 定義 | JSクラス定義 |
| crypto.zig | `src/bun.js/api/crypto.zig` | ソース | cryptoモジュールエクスポート |
| BunObject.zig | `src/bun.js/api/BunObject.zig` | ソース | Bun.CryptoHasherプロパティ登録 |
| sha.zig | `src/sha.zig` | ソース | 静的ハッシャーの定義 |
| 09555.test.ts | `test/regression/issue/09555.test.ts` | テスト | CryptoHasher使用例 |
