Commit ab5809ac authored by Dries's avatar Dries

- Patch #488062 by catch, walkah, spiderman, paul.lovvik, klausi: speed up...

- Patch #488062 by catch, walkah, spiderman, paul.lovvik, klausi: speed up OpenID by using GMP instead of BCMath if available.
parent 39fc52de
...@@ -448,15 +448,15 @@ function _openid_dh_binary_to_long($str) { ...@@ -448,15 +448,15 @@ function _openid_dh_binary_to_long($str) {
$n = 0; $n = 0;
foreach ($bytes as $byte) { foreach ($bytes as $byte) {
$n = bcmul($n, pow(2, 8)); $n = _openid_math_mul($n, pow(2, 8));
$n = bcadd($n, $byte); $n = _openid_math_add($n, $byte);
} }
return $n; return $n;
} }
function _openid_dh_long_to_binary($long) { function _openid_dh_long_to_binary($long) {
$cmp = bccomp($long, 0); $cmp = _openid_math_cmp($long, 0);
if ($cmp < 0) { if ($cmp < 0) {
return FALSE; return FALSE;
} }
...@@ -467,9 +467,9 @@ function _openid_dh_long_to_binary($long) { ...@@ -467,9 +467,9 @@ function _openid_dh_long_to_binary($long) {
$bytes = array(); $bytes = array();
while (bccomp($long, 0) > 0) { while (_openid_math_cmp($long, 0) > 0) {
array_unshift($bytes, bcmod($long, 256)); array_unshift($bytes, _openid_math_mod($long, 256));
$long = bcdiv($long, pow(2, 8)); $long = _openid_math_div($long, pow(2, 8));
} }
if ($bytes && ($bytes[0] > 127)) { if ($bytes && ($bytes[0] > 127)) {
...@@ -512,11 +512,11 @@ function _openid_dh_rand($stop) { ...@@ -512,11 +512,11 @@ function _openid_dh_rand($stop) {
$nbytes = strlen($rbytes); $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 // If we get a number less than this, then it is in the
// duplicated range. // duplicated range.
$duplicate = bcmod($mxrand, $stop); $duplicate = _openid_math_mod($mxrand, $stop);
if (count($duplicate_cache) > 10) { if (count($duplicate_cache) > 10) {
$duplicate_cache = array(); $duplicate_cache = array();
...@@ -529,9 +529,9 @@ function _openid_dh_rand($stop) { ...@@ -529,9 +529,9 @@ function _openid_dh_rand($stop) {
$bytes = "\x00" . _openid_get_bytes($nbytes); $bytes = "\x00" . _openid_get_bytes($nbytes);
$n = _openid_dh_binary_to_long($bytes); $n = _openid_dh_binary_to_long($bytes);
// Keep looping if this value is in the low duplicated range. // 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) { function _openid_get_bytes($num_bytes) {
...@@ -683,3 +683,111 @@ function openid_extract_ax_values($values, $uris) { ...@@ -683,3 +683,111 @@ function openid_extract_ax_values($values, $uris) {
return $output; return $output;
} }
/**
* 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);
}
}
...@@ -92,20 +92,27 @@ function openid_requirements($phase) { ...@@ -92,20 +92,27 @@ function openid_requirements($phase) {
if ($phase == 'runtime') { if ($phase == 'runtime') {
// Check for the PHP BC Math library. // Check for the PHP BC Math library.
if (!function_exists('bcadd')) { if (!function_exists('bcadd') && !function_exists('gmp_add')) {
$requirements['bcmath'] = array( $requirements['openid_math'] = array(
'value' => t('Not installed'), 'value' => t('Not installed'),
'severity' => REQUIREMENT_ERROR, 'severity' => REQUIREMENT_ERROR,
'description' => t('OpenID requires the BC Math library for PHP which is missing or outdated. Check the <a href="@url">PHP BC Math Library documentation</a> for information on how to correct this.', array('@url' => 'http://www.php.net/manual/en/book.bc.php')), 'description' => t('OpenID suggest the use of either the 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_WARNING,
'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 { else {
$requirements['bcmath'] = array( $requirements['openid_math'] = array(
'value' => t('Installed'), 'value' => t('Installed'),
'severity' => REQUIREMENT_OK, 'severity' => REQUIREMENT_OK,
); );
} }
$requirements['bcmath']['title'] = t('BC Math library'); $requirements['openid_math']['title'] = t('OpenID Math library');
} }
return $requirements; return $requirements;
......
...@@ -275,9 +275,9 @@ function openid_begin($claimed_id, $return_to = '', $form_values = array()) { ...@@ -275,9 +275,9 @@ function openid_begin($claimed_id, $return_to = '', $form_values = array()) {
// user_exteral_login later. // user_exteral_login later.
$_SESSION['openid']['user_login_values'] = $form_values; $_SESSION['openid']['user_login_values'] = $form_values;
// If bcmath is present, then create an association // If a supported math library is present, then create an association.
$assoc_handle = ''; $assoc_handle = '';
if (function_exists('bcadd')) { if (_openid_get_math_library()) {
$assoc_handle = openid_association($service['uri']); $assoc_handle = openid_association($service['uri']);
} }
...@@ -540,8 +540,8 @@ function openid_association($op_endpoint) { ...@@ -540,8 +540,8 @@ function openid_association($op_endpoint) {
$mod = OPENID_DH_DEFAULT_MOD; $mod = OPENID_DH_DEFAULT_MOD;
$gen = OPENID_DH_DEFAULT_GEN; $gen = OPENID_DH_DEFAULT_GEN;
$r = _openid_dh_rand($mod); $r = _openid_dh_rand($mod);
$private = bcadd($r, 1); $private = _openid_math_add($r, 1);
$public = bcpowmod($gen, $private, $mod); $public = _openid_math_powmod($gen, $private, $mod);
// If there is no existing association, then request one // If there is no existing association, then request one
$assoc_request = openid_association_request($public); $assoc_request = openid_association_request($public);
...@@ -564,7 +564,7 @@ function openid_association($op_endpoint) { ...@@ -564,7 +564,7 @@ function openid_association($op_endpoint) {
if ($assoc_response['session_type'] == 'DH-SHA1') { if ($assoc_response['session_type'] == 'DH-SHA1') {
$spub = _openid_dh_base64_to_long($assoc_response['dh_server_public']); $spub = _openid_dh_base64_to_long($assoc_response['dh_server_public']);
$enc_mac_key = base64_decode($assoc_response['enc_mac_key']); $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)); $assoc_response['mac_key'] = base64_encode(_openid_dh_xorsecret($shared, $enc_mac_key));
} }
db_insert('openid_association') db_insert('openid_association')
......
...@@ -228,14 +228,14 @@ function _openid_test_endpoint_associate() { ...@@ -228,14 +228,14 @@ function _openid_test_endpoint_associate() {
// Generate private Diffie-Helmann key. // Generate private Diffie-Helmann key.
$r = _openid_dh_rand($mod); $r = _openid_dh_rand($mod);
$private = bcadd($r, 1); $private = _openid_math_add($r, 1);
// Calculate public Diffie-Helmann key. // Calculate public Diffie-Helmann key.
$public = bcpowmod($gen, $private, $mod); $public = _openid_math_powmod($gen, $private, $mod);
// Calculate shared secret based on Relying Party's public key. // Calculate shared secret based on Relying Party's public key.
$cpub = _openid_dh_base64_to_long($_REQUEST['openid_dh_consumer_public']); $cpub = _openid_dh_base64_to_long($_REQUEST['openid_dh_consumer_public']);
$shared = bcpowmod($cpub, $private, $mod); $shared = _openid_math_powmod($cpub, $private, $mod);
// Encrypt the MAC key using the shared secret. // Encrypt the MAC key using the shared secret.
$enc_mac_key = base64_encode(_openid_dh_xorsecret($shared, base64_decode(variable_get('mac_key')))); $enc_mac_key = base64_encode(_openid_dh_xorsecret($shared, base64_decode(variable_get('mac_key'))));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment