アルゴリズムを指定しなくてもpassword_verify()で認証できる理由

## TL; DR
`password_hash()`で生成されるハッシュ値にハッシュ化に用いたアルゴリズムおよびソルトなどの情報が含まれているため。

## 各情報が含まれている場所
実際に`password_hash()`の返り値のどこに各情報が含まれているかを見ていきます。
### ハッシュ化アルゴリズム
PHP7.3時点では、ハッシュ化のアルゴリズムとして`PASSWORD_BCRYPT`と`PASSWORD_ARGON2I`の2種類を使用することができます。
`PASSWORD_ARGON2I`はPHP7.2で追加されました。

```
# PASSWORD_BCRYPT
echo password_hash( 'password', PASSWORD_BCRYPT );
$2y$10$Fn1sh4A7w0G7XYEVu7TDf.lDAJGLwKRwvZBel3FJ9f0cMjLCOgDs6

# PASSWORD_ARGON2I
echo password_hash( 'password', PASSWORD_ARGON2I );
$argon2i$v=19$m=1024,t=2,p=2$YWJHdzJUL001Nlp2NEw0Nw$mCjdG6lbo0ccc77QRBzlhEhHJJVIVLBILoWh/5zmQSs

# PASSWORD_DEFAULT
echo password_hash( 'password', PASSWORD_DEFAULT );
$2y$10$TCtG3d5te5yhSMAgJwLAou7xrleJEdj.QV8a3uoRltOUknmzUmWYe
```

`$2y`から始まるのが`PASSWORD_BCRYPT`で`$argon2i`から始まるのが`PASSWORD_BCRYPT`になります。
サポートするオプションが違うので他にも明らかに違いますが。

また、`PASSWORD_DEFAULT`の返り値を見てください。
`$2y`で始まるので`PASSWORD_DEFAULT`は`PASSWORD_BCRYPT`と同一のアルゴリズムであることが分かります。

ソース上は、[ext/standard/php_password.h](https://github.com/php/php-src/blob/eb4624fa2ecff866a4ae03c28d6e06ef347940f4/ext/standard/php_password.h)で定義されています。

### PASSWORD_BCRYPTのオプション
#### コスト（cost）
利用するアルゴリズムのコストを指定することができます。
指定されたコストにより計算された回数だけストレッチング処理が行われます。

コストの詳細について気になる方は、以下の記事をご参照ください。
https://qiita.com/hayashi-ay/items/361f67f18b023e674d15

```
# コストを未指定
echo password_hash( 'password', PASSWORD_BCRYPT );
$2y$10$Fn1sh4A7w0G7XYEVu7TDf.lDAJGLwKRwvZBel3FJ9f0cMjLCOgDs6

# コストを指定
$options = array();
$options['cost'] = 14;
echo password_hash( 'password', PASSWORD_BCRYPT, $options );
$2y$14$HpW15mXL7M0Iwrzg4XCnuOWU/7NGxqZjnrlPMcUJEIhRs8IfDrLBW
```
`$2y`以下の数字がコストを表します。
未指定の場合`$10`、つまり10がコストのデフォルト値となることが分かります。

#### ソルト（salt）
パスワードのハッシュに使うソルトを手動で設定することができます。
ソルトの長さは22文字であり、それより長いものを指定すると22文字に切り詰められます。

※PHP7.0.0以降ではソルト・オプションは非推奨になりました。

```
# ソルトを未指定
echo password_hash( 'password', PASSWORD_BCRYPT );
$2y$10$Fn1sh4A7w0G7XYEVu7TDf.lDAJGLwKRwvZBel3FJ9f0cMjLCOgDs6

# ソルトを指定
$options = array();
$options['salt'] = 'xxxxxxxxxxxxxxxxxxxxxx'
echo password_hash( 'password', PASSWORD_BCRYPT, $options );
$2y$10$xxxxxxxxxxxxxxxxxxxxxuOd9YtxiLKHM/l98x//sqUV1V2XTZEZ.
```
コスト`$10`の後に続く`$`以下がソルトになります。
未指定の場合はランダムに生成された値になります。

### PASSWORD_ARGON2Iのオプション
#### メモリの最大値（memory_cost）
```
# メモリの最大値を未指定
echo password_hash( 'password', PASSWORD_ARGON2I );
$argon2i$v=19$m=1024,t=2,p=2$YWJHdzJUL001Nlp2NEw0Nw$mCjdG6lbo0ccc77QRBzlhEhHJJVIVLBILoWh/5zmQSs

# メモリの最大値を指定
$options = array();
$options['memory_cost'] = 10000;
echo password_hash( 'password', PASSWORD_ARGON2I, $options );
$argon2i$v=19$m=10000,t=2,p=2$L2VJSkxNSHJIV094ek05SQ$s3yRsqTM33df55rS2GHIykFAcVRm1UuNHfpdsS0cNwo
```

`$m=`以下がメモリの最大値になります。

#### 時間の最大値（time_cost）
```
# 時間の最大値を未指定
echo password_hash( 'password', PASSWORD_ARGON2I );
$argon2i$v=19$m=1024,t=2,p=2$YWJHdzJUL001Nlp2NEw0Nw$mCjdG6lbo0ccc77QRBzlhEhHJJVIVLBILoWh/5zmQSs

# 時間の最大値を指定
$options = array();
$options['time_cost'] = 4;
echo password_hash( 'password', PASSWORD_ARGON2I, $options );
$argon2i$v=19$m=1024,t=4,p=2$c0FHME9vekJhNmxuR2ZTLw$OcuEesY2gnKNHgMVd7hUPMBYCbqYIAHEGT0dJ5TKtu4
```

`$t=`以下が時間の最大値になります。

#### スレッド数（threads）
```
# スレッド数を未指定
echo password_hash( 'password', PASSWORD_ARGON2I );
$argon2i$v=19$m=1024,t=2,p=2$YWJHdzJUL001Nlp2NEw0Nw$mCjdG6lbo0ccc77QRBzlhEhHJJVIVLBILoWh/5zmQSs

# スレッド数を指定
$options = array();
$options['threads'] = 4;
echo password_hash( 'password', PASSWORD_ARGON2I, $options );
$argon2i$v=19$m=1024,t=2,p=4$R2ZxekRVTnBsSks2NXllTQ$nBeQdObmceth+zcZkaqHzNhIFseAW0stEiNk430wHng
```

`$p=`以下がスレッド数になります。