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