1--TEST--
2Test interoperability of password_verify()
3--SKIPIF--
4<?php
5if (!function_exists('sodium_crypto_pwhash_str')) {
6  echo "skip - No crypto_pwhash_str_verify";
7}
8
9// Depending on library version, libsodium may provide argon2i or argon2id hashes.
10$hash = sodium_crypto_pwhash_str("test", SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE);
11list(, $algo) = explode('$', $hash, 3);
12
13if (!in_array($algo, password_algos(), true /* strict */)) {
14 echo "skip - No $algo support in password_verify()";
15}
16--FILE--
17<?php
18
19$opsSet = [
20  SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
21  SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE,
22  SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE,
23];
24$memSet = [
25  SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE,
26  SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE,
27  SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE,
28];
29
30echo 'Argon2 provider: ';
31var_dump(PASSWORD_ARGON2_PROVIDER);
32
33foreach($opsSet as $ops) {
34  foreach($memSet as $mem) {
35    $password = random_bytes(32);
36    echo "Using password: ";
37    var_dump(base64_encode($password));
38    $hash = sodium_crypto_pwhash_str($password, $ops, $mem);
39    echo "Hash: "; var_dump($hash);
40    var_dump(password_verify($password, $hash));
41
42    // And verify that incorrect passwords fail.
43    $password[0] = chr(ord($password[0]) ^ 1);
44    var_dump(password_verify($password, $hash));
45  }
46}
47--EXPECTF--
48Argon2 provider: string(%d) "%s"
49Using password: string(44) "%s"
50Hash: string(97) "$argon2id$v=19$m=65536,t=2,p=1$%s$%s"
51bool(true)
52bool(false)
53Using password: string(44) "%s"
54Hash: string(98) "$argon2id$v=19$m=262144,t=2,p=1$%s$%s"
55bool(true)
56bool(false)
57Using password: string(44) "%s"
58Hash: string(99) "$argon2id$v=19$m=1048576,t=2,p=1$%s$%s"
59bool(true)
60bool(false)
61Using password: string(44) "%s"
62Hash: string(97) "$argon2id$v=19$m=65536,t=3,p=1$%s$%s"
63bool(true)
64bool(false)
65Using password: string(44) "%s"
66Hash: string(98) "$argon2id$v=19$m=262144,t=3,p=1$%s$%s"
67bool(true)
68bool(false)
69Using password: string(44) "%s"
70Hash: string(99) "$argon2id$v=19$m=1048576,t=3,p=1$%s$%s"
71bool(true)
72bool(false)
73Using password: string(44) "%s"
74Hash: string(97) "$argon2id$v=19$m=65536,t=4,p=1$%s$%s"
75bool(true)
76bool(false)
77Using password: string(44) "%s"
78Hash: string(98) "$argon2id$v=19$m=262144,t=4,p=1$%s$%s"
79bool(true)
80bool(false)
81Using password: string(44) "%s"
82Hash: string(99) "$argon2id$v=19$m=1048576,t=4,p=1$%s$%s"
83bool(true)
84bool(false)
85