1--TEST-- 2Test interoperability of password_verify() 3--EXTENSIONS-- 4sodium 5--SKIPIF-- 6<?php 7if (!function_exists('sodium_crypto_pwhash_str')) { 8 echo "skip - No crypto_pwhash_str_verify"; 9} 10 11// Depending on library version, libsodium may provide argon2i or argon2id hashes. 12$hash = sodium_crypto_pwhash_str("test", SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE); 13list(, $algo) = explode('$', $hash, 3); 14 15if (!in_array($algo, password_algos(), true /* strict */)) { 16 echo "skip - No $algo support in password_verify()"; 17} 18--FILE-- 19<?php 20 21$opsSet = [ 22 SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, 23 SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE, 24]; 25$memSet = [ 26 SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE, 27 SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE, 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?> 48--EXPECTF-- 49Argon2 provider: string(%d) "%s" 50Using password: string(44) "%s" 51Hash: string(97) "$argon2id$v=19$m=65536,t=2,p=1$%s$%s" 52bool(true) 53bool(false) 54Using password: string(44) "%s" 55Hash: string(98) "$argon2id$v=19$m=262144,t=2,p=1$%s$%s" 56bool(true) 57bool(false) 58Using password: string(44) "%s" 59Hash: string(97) "$argon2id$v=19$m=65536,t=3,p=1$%s$%s" 60bool(true) 61bool(false) 62Using password: string(44) "%s" 63Hash: string(98) "$argon2id$v=19$m=262144,t=3,p=1$%s$%s" 64bool(true) 65bool(false) 66