# 機能設計書 120-RC4暗号化

## 概要

本ドキュメントは、K-Shoot MANIAにおけるRC4暗号化機能の設計を記述する。RC4アルゴリズムによるデータ暗号化・復号機能を提供する。

### 本機能の処理概要

RC4(Rivest Cipher 4)ストリーム暗号アルゴリズムを実装したモジュールである。パスワード(鍵)に基づく256バイトのS-Boxを初期化し、データのXOR暗号化・復号を行う。

**業務上の目的・背景**：スコアデータやセーブデータを平文で保存すると改ざんが容易であるため、RC4暗号化により簡易的なデータ保護を実現する。RC4は同じ鍵とアルゴリズムで暗号化・復号が可能な対称暗号であり、実装がシンプルである。

**機能の利用シーン**：スコアデータの保存・読み込み時にデータの暗号化・復号に利用される。rc4_encode命令でパスワードとデータを指定してワンコール暗号化を行う。

**主要な処理内容**：
1. rc4_encode(data, key, size): パスワードによるRC4暗号化のワンコール関数
2. rc4_init(key): 256バイトS-Boxの初期化(Key Scheduling Algorithm)
3. rc4_crypt(data, size, offset): データのXOR暗号化/復号(Pseudo-Random Generation Algorithm)

**関連システム・外部連携**：外部システムとの連携はない。

**権限による制御**：権限による制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | (バックグラウンド処理) | 補助機能 | スコアデータの暗号化・復号 |

## 機能種別

暗号処理 / ユーティリティ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| data (rc4_encode) | val | Yes | 暗号化/復号対象のデータ(参照渡し、インプレース変更) | - |
| key (rc4_encode) | str | Yes | 暗号化キー(パスワード文字列) | - |
| size (rc4_encode) | int | Yes | データのバイト数 | 正の整数 |
| key (rc4_init) | str | Yes | 暗号化キー(パスワード文字列) | - |
| data (rc4_crypt) | val | Yes | 暗号化/復号対象のデータ(参照渡し) | - |
| size (rc4_crypt) | int | Yes | データのバイト数 | 正の整数 |
| offset (rc4_crypt) | int | No | データの開始オフセット(デフォルト: 0) | 0以上 |

### 入力データソース

- スコアデータなどのバイナリデータ
- 暗号化キー文字列

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| data | val | 暗号化/復号されたデータ(インプレース変更) |

### 出力先

- 入力データ変数(インプレースで暗号化/復号結果を上書き)

## 処理フロー

### 処理シーケンス

```
■ rc4_encode(data, key, size):
1. rc4_init(key)を呼び出してS-Boxを初期化
   └─ Key Scheduling Algorithm (KSA)
2. rc4_crypt(data, size)を呼び出してデータを暗号化/復号
   └─ Pseudo-Random Generation Algorithm (PRGA)

■ rc4_init(key) - KSA:
1. rc4_x=0, rc4_y=0 を初期化
2. rc4_dat配列(256要素)を0~255で初期化
3. パスワードに基づいてS-Boxをシャッフル
   └─ 256回のスワップ操作

■ rc4_crypt(data, size, offset) - PRGA:
1. sizeバイト分のループ
2. 各バイトに対してキーストリームバイトを生成
   └─ rc4_x, rc4_yの更新とS-Boxのスワップ
3. データバイトとキーストリームバイトのXOR
   └─ c = peek(data, cnt+offset) ^ rc4_dat.a
4. 結果を元のデータに書き戻し
   └─ poke data, cnt+offset, c
```

### フローチャート

```mermaid
flowchart TD
    A[rc4_encode呼び出し] --> B[rc4_init: S-Box初期化]
    B --> C[S-Box: 0,1,...,255で初期化]
    C --> D[KSA: パスワードでS-Boxシャッフル]
    D --> E[rc4_crypt: データ暗号化]
    E --> F[ループ: i=0 to size-1]
    F --> G[rc4_x++, S-Boxスワップ]
    G --> H[キーストリームバイト生成]
    H --> I[data XOR キーストリーム]
    I --> J{ループ終了?}
    J -->|No| F
    J -->|Yes| K[暗号化完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-120-01 | 対称暗号 | 暗号化と復号は同じ鍵・同じ操作で行える | 常時 |
| BR-120-02 | インプレース処理 | 暗号化結果は入力データ変数を直接上書きする | 常時 |
| BR-120-03 | S-Box初期化 | rc4_crypt前に必ずrc4_initを呼び出す必要がある | 常時 |
| BR-120-04 | 鍵長制限 | 鍵長はstrlen(key)で自動取得される | 常時 |
| BR-120-05 | オフセット対応 | rc4_cryptはoffsetパラメータでデータの一部のみを暗号化可能 | offset指定時 |

### 計算ロジック

- KSA(Key Scheduling Algorithm):
  ```
  for i = 0 to 255:
    a = rc4_dat[i]
    b = (b + a + key[i mod keylen]) & 0xFF
    swap(rc4_dat[i], rc4_dat[b])
  ```
- PRGA(Pseudo-Random Generation Algorithm):
  ```
  for each byte:
    rc4_x = (rc4_x + 1) & 0xFF
    a = rc4_dat[rc4_x]
    rc4_y = (rc4_y + a) & 0xFF
    swap(rc4_dat[rc4_x], rc4_dat[rc4_y])
    output = data[i] XOR rc4_dat[(a + rc4_dat[rc4_y]) & 0xFF]
  ```

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

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

データベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | - | エラー処理は含まれていない |

### リトライ仕様

リトライ処理はない。

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

トランザクション管理はない。

## パフォーマンス要件

- RC4は高速なストリーム暗号であり、データサイズに比例した線形時間で処理される
- S-Box初期化は256回のスワップ操作で固定時間

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

- RC4は現在では暗号学的に安全とは見なされていない(既知の脆弱性が複数存在)
- 本用途ではゲームスコアの簡易的な改ざん防止を目的としており、高いセキュリティレベルは求められていない
- 暗号化キーがソースコード内にハードコードされている場合、リバースエンジニアリングによる解読が容易である

## 備考

- 原作者: K-K 2003、masaka により改修
- `#module "RC4"` としてモジュール化されている
- RC4は暗号化と復号が同一操作であるため、rc4_cryptを2回同じ鍵で呼び出すと元のデータに戻る
- HSPのpeek/poke命令でバイト単位のデータ操作を行っている

---

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

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

### 推奨読解順序

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

RC4の内部状態変数を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | rc4_crypt.hsp | `third_party/rc4_crypt.hsp` | **3行目**: `#module "RC4"` - モジュール宣言 |
| 1-2 | rc4_crypt.hsp | `third_party/rc4_crypt.hsp` | **14-16行目**: rc4_x, rc4_y, rc4_dat[256] - RC4内部状態 |

**読解のコツ**: RC4の核心はrc4_dat配列(256要素のS-Box)である。KSAでパスワードに基づきシャッフルし、PRGAでキーストリームを生成する。

#### Step 2: rc4_encode(ワンコール関数)を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | rc4_crypt.hsp | `third_party/rc4_crypt.hsp` | **5-8行目**: rc4_encode命令定義 |

**主要処理フロー**:
1. **6行目**: `rc4_init key1` - S-Box初期化
2. **7行目**: `rc4_crypt data1, size1` - データ暗号化/復号

#### Step 3: rc4_init(KSA)を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | rc4_crypt.hsp | `third_party/rc4_crypt.hsp` | **11-29行目**: rc4_init命令定義 |

**主要処理フロー**:
1. **12行目**: `kl=strlen(key)` - 鍵長取得
2. **14-15行目**: `rc4_x=0, rc4_y=0` - カウンタ初期化
3. **16-18行目**: `dim rc4_dat,256` → 0~255で初期化
4. **20-28行目**: KSAループ - パスワードに基づくS-Boxシャッフル
   - **23行目**: `a=rc4_dat.cnt` - 現在値取得
   - **24行目**: `c=peek(key2,cnt\kl)` - パスワードバイト取得(mod鍵長)
   - **25行目**: `b=b+a+c & 0xff` - インデックス計算
   - **26-27行目**: スワップ操作

#### Step 4: rc4_crypt(PRGA)を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | rc4_crypt.hsp | `third_party/rc4_crypt.hsp` | **32-48行目**: rc4_crypt命令定義 |

**主要処理フロー**:
1. **34行目**: `repeat size` - データサイズ分のループ開始
2. **35行目**: `rc4_x=rc4_x+1 & 0xff` - xカウンタ更新
3. **36行目**: `a=rc4_dat.rc4_x` - S-Box値取得
4. **37行目**: `rc4_y=rc4_y+a & 0xff` - yカウンタ更新
5. **38-40行目**: S-Boxのスワップ
6. **43行目**: `c=peek(data,cnt+offset)` - データバイト取得
7. **44行目**: `a=a+b & 0xff` - キーストリームインデックス計算
8. **45行目**: `c=c^rc4_dat.a` - XOR暗号化
9. **46行目**: `poke data,cnt+offset,c` - 結果書き戻し

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

```
呼び出し元
    |
    +-- rc4_encode(data, key, size)
            |
            +-- rc4_init(key)
            |       +-- strlen(key) → 鍵長取得
            |       +-- dim rc4_dat, 256 → S-Box初期化
            |       +-- KSAループ(256回) → S-Boxシャッフル
            |
            +-- rc4_crypt(data, size)
                    +-- PRGAループ(size回)
                        +-- peek → データバイト取得
                        +-- S-Boxスワップ → キーストリーム生成
                        +-- XOR → 暗号化
                        +-- poke → 結果書き戻し
```

### データフロー図

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

鍵(key) --------+--> rc4_init (KSA) ---------> S-Box[256]
                |
平文データ -----+--> rc4_crypt (PRGA) -------> 暗号化データ
バイト数(size)          +-- S-Box参照              (インプレース)
                       +-- XOR演算
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| rc4_crypt.hsp | `third_party/rc4_crypt.hsp` | ソース | RC4暗号化モジュール本体(全50行) |
| kshootmania.hsp | `kshootmania.hsp` | ソース | ゲーム本体。スコアデータ暗号化時にrc4_encodeを使用 |
