# 機能設計書 90-node:crypto

## 概要

本ドキュメントは、Bunランタイムにおけるnode:crypto（暗号化API）モジュールの設計を記述するものである。Node.jsのcryptoモジュールと互換性のある暗号化APIを提供する。

### 本機能の処理概要

node:crypto機能は、ハッシュ計算、暗号化/復号、署名/検証、鍵生成など、各種暗号化操作を提供するNode.js互換モジュールである。Web Crypto API（機能No.81）とは異なるインターフェースを提供する。

**業務上の目的・背景**：Node.jsアプリケーションでは、cryptoモジュールが認証、データ保護、セキュア通信などの暗号化機能で広く使用されている。BunがこのAPIと互換性を持つことで、既存のNode.jsアプリケーションをそのまま動作させることができ、パスワードハッシュ、JWT署名、データ暗号化などのセキュリティ機能を実装できる。

**機能の利用シーン**：
- パスワードのハッシュ化と検証（bcrypt、scrypt、pbkdf2）
- データの暗号化/復号（AES、DES等）
- デジタル署名の作成と検証
- X.509証明書の処理
- 安全な乱数生成
- Diffie-Hellman鍵交換

**主要な処理内容**：
1. ハッシュ計算（createHash, Hash, hash）
2. HMAC計算（createHmac, Hmac）
3. 暗号化/復号（createCipheriv, createDecipheriv）
4. 署名/検証（createSign, createVerify, sign, verify）
5. 鍵生成（generateKeyPair, generateKey）
6. 鍵導出（pbkdf2, scrypt, hkdf）
7. 乱数生成（randomBytes, randomFill, randomUUID）
8. 証明書処理（X509Certificate, Certificate）
9. Diffie-Hellman/ECDH鍵交換

**関連システム・外部連携**：BoringSSL（Googleが管理するOpenSSLフォーク）、libuv（一部Windows対応）。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | APIとして利用 |

## 機能種別

暗号化API / Node.js互換

## 入力仕様

### 主要入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| algorithm | string | Yes | アルゴリズム名 | サポート対象 |
| key | Buffer/KeyObject | Yes | 暗号鍵 | 有効な鍵 |
| iv | Buffer | Yes (cipher) | 初期化ベクトル | 適切な長さ |
| data | Buffer/string | Yes | 処理対象データ | - |

### 入力データソース

JavaScript API呼び出し。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| hash | Buffer/string | ハッシュ値 |
| encrypted | Buffer | 暗号化データ |
| signature | Buffer | 署名データ |
| key | KeyObject | 生成された鍵 |

### 出力先

JavaScript呼び出し元への戻り値/コールバック/Promise。

## 処理フロー

### 処理シーケンス

```
1. crypto.*メソッドの呼び出し
   └─ 引数のバリデーション
2. 鍵/データの準備
   └─ KeyObject化、エンコーディング処理
3. BoringSSL関数呼び出し
   └─ 暗号プリミティブ実行
4. 結果の変換
   └─ Buffer/stringへの変換
5. 結果の返却
```

### フローチャート

```mermaid
flowchart TD
    A[crypto.* 呼び出し] --> B{同期/非同期?}
    B -->|同期| C[BoringSSL直接呼び出し]
    B -->|非同期| D[CryptoJob作成]
    C --> E[結果変換]
    D --> F[WorkPool実行]
    F --> G[コールバック/Promise]
    E --> H[結果返却]
    G --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Node.js互換 | Node.js cryptoモジュールのAPIと互換 | 全API |
| BR-02 | BoringSSL使用 | 暗号処理にBoringSSLを使用 | 暗号操作時 |
| BR-03 | KeyObject管理 | 鍵はKeyObjectで管理 | 鍵操作時 |
| BR-04 | FIPS非対応 | FIPSモードは非サポート | getFips=0 |

### 計算ロジック

- PBKDF2: 反復回数とソルトで派生鍵を計算
- scrypt: N, r, pパラメータで派生鍵を計算
- timingSafeEqual: 一定時間比較で結果を返す

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR_INVALID_ARG_TYPE | 型エラー | 不正な引数型 | 型を確認 |
| ERR_OUT_OF_RANGE | 範囲エラー | パラメータ範囲外 | 値を確認 |
| ERR_CRYPTO_* | 暗号エラー | 暗号操作失敗 | パラメータ確認 |

### リトライ仕様

暗号操作エラー時は自動リトライなし。

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

該当なし

## パフォーマンス要件

- WorkPoolによる非同期暗号操作
- BoringSSLのハードウェアアクセラレーション活用
- timingSafeEqualで定数時間比較

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

- タイミング攻撃への耐性（timingSafeEqual）
- 鍵データのメモリ保護
- 安全な乱数生成器（CSPRNG）使用

## 備考

Web Crypto API（crypto.subtle）も利用可能。

---

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

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

### 推奨読解順序

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

node:crypto処理の中心となるデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | node_crypto_binding.zig | `src/bun.js/node/node_crypto_binding.zig` | CryptoJob、ExternCryptoJob構造体 |

**読解のコツ**:
- **1-87行目**: ExternCryptoJob関数（C++定義のジョブをZigで扱う）
- **90-114行目**: 各種CryptoJob定義（CheckPrime, GeneratePrime, Hkdf等）
- **116-184行目**: CryptoJob関数（Zig定義のジョブ用）

#### Step 2: 乱数生成を理解する

乱数生成の実装を把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | node_crypto_binding.zig | `src/bun.js/node/node_crypto_binding.zig` | random構造体 |

**主要処理フロー**:
1. **186-265行目**: randomInt関数
2. **267-290行目**: randomUUID関数
3. **320-346行目**: randomBytes関数
4. **348-376行目**: randomFillSync関数
5. **378-421行目**: randomFill関数

#### Step 3: JavaScript側APIを理解する

高レベルAPIの実装を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | crypto.ts | `src/js/node/crypto.ts` | Hash、Hmac、Cipher、Sign等のクラス |

**主要処理フロー**:
- **189-215行目**: Sign クラス
- **224-251行目**: Verify クラス
- **254-292行目**: Hash クラス
- **295-328行目**: Hmac クラス
- **449-495行目**: Cipheriv / Decipheriv クラス

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

```
crypto.randomBytes() (JavaScript)
    │
    └─ random.randomBytes() (Zig, lines 320-346)
           │
           ├─ assertSize() - サイズバリデーション
           │
           ├─ 同期呼び出し → bun.csprng() → Buffer返却
           │
           └─ 非同期呼び出し
                  │
                  ├─ Job.initAndSchedule() - ジョブ作成
                  └─ WorkPool実行 → コールバック

crypto.createHash() (JavaScript)
    │
    └─ new Hash() (TypeScript, lines 254-292)
           │
           └─ this[kHandle] = new _Hash() (C++)
                  │
                  ├─ update() → EVP_DigestUpdate
                  └─ digest() → EVP_DigestFinal
```

### データフロー図

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

algorithm, key  ───▶ バリデーション          ───▶ 準備済みパラメータ
data                 │
                     └─ KeyObject化

パラメータ      ───▶ BoringSSL関数          ───▶ 暗号処理結果
                     │
                     ├─ EVP_* (ハッシュ/暗号)
                     ├─ HMAC_* (HMAC)
                     └─ RSA_*/EC_* (署名)

結果            ───▶ エンコーディング        ───▶ Buffer/string
                     (hex/base64/buffer)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| node_crypto_binding.zig | `src/bun.js/node/node_crypto_binding.zig` | ソース | Zig側バインディング |
| node_crypto_binding.cpp | `src/bun.js/bindings/node_crypto_binding.cpp` | ソース | C++側バインディング |
| crypto.ts | `src/js/node/crypto.ts` | ソース | JavaScript側実装 |
| PBKDF2.zig | `src/bun.js/node/PBKDF2.zig` | ソース | PBKDF2実装 |
