# 機能設計書 88-md5

## 概要

本ドキュメントは、Nim標準ライブラリのmd5モジュールに関する機能設計書である。MD5チェックサムの計算機能を提供する。

### 本機能の処理概要

md5モジュールは、RFC 1321で定義されたMD5（Message-Digest Algorithm 5）ハッシュアルゴリズムを実装する。128ビット（16バイト）のハッシュ値を生成し、データの整合性検証やレガシーシステムとの互換性維持に使用される。

**業務上の目的・背景**：MD5はセキュリティ目的では非推奨となっているが、ファイルのチェックサム検証、キャッシュキー生成、レガシーシステムとの互換性維持などの用途では依然として広く使用されている。

**機能の利用シーン**：ファイルの整合性チェック、データベースのキャッシュキー生成、レガシーAPIとの互換性、Content-MD5ヘッダの検証など。

**主要な処理内容**：
1. 文字列からMD5ハッシュを計算（toMD5, getMD5関数）
2. インクリメンタルハッシュ計算（md5Init, md5Update, md5Final関数）
3. MD5ダイジェストの文字列変換（$演算子）

**関連システム・外部連携**：checksums外部パッケージへの移行が推奨されている。

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

## 関連画面

該当なし

## 機能種別

暗号化ハッシュ（非推奨）/ データ整合性検証

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| s | string | Yes | ハッシュ対象の文字列 | - |
| input | openArray[uint8] | Yes | インクリメンタル入力データ | - |
| c | var MD5Context | Yes | MD5コンテキスト | 初期化済み |

### 入力データソース

任意のバイナリ/文字列データ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| MD5Digest | array[0..15, uint8] | 16バイトのMD5ハッシュ値 |
| string | string | 32文字の16進数文字列表現 |

### 出力先

戻り値

## 処理フロー

### 処理シーケンス

```
1. 一括ハッシュ計算
   └─ toMD5(s) / getMD5(s)
      ├─ md5Init(c)でコンテキスト初期化
      ├─ md5Update(c, s)でデータ処理
      └─ md5Final(c, digest)で結果取得

2. インクリメンタルハッシュ計算
   └─ md5Init(c)
      ├─ state[0..3]を初期値に設定
      ├─ count[0..1] = 0
      └─ buffer クリア

   └─ md5Update(c, data) ※複数回呼び出し可能
      ├─ countを更新
      ├─ 64バイトブロックごとにtransform
      └─ 残りはbufferに保持

   └─ md5Final(c, digest)
      ├─ パディング追加（0x80 + 0x00...）
      ├─ 長さ追加（64ビット）
      ├─ 最終transform
      └─ stateからdigestを生成
```

### フローチャート

```mermaid
flowchart TD
    A[データ入力] --> B{処理モード}
    B -->|一括| C[toMD5/getMD5]
    B -->|インクリメンタル| D[md5Init]

    C --> E[内部でInit/Update/Final]
    E --> F[MD5Digest]

    D --> G[md5Update ×n回]
    G --> H[md5Final]
    H --> F

    F --> I{出力形式}
    I -->|バイナリ| J[MD5Digest]
    I -->|文字列| K[$ 演算子]
    K --> L[32文字の16進数文字列]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-88-01 | 非推奨警告 | モジュール使用時に非推奨警告を出力 | コンパイル時 |
| BR-88-02 | 移行推奨 | checksums/md5への移行を推奨 | 新規開発時 |
| BR-88-03 | 出力形式 | ハッシュ値は小文字の16進数で出力 | $演算子使用時 |
| BR-88-04 | コンパイル時計算 | コンパイル時およびJavaScriptでも動作 | 常時 |

### 計算ロジック

**MD5アルゴリズム**:
1. 初期ハッシュ値: A=0x67452301, B=0xEFCDAB89, C=0x98BADCFE, D=0x10325476
2. 512ビット（64バイト）ブロック単位で処理
3. 4ラウンド × 16ステップの変換（F, G, H, I関数）
4. パディング: 0x80 + 0x00... + 64ビット長さ

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

該当なし

## エラー処理

### エラーケース一覧

特にエラーは発生しない（純粋な計算処理）

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- O(n) where n = 入力データサイズ
- 64バイトブロック単位での効率的な処理
- コンパイル時計算対応

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

- **警告**: MD5は暗号学的に安全ではない（衝突攻撃が実用的）
- パスワードハッシュには使用禁止
- 新規開発ではSHA-256以上を推奨
- レガシー互換性のみでの使用に限定すべき

## 備考

- checksums外部パッケージへの移行が推奨
- `nimble install checksums`でインストール
- `import checksums/md5`で使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | md5.nim | `lib/pure/md5.nim` | MD5State, MD5Block等の型定義（26-36行目） |
| 1-2 | md5.nim | `lib/pure/md5.nim` | MD5Digest型（30-31行目） |
| 1-3 | md5.nim | `lib/pure/md5.nim` | MD5Context型（33-36行目） |
| 1-4 | md5.nim | `lib/pure/md5.nim` | padding定数（38-48行目） |

**読解のコツ**:
- MD5Stateは4つのuint32（A, B, C, D）
- MD5Blockは16のuint32（512ビット）
- MD5Digestは16のuint8（128ビット）

#### Step 2: 基本関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | md5.nim | `lib/pure/md5.nim` | F, G, H, I関数（50-60行目） |
| 2-2 | md5.nim | `lib/pure/md5.nim` | rot関数（62-63行目） |
| 2-3 | md5.nim | `lib/pure/md5.nim` | FF, GG, HH, II関数（65-83行目） |

**主要処理フロー**:
- **50-60行目**: 4つの非線形関数（各ラウンドで1つ使用）
- **62-63行目**: 左回転（ビットローテーション）
- **65-83行目**: メインの変換ステップ

#### Step 3: transform関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | md5.nim | `lib/pure/md5.nim` | encode/decode関数（85-101行目） |
| 3-2 | md5.nim | `lib/pure/md5.nim` | transform関数（128-203行目） |

**主要処理フロー**:
- **85-101行目**: バイト配列とuint32間の変換
- **136-199行目**: 4ラウンド各16ステップの変換
- **200-203行目**: 状態の更新

#### Step 4: 公開APIを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | md5.nim | `lib/pure/md5.nim` | md5Init関数（271-282行目） |
| 4-2 | md5.nim | `lib/pure/md5.nim` | md5Update関数（294-314行目） |
| 4-3 | md5.nim | `lib/pure/md5.nim` | md5Final関数（316-331行目） |
| 4-4 | md5.nim | `lib/pure/md5.nim` | toMD5関数（219-232行目） |
| 4-5 | md5.nim | `lib/pure/md5.nim` | getMD5関数（242-256行目） |
| 4-6 | md5.nim | `lib/pure/md5.nim` | $演算子（234-240行目） |

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

```
アプリケーションコード
    │
    ├─ toMD5(s) / getMD5(s)
    │      ├─ md5Init(c)
    │      │      └─ state初期化、count=0、bufferクリア
    │      ├─ md5Update(c, s)
    │      │      ├─ countインクリメント
    │      │      └─ transform(buffer, state) ×n回
    │      └─ md5Final(c, digest)
    │             ├─ padding追加
    │             ├─ 長さ追加
    │             ├─ transform
    │             └─ decode(digest, state)
    │
    └─ $digest
           └─ 16進数文字列変換
```

### データフロー図

```
[入力データ]              [MD5処理]               [出力]

"Hello"  ──────▶ md5Init
                    │
                    ▼
                ┌───────────────┐
                │ state[0..3]   │
                │ count[0..1]   │
                │ buffer[0..63] │
                └───────────────┘
                    │
             md5Update
                    │
                    ▼
          512ビットブロック処理
                    │
             transform
                    │
                    ▼
             md5Final
                    │
                    ▼
             ┌─────────────────────┐
             │ MD5Digest (16 bytes)│
             └─────────────────────┘
                    │
                $ 演算子
                    │
                    ▼
    "8b1a9953c4611296a827abf8c47804d7"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| md5.nim | `lib/pure/md5.nim` | メインソース | MD5ハッシュ実装 |
| sha1.nim | `lib/std/sha1.nim` | 関連 | SHA-1ハッシュ（参照用） |
| base64.nim | `lib/pure/base64.nim` | 関連 | Base64エンコード（併用） |
