Argon2
RFC 9106 Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications
パスワードハッシュとproof-of-work アプリケーションのためのArgon2メモリハード関数
パスワードハッシュおよびproof-of-work アプリケーション向けArgon2メモリハード関数
概要
本文書は、パスワードハッシュおよびproof-of-work アプリケーション向けArgon2メモリハード関数について解説します。実装者向けの説明とテストベクトルを提供します。本文書の目的は、インターネットプロトコルへのArgon2の導入を簡素化することです。本文書は、IRTFのCrypto Forum Research Group (CFRG) の成果物です。
1. はじめに
本文書では、パスワードハッシュおよびproof-of-work (PoW) アプリケーション向けのメモリハード関数Argon2 ARGON2ESP について説明します。実装者向けの説明とテストベクトルを提供します。インターネットプロトコルへのArgon2の導入を容易にすることを目的としています。本文書は、Argon2ハッシュ関数のバージョン1.3に対応しています。 Argon2はメモリハード関数HARDです。合理化された設計で、最高のメモリ占有率と複数のコンピューティングユニットの効率的な利用を目指しつつ、トレードオフ攻撃に対する防御機能も備えています。Argon2はx86アーキテクチャ向けに最適化されており、最新のIntelおよびAMDプロセッサのキャッシュとメモリ構成を活用します。Argon2には、主要なバリアント(変種)であるArgon2idと、補助的なバリアントであるArgon2dおよびArgon2iの2つがあります。Argon2dはデータ依存型メモリアクセスを使用するため、サイドチャネルタイミング攻撃の脅威がなく、暗号通貨やPoWアプリケーションに適しています。 Argon2iはデータ非依存メモリアクセスを採用しており、パスワードハッシュやパスワードベースの鍵導出に適しています。Argon2idは、メモリ上の最初のパスの前半はArgon2iとして動作し、残りの半分はArgon2dとして動作することで、サイドチャネル攻撃からの保護と、時間とメモリのトレードオフによるブルートフォース攻撃のコスト削減の両方を実現します。Argon2iは、トレードオフ攻撃から保護するために、メモリ上のパスを複数回実行しますAB15。 Argon2id は、本文書のいかなる実装においてもサポートされなければなりません(MUST)。一方、Argon2d と Argon2i はサポートされてもよい(MAY)。
Argon2 は、固定入力長の圧縮関数 G と可変入力長のハッシュ関数 H 上で動作するモードでもあります。Argon2 は、64 バイトまでの出力を提供する限り、任意の関数 H と組み合わせて使用できる可能性がありますが、本文書では BLAKE2b 関数 BLAKE2 を使用します。 詳細な背景と議論については、Argon2 に関する論文 ARGON2 を参照してください。 本文書は、Crypto Forum Research Group (CFRG) の合意事項を反映しています。
1.1. 要件言語
本文書におけるキーワード「MUST(しなければならない)」「MUST NOT(してはならない)」「REQUIRED(必須)」「SHALL(すべき)」「SHALL NOT(すべきではない)」「SHOULD(すべきではない)」「RECOMMENDED(推奨)」「NOT RECOMMENDED(推奨されない)」「MAY(してもよい)」「OPTIONAL(任意)」は、ここで示すようにすべて大文字で表記されている場合に限り、BCP 14 RFC 2119 RFC 8174 の規定に従って解釈されます。 2. 表記法と規則
table:表記と規則
x^y 整数 x をそれ自身で整数 y 回乗算した値
a*b 整数 a と整数 b の乗算
c-d 整数 d を整数 c から減算した値
E_f 添字インデックス f を持つ変数 E
g / h 整数 g を整数 h で割った値。結果は有理数。
I(j) 関数 I を j で評価した値
K || L 文字列 K と文字列 L の連結
a XOR b ビット列 a と b のビット単位の排他的論理和
a mod b 整数 a の剰余 (常に 0, b-1 の範囲) a >>> n 64 ビット文字列 a を右に n ビット回転
trunc(a) 64 ビット値 (下位 32 ビットに切り捨て)
floor(a) a より大きくない最大の整数
ceil(a) a より小さくない最小の整数
extract(a, i) ビット列 a から i 番目の 32 ビットセット (0 番目から開始)
|A| 集合Aの要素数
LE32(a) 32ビット整数aをリトルエンディアンのバイト文字列に変換したもの(例えば、123456(10進数)は40 E2 01 00 です)
LE64(a) 64ビット整数aをリトルエンディアンのバイト文字列に変換したもの(例えば、123456(10進数)は40 E2 01 00 00 00 00 00 です)
int32(s) 32ビット文字列sをリトルエンディアンの非負整数に変換したもの
int64(s) 64ビット文字列sをリトルエンディアンの非負整数に変換したもの
length(P) 文字列Pのバイト長を32ビット整数で表したもの
ZERO(P) Pバイトのゼロ文字列
3. Argon2 アルゴリズム
3.1. Argon2 の入力と出力
Argon2 には以下の入力パラメータがあります。
メッセージ文字列 P は、パスワードハッシュアプリケーションにおけるパスワードです。長さは $ 2^{32}-1 バイト以下である必要があります。
ノンス S は、パスワードハッシュアプリケーションにおけるソルトです。長さは $ 2^{32}-1 バイト以下である必要があります。パスワードハッシュには 16 バイトが推奨されます。ソルトはパスワードごとに一意である必要があります。
並列度 p は、実行可能な独立した(ただし同期する)計算チェーン(レーン)の数を決定します。1 から 2^(24)-1 までの整数値である必要があります。
タグ長 T は 4 から $ 2^{32}-1 までの整数バイトでなければなりません。
メモリサイズ m は 8p から 2^(32)-1 までの整数キビバイトでなければなりません。実際のブロック数は m' で、これは m を 4p の倍数に切り捨てた値です。
パス数 t (メモリサイズとは独立して実行時間を調整するために使用) は 1 から $ 2^{32}-1 までの整数でなければなりません。
バージョン番号 v は 1 バイト 0x13 でなければなりません。
秘密値 K はオプションです。使用する場合、その長さは $ 2^{32}-1 バイト以下でなければなりません。
関連データ X はオプションです。使用する場合、その長さは $ 2^{32}-1 バイト以下でなければなりません。
y 型は、Argon2d の場合は 0、Argon2i の場合は 1、Argon2id の場合は 2 でなければなりません。
Argon2 の出力、つまり「タグ」は、T バイトの長さの文字列です。
3.2. Argon2 の動作
Argon2 は、2つの1024バイトの入力と1つの1024バイトの出力を持つ内部圧縮関数 G と、内部ハッシュ関数 H^x() を使用します。ここで、x は出力の長さ(バイト単位)です。ここで、文字列 A に適用される H^x() は BLAKE2b (BLAKE2、セクション 3.3) 関数であり、(d,ll,kk=0,nn=x) をパラメータとして受け取ります。ここで、d は A を128バイトの倍数にパディングしたもの、ll は d のバイト単位の長さです。圧縮関数 G は、その内部順列に基づいています。また、H に基づいて構築された可変長ハッシュ関数 H' も使用されます。G についてはセクション 3.5 で、H' についてはセクション 3.3 で説明します。 Argon2 の動作は以下のとおりです。
1. H_0を以下の64バイト値として設定します。K、X、またはSの長さが0の場合、それらは単に存在しないだけで、長さフィールドは残ります。
code:図1 H_0 生成
H_0 = H^(64)(LE32(p) || LE32(T) || LE32(m) || LE32(t) ||
LE32(v) || LE32(y) || LE32(length(P)) || P ||
LE32(length(S)) || S || LE32(length(K)) || K ||
LE32(length(X)) || X)
2. メモリをm'個の1024バイトブロックとして割り当てます。ここで、m'は次のように求められます。
code:図2 メモリ割当
m' = 4 * p * floor (m / 4p)
p個のプレーンの場合、メモリはp行(レーン)とq = m' / p列のブロックからなる行列B[i][j]で構成されます。
3. 0(含む)からp(含まない)までのすべてのiについてB[i][0]を計算します。
code:図3 レーン開始ブロック
Bi0 = H'^(1024)(H_0 || LE32(0) || LE32(i)) 4. 0(含む)からp(含まない)までのすべてのiについてB[i][1]を計算します。
code:図4 次レーン ブロック
Bi1 = H'^(1024)(H_0 || LE32(1) || LE32(i)) 5. 0(含む)からp(含まない)までのすべてのiと、2(含む)からq(含まない)までのすべてのjについて、B[i][j]を計算する。計算はスライス単位で行われなければならない(セクション3.4)。まず、スライス0のブロックがすべてのレーンについて(レーンの順序は任意)、次にスライス1のブロックが計算される、というように行われる。ブロックインデックスlとzは、Argon2d、Argon2i、Argon2idごとにi、jごとに異なる方法で決定される。
code:図5:さらなるブロック生成
6. パス数tが1より大きい場合、手順5を繰り返します。0(含む)からp(含まない)までのすべてのiと、1(含む)からq(含まない)までのすべてのjについて、B[i][0]とB[i][j]を計算します。ただし、ブロックの計算方法は異なり、古い値と新しい値の排他的論理和が取られます。
code:図6 さらなるパス
7. tステップが反復された後、最終ブロックCは最後の列のXORとして計算されます。
code:図6 最終ブロック
8. 出力タグはH'^T(C)として計算されます。
3.3. 可変長ハッシュ関数 H'
V_i を64バイトのブロックとし、W_i をその最初の32バイトとします。関数 H' を以下のように定義します。
code:図8: タグと初期ブロックの計算のための関数H'
if T <= 64
H'^T(A) = H^T(LE32(T)||A)
else
r = ceil(T/32)-2
V_1 = H^(64)(LE32(T)||A)
V_2 = H^(64)(V_1)
...
V_r = H^(64)(V_{r-1})
V_{r+1} = H^(T-32*r)(V_{r})
H'^T(X) = W_1 || W_2 || ... || W_r || V_{r+1}
3.4. インデックス
並列ブロック計算を可能にするため、メモリマトリックスをさらにSL = 4の垂直スライスに分割します。スライスとレーンの交差はセグメントと呼ばれ、長さはq/SLです。同じスライス内のセグメントは並列計算が可能で、互いにブロックを参照しません。他のすべてのブロックは参照可能です。
code:図9 pレーンと4スライスを備えたシングルパスArgon2
slice 0 slice 1 slice 2 slice 3
___/\___ ___/\___ ___/\___ ___/\___
/ \ / \ / \ / \
+----------+----------+----------+----------+
| | | | | > lane 0
+----------+----------+----------+----------+
| | | | | > lane 1
+----------+----------+----------+----------+
| | | | | > lane 2
+----------+----------+----------+----------+
| ... ... ... | ...
+----------+----------+----------+----------+
| | | | | > lane p - 1
+----------+----------+----------+----------+
3.4.1. 32ビット値 J_1 と J_2 の計算
3.4.1.1. Argon2d
J_1 はブロック B[i][j-1] の最初の32ビットで与えられ、J_2 はブロック B[i][j-1] の次の32ビットで与えられます。
code:図10: Argon2dでJ1、J2を導出する
J_1 = int32(extract(Bij-1, 0)) J_2 = int32(extract(Bij-1, 1)) 3.4.1.2. Argon2i
各セグメントについて、以下の処理を行います。まず、値Zを次のように計算します。
code:図11: Argon2iでJ1、J2を計算するための入力
Z= ( LE64(r) || LE64(l) || LE64(sl) || LE64(m') ||
LE64(t) || LE64(y) )
ここで
r: パス番号
l: レーン番号
sl: スライス番号
m': メモリブロックの総数
t: パスの総数
y: Argon2 のタイプ (Argon2d の場合は 0、Argon2i の場合は 1、Argon2id の場合は 2)
次に、以下の値を計算します。
q/(128*SL) 個の 1024 バイト値
G(ZERO(1024),G(ZERO(1024),
Z || LE64(1) || ZERO(968) )),
G(ZERO(1024),G(ZERO(1024),
Z || LE64(2) || ZERO(968) )),... ,
G(ZERO(1024),G(ZERO(1024),
Z || LE64(q/(128*SL)) || ZERO(968) )),
これらはq/(SL)個の8バイト値Xに分割され、X1||X2として扱われ、J_1=int32(X1)、J_2=int32(X2)に変換されます。
r、l、sl、m'、t、y、iの値は、リトルエンディアンで8バイトとして表現されます。
3.4.1.3. Argon2id
パス番号が0でスライス番号が0または1の場合、Argon2iと同様にJ_1とJ_2を計算します。それ以外の場合は、Argon2dと同様にJ_1とJ_2を計算します。
[* 3.4.2. J_1 と J_2 を参照ブロックインデックス [l][z] にマッピングする]
l = J_2 mod p の値は、ブロックが取得されるレーンのインデックスを示します。最初のパス (r=0) と最初のスライス (sl=0) では、ブロックは現在のレーンから取得されます。
集合 W には、以下の規則に従って参照されるインデックスが含まれます。
1. l が現在のレーンである場合、W には、計算され完了した最後の SL - 1 = 3 セグメント内のすべてのブロックのインデックスと、現在のパスの現在のセグメントで計算されたブロック(Bij-1 を除く)が含まれます。 2. l が現在のレーンでない場合、W には、レーン l で計算され完了した最後の SL - 1 = 3 セグメント内のすべてのブロックのインデックスが含まれます。Bij がセグメントの最初のブロックである場合、W の最後のインデックスは除外されます。 次に、次のマッピングを使用して、W から [0, |W|) に不均一に分布するブロックを 1 つ取得します。
code:図12: コンピューティング J1
J_1 -> |W|(1 - J_1^2 / 2^(64))
浮動小数点計算を回避するために、次の近似値が使用されます。
code:図13: コンピューティング J1、パート2
x = J_1^2 / 2^(32)
y = (|W| * x) / 2^(32)
zz = |W| - 1 - y
次にWからzz番目のインデックスを取得します。これが参照ブロックインデックス[l][z]のz値になります。
3.5. 圧縮関数G
圧縮関数 G は、BLAKE2b ベースの変換 P に基づいて構築されます。P は 128 バイトの入力に対して動作し、これは 8 つの 16 バイト レジスタとして見ることができます。
code:図14 ブレイクラウンド関数P
P(A_0, A_1, ... ,A_7) = (B_0, B_1, ... ,B_7)
圧縮関数 G(X, Y) は、2つの1024バイトブロック X と Y に対して作用します。まず、R = X XOR Y を計算します。次に、R は16バイトレジスタ R_0、R_1、…、R_63 からなる8x8行列とみなされます。次に、P を各行に適用し、次に各列に適用して Z を取得します。
code:図15: 圧縮関数Gのコア
( Q_0, Q_1, Q_2, ... , Q_7) <- P( R_0, R_1, R_2, ... , R_7)
( Q_8, Q_9, Q_10, ... , Q_15) <- P( R_8, R_9, R_10, ... , R_15)
...
(Q_56, Q_57, Q_58, ... , Q_63) <- P(R_56, R_57, R_58, ... , R_63)
( Z_0, Z_8, Z_16, ... , Z_56) <- P( Q_0, Q_8, Q_16, ... , Q_56)
( Z_1, Z_9, Z_17, ... , Z_57) <- P( Q_1, Q_9, Q_17, ... , Q_57)
...
( Z_7, Z_15, Z 23, ... , Z_63) <- P( Q_7, Q_15, Q_23, ... , Q_63)
最後に、G は Z XOR R を出力します。
code:図16: Argon2圧縮関数G
G: (X, Y) -> R -> Q -> Z -> Z XOR R
+---+ +---+
| X | | Y |
+---+ +---+
| |
---->XOR<----
--------|
| \ /
| +---+
| | R |
| +---+
| |
| \ /
| P rowwise
| |
| \ /
| +---+
| | Q |
| +---+
| |
| \ /
| P columnwise
| |
| \ /
| +---+
| | Z |
| +---+
| |
| \ /
------>XOR
|
\ /
3.6. 順列P
順列PはBLAKE2bのラウンド関数に基づいています。8つの16バイト入力S_0、S_1、…、S_7は、64ビットワードの4x4行列として扱われます。ここで、S_i = (v_{2*i+1} || v_{2*i}) です。
code:図17:行列要素のラベル付け
v_0 v_1 v_2 v_3
v_4 v_5 v_6 v_7
v_8 v_9 v_10 v_11
v_12 v_13 v_14 v_15
動作は次のようになります。
code:図18: 行列要素をGBに入力する
GB(v_0, v_4, v_8, v_12)
GB(v_1, v_5, v_9, v_13)
GB(v_2, v_6, v_10, v_14)
GB(v_3, v_7, v_11, v_15)
GB(v_0, v_5, v_10, v_15)
GB(v_1, v_6, v_11, v_12)
GB(v_2, v_7, v_8, v_13)
GB(v_3, v_4, v_9, v_14)
GB(a, b, c, d)は次のように定義されます。
code:図19: GBの詳細
a = (a + b + 2 * trunc(a) * trunc(b)) mod 2^(64)
d = (d XOR a) >>> 32
c = (c + d + 2 * trunc(c) * trunc(d)) mod 2^(64)
b = (b XOR c) >>> 24
a = (a + b + 2 * trunc(a) * trunc(b)) mod 2^(64)
d = (d XOR a) >>> 16
c = (c + d + 2 * trunc(c) * trunc(d)) mod 2^(64)
b = (b XOR c) >>> 63
GBにおけるモジュラー加算は、64ビット乗算と組み合わせられています。乗算は、オリジナルのBLAKE2b設計との唯一の違いです。この選択は、回路の深さを増やし、ASIC実装の実行時間を短縮する一方で、並列処理とパイプライン化によりCPUとほぼ同等の実行時間を実現するためです。
4. パラメータの選択
Argon2dは、攻撃者がシステムメモリやCPUに定期的にアクセスできない環境向けに最適化されています。つまり、タイミング情報に基づくサイドチャネル攻撃を実行できず、ガベージコレクションを用いてパスワードを高速に復元することもできません。これらの設定は、バックエンドサーバーや暗号通貨マイニングにおいてより一般的です。実践的な例として、以下の設定をお勧めします。
暗号通貨マイニング:2GHz CPU、1コアで0.1秒(Argon2d、2レーン、250MB RAM)
Argon2idは、攻撃者が同じマシンにアクセスしたり、CPUを利用したり、コールドブート攻撃を仕掛けたりする可能性のある、より現実的な環境向けに最適化されています。以下の設定をお勧めします。
バックエンドサーバーの認証:2GHz CPU、4コアで0.5秒(Argon2id、8レーン、4GiB RAM)
ハードドライブ暗号化のための鍵導出。2GHz CPU、2コア、4レーン、6GiB RAMのArgon2idで3秒かかります。
フロントエンドサーバーの認証。2GHz CPU、2コア、4レーン、1GiB RAMのArgon2idで0.5秒かかります。
Argon2を実際に使用する場合、タイプとパラメータを選択するには、以下の手順をお勧めします。
1. アプリケーションやハードウェアに合わせてカスタマイズされていない、均一に安全なオプションが許容される場合は、t=1 反復、p=4 レーン、m=2^(21) (RAM 2GiB)、128 ビットソルト、256 ビットタグサイズの Argon2id を選択します。これが第一推奨オプションです。
2. 使用可能なメモリがはるかに少ない場合、均一に安全なオプションは、t=3 反復、p=4 レーン、m=2^(16) (RAM 64MiB)、128 ビットソルト、256 ビットタグサイズの Argon2id です。これが第二推奨オプションです。
3. それ以外の場合は、まずタイプ y を選択します。タイプの違いがわからない場合、またはサイドチャネル攻撃が現実的な脅威であると考えられる場合は、Argon2id を選択します。
4. p=4 レーンを選択します。
5. 各呼び出しが許容できる最大メモリ量を計算し、それをパラメータ m に変換します。
6. 各呼び出しが許容できる最大時間(秒単位)を計算します。
7. ソルト長を選択します。128 ビット長はすべてのアプリケーションで十分ですが、メモリ容量の制約がある場合は 64 ビットに短縮できます。
8. タグ長を選択します。128 ビット長は、鍵導出を含むほとんどのアプリケーションで十分です。より長い鍵が必要な場合は、より長いタグを選択します。
9. サイドチャネル攻撃が現実的な脅威である場合、または不確かな場合は、ライブラリ呼び出しでメモリワイピングオプショ ンを有効にします。
10. タイプ y、メモリ m、プレーンのスキームを、異なるパス数 t を使用して実行します。実行時間が許容時間を超えないような最大 t を計算します。t = 1 の場合でも許容時間を超える場合は、m をそれに応じて減らします。
11. m、p、t の値を決定して Argon2 を使用します。
5. テストベクトル
このセクションでは、Argon2 のテストベクトルについて説明します。
5.1. Argon2d テストベクトル
完全な出力(タグ)を持つテストベクターを提供します。開発者の利便性を考慮し、中間変数(具体的には各パスの最初と最後のメモリブロック)もいくつか提供します。
code:Argon2d バージョン番号 19
=======================================
Argon2d バージョン番号 19
=======================================
Memory: 32 KiB
Passes: 3
Parallelism: 4 lanes
Tag length: 32 bytes
Password32: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01
Salt16: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 Secret8: 03 03 03 03 03 03 03 03 Associated data12: 04 04 04 04 04 04 04 04 04 04 04 04 Pre-hashing digest: b8 81 97 91 a0 35 96 60
bb 77 09 c8 5f a4 8f 04
d5 d8 2c 05 c5 f2 15 cc
db 88 54 91 71 7c f7 57
08 2c 28 b9 51 be 38 14
10 b5 fc 2e b7 27 40 33
b9 fd c7 ae 67 2b ca ac
5d 17 90 97 a4 af 31 09
After pass 0:
Block 0000 0: db2fea6b2c6f5c8a Block 0000 1: 719413be00f82634 Block 0000 2: a1e3f6dd42aa25cc Block 0000 3: 3ea8efd4d55ac0d1 ...
Block 0031 124: 28d17914aea9734c Block 0031 125: 6a4622176522e398 Block 0031 126: 951aa08aeecb2c05 Block 0031 127: 6a6c49d2cb75d5b6 After pass 1:
Block 0000 0: d3801200410f8c0d Block 0000 1: 0bf9e8a6e442ba6d Block 0000 2: e2ca92fe9c541fcc Block 0000 3: 6269fe6db177a388 ...
Block 0031 124: 9eacfcfbdb3ce0fc Block 0031 125: 07dedaeb0aee71ac Block 0031 126: 074435fad91548f4 Block 0031 127: 2dbfff23f31b5883 After pass 2:
Block 0000 0: 5f047b575c5ff4d2 Block 0000 1: f06985dbf11c91a8 Block 0000 2: 89efb2759f9a8964 Block 0000 3: 7486a73f62f9b142 ...
Block 0031 124: 57cfb9d20479da49 Block 0031 125: 4099654bc6607f69 Block 0031 126: f142a1126075a5c8 Block 0031 127: c341b3ca45c10da5 Tag: 51 2b 39 1b 6f 11 62 97
53 71 d3 09 19 73 42 94
f8 68 e3 be 39 84 f3 c1
a1 3a 4d b9 fa be 4a cb
5.2. Argon2i テストベクトル
code:Argon2i バージョン番号 19
=======================================
Argon2i バージョン番号 19
=======================================
Memory: 32 KiB
Passes: 3
Parallelism: 4 lanes
Tag length: 32 bytes
Password32: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01
Salt16: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 Secret8: 03 03 03 03 03 03 03 03 Associated data12: 04 04 04 04 04 04 04 04 04 04 04 04 Pre-hashing digest: c4 60 65 81 52 76 a0 b3
e7 31 73 1c 90 2f 1f d8
0c f7 76 90 7f bb 7b 6a
5c a7 2e 7b 56 01 1f ee
ca 44 6c 86 dd 75 b9 46
9a 5e 68 79 de c4 b7 2d
08 63 fb 93 9b 98 2e 5f
39 7c c7 d1 64 fd da a9
After pass 0:
Block 0000 0: f8f9e84545db08f6 Block 0000 1: 9b073a5c87aa2d97 Block 0000 2: d1e868d75ca8d8e4 Block 0000 3: 349634174e1aebcc ...
Block 0031 124: 975f596583745e30 Block 0031 125: e349bdd7edeb3092 Block 0031 126: b751a689b7a83659 Block 0031 127: c570f2ab2a86cf00 After pass 1:
Block 0000 0: b2e4ddfcf76dc85a Block 0000 1: 4ffd0626c89a2327 Block 0000 2: 4af1440fff212980 Block 0000 3: 1e77299c7408505b ...
Block 0031 124: e4274fd675d1e1d6 Block 0031 125: 903fffb7c4a14c98 Block 0031 126: 7e5db55def471966 Block 0031 127: 421b3c6e9555b79d After pass 2:
Block 0000 0: af2a8bd8482c2f11 Block 0000 1: 785442294fa55e6d Block 0000 2: 9256a768529a7f96 Block 0000 3: 25a1c1f5bb953766 ...
Block 0031 124: 68cf72fccc7112b9 Block 0031 125: 91e8c6f8bb0ad70d Block 0031 126: 4f59c8bd65cbb765 Block 0031 127: 71e436f035f30ed0 Tag: c8 14 d9 d1 dc 7f 37 aa
13 f0 d7 7f 24 94 bd a1
c8 de 6b 01 6d d3 88 d2
99 52 a4 c4 67 2b 6c e8
5.3. Argon2idテストベクトル
code:Argon2id バージョン番号 19
=======================================
Argon2id version number 19
=======================================
Memory: 32 KiB, Passes: 3,
Parallelism: 4 lanes, Tag length: 32 bytes
Password32: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
Salt16: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 Secret8: 03 03 03 03 03 03 03 03 Associated data12: 04 04 04 04 04 04 04 04 04 04 04 04 Pre-hashing digest: 28 89 de 48 7e b4 2a e5 00 c0 00 7e d9 25 2f
10 69 ea de c4 0d 57 65 b4 85 de 6d c2 43 7a 67 b8 54 6a 2f 0a
cc 1a 08 82 db 8f cf 74 71 4b 47 2e 94 df 42 1a 5d a1 11 2f fa
11 43 43 70 a1 e9 97
After pass 0:
Block 0000 0: 6b2e09f10671bd43 Block 0000 1: f69f5c27918a21be Block 0000 2: dea7810ea41290e1 Block 0000 3: 6787f7171870f893 ...
Block 0031 124: 377fa81666dc7f2b Block 0031 125: 50e586398a9c39c8 Block 0031 126: 6f732732a550924a Block 0031 127: 81f88b28683ea8e5 After pass 1:
Block 0000 0: 3653ec9d01583df9 Block 0000 1: 69ef53a72d1e1fd3 Block 0000 2: 35635631744ab54f Block 0000 3: 599512e96a37ab6e ...
Block 0031 124: 4d4b435cea35caa6 Block 0031 125: c582210d99ad1359 Block 0031 126: d087971b36fd6d77 Block 0031 127: a55222a93754c692 After pass 2:
Block 0000 0: 942363968ce597a4 Block 0000 1: a22448c0bdad5760 Block 0000 2: a5f80662b6fa8748 Block 0000 3: a0f9b9ce392f719f ...
Block 0031 124: d723359b485f509b Block 0031 125: cb78824f42375111 Block 0031 126: 35bc8cc6e83b1875 Block 0031 127: 0b012846a40f346a Tag: 0d 64 0d f5 8d 78 76 6c 08 c0 37 a3 4a 8b 53 c9 d0
1e f0 45 2d 75 b6 5e b5 25 20 e9 6b 01 e6 59
6. IANAに関する考慮事項
この文書はIANAの承認を受けていません。
7. セキュリティに関する考慮事項
7.1. ハッシュ関数およびKDFとしてのセキュリティ
Argon2の衝突耐性および原像耐性レベルは、基礎となるBLAKE2bハッシュ関数のそれと同等です。衝突を発生させるには2^(256)回の入力が必要です。原像を見つけるには2^(512)回の入力を試行する必要があります。
KDFのセキュリティは、鍵長とハッシュ関数H'の内部状態のサイズによって決まります。鍵付きArgon2の出力をランダムな値と区別するには、BLAKE2bを少なくとも(2^(128),2^length(K))回呼び出す必要があります。
7.2. 時間空間トレードオフ攻撃に対するセキュリティ
時間空間トレードオフは、メモリ容量の少ないメモリブロックを格納することで、内部圧縮関数の呼び出し回数を増やすメモリ難関数の計算を可能にします。トレードオフ攻撃の利点は、時間と面積の積に対する削減係数で測定されます。メモリと追加の圧縮関数コアが面積に寄与し、欠落したブロックの再計算に対応するために処理時間が長くなります。削減係数が高いと、原像探索が高速化される可能性があります。
1パスおよび2パスのArgon2iに対する最もよく知られた攻撃は、CBS16で説明されている低ストレージ攻撃であり、これは(ピークメモリ値を使用して)時間面積積を5分の1に削減します。3パス以上のArgon2iに対する最良の攻撃はAB16で説明されており、削減係数はメモリサイズとパス数の関数です(例えば、1ギガバイトのメモリの場合、3パスで削減係数は3、4パスで2.5、6パスで2)。削減係数は、メモリサイズが2倍になるごとに約0.5ずつ増加します。 AB16 による時間と空間のトレードオフを完全に防ぐには、パス数はメモリの2進対数から26を引いた値を超えなければならない。漸近的に、1パスArgon2iに対する最善の攻撃はBZ17で示されており、攻撃者の最大優位性の上限はO(m^(0.233))である。ここで、mはブロック数である。BZ17では、あらゆる攻撃の上限がO(m^(0.25))であることも証明されているため、この攻撃も漸近的に最適である。 tパスArgon2dに対する最善のトレードオフ攻撃はランキングトレードオフ攻撃であり、これは時間と面積の積を1.33分の1に削減する。
Argon2idに対する最善の攻撃は、1パスArgon2iに対する最善の攻撃とマルチパスArgon2dに対する最善の攻撃を補完することで得られる。したがって、1パスArgon2idに対する最良のトレードオフ攻撃は、メモリ前半に対するローストレージ攻撃と後半に対するランキング攻撃を組み合わせたものであり、これにより約2.1倍の係数が生成される。tパスArgon2idに対する最良のトレードオフ攻撃はランキングトレードオフ攻撃であり、時間面積積は1.33倍に減少する。
7.3. 時間制限のある防御者に対するセキュリティ
パスワードハッシュ関数を用いるシステムにおけるボトルネックは、メモリコストではなく関数のレイテンシであることが多い。合理的な防御者は、ハッシュ、ソルト、およびタイミング情報のリストを持つ攻撃者のブルートフォース攻撃コストを、防御者のマシン上で一定の計算時間で最大化する。AB16による攻撃コストの推定によると、Argon2iの場合、ほとんどの合理的なメモリサイズでは3パスがほぼ最適である。一方、Argon2dとArgon2idの場合、防御者の計算時間が一定であれば、1パスで攻撃コストが最大化される。 7.4. 推奨事項
t=1、メモリ容量2GiBのArgon2idバリアントは、第一推奨オプションであり、すべての環境のデフォルト設定として提案されています。この設定はサイドチャネル攻撃に対して安全であり、専用のブルートフォースハードウェアにおける攻撃コストを最大化します。t=3、メモリ容量64MiBのArgon2idバリアントは、第二推奨オプションであり、メモリ制約のある環境のデフォルト設定として提案されています。
8. 参考文献
8.1. 規範的な参考文献
BLAKE2 Saarinen, M-J. 編、J-P. Aumasson, "BLAKE2 暗号ハッシュおよびメッセージ認証コード (MAC)", RFC 7693, DOI 10.17487/RFC7693, 2015年11月, RFC 2119 Bradner, S., "RFC で要件レベルを示すためのキーワード", BCP 14, RFC 2119, DOI 10.17487/RFC2119, 1997年3月, 8.2. 参考文献
AB15 Biryukov, A. and D. Khovratovich, "Tradeoff Cryptanalysis of Memory-Hard Functions", ASIACRYPT 2015, DOI 10.1007/978-3-662-48800-3_26, 2015年12月, AB16 Alwen, J.、J. Blocki、「データ非依存のメモリハード関数の効率的な計算」、CRYPTO 2016、DOI 10.1007/978-3-662-53008-5_9、2016年3月、 ARGON2 Biryukov, A.、Dinu, D.、D. Khovratovich、「Argon2:パスワードハッシュやその他のアプリケーションのためのメモリハード関数」、2017年3月、 Biryukov, A.、Dinu, D.、D. Khovratovich、「Argon2:パスワードハッシュおよびその他のアプリケーションのためのメモリハードな新世代関数」、Euro SnP 2016、DOI 10.1109/EuroSP.2016.31、2016年3月、
BZ17 Blocki, J.、S. Zhou、「Argon2iの深度ロバスト性と累積ペブリングコストについて」、TCC 2017、DOI 10.1007/978-3-319-70500-2_15、2017年5月、 CBS16 Boneh, D., Corrigan-Gibbs, H., S. Schechter, 「バルーンハッシング:逐次攻撃に対する証明可能な防御を提供するメモリ困難な関数」, ASIACRYPT 2016, DOI 10.1007/978-3-662-53887-6_8, 2017年5月, HARD Alwen, J., V. Serbinenko, 「高並列計算量グラフとメモリ困難な関数」, STOC '15, DOI 10.1145/2746539.2746622, 2015年6月, 謝辞
この文書の作成とレビューにご協力いただいた以下の方々に深く感謝いたします。Jean-Philippe Aumasson、Samuel Neves、Joel Alwen、Jeremiah Blocki、Bill Cox、Arnold Reinhold、Solar Designer、Russ Housley、Stanislav Smyshlyaev、Kenny Paterson、Alexey Melnikov、Gwynne Raskind。
この文書に記載されている作業は、Daniel DinuがIntelに入社する前、ルクセンブルク大学在学中に行われました。
著者のアドレス
Alex Biryukov
ルクセンブルク大学
メールアドレス: alex.biryukov@uni.lu
Daniel Dinu
ルクセンブルク大学
メールアドレス: daniel.dinu@intel.com
Dmitry Khovratovich
ABDKコンサルティング
メールアドレス: khovratovich@gmail.com
Simon Josefsson
SJD AB
メールアドレス: simon@josefsson.org