本文へスキップ
ecdsa.com

SHA-256 と SHA-3 の比較|Merkle–Damgård かスポンジか

どちらも 128 ビットの衝突耐性を持ち、量子コンピューターにも耐えます。SHA-256 は最新の CPU ではより高速で、ほとんどのプロトコルで必須です。SHA-3 は構造の異なる予備の選択肢です。
比較対象SHA-256SHA-3

SHA-256 と SHA-3 の比較で取り上げるのは、SHA-2 ファミリーの主力と、NIST が 2015年に公開した Keccak ベースの標準です。どちらも破られておらず、破られる兆しもありません。また、256 ビットの出力サイズでは、どちらも名目上は同じ安全性を提供します。違いは内部設計にあり、それが伸長攻撃への耐性、速度、そして新しいアルゴリズムの内部での使われ方に影響します。

比較表

SHA-256SHA3-256
標準FIPS 180-4(ファミリーは 2001年、改訂は 2015年)FIPS 202(2015年)
構造Merkle–Damgård、32 ビットの圧縮関数を 64 ラウンド1600 ビットの Keccak-f 置換によるスポンジ、24 ラウンド
出力256 ビット256 ビット
衝突耐性 / 原像耐性128 / 256 ビット128 / 256 ビット
伸長攻撃可能。hash(secret ‖ m) は MAC として使えない不可能
可変長出力の派生関数なしSHAKE128、SHAKE256
スループット(16 KiB の入力、OpenSSL 3.6.5)約 2.85 GB/s約 1.01 GB/s
スループット(16 バイトの入力)約 0.17 GB/s約 0.07 GB/s
CPU 命令Intel と AMD の SHA 拡張命令、ARMv8 SHA2ARMv8.2 の SHA3 命令(EOR3、RAX1、XAR、BCAX)
必須とするものTLS、X.509、JOSE の S256 や RS256 など、Bitcoin、Git(SHA-256 リポジトリ)ML-KEM、ML-DSA(SHAKE と SHA3)、SLH-DSA の SHAKE 系パラメーターセット、Ed448(SHAKE256)
量子コンピューターの影響Grover:原像探索の計算量は最大でも平方根まで減る程度。引き続き承認済み同じ

スループットは、両ファミリーのハードウェア支援を備えた Apple M4 Max のシングルコアで、openssl speed -evp を使って計測しました。

設計の違い

SHA-256 はメッセージを 64 バイトのブロック単位で処理し、各ブロックを直前の 256 ビットの状態とともに圧縮関数に入力します。最後の状態がダイジェストになります。ダイジェストが内部状態そのものであるため、SHA-256(x) と x の長さを知っていれば誰でも、x を知らないままハッシュ計算を続けて SHA-256(x ‖ padding ‖ y) を求められます。この伸長攻撃は署名や HMAC には影響しませんが、SHA-256(key ‖ message) のような素朴な MAC を破ります。

SHA-3 はスポンジ構造です。Keccak-f 置換を通じて入力を 1600 ビットの状態に吸収し、その一部から出力を絞り出します。SHA3-256 では、状態のうち 1088 ビットがレート、512 ビットがキャパシティで、キャパシティは決して出力されません。そのため伸長攻撃は不可能で、SHA3-256(key ‖ message) は健全な MAC になります(NIST はこの用途のために KMAC を標準化しています)。同じスポンジ構造から、可変長出力関数である SHAKE128 と SHAKE256 も得られます。ポスト量子アルゴリズムは、これらを使ってシードを行列やノイズに展開します。

NIST は、5 年にわたるコンペティションを経て 2012年に Keccak を選定しました。このコンペティションは、MD5 と SHA-1 への攻撃によって、構造の似た SHA-2 にも懸念が生じたことをきっかけに始まったものです。その懸念は現実になりませんでした。SHA-256 に対する最良の攻撃でも、衝突については 64 ステップ中約 31 ステップまでしか届いておらず、全ステップの完全な関数には弱点が見つかっていません。したがって SHA-3 は保険であり、置き換えではありません。

速度

Apple M4 Max には両ファミリーの命令がありますが、長い入力では SHA-256 のほうが 3 倍近く高速です。OpenSSL 3.6.5 では SHA-256 が約 2.85 GB/s、SHA3-256 が 1.01 GB/s で、SHA3-512 は 0.53 GB/s でした。SHA 拡張命令を備えた x86 CPU でも傾向は同様です。ハッシュ命令を持たないプロセッサーでは SHA-3 と SHA-256 の差は縮まり、BLAKE2 や BLAKE3 はそのどちらよりも高速です。ほとんどのアプリケーションでは、どちらも周囲の I/O よりはるかに高速です。差が問題になるのは、非常に大きなファイルのハッシュ計算、Merkle ツリー、ブロックチェーンです。

SHA3-256 は Keccak-256 ではない

Ethereum は FIPS 202 が確定する前に Keccak を採用し、その後 FIPS 202 でパディングが変更されました(ドメイン分離ビットの追加)。両者は同じ置換を共有していますが、ダイジェストはまったく無関係な値になります。Solidity の keccak256、web3_sha3 RPC、そして Ethereum のすべてのアドレス、関数セレクター、EIP-712 ダイジェストは Keccak-256 を使用します。Ethereum のコードでライブラリの SHA3-256 を呼び出すと、エラーが出ないまま誤った結果になります。

Node.js 26 と @noble/hashes:入力 abc に対する 3 種類の 256 ビットダイジェスト
import { createHash } from "node:crypto";
import { keccak_256 } from "@noble/hashes/sha3.js";

const input = Buffer.from("abc");
console.log("SHA-256   ", createHash("sha256").update(input).digest("hex"));
console.log("SHA3-256  ", createHash("sha3-256").update(input).digest("hex"));
console.log("Keccak-256", Buffer.from(keccak_256(input)).toString("hex"));
出力
SHA-256    ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
SHA3-256   3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532
Keccak-256 4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45

SHA-256 と SHA3-256 の値は、FIPS 180-4 と FIPS 202 に掲載されている「abc」の例と一致します。

どちらを選ぶべきか

  • プロトコルの相互運用性(TLS、証明書、JWT、SSH、Git、パッケージマネージャー、Bitcoin):SHA-256 を使います。相手側が計算するのが SHA-256 だからです。
  • 鍵付きハッシュ:HMAC(HMAC-SHA256 など)はどの SHA-2 ハッシュとも組み合わせて使えます。単純な鍵付き構成を好む場合は、KMAC か鍵付き SHA-3 を使えば、HMAC の二重のハッシュ計算を避けられます。
  • シードの展開、決定的な乱数列、可変長の出力:SHAKE256 または SHAKE128 を使います。
  • ポスト量子アルゴリズム:標準が内部で定めているものを使います。ML-KEM と ML-DSA は SHA3 と SHAKE を使用するため、これらを実装したライブラリにはすでに SHA-3 が含まれています。
  • Ethereum:Keccak-256 を使います。FIPS の SHA3-256 を使ってはいけません。
  • 多層防御のための、構造の異なる別のハッシュ(長期アーカイブの二重ハッシュなど):SHA-256 と併せて SHA-3 を使います。
  • FIPS の要件がなく、純粋に速度を求める場合:ハッシュ命令のない CPU では BLAKE2 または BLAKE3 を使います。

移行時の注意点

ハッシュ関数を切り替えるとすべてのダイジェストが変わるため、これはライブラリの差し替えではなく形式の変更です。

  1. 識別子にバージョンを持たせる:コンテナレジストリや SRI などのコンテンツアドレス方式のシステムと同様に、各ダイジェストとともにアルゴリズムを記録します(sha256:、sha3-256:、multihash、OID)。
  2. 移行期間中は両方を公開する:両方のダイジェストを計算し、利用側が知っているほうで検証し、利用側の更新が済んだら古いほうを廃止します。
  3. 伸長攻撃に関する前提を確認する:コードが hash(secret ‖ message) の形で MAC を構成している場合、SHA-3 に移行すれば問題は解消しますが、HMAC に移行すれば SHA-256 のままでも解消します。
  4. 切り詰めとエンコーディングに注意する:ダイジェストは hex、base64、base64url のいずれかで受け渡されます。アルゴリズムの不一致よりも、エンコーディングの不一致のほうがよく起こります。
  5. 量子コンピューターだけを理由に移行しない:どちらの関数も Grover のアルゴリズムに対して 128 ビット以上の原像計算困難性を保ち、NIST の移行計画案でもどちらも引き続き使用されます。

参考資料

すべての比較