Index: modules/openid/openid.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/openid/openid.inc,v retrieving revision 1.37 diff -u -p -r1.37 openid.inc --- modules/openid/openid.inc 28 Oct 2010 02:27:09 -0000 1.37 +++ modules/openid/openid.inc 20 Dec 2010 03:23:24 -0000 @@ -448,15 +448,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; } @@ -467,9 +467,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)) { @@ -512,11 +512,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(); @@ -529,9 +529,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) { @@ -683,3 +683,90 @@ function openid_extract_ax_values($value return $output; } +/** + * Determine the available math library GMP vs. BCMath. + */ +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; +} + +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); + } +} + +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); + } +} + +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); + } +} + +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); + } +} + +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); + } +} + +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); + } +} + +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); + } +} Index: modules/openid/openid.install =================================================================== RCS file: /cvs/drupal/drupal/modules/openid/openid.install,v retrieving revision 1.12 diff -u -p -r1.12 openid.install --- modules/openid/openid.install 22 Aug 2010 22:00:16 -0000 1.12 +++ modules/openid/openid.install 20 Dec 2010 03:23:24 -0000 @@ -92,20 +92,27 @@ function openid_requirements($phase) { if ($phase == 'runtime') { // Check for the PHP BC Math library. - if (!function_exists('bcadd')) { - $requirements['bcmath'] = array( + if (!function_exists('bcadd') && !function_exists('gmp_add')) { + $requirements['openid_math'] = array( 'value' => t('Not installed'), 'severity' => REQUIREMENT_ERROR, - 'description' => t('OpenID requires the BC Math library for PHP which is missing or outdated. Check the PHP BC Math Library documentation 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 GMP Math (recommended for performance) or BC Math 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 GMP Math Library documentation for installation instructions.', array('@url' => 'http://www.php.net/manual/en/book.gmp.php')), ); } else { - $requirements['bcmath'] = array( + $requirements['openid_math'] = array( 'value' => t('Installed'), 'severity' => REQUIREMENT_OK, ); } - $requirements['bcmath']['title'] = t('BC Math library'); + $requirements['openid_math']['title'] = t('OpenID Math library'); } return $requirements; Index: modules/openid/openid.module =================================================================== RCS file: /cvs/drupal/drupal/modules/openid/openid.module,v retrieving revision 1.98 diff -u -p -r1.98 openid.module --- modules/openid/openid.module 30 Nov 2010 17:16:37 -0000 1.98 +++ modules/openid/openid.module 20 Dec 2010 03:23:24 -0000 @@ -275,9 +275,9 @@ function openid_begin($claimed_id, $retu // user_exteral_login later. $_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 = ''; - if (function_exists('bcadd')) { + if (_openid_get_math_library()) { $assoc_handle = openid_association($service['uri']); } @@ -540,8 +540,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); @@ -564,7 +564,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_insert('openid_association') Index: modules/openid/tests/openid_test.module =================================================================== RCS file: /cvs/drupal/drupal/modules/openid/tests/openid_test.module,v retrieving revision 1.17 diff -u -p -r1.17 openid_test.module --- modules/openid/tests/openid_test.module 7 Jul 2010 08:05:01 -0000 1.17 +++ modules/openid/tests/openid_test.module 20 Dec 2010 03:23:24 -0000 @@ -228,14 +228,14 @@ function _openid_test_endpoint_associate // Generate private Diffie-Helmann key. $r = _openid_dh_rand($mod); - $private = bcadd($r, 1); + $private = _openid_math_add($r, 1); // 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. $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. $enc_mac_key = base64_encode(_openid_dh_xorsecret($shared, base64_decode(variable_get('mac_key'))));