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]; 23$memSet = [ 24 SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE, 25 SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE, 26]; 27 28echo 'Argon2 provider: '; 29var_dump(PASSWORD_ARGON2_PROVIDER); 30 31foreach($opsSet as $ops) { 32 foreach($memSet as $mem) { 33 $password = random_bytes(32); 34 echo "Using password: "; 35 var_dump(base64_encode($password)); 36 $hash = sodium_crypto_pwhash_str($password, $ops, $mem); 37 echo "Hash: "; var_dump($hash); 38 var_dump(password_verify($password, $hash)); 39 40 // And verify that incorrect passwords fail. 41 $password[0] = chr(ord($password[0]) ^ 1); 42 var_dump(password_verify($password, $hash)); 43 } 44} 45?> 46--EXPECTF-- 47Argon2 provider: string(%d) "%s" 48Using password: string(44) "%s" 49Hash: string(97) "$argon2id$v=19$m=65536,t=2,p=1$%s$%s" 50bool(true) 51bool(false) 52Using password: string(44) "%s" 53Hash: string(98) "$argon2id$v=19$m=262144,t=2,p=1$%s$%s" 54bool(true) 55bool(false) 56Using password: string(44) "%s" 57Hash: string(97) "$argon2id$v=19$m=65536,t=3,p=1$%s$%s" 58bool(true) 59bool(false) 60Using password: string(44) "%s" 61Hash: string(98) "$argon2id$v=19$m=262144,t=3,p=1$%s$%s" 62bool(true) 63bool(false) 64