Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenID performance tweak - allows the use of GMP library #68

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 120 additions & 11 deletions modules/openid/openid.inc
Original file line number Diff line number Diff line change
Expand Up @@ -283,15 +283,15 @@ function _openid_dh_binary_to_long($str) {

$n = 0;
foreach ($bytes as $byte) {
$n = bcmul($n, pow(2, 8));
$n = bcadd($n, $byte);
$n = _openid_math_mul($n, pow(2, 8));
$n = _openid_math_add($n, $byte);
}

return $n;
}

function _openid_dh_long_to_binary($long) {
$cmp = bccomp($long, 0);
$cmp = _openid_math_cmp($long, 0);
if ($cmp < 0) {
return FALSE;
}
Expand All @@ -302,9 +302,9 @@ function _openid_dh_long_to_binary($long) {

$bytes = array();

while (bccomp($long, 0) > 0) {
array_unshift($bytes, bcmod($long, 256));
$long = bcdiv($long, pow(2, 8));
while (_openid_math_cmp($long, 0) > 0) {
array_unshift($bytes, _openid_math_mod($long, 256));
$long = _openid_math_div($long, pow(2, 8));
}

if ($bytes && ($bytes[0] > 127)) {
Expand Down Expand Up @@ -347,11 +347,11 @@ function _openid_dh_rand($stop) {
$nbytes = strlen($rbytes);
}

$mxrand = bcpow(256, $nbytes);
$mxrand = _openid_math_pow(256, $nbytes);

// If we get a number less than this, then it is in the
// duplicated range.
$duplicate = bcmod($mxrand, $stop);
$duplicate = _openid_math_mod($mxrand, $stop);

if (count($duplicate_cache) > 10) {
$duplicate_cache = array();
Expand All @@ -364,9 +364,9 @@ function _openid_dh_rand($stop) {
$bytes = "\x00". _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);
} while (_openid_math_cmp($n, $duplicate) < 0);

return bcmod($n, $stop);
return _openid_math_mod($n, $stop);
}

function _openid_get_bytes($num_bytes) {
Expand All @@ -391,7 +391,7 @@ function _openid_get_bytes($num_bytes) {

function _openid_response($str = NULL) {
$data = array();

if (isset($_SERVER['REQUEST_METHOD'])) {
$data = _openid_get_params($_SERVER['QUERY_STRING']);

Expand Down Expand Up @@ -442,3 +442,112 @@ if (!function_exists('bcpowmod')) {
return $result;
}
}

/**
* Determine the available math library GMP vs. BCMath, favouring GMP for performance.
*/
function _openid_get_math_library() {
$library = &drupal_static(__FUNCTION__);

if (empty($library)) {
if (function_exists('gmp_add')) {
$library = 'gmp';
}
elseif (function_exists('bcadd')) {
$library = 'bcmath';
}
}

return $library;
}

/**
* Calls the add function from the available math library for OpenID.
*/
function _openid_math_add($x, $y) {
$library = _openid_get_math_library();
switch ($library) {
case 'gmp':
return gmp_strval(gmp_add($x, $y));
case 'bcmath':
return bcadd($x, $y);
}
}

/**
* Calls the mul function from the available math library for OpenID.
*/
function _openid_math_mul($x, $y) {
$library = _openid_get_math_library();
switch ($library) {
case 'gmp':
return gmp_mul($x, $y);
case 'bcmath':
return bcmul($x, $y);
}
}

/**
* Calls the div function from the available math library for OpenID.
*/
function _openid_math_div($x, $y) {
$library = _openid_get_math_library();
switch ($library) {
case 'gmp':
return gmp_div($x, $y);
case 'bcmath':
return bcdiv($x, $y);
}
}

/**
* Calls the cmp function from the available math library for OpenID.
*/
function _openid_math_cmp($x, $y) {
$library = _openid_get_math_library();
switch ($library) {
case 'gmp':
return gmp_cmp($x, $y);
case 'bcmath':
return bccomp($x, $y);
}
}

/**
* Calls the mod function from the available math library for OpenID.
*/
function _openid_math_mod($x, $y) {
$library = _openid_get_math_library();
switch ($library) {
case 'gmp':
return gmp_mod($x, $y);
case 'bcmath':
return bcmod($x, $y);
}
}

/**
* Calls the pow function from the available math library for OpenID.
*/
function _openid_math_pow($x, $y) {
$library = _openid_get_math_library();
switch ($library) {
case 'gmp':
return gmp_pow($x, $y);
case 'bcmath':
return bcpow($x, $y);
}
}

/**
* Calls the mul function from the available math library for OpenID.
*/
function _openid_math_powmod($x, $y, $z) {
$library = _openid_get_math_library();
switch ($library) {
case 'gmp':
return gmp_powm($x, $y, $z);
case 'bcmath':
return bcpowmod($x, $y, $z);
}
}
34 changes: 34 additions & 0 deletions modules/openid/openid.install
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,40 @@ function openid_schema() {
return $schema;
}

/**
* Implements hook_requirements().
*/
function openid_requirements($phase) {
$requirements = array();

if ($phase == 'runtime') {
// Check for the PHP BC Math library.
if (!function_exists('bcadd') && !function_exists('gmp_add')) {
$requirements['openid_math'] = array(
'value' => t('Not installed'),
'severity' => REQUIREMENT_INFO,
'description' => t('OpenID suggests the use of either the <a href="@gmp">GMP Math</a> (recommended for performance) or <a href="@bc">BC Math</a> libraries to enable OpenID associations.', array('@gmp' => 'http://php.net/manual/en/book.gmp.php', '@bc' => 'http://www.php.net/manual/en/book.bc.php')),
);
}
elseif (!function_exists('gmp_add')) {
$requirements['openid_math'] = array(
'value' => t('Not optimized'),
'severity' => REQUIREMENT_INFO,
'description' => t('OpenID suggests the use of the GMP Math library for PHP for optimal performance. Check the <a href="@url">GMP Math Library documentation</a> for installation instructions.', array('@url' => 'http://www.php.net/manual/en/book.gmp.php')),
);
}
else {
$requirements['openid_math'] = array(
'value' => t('Installed'),
'severity' => REQUIREMENT_OK,
);
}
$requirements['openid_math']['title'] = t('OpenID Math library');
}

return $requirements;
}

/**
* @addtogroup updates-6.x-extra
* @{
Expand Down
10 changes: 5 additions & 5 deletions modules/openid/openid.module
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,9 @@ function openid_begin($claimed_id, $return_to = '', $form_values = array()) {
$_SESSION['openid']['user_login_values'] = $form_values;

$op_endpoint = $services[0]['uri'];
// If bcmath is present, then create an association
// If a supported math library is present, then create an association.
$assoc_handle = '';
if (function_exists('bcadd')) {
if (_openid_get_math_library()) {
$assoc_handle = openid_association($op_endpoint);
}

Expand Down Expand Up @@ -373,8 +373,8 @@ function openid_association($op_endpoint) {
$mod = OPENID_DH_DEFAULT_MOD;
$gen = OPENID_DH_DEFAULT_GEN;
$r = _openid_dh_rand($mod);
$private = bcadd($r, 1);
$public = bcpowmod($gen, $private, $mod);
$private = _openid_math_add($r, 1);
$public = _openid_math_powmod($gen, $private, $mod);

// If there is no existing association, then request one
$assoc_request = openid_association_request($public);
Expand All @@ -393,7 +393,7 @@ function openid_association($op_endpoint) {
if ($assoc_response['session_type'] == 'DH-SHA1') {
$spub = _openid_dh_base64_to_long($assoc_response['dh_server_public']);
$enc_mac_key = base64_decode($assoc_response['enc_mac_key']);
$shared = bcpowmod($spub, $private, $mod);
$shared = _openid_math_powmod($spub, $private, $mod);
$assoc_response['mac_key'] = base64_encode(_openid_dh_xorsecret($shared, $enc_mac_key));
}
db_query("INSERT INTO {openid_association} (idp_endpoint_uri, session_type, assoc_handle, assoc_type, expires_in, mac_key, created) VALUES('%s', '%s', '%s', '%s', %d, '%s', %d)",
Expand Down