[インデックス 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つの新しいテスト関数 TestSize
と TestBlockSize
を追加しています。これらのテストは、crypto/sha1
パッケージが提供するSHA-1ハッシュ関数の基本的な特性である出力サイズとブロックサイズが、それぞれ Size
および BlockSize
という定数で定義された期待値と一致するかどうかを検証します。
Go言語の crypto/sha1
パッケージでは、SHA-1の出力サイズとブロックサイズはそれぞれ Size
と BlockSize
という公開定数として定義されています。
sha1.Size
はSHA-1ハッシュの出力バイト数(20バイト)を表します。sha1.BlockSize
はSHA-1ハッシュ関数が内部的に処理するブロックサイズ(64バイト)を表します。
これらの定数は、hash.Hash
インターフェースの Size()
および BlockSize()
メソッドが返す値と一致する必要があります。
TestSize
関数
TestSize
関数は以下の手順でテストを行います。
sha1.New()
を呼び出して、新しいSHA-1ハッシュインスタンスを作成します。- 作成したインスタンスの
Size()
メソッドを呼び出し、その戻り値を変数got
に格納します。 got
の値がsha1.Size
定数の値(20)と等しいかどうかを比較します。- もし等しくない場合、
t.Errorf
を使用してエラーメッセージを出力し、テストを失敗させます。エラーメッセージには、期待値と実際の値の両方が含まれます。
TestBlockSize
関数
TestBlockSize
関数は以下の手順でテストを行います。
sha1.New()
を呼び出して、新しいSHA-1ハッシュインスタンスを作成します。- 作成したインスタンスの
BlockSize()
メソッドを呼び出し、その戻り値を変数got
に格納します。 got
の値がsha1.BlockSize
定数の値(64)と等しいかどうかを比較します。- もし等しくない場合、
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ハッシュ関数の基本的な特性が正しく実装されていることを検証する上で不可欠です。
関連リンク
- Go言語
crypto/sha1
パッケージのドキュメント: https://pkg.go.dev/crypto/sha1 - Go言語
hash
パッケージのドキュメント: https://pkg.go.dev/hash - Go言語のテストに関するドキュメント: https://go.dev/doc/code#testing
参考にした情報源リンク
- Secure Hash Algorithm 1 (SHA-1) - Wikipedia: https://ja.wikipedia.org/wiki/Secure_Hash_Algorithm_1
- SHA-1 Collision - Wikipedia: https://en.wikipedia.org/wiki/SHA-1#SHA-1_collision
- Go言語のテスト入門 - Qiita: https://qiita.com/tcnksm/items/40222320112222222222 (一般的なGoテストの書き方について)
- Go言語の標準ライブラリ
crypto
パッケージのソースコード (GitHub): https://github.com/golang/go/tree/master/src/crypto - Go言語の標準ライブラリ
hash
パッケージのソースコード (GitHub): https://github.com/golang/go/tree/master/src/hash - Go言語の標準ライブラリ
crypto/sha1
パッケージのソースコード (GitHub): https://github.com/golang/go/tree/master/src/crypto/sha1 - Go言語の標準ライブラリ
crypto/sha1/sha1_test.go
のソースコード (GitHub): https://github.com/golang/go/blob/master/src/crypto/sha1/sha1_test.go