Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 18142] ファイルの概要

このコミットは、Go言語の標準ライブラリ crypto/sha1 パッケージにおけるSHA-1ハッシュ関数のテストコードに、Size() メソッドと BlockSize() メソッドのテストケースを追加するものです。これにより、SHA-1ハッシュの出力サイズとブロックサイズが期待通りであることを検証します。

コミット

commit 0333e80d63afd4cc7595fab589feaf8140154bc7
Author: Shawn Smith <shawn.p.smith@gmail.com>
Date:   Tue Dec 31 23:13:05 2013 +1100

    crypto/sha1: add tests for Size() and BlockSize()
    
    R=golang-codereviews, dave
    CC=golang-codereviews
    https://golang.org/cl/46400044

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/0333e80d63afd4cc7595fab589feaf8140154bc7

元コミット内容

crypto/sha1: add tests for Size() and BlockSize()

このコミットは、crypto/sha1 パッケージに Size() および BlockSize() メソッドのテストを追加します。

変更の背景

Go言語の標準ライブラリ crypto/sha1 パッケージは、Secure Hash Algorithm 1 (SHA-1) を実装しています。ハッシュ関数は、任意のサイズのデータを固定長のハッシュ値(メッセージダイジェスト)に変換するために使用されます。SHA-1の場合、出力されるハッシュ値は160ビット(20バイト)です。また、ハッシュ計算はデータを特定のブロックサイズ(SHA-1の場合は64バイト)に分割して処理します。

Go言語の hash パッケージには、ハッシュ関数が満たすべき hash.Hash インターフェースが定義されています。このインターフェースには、ハッシュ値のバイト数を返す Size() メソッドと、ハッシュ関数が一度に処理するブロックサイズを返す BlockSize() メソッドが含まれています。

このコミットが作成された背景には、crypto/sha1 パッケージが hash.Hash インターフェースを正しく実装していることを保証し、その振る舞いを明確にする目的があります。特に、Size()BlockSize() はハッシュ関数の基本的な特性を示すものであり、これらの値がSHA-1の仕様と一致していることをテストで確認することは、ライブラリの堅牢性と正確性を高める上で重要です。

テストを追加することで、将来の変更によってこれらの定数が誤って変更されたり、実装が仕様から逸脱したりするのを防ぐことができます。これは、ソフトウェア開発における「テスト駆動開発 (TDD)」や「回帰テスト」の原則に沿ったものであり、コードの品質と信頼性を維持するために不可欠なプラクティスです。

前提知識の解説

1. SHA-1 (Secure Hash Algorithm 1)

SHA-1は、アメリカ国家安全保障局 (NSA) によって設計された暗号学的ハッシュ関数です。入力されたデータから、160ビット(20バイト)の固定長のハッシュ値(メッセージダイジェスト)を生成します。このハッシュ値は、データの整合性を検証するために使用されます。例えば、ファイルがダウンロード中に改ざんされていないかを確認する際などに利用されます。

しかし、SHA-1は2005年頃から衝突攻撃(異なる入力から同じハッシュ値が生成されること)の脆弱性が指摘され始め、2017年には実際に衝突攻撃が成功したことが発表されました。このため、現在ではセキュリティが要求される多くのアプリケーションではSHA-256やSHA-3などのより強力なハッシュ関数への移行が推奨されており、SHA-1は非推奨となっています。Go言語の crypto/sha1 パッケージも、主にレガシーシステムとの互換性のために提供されています。

2. 暗号学的ハッシュ関数

暗号学的ハッシュ関数は、以下の特性を持つ数学的な関数です。

  • 一方向性 (Preimage Resistance): ハッシュ値から元のデータを効率的に復元することは非常に困難である。
  • 第二原像耐性 (Second Preimage Resistance): あるデータと同じハッシュ値を持つ別のデータを効率的に見つけることは非常に困難である。
  • 衝突耐性 (Collision Resistance): 同じハッシュ値を持つ異なる2つのデータを効率的に見つけることは非常に困難である。

これらの特性により、ハッシュ関数はデータの改ざん検出、デジタル署名、パスワードの保存などに利用されます。

3. Go言語の hash パッケージと hash.Hash インターフェース

Go言語の標準ライブラリには、ハッシュ関数を扱うための hash パッケージが用意されています。このパッケージは、様々なハッシュ関数(MD5, SHA-1, SHA-256など)が共通のインターフェースを通じて操作できるように、hash.Hash インターフェースを定義しています。

hash.Hash インターフェースの主要なメソッドは以下の通りです。

  • Write(p []byte) (n int, err error): ハッシュ計算のためにデータを入力します。
  • Sum(b []byte) []byte: 現在のハッシュ値を計算し、b に追加して返します。
  • Reset(): ハッシュ関数を初期状態に戻します。
  • Size() int: ハッシュ値のバイト数を返します。SHA-1の場合は20バイト(160ビット)です。
  • BlockSize() int: ハッシュ関数が一度に処理するブロックのバイト数を返します。SHA-1の場合は64バイトです。

crypto/sha1 パッケージの New() 関数は、この hash.Hash インターフェースを満たす型を返します。

4. テスト駆動開発 (TDD) と回帰テスト

  • テスト駆動開発 (TDD): ソフトウェア開発手法の一つで、コードを書く前にテストコードを先に書くことから始めます。テストが失敗することを確認し、そのテストが成功するように最小限のコードを書き、その後リファクタリングを行います。このサイクルを繰り返すことで、高品質で保守性の高いコードを効率的に開発できます。
  • 回帰テスト (Regression Testing): ソフトウェアの変更(新機能の追加、バグ修正など)が、既存の機能に悪影響を与えていないことを確認するために行われるテストです。自動化されたテストスイートは、回帰テストを効率的に実行するために非常に重要です。

このコミットは、Size()BlockSize() のテストを追加することで、crypto/sha1 パッケージの回帰テストカバレッジを向上させています。

技術的詳細

このコミットは、crypto/sha1 パッケージの sha1_test.go ファイルに2つの新しいテスト関数 TestSizeTestBlockSize を追加しています。これらのテストは、crypto/sha1 パッケージが提供するSHA-1ハッシュ関数の基本的な特性である出力サイズとブロックサイズが、それぞれ Size および BlockSize という定数で定義された期待値と一致するかどうかを検証します。

Go言語の crypto/sha1 パッケージでは、SHA-1の出力サイズとブロックサイズはそれぞれ SizeBlockSize という公開定数として定義されています。

  • sha1.Size はSHA-1ハッシュの出力バイト数(20バイト)を表します。
  • sha1.BlockSize はSHA-1ハッシュ関数が内部的に処理するブロックサイズ(64バイト)を表します。

これらの定数は、hash.Hash インターフェースの Size() および BlockSize() メソッドが返す値と一致する必要があります。

TestSize 関数

TestSize 関数は以下の手順でテストを行います。

  1. sha1.New() を呼び出して、新しいSHA-1ハッシュインスタンスを作成します。
  2. 作成したインスタンスの Size() メソッドを呼び出し、その戻り値を変数 got に格納します。
  3. got の値が sha1.Size 定数の値(20)と等しいかどうかを比較します。
  4. もし等しくない場合、t.Errorf を使用してエラーメッセージを出力し、テストを失敗させます。エラーメッセージには、期待値と実際の値の両方が含まれます。

TestBlockSize 関数

TestBlockSize 関数は以下の手順でテストを行います。

  1. sha1.New() を呼び出して、新しいSHA-1ハッシュインスタンスを作成します。
  2. 作成したインスタンスの BlockSize() メソッドを呼び出し、その戻り値を変数 got に格納します。
  3. got の値が sha1.BlockSize 定数の値(64)と等しいかどうかを比較します。
  4. もし等しくない場合、t.Errorf を使用してエラーメッセージを出力し、テストを失敗させます。エラーメッセージには、期待値と実際の値の両方が含まれます。

これらのテストは非常にシンプルですが、crypto/sha1 パッケージの基本的な契約(hash.Hash インターフェースの実装)が正しく守られていることを保証するために重要です。これにより、このパッケージを利用する他のコードが、SHA-1ハッシュの特性を前提として安全に動作することが保証されます。

コアとなるコードの変更箇所

変更は src/pkg/crypto/sha1/sha1_test.go ファイルに集中しています。

--- a/src/pkg/crypto/sha1/sha1_test.go
+++ b/src/pkg/crypto/sha1/sha1_test.go
@@ -76,6 +76,20 @@ func TestGolden(t *testing.T) {
 	}\n
 }\n
 \n+func TestSize(t *testing.T) {\n+	c := New()\n+	if got := c.Size(); got != Size {\n+		t.Errorf(\"Size = %d; want %d\", got, Size)\n+	}\n+}\n+\n+func TestBlockSize(t *testing.T) {\n+	c := New()\n+	if got := c.BlockSize(); got != BlockSize {\n+		t.Errorf(\"BlockSize = %d; want %d\", got, BlockSize)\n+	}\n+}\n+\n var bench = New()\n var buf = make([]byte, 8192)\n \n```

## コアとなるコードの解説

追加されたコードは以下の2つのテスト関数です。

### `func TestSize(t *testing.T)`

```go
func TestSize(t *testing.T) {
	c := New() // 新しいSHA-1ハッシュインスタンスを作成
	if got := c.Size(); got != Size { // インスタンスのSize()メソッドを呼び出し、sha1.Size定数と比較
		t.Errorf("Size = %d; want %d", got, Size) // 期待値と異なる場合はエラーを出力
	}
}

このテスト関数は、crypto/sha1 パッケージの New() 関数で作成されたSHA-1ハッシュインスタンスが返すハッシュサイズが、パッケージ内で定義されている Size 定数(SHA-1の出力サイズである20バイト)と一致するかどうかを確認します。t.Errorf は、テストが失敗した場合にエラーメッセージを整形して出力するためのGoのテストフレームワークの関数です。

func TestBlockSize(t *testing.T)

func TestBlockSize(t *testing.T) {
	c := New() // 新しいSHA-1ハッシュインスタンスを作成
	if got := c.BlockSize(); got != BlockSize { // インスタンスのBlockSize()メソッドを呼び出し、sha1.BlockSize定数と比較
		t.Errorf("BlockSize = %d; want %d", got, BlockSize) // 期待値と異なる場合はエラーを出力
	}
}

このテスト関数は、crypto/sha1 パッケージの New() 関数で作成されたSHA-1ハッシュインスタンスが返すブロックサイズが、パッケージ内で定義されている BlockSize 定数(SHA-1の内部処理ブロックサイズである64バイト)と一致するかどうかを確認します。同様に、t.Errorf を使用してエラーを報告します。

これらのテストは、crypto/sha1 パッケージが hash.Hash インターフェースの仕様に準拠していることを保証し、SHA-1ハッシュ関数の基本的な特性が正しく実装されていることを検証する上で不可欠です。

関連リンク

参考にした情報源リンク