# 機能設計書 89-sha1

## 概要

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

### 本機能の処理概要

sha1モジュールは、FIPS 180-1で定義されたSHA-1（Secure Hash Algorithm 1）ハッシュアルゴリズムを実装する。160ビット（20バイト）のハッシュ値を生成し、データの整合性検証に使用される。

**業務上の目的・背景**：SHA-1はMD5より強力だが、やはりセキュリティ目的では非推奨となっている。ただし、GitコミットハッシュやTLSの一部で依然として使用されており、レガシーシステムとの互換性維持に必要である。

**機能の利用シーン**：Gitオブジェクトのハッシュ計算、レガシーシステムとの互換性、ファイルの整合性チェック、デジタル署名の検証（レガシー）など。

**主要な処理内容**：
1. 文字列からSHA-1ハッシュを計算（secureHash関数）
2. ファイルからSHA-1ハッシュを計算（secureHashFile関数）
3. インクリメンタルハッシュ計算（Sha1State型）
4. ハッシュ値の文字列変換と比較

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

**権限による制御**：ファイルアクセス時はOSの権限に従う。

## 関連画面

該当なし

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| str | openArray[char] | Yes | ハッシュ対象の文字列 | - |
| filename | string | Yes | ハッシュ対象のファイルパス | 有効なファイルパス |
| data | openArray[char] | Yes | インクリメンタル入力データ | - |
| hash | string | Yes | パース対象の16進数文字列 | 40文字の16進数 |

### 入力データソース

任意のバイナリ/文字列データ、ファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| SecureHash | distinct Sha1Digest | 20バイトのSHA-1ハッシュ値 |
| Sha1Digest | array[0..19, uint8] | 20バイトの配列 |
| string | string | 40文字の16進数文字列表現（大文字） |

### 出力先

戻り値

## 処理フロー

### 処理シーケンス

```
1. 一括ハッシュ計算
   └─ secureHash(str)
      ├─ newSha1State()でコンテキスト初期化
      ├─ state.update(str)でデータ処理
      └─ SecureHash(state.finalize())で結果取得

2. ファイルハッシュ計算
   └─ secureHashFile(filename)
      ├─ newSha1State()
      ├─ ファイルを8192バイトずつ読み込み
      ├─ state.update(buffer) ×n回
      └─ SecureHash(state.finalize())

3. インクリメンタルハッシュ計算
   └─ newSha1State()
      └─ state[0..4]を初期値に設定

   └─ update(data) ※複数回呼び出し可能
      ├─ 64バイトブロックごとにtransform
      └─ 残りはbufに保持

   └─ finalize()
      ├─ 0x80パディング追加
      ├─ 64ビット長さ追加（ビッグエンディアン）
      └─ Sha1Digest生成
```

### フローチャート

```mermaid
flowchart TD
    A[入力データ] --> B{処理モード}
    B -->|文字列| C[secureHash]
    B -->|ファイル| D[secureHashFile]
    B -->|インクリメンタル| E[newSha1State]

    C --> F[内部でstate管理]
    D --> G[8192バイトずつ読み込み]
    E --> H[update ×n回]

    F --> I[finalize]
    G --> I
    H --> I

    I --> J[SecureHash]

    J --> K{出力形式}
    K -->|バイナリ| L[Sha1Digest]
    K -->|文字列| M[$ 演算子]
    M --> N[40文字の16進数文字列]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-89-01 | 非推奨警告 | モジュール使用時に非推奨警告を出力 | コンパイル時 |
| BR-89-02 | 移行推奨 | checksums/sha1への移行を推奨 | 新規開発時 |
| BR-89-03 | 出力形式 | ハッシュ値は大文字の16進数で出力 | $演算子使用時 |
| BR-89-04 | 有効性検証 | isValidSha1Hashで文字列の形式を検証可能 | 文字列検証時 |

### 計算ロジック

**SHA-1アルゴリズム**:
1. 初期ハッシュ値: H0=0x67452301, H1=0xEFCDAB89, H2=0x98BADCFE, H3=0x10325476, H4=0xC3D2E1F0
2. 512ビット（64バイト）ブロック単位で処理
3. 80ラウンドの変換（shaF1〜shaF4）
4. パディング: 0x80 + 0x00... + 64ビット長さ（ビッグエンディアン）

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IOError | ファイル読み込みエラー | secureHashFileでファイルが存在しない | パス確認 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- O(n) where n = 入力データサイズ
- 64バイトブロック単位での効率的な処理
- ファイル読み込みは8192バイトバッファ

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

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

## 備考

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

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sha1.nim | `lib/std/sha1.nim` | Sha1DigestSize定数（38行目） |
| 1-2 | sha1.nim | `lib/std/sha1.nim` | Sha1Digest型（40-41行目） |
| 1-3 | sha1.nim | `lib/std/sha1.nim` | SecureHash型（42行目） |
| 1-4 | sha1.nim | `lib/std/sha1.nim` | Sha1State型（44-48行目） |

**読解のコツ**:
- Sha1DigestSizeは20（160ビット）
- SecureHashはSha1Digestのdistinct型
- Sha1Stateはcount, state[5], buf[64]を持つ

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | sha1.nim | `lib/std/sha1.nim` | ror27/ror2/ror31テンプレート（65-67行目） |
| 2-2 | sha1.nim | `lib/std/sha1.nim` | transform関数（69-148行目） |

**主要処理フロー**:
- **65-67行目**: 回転シフト操作
- **80-102行目**: shaF1（ラウンド0-19）
- **104-116行目**: shaF2（ラウンド20-39）
- **118-129行目**: shaF3（ラウンド40-59）
- **131-142行目**: shaF4（ラウンド60-79）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | sha1.nim | `lib/std/sha1.nim` | newSha1State関数（53-63行目） |
| 3-2 | sha1.nim | `lib/std/sha1.nim` | update関数（150-183行目） |
| 3-3 | sha1.nim | `lib/std/sha1.nim` | finalize関数（185-203行目） |
| 3-4 | sha1.nim | `lib/std/sha1.nim` | secureHash関数（207-219行目） |
| 3-5 | sha1.nim | `lib/std/sha1.nim` | secureHashFile関数（221-242行目） |
| 3-6 | sha1.nim | `lib/std/sha1.nim` | $演算子（244-255行目） |
| 3-7 | sha1.nim | `lib/std/sha1.nim` | parseSecureHash関数（257-270行目） |
| 3-8 | sha1.nim | `lib/std/sha1.nim` | isValidSha1Hash関数（285-287行目） |

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

```
アプリケーションコード
    │
    ├─ secureHash(str)
    │      ├─ newSha1State()
    │      │      └─ state[0..4]初期化
    │      ├─ update(str)
    │      │      └─ transform(buf, state) ×n回
    │      └─ finalize()
    │             ├─ パディング追加
    │             └─ SecureHash(digest)
    │
    ├─ secureHashFile(filename)
    │      ├─ newSha1State()
    │      ├─ readChars(f, buffer) ×n回
    │      │      └─ update(buffer)
    │      └─ finalize()
    │
    ├─ parseSecureHash(hash)
    │      └─ 16進数文字列→SecureHash変換
    │
    └─ isValidSha1Hash(s)
           └─ 長さ40 AND HexDigitsのみ
```

### データフロー図

```
[入力データ]              [SHA-1処理]              [出力]

"Hello World"
      │
      ▼
newSha1State()
      │
      ▼
┌────────────────────┐
│ count: 0           │
│ state[0..4]        │
│ buf[0..63]         │
└────────────────────┘
      │
update(data)
      │
      ▼
512ビットブロック処理
      │
transform (80 rounds)
      │
      ▼
finalize()
      │
      ▼
┌──────────────────────────┐
│ SecureHash (20 bytes)    │
└──────────────────────────┘
      │
   $ 演算子
      │
      ▼
"0A4D55A8D778E5022FAB701977C5D840BBC486D0"
```

### 関連ファイル一覧

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