64 hex) $saltBin = random_bytes(32); // h1 = SHA1(U:P) $h1 = sha1($U . ':' . $P, true); // h2 = SHA1(salt || h1) $h2 = sha1($saltBin . $h1, true); // x = int( h2 ) (interprété comme un entier non signé big-endian) // -> on passe par l'hex pour éviter les soucis d'endianness $x = gmp_init(bin2hex($h2), 16); $N = gmp_init(self::N_HEX, 16); $g = gmp_init(self::G_HEX, 16); // v = g^x mod N $v = gmp_powm($g, $x, $N); // Longueur hex attendue = longueur de N en hex (ici 64 chars) $nLen = strlen(self::N_HEX); // Hex MAJUSCULE + padding $vHex = strtoupper(str_pad(gmp_strval($v, 16), $nLen, '0', STR_PAD_LEFT)); $sHex = strtoupper(str_pad(bin2hex($saltBin), 64, '0', STR_PAD_LEFT)); // 32 bytes => 64 hex return ['v' => $vHex, 's' => $sHex]; } }