function _openid_dh_rand($stop) { static $duplicate_cache = array(); // Used as the key for the duplicate cache $rbytes = _openid_dh_long_to_binary($stop); if (array_key_exists($rbytes, $duplicate_cache)) { list($duplicate, $nbytes) = $duplicate_cache[$rbytes]; } else { if ($rbytes[0] == "") { $nbytes = strlen($rbytes) - 1; } else { $nbytes = strlen($rbytes); } $mxrand = bcpow(256, $nbytes); // If we get a number less than this, then it is in the // duplicated range. $duplicate = bcmod($mxrand, $stop); if (count($duplicate_cache) > 10) { $duplicate_cache = array(); } $duplicate_cache[$rbytes] = array($duplicate, $nbytes); } do { $bytes = "" . _openid_get_bytes($nbytes); $n = _openid_dh_binary_to_long($bytes); // Keep looping if this value is in the low duplicated range. } while (bccomp($n, $duplicate) < 0); return bcmod($n, $stop); }
/** * Is copy of _opend_dh_xorsecret() but uses PHP5 hash() function. Should be merged back into openid client * for D7. * * @param long $shared * @param string $secret * @param string $algo * @return binary string */ function _openid_provider_dh_xorsecret($shared, $secret, $algo = 'sha1') { $dh_shared_str = _openid_dh_long_to_binary($shared); $sha1_dh_shared = hash($algo, $dh_shared_str, true); $xsecret = ""; for ($i = 0; $i < strlen($secret); $i++) { $xsecret .= chr(ord($secret[$i]) ^ ord($sha1_dh_shared[$i])); } return $xsecret; }