summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Hoyt <josh@janrain.com>2006-01-23 22:25:50 +0000
committerJosh Hoyt <josh@janrain.com>2006-01-23 22:25:50 +0000
commit7eaa8521ea9ec49b9ff493aa37c2883dddd4fc36 (patch)
tree4184a098e34e03ebdc6a1bd65e17ed88854540c0
parent31972ad02a8f62ee1bb2c14713743c382d731aeb (diff)
downloadphp-openid-7eaa8521ea9ec49b9ff493aa37c2883dddd4fc36.zip
php-openid-7eaa8521ea9ec49b9ff493aa37c2883dddd4fc36.tar.gz
php-openid-7eaa8521ea9ec49b9ff493aa37c2883dddd4fc36.tar.bz2
[project @ Move arbitrary-precision integer functions to BigMath module]
-rw-r--r--Auth/OpenID/BigMath.php429
-rw-r--r--Auth/OpenID/CryptUtil.php464
-rw-r--r--Auth/OpenID/DiffieHellman.php2
-rw-r--r--Tests/Auth/OpenID/BigMath.php222
-rw-r--r--Tests/Auth/OpenID/CryptUtil.php206
-rw-r--r--Tests/TestDriver.php9
6 files changed, 683 insertions, 649 deletions
diff --git a/Auth/OpenID/BigMath.php b/Auth/OpenID/BigMath.php
new file mode 100644
index 0000000..8865317
--- /dev/null
+++ b/Auth/OpenID/BigMath.php
@@ -0,0 +1,429 @@
+<?php
+
+/**
+ * BigMath: A math library wrapper that abstracts out the underlying
+ * long integer library.
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: See the COPYING file included in this distribution.
+ *
+ * @package OpenID
+ * @author JanRain, Inc. <openid@janrain.com>
+ * @copyright 2005 Janrain, Inc.
+ * @license http://www.gnu.org/copyleft/lesser.html LGPL
+ */
+
+// For Auth_OpenID_randrange
+require_once('Auth/OpenID/CryptUtil.php');
+
+
+/**
+ * Exposes BCmath math library functionality.
+ *
+ * Auth_OpenID_BcMathWrapper wraps the functionality provided by the
+ * BCMath extension.
+ *
+ * @package OpenID
+ */
+class Auth_OpenID_BcMathWrapper {
+ var $type = 'bcmath';
+
+ function add($x, $y)
+ {
+ return bcadd($x, $y);
+ }
+
+ function sub($x, $y)
+ {
+ return bcsub($x, $y);
+ }
+
+ function pow($base, $exponent)
+ {
+ return bcpow($base, $exponent);
+ }
+
+ function cmp($x, $y)
+ {
+ return bccomp($x, $y);
+ }
+
+ function init($number, $base = 10)
+ {
+ return $number;
+ }
+
+ function mod($base, $modulus)
+ {
+ return bcmod($base, $modulus);
+ }
+
+ function mul($x, $y)
+ {
+ return bcmul($x, $y);
+ }
+
+ function div($x, $y)
+ {
+ return bcdiv($x, $y);
+ }
+
+ /**
+ * Same as bcpowmod when bcpowmod is missing
+ *
+ * @access private
+ */
+ function _powmod($base, $exponent, $modulus)
+ {
+ $square = $this->mod($base, $modulus);
+ $result = 1;
+ while($this->cmp($exponent, 0) > 0) {
+ if ($this->mod($exponent, 2)) {
+ $result = $this->mod($this->mul($result, $square), $modulus);
+ }
+ $square = $this->mod($this->mul($square, $square), $modulus);
+ $exponent = $this->div($exponent, 2);
+ }
+ return $result;
+ }
+
+ function powmod($base, $exponent, $modulus)
+ {
+ if (function_exists('bcpowmod')) {
+ return bcpowmod($base, $exponent, $modulus);
+ } else {
+ return $this->_powmod($base, $exponent, $modulus);
+ }
+ }
+}
+
+/**
+ * Exposes GMP math library functionality.
+ *
+ * Auth_OpenID_GmpMathWrapper wraps the functionality provided by the
+ * GMP extension.
+ *
+ * @package OpenID
+ */
+class Auth_OpenID_GmpMathWrapper {
+ var $type = 'gmp';
+
+ function add($x, $y)
+ {
+ return gmp_add($x, $y);
+ }
+
+ function sub($x, $y)
+ {
+ return gmp_sub($x, $y);
+ }
+
+ function pow($base, $exponent)
+ {
+ return gmp_pow($base, $exponent);
+ }
+
+ function cmp($x, $y)
+ {
+ return gmp_cmp($x, $y);
+ }
+
+ function init($number, $base = 10)
+ {
+ return gmp_init($number, $base);
+ }
+
+ function mod($base, $modulus)
+ {
+ return gmp_mod($base, $modulus);
+ }
+
+ function mul($x, $y)
+ {
+ return gmp_mul($x, $y);
+ }
+
+ function div($x, $y)
+ {
+ return gmp_div_q($x, $y);
+ }
+
+ function powmod($base, $exponent, $modulus)
+ {
+ return gmp_powm($base, $exponent, $modulus);
+ }
+
+}
+
+/**
+ * Define the supported extensions. An extension array has keys
+ * 'modules', 'extension', and 'class'. 'modules' is an array of PHP
+ * module names which the loading code will attempt to load. These
+ * values will be suffixed with a library file extension (e.g. ".so").
+ * 'extension' is the name of a PHP extension which will be tested
+ * before 'modules' are loaded. 'class' is the string name of a
+ * Auth_OpenID_MathWrapper subclass which should be instantiated if a
+ * given extension is present.
+ *
+ * You can define new math library implementations and add them to
+ * this array.
+ */
+$_Auth_OpenID_supported_extensions = array(
+ array('modules' => array('gmp', 'php_gmp'),
+ 'extension' => 'gmp',
+ 'class' => 'Auth_OpenID_GmpMathWrapper'),
+ array('modules' => array('bcmath', 'php_bcmath'),
+ 'extension' => 'bcmath',
+ 'class' => 'Auth_OpenID_BcMathWrapper')
+ );
+
+function Auth_OpenID_detectMathLibrary($exts)
+{
+ $loaded = false;
+
+ foreach ($exts as $extension) {
+ // See if the extension specified is already loaded.
+ if ($extension['extension'] &&
+ extension_loaded($extension['extension'])) {
+ $loaded = true;
+ }
+
+ // Try to load dynamic modules.
+ if (!$loaded) {
+ foreach ($extension['modules'] as $module) {
+ if (@dl($module . "." . PHP_SHLIB_SUFFIX)) {
+ $loaded = true;
+ break;
+ }
+ }
+ }
+
+ // If the load succeeded, supply an instance of
+ // Auth_OpenID_MathWrapper which wraps the specified
+ // module's functionality.
+ if ($loaded) {
+ return $extension['class'];
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Auth_OpenID_getMathLib checks for the presence of long number
+ * extension modules and returns an instance of Auth_OpenID_MathWrapper
+ * which exposes the module's functionality.
+ *
+ * Checks for the existence of an extension module described by the
+ * local Auth_OpenID_supported_extensions array and returns an
+ * instance of a wrapper for that extension module. If no extension
+ * module is found, an instance of Auth_OpenID_MathWrapper is
+ * returned, which wraps the native PHP integer implementation. The
+ * proper calling convention for this method is $lib =&
+ * Auth_OpenID_getMathLib().
+ *
+ * This function checks for the existence of specific long number
+ * implementations in the following order: GMP followed by BCmath.
+ *
+ * @return Auth_OpenID_MathWrapper $instance An instance of
+ * Auth_OpenID_MathWrapper or one of its subclasses
+ *
+ * @package OpenID
+ */
+function &Auth_OpenID_getMathLib()
+{
+ // The instance of Auth_OpenID_MathWrapper that we choose to
+ // supply will be stored here, so that subseqent calls to this
+ // method will return a reference to the same object.
+ static $lib = null;
+
+ if (isset($lib)) {
+ return $lib;
+ }
+
+ if (defined('Auth_OpenID_NO_MATH_SUPPORT')) {
+ return null;
+ }
+
+ // If this method has not been called before, look at
+ // $Auth_OpenID_supported_extensions and try to find an
+ // extension that works.
+ global $_Auth_OpenID_supported_extensions;
+ $ext = Auth_OpenID_detectMathLibrary($_Auth_OpenID_supported_extensions);
+ if ($ext === false) {
+ $tried = array();
+ foreach ($_Auth_OpenID_supported_extensions as $extinfo) {
+ $tried[] = $extinfo['extension'];
+ }
+ $triedstr = implode(", ", $tried);
+ $msg = 'This PHP installation has no big integer math ' .
+ 'library. Define Auth_OpenID_NO_MATH_SUPPORT to use ' .
+ 'this library in dumb mode. Tried: ' . $triedstr;
+ trigger_error($msg, E_USER_ERROR);
+ }
+
+ // Instantiate a new wrapper
+ $lib = new $ext();
+
+ return $lib;
+}
+
+/**
+ * Given a long integer, returns the number converted to a binary
+ * string. This function accepts long integer values of arbitrary
+ * magnitude and uses the local large-number math library when
+ * available.
+ *
+ * @param integer $long The long number (can be a normal PHP
+ * integer or a number created by one of the available long number
+ * libraries)
+ * @return string $binary The binary version of $long
+ */
+function Auth_OpenID_longToBinary($long)
+{
+ $lib =& Auth_OpenID_getMathLib();
+
+ $cmp = $lib->cmp($long, 0);
+ if ($cmp < 0) {
+ $msg = __FUNCTION__ . " takes only positive integers.";
+ trigger_error($msg, E_USER_ERROR);
+ return null;
+ }
+
+ if ($cmp == 0) {
+ return "\x00";
+ }
+
+ $bytes = array();
+
+ while ($lib->cmp($long, 0) > 0) {
+ array_unshift($bytes, $lib->mod($long, 256));
+ $long = $lib->div($long, pow(2, 8));
+ }
+
+ if ($bytes && ($bytes[0] > 127)) {
+ array_unshift($bytes, 0);
+ }
+
+ $string = '';
+ foreach ($bytes as $byte) {
+ $string .= pack('C', $byte);
+ }
+
+ return $string;
+}
+
+/**
+ * Converts a long number to its base64-encoded representation.
+ *
+ * @param integer $long The long number to be converted
+ * @return string $str The base64-encoded version of $long
+ */
+function Auth_OpenID_longToBase64($long)
+{
+ return base64_encode(Auth_OpenID_longToBinary($long));
+}
+
+/**
+ * Converts a base64-encoded string to a long number.
+ *
+ * @param string $str A base64-encoded string
+ * @return integer $long A long number
+ */
+function Auth_OpenID_base64ToLong($str)
+{
+ return Auth_OpenID_binaryToLong(base64_decode($str));
+}
+
+/**
+ * Given a binary string, returns the binary string converted to a
+ * long number.
+ *
+ * @param string $binary The binary version of a long number,
+ * probably as a result of calling longToBinary
+ * @return integer $long The long number equivalent of the binary
+ * string $str
+ */
+function Auth_OpenID_binaryToLong($str)
+{
+ $lib =& Auth_OpenID_getMathLib();
+
+ if ($str === null) {
+ return null;
+ }
+
+ // Use array_merge to return a zero-indexed array instead of a
+ // one-indexed array.
+ $bytes = array_merge(unpack('C*', $str));
+
+ $n = $lib->init(0);
+
+ if ($bytes && ($bytes[0] > 127)) {
+ trigger_error("bytesToNum works only for positive integers.",
+ E_USER_WARNING);
+ return null;
+ }
+
+ foreach ($bytes as $byte) {
+ $n = $lib->mul($n, pow(2, 8));
+ $n = $lib->add($n, $byte);
+ }
+
+ return $n;
+}
+
+/**
+ * Returns a random number in the specified range. This function
+ * accepts $start, $stop, and $step values of arbitrary magnitude
+ * and will utilize the local large-number math library when
+ * available.
+ *
+ * @param integer $start The start of the range, or the minimum
+ * random number to return
+ * @param integer $stop The end of the range, or the maximum
+ * random number to return
+ * @param integer $step The step size, such that $result - ($step
+ * * N) = $start for some N
+ * @return integer $result The resulting randomly-generated number
+ */
+function Auth_OpenID_randrange($stop)
+{
+ static $duplicate_cache = array();
+ $lib =& Auth_OpenID_getMathLib();
+
+ // Used as the key for the duplicate cache
+ $rbytes = Auth_OpenID_longToBinary($stop);
+
+ if (array_key_exists($rbytes, $duplicate_cache)) {
+ list($duplicate, $nbytes) = $duplicate_cache[$rbytes];
+ } else {
+ if ($rbytes[0] == "\x00") {
+ $nbytes = strlen($rbytes) - 1;
+ } else {
+ $nbytes = strlen($rbytes);
+ }
+
+ $mxrand = $lib->pow(256, $nbytes);
+
+ // If we get a number less than this, then it is in the
+ // duplicated range.
+ $duplicate = $lib->mod($mxrand, $stop);
+
+ if (count($duplicate_cache) > 10) {
+ $duplicate_cache = array();
+ }
+
+ $duplicate_cache[$rbytes] = array($duplicate, $nbytes);
+ }
+
+ do {
+ $bytes = "\x00" . Auth_OpenID_getBytes($nbytes);
+ $n = Auth_OpenID_binaryToLong($bytes);
+ // Keep looping if this value is in the low duplicated range
+ } while ($lib->cmp($n, $duplicate) < 0);
+
+ return $lib->mod($n, $stop);
+}
+
+?> \ No newline at end of file
diff --git a/Auth/OpenID/CryptUtil.php b/Auth/OpenID/CryptUtil.php
index 6ed5f5b..24884ae 100644
--- a/Auth/OpenID/CryptUtil.php
+++ b/Auth/OpenID/CryptUtil.php
@@ -14,11 +14,6 @@
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*/
-/**
- * Require the HMAC/SHA-1 implementation for creating such hashes.
- */
-require_once('HMACSHA1.php');
-
if (!defined('Auth_OpenID_RAND_SOURCE')) {
/**
* The filename for a source of random bytes. Define this yourself
@@ -27,203 +22,6 @@ if (!defined('Auth_OpenID_RAND_SOURCE')) {
define('Auth_OpenID_RAND_SOURCE', '/dev/urandom');
}
-/**
- * Given a long integer, returns the number converted to a binary
- * string. This function accepts long integer values of arbitrary
- * magnitude and uses the local large-number math library when
- * available.
- *
- * @param integer $long The long number (can be a normal PHP
- * integer or a number created by one of the available long number
- * libraries)
- * @return string $binary The binary version of $long
- */
-function Auth_OpenID_longToBinary($long)
-{
-
- $lib =& Auth_OpenID_getMathLib();
-
- $cmp = $lib->cmp($long, 0);
- if ($cmp < 0) {
- $msg = __FUNCTION__ . " takes only positive integers.";
- trigger_error($msg, E_USER_ERROR);
- return null;
- }
-
- if ($cmp == 0) {
- return "\x00";
- }
-
- $bytes = array();
-
- while ($lib->cmp($long, 0) > 0) {
- array_unshift($bytes, $lib->mod($long, 256));
- $long = $lib->div($long, pow(2, 8));
- }
-
- if ($bytes && ($bytes[0] > 127)) {
- array_unshift($bytes, 0);
- }
-
- $string = '';
- foreach ($bytes as $byte) {
- $string .= pack('C', $byte);
- }
-
- return $string;
-}
-
-/**
- * Produce a string of length random bytes, chosen from chrs. If
- * $chrs is null, the resulting string may contain any characters.
- *
- * @param integer $length The length of the resulting
- * randomly-generated string
- * @param string $chrs A string of characters from which to choose
- * to build the new string
- * @return string $result A string of randomly-chosen characters
- * from $chrs
- */
-function Auth_OpenID_randomString($length, $population = null)
-{
- if ($population === null) {
- return Auth_OpenID_getBytes($length);
- }
-
- $popsize = strlen($population);
-
- if ($popsize > 256) {
- $msg = 'More than 256 characters supplied to ' . __FUNCTION__;
- trigger_error($msg, E_USER_ERROR);
- }
-
- $duplicate = 256 % $popsize;
-
- $str = "";
- for ($i = 0; $i < $length; $i++) {
- do {
- $n = ord(Auth_OpenID_getBytes(1));
- } while ($n < $duplicate);
-
- $n %= $popsize;
- $str .= $population[$n];
- }
-
- return $str;
-}
-
-/**
- * Converts a long number to its base64-encoded representation.
- *
- * @param integer $long The long number to be converted
- * @return string $str The base64-encoded version of $long
- */
-function Auth_OpenID_longToBase64($long)
-{
- return base64_encode(Auth_OpenID_longToBinary($long));
-}
-
-/**
- * Converts a base64-encoded string to a long number.
- *
- * @param string $str A base64-encoded string
- * @return integer $long A long number
- */
-function Auth_OpenID_base64ToLong($str)
-{
- return Auth_OpenID_binaryToLong(base64_decode($str));
-}
-
-/**
- * Given a binary string, returns the binary string converted to a
- * long number.
- *
- * @param string $binary The binary version of a long number,
- * probably as a result of calling longToBinary
- * @return integer $long The long number equivalent of the binary
- * string $str
- */
-function Auth_OpenID_binaryToLong($str)
-{
- $lib =& Auth_OpenID_getMathLib();
-
- if ($str === null) {
- return null;
- }
-
- // Use array_merge to return a zero-indexed array instead of a
- // one-indexed array.
- $bytes = array_merge(unpack('C*', $str));
-
- $n = $lib->init(0);
-
- if ($bytes && ($bytes[0] > 127)) {
- trigger_error("bytesToNum works only for positive integers.",
- E_USER_WARNING);
- return null;
- }
-
- foreach ($bytes as $byte) {
- $n = $lib->mul($n, pow(2, 8));
- $n = $lib->add($n, $byte);
- }
-
- return $n;
-}
-
-/**
- * Returns a random number in the specified range. This function
- * accepts $start, $stop, and $step values of arbitrary magnitude
- * and will utilize the local large-number math library when
- * available.
- *
- * @param integer $start The start of the range, or the minimum
- * random number to return
- * @param integer $stop The end of the range, or the maximum
- * random number to return
- * @param integer $step The step size, such that $result - ($step
- * * N) = $start for some N
- * @return integer $result The resulting randomly-generated number
- */
-function Auth_OpenID_randrange($stop)
-{
- static $duplicate_cache = array();
- $lib =& Auth_OpenID_getMathLib();
-
- // Used as the key for the duplicate cache
- $rbytes = Auth_OpenID_longToBinary($stop);
-
- if (array_key_exists($rbytes, $duplicate_cache)) {
- list($duplicate, $nbytes) = $duplicate_cache[$rbytes];
- } else {
- if ($rbytes[0] == "\x00") {
- $nbytes = strlen($rbytes) - 1;
- } else {
- $nbytes = strlen($rbytes);
- }
-
- $mxrand = $lib->pow(256, $nbytes);
-
- // If we get a number less than this, then it is in the
- // duplicated range.
- $duplicate = $lib->mod($mxrand, $stop);
-
- if (count($duplicate_cache) > 10) {
- $duplicate_cache = array();
- }
-
- $duplicate_cache[$rbytes] = array($duplicate, $nbytes);
- }
-
- do {
- $bytes = "\x00" . Auth_OpenID_getBytes($nbytes);
- $n = Auth_OpenID_binaryToLong($bytes);
- // Keep looping if this value is in the low duplicated range
- } while ($lib->cmp($n, $duplicate) < 0);
-
- return $lib->mod($n, $stop);
-}
-
/**
* Get the specified number of random bytes.
*
@@ -260,254 +58,42 @@ function Auth_OpenID_getBytes($num_bytes)
}
/**
- * Exposes BCmath math library functionality.
- *
- * Auth_OpenID_BcMathWrapper wraps the functionality provided by the
- * BCMath extension.
- *
- * @package OpenID
- */
-class Auth_OpenID_BcMathWrapper {
- var $type = 'bcmath';
-
- function add($x, $y)
- {
- return bcadd($x, $y);
- }
-
- function sub($x, $y)
- {
- return bcsub($x, $y);
- }
-
- function pow($base, $exponent)
- {
- return bcpow($base, $exponent);
- }
-
- function cmp($x, $y)
- {
- return bccomp($x, $y);
- }
-
- function init($number, $base = 10)
- {
- return $number;
- }
-
- function mod($base, $modulus)
- {
- return bcmod($base, $modulus);
- }
-
- function mul($x, $y)
- {
- return bcmul($x, $y);
- }
-
- function div($x, $y)
- {
- return bcdiv($x, $y);
- }
-
- /**
- * Same as bcpowmod when bcpowmod is missing
- *
- * @access private
- */
- function _powmod($base, $exponent, $modulus)
- {
- $square = $this->mod($base, $modulus);
- $result = 1;
- while($this->cmp($exponent, 0) > 0) {
- if ($this->mod($exponent, 2)) {
- $result = $this->mod($this->mul($result, $square), $modulus);
- }
- $square = $this->mod($this->mul($square, $square), $modulus);
- $exponent = $this->div($exponent, 2);
- }
- return $result;
- }
-
- function powmod($base, $exponent, $modulus)
- {
- if (function_exists('bcpowmod')) {
- return bcpowmod($base, $exponent, $modulus);
- } else {
- return $this->_powmod($base, $exponent, $modulus);
- }
- }
-}
-
-/**
- * Exposes GMP math library functionality.
- *
- * Auth_OpenID_GmpMathWrapper wraps the functionality provided by the
- * GMP extension.
- *
- * @package OpenID
- */
-class Auth_OpenID_GmpMathWrapper {
- var $type = 'gmp';
-
- function add($x, $y)
- {
- return gmp_add($x, $y);
- }
-
- function sub($x, $y)
- {
- return gmp_sub($x, $y);
- }
-
- function pow($base, $exponent)
- {
- return gmp_pow($base, $exponent);
- }
-
- function cmp($x, $y)
- {
- return gmp_cmp($x, $y);
- }
-
- function init($number, $base = 10)
- {
- return gmp_init($number, $base);
- }
-
- function mod($base, $modulus)
- {
- return gmp_mod($base, $modulus);
- }
-
- function mul($x, $y)
- {
- return gmp_mul($x, $y);
- }
-
- function div($x, $y)
- {
- return gmp_div_q($x, $y);
- }
-
- function powmod($base, $exponent, $modulus)
- {
- return gmp_powm($base, $exponent, $modulus);
- }
-
-}
-
-/**
- * Define the supported extensions. An extension array has keys
- * 'modules', 'extension', and 'class'. 'modules' is an array of PHP
- * module names which the loading code will attempt to load. These
- * values will be suffixed with a library file extension (e.g. ".so").
- * 'extension' is the name of a PHP extension which will be tested
- * before 'modules' are loaded. 'class' is the string name of a
- * Auth_OpenID_MathWrapper subclass which should be instantiated if a
- * given extension is present.
+ * Produce a string of length random bytes, chosen from chrs. If
+ * $chrs is null, the resulting string may contain any characters.
*
- * You can define new math library implementations and add them to
- * this array.
+ * @param integer $length The length of the resulting
+ * randomly-generated string
+ * @param string $chrs A string of characters from which to choose
+ * to build the new string
+ * @return string $result A string of randomly-chosen characters
+ * from $chrs
*/
-$_Auth_OpenID_supported_extensions = array(
- array('modules' => array('gmp', 'php_gmp'),
- 'extension' => 'gmp',
- 'class' => 'Auth_OpenID_GmpMathWrapper'),
- array('modules' => array('bcmath', 'php_bcmath'),
- 'extension' => 'bcmath',
- 'class' => 'Auth_OpenID_BcMathWrapper')
- );
-
-function Auth_OpenID_detectMathLibrary($exts)
+function Auth_OpenID_randomString($length, $population = null)
{
- $loaded = false;
-
- foreach ($exts as $extension) {
- // See if the extension specified is already loaded.
- if ($extension['extension'] &&
- extension_loaded($extension['extension'])) {
- $loaded = true;
- }
-
- // Try to load dynamic modules.
- if (!$loaded) {
- foreach ($extension['modules'] as $module) {
- if (@dl($module . "." . PHP_SHLIB_SUFFIX)) {
- $loaded = true;
- break;
- }
- }
- }
-
- // If the load succeeded, supply an instance of
- // Auth_OpenID_MathWrapper which wraps the specified
- // module's functionality.
- if ($loaded) {
- return $extension['class'];
- }
+ if ($population === null) {
+ return Auth_OpenID_getBytes($length);
}
- return false;
-}
-
-/**
- * Auth_OpenID_getMathLib checks for the presence of long number
- * extension modules and returns an instance of Auth_OpenID_MathWrapper
- * which exposes the module's functionality.
- *
- * Checks for the existence of an extension module described by the
- * local Auth_OpenID_supported_extensions array and returns an
- * instance of a wrapper for that extension module. If no extension
- * module is found, an instance of Auth_OpenID_MathWrapper is
- * returned, which wraps the native PHP integer implementation. The
- * proper calling convention for this method is $lib =&
- * Auth_OpenID_getMathLib().
- *
- * This function checks for the existence of specific long number
- * implementations in the following order: GMP followed by BCmath.
- *
- * @return Auth_OpenID_MathWrapper $instance An instance of
- * Auth_OpenID_MathWrapper or one of its subclasses
- *
- * @package OpenID
- */
-function &Auth_OpenID_getMathLib()
-{
- // The instance of Auth_OpenID_MathWrapper that we choose to
- // supply will be stored here, so that subseqent calls to this
- // method will return a reference to the same object.
- static $lib = null;
+ $popsize = strlen($population);
- if (isset($lib)) {
- return $lib;
+ if ($popsize > 256) {
+ $msg = 'More than 256 characters supplied to ' . __FUNCTION__;
+ trigger_error($msg, E_USER_ERROR);
}
- if (defined('Auth_OpenID_NO_MATH_SUPPORT')) {
- return null;
- }
+ $duplicate = 256 % $popsize;
- // If this method has not been called before, look at
- // $Auth_OpenID_supported_extensions and try to find an
- // extension that works.
- global $_Auth_OpenID_supported_extensions;
- $ext = Auth_OpenID_detectMathLibrary($_Auth_OpenID_supported_extensions);
- if ($ext === false) {
- $tried = array();
- foreach ($_Auth_OpenID_supported_extensions as $extinfo) {
- $tried[] = $extinfo['extension'];
- }
- $triedstr = implode(", ", $tried);
- $msg = 'This PHP installation has no big integer math ' .
- 'library. Define Auth_OpenID_NO_MATH_SUPPORT to use ' .
- 'this library in dumb mode. Tried: ' . $triedstr;
- trigger_error($msg, E_USER_ERROR);
- }
+ $str = "";
+ for ($i = 0; $i < $length; $i++) {
+ do {
+ $n = ord(Auth_OpenID_getBytes(1));
+ } while ($n < $duplicate);
- // Instantiate a new wrapper
- $lib = new $ext();
+ $n %= $popsize;
+ $str .= $population[$n];
+ }
- return $lib;
+ return $str;
}
?> \ No newline at end of file
diff --git a/Auth/OpenID/DiffieHellman.php b/Auth/OpenID/DiffieHellman.php
index b02da2c..3ca500d 100644
--- a/Auth/OpenID/DiffieHellman.php
+++ b/Auth/OpenID/DiffieHellman.php
@@ -17,7 +17,7 @@
* Require CryptUtil because we need to get a Auth_OpenID_MathWrapper
* object.
*/
-require_once('CryptUtil.php');
+require_once('BigMath.php');
$_Auth_OpenID_DEFAULT_MOD = '155172898181473697471232257763715539915724801'.
'966915404479707795314057629378541917580651227423698188993727816152646631'.
diff --git a/Tests/Auth/OpenID/BigMath.php b/Tests/Auth/OpenID/BigMath.php
new file mode 100644
index 0000000..f42980e
--- /dev/null
+++ b/Tests/Auth/OpenID/BigMath.php
@@ -0,0 +1,222 @@
+<?php
+
+/**
+ * Tests for the BigMath functions.
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: See the COPYING file included in this distribution.
+ *
+ * @package OpenID
+ * @author JanRain, Inc. <openid@janrain.com>
+ * @copyright 2005 Janrain, Inc.
+ * @license http://www.gnu.org/copyleft/lesser.html LGPL
+ */
+
+require_once('PHPUnit.php');
+require_once('Auth/OpenID/BigMath.php');
+
+class Tests_Auth_OpenID_BinLongConvertRnd extends PHPUnit_TestCase {
+ var $lib;
+ var $max;
+
+ function Tests_Auth_OpenID_BinLongConvertRnd(&$lib, $max)
+ {
+ $this->lib =& $lib;
+ $this->max = $max;
+ }
+
+ function runTest()
+ {
+ $n = $this->lib->init(0);
+ foreach (range(0, 9) as $i) {
+ $rnd = Auth_OpenID_randrange($this->max);
+ $n = $this->lib->add($n, $rnd);
+ }
+ $s = Auth_OpenID_longToBinary($n);
+ $this->assertTrue(is_string($s));
+ $n_prime = Auth_OpenID_binaryToLong($s);
+ $this->assertEquals($this->lib->cmp($n, $n_prime), 0);
+ }
+}
+
+class Tests_Auth_OpenID_BinLongConvert extends PHPUnit_TestCase {
+ var $lib;
+ var $bin;
+ var $lng;
+
+ function Tests_Auth_OpenID_BinLongConvert(&$lib, $bin, $lng)
+ {
+ $this->lib =& $lib;
+ $this->bin = $bin;
+ $this->lng = $lng;
+ }
+
+ function runTest()
+ {
+ $n_prime = Auth_OpenID_binaryToLong($this->bin);
+ $s_prime = Auth_OpenID_longToBinary($this->lng);
+ $this->assertEquals($this->lib->cmp($this->lng, $n_prime), 0);
+ $this->assertTrue($this->bin == $s_prime);
+ }
+}
+
+class Tests_Auth_OpenID_Base64ToLong extends PHPUnit_TestCase {
+ var $num;
+ var $b64;
+ var $lib;
+
+ function Tests_Auth_OpenID_Base64ToLong(&$lib, $b64, $num)
+ {
+ $this->lib = $lib;
+ $this->b64 = $b64;
+ $this->num = $num;
+ }
+
+ function runTest()
+ {
+ $actual = Auth_OpenID_base64ToLong($this->b64);
+ $this->assertTrue($this->lib->cmp($this->num, $actual) == 0);
+ }
+}
+
+class Tests_Auth_OpenID_LongToBase64 extends Tests_Auth_OpenID_Base64ToLong {
+ function Tests_Auth_OpenID_LongToBase64(&$lib, $b64, $num)
+ {
+ $this->lib = $lib;
+ $this->b64 = $b64;
+ $this->num = $num;
+ }
+
+ function runTest()
+ {
+ $actual = Auth_OpenID_longToBase64($this->num);
+ $this->assertEquals($this->b64, $actual);
+ }
+}
+
+class Tests_Auth_OpenID_RandRange extends PHPUnit_TestCase {
+ function Tests_Auth_OpenID_RandRange(&$lib)
+ {
+ $this->lib =& $lib;
+ }
+
+ function runTest()
+ {
+ $stop = $this->lib->pow(2, 128);
+ $a = Auth_OpenID_randrange($stop);
+ $b = Auth_OpenID_randrange($stop);
+
+ $this->assertFalse($this->lib->cmp($b, $a) == 0, "Same: $a $b");
+
+ $n = $this->lib->init(Tests_Auth_OpenID_maxint());
+ $n = $this->lib->add($n, 1);
+
+ // Make sure that we can generate random numbers that are
+ // larger than platform int size
+ $result = Auth_OpenID_randrange($n);
+
+ // What can we say about the result?
+ }
+}
+
+/**
+ * Computes the maximum integer value for this PHP installation.
+ *
+ * @return int $max_int_value The maximum integer value for this
+ * PHP installation
+ */
+function Tests_Auth_OpenID_maxint()
+{
+ /* assumes largest integer is of form 2^n - 1 */
+ $to_test = pow(2, 16);
+ while (1) {
+ $last = $to_test;
+ $to_test = 2 * $to_test;
+ if (($to_test < $last) || (!is_int($to_test))) {
+ return($last + ($last - 1));
+ }
+ }
+}
+
+
+class Tests_Auth_OpenID_BigMath extends PHPUnit_TestSuite {
+ function _parseBase64Data()
+ {
+ $lines = file_get_contents('Tests/n2b64', true);
+ $lines = explode("\n", $lines);
+
+ $data = array();
+ foreach ($lines as $line) {
+ if (!$line) {
+ continue;
+ }
+ list($b64, $ascii) = explode(' ', $line);
+ $data[$b64] = $ascii;
+ }
+ return $data;
+ }
+
+ function Tests_Auth_OpenID_BigMath($name)
+ {
+ $this->setName($name);
+
+ if (!defined('Auth_OpenID_NO_MATH_SUPPORT')) {
+ $this->addTestSuite('Tests_Auth_OpenID_BigInt');
+
+ $lib =& Auth_OpenID_getMathLib();
+ $max = Tests_Auth_OpenID_maxint();
+ $upper = defined('Tests_Auth_OpenID_thorough') ? 499 : 3;
+
+ foreach (range(0, $upper) as $iteration) {
+ $test = new Tests_Auth_OpenID_BinLongConvertRnd($lib, $max);
+ $test->setName("BinLongConvertRnd " . strval($iteration));
+ $this->addTest($test);
+ }
+
+ $cases = array(
+ "\x00" => 0,
+ "\x01" => 1,
+ "\x00\xFF" => 255,
+ "\x00\x80" => 128,
+ "\x00\x81" => 129,
+ "\x00\x80\x00" => 32768,
+ "OpenID is cool" => "1611215304203901150134421257416556"
+ );
+
+ foreach ($cases as $bin => $lng_m) {
+ $lng = $lib->init($lng_m);
+ $test = new Tests_Auth_OpenID_BinLongConvert($lib, $bin, $lng);
+ $test->setName('BinLongConvert ' . bin2hex($bin));
+ $this->addTest($test);
+ }
+
+ $count = defined('Tests_Auth_OpenID_thorough') ? -1 : 2;
+ $data = $this->_parseBase64Data();
+ foreach ($data as $b64 => $num_s) {
+ // Only test the first few unless thorough is defined
+ if (strlen($num_s) > 5) {
+ if ($count == 0) {
+ break;
+ } else {
+ $count -= 1;
+ }
+ }
+ $num = $lib->init($num_s);
+ $test = new Tests_Auth_OpenID_Base64ToLong($lib, $b64, $num);
+ $test->setName("B64->Long $num_s");
+ $this->addTest($test);
+
+ $test = new Tests_Auth_OpenID_LongToBase64($lib, $b64, $num);
+ $test->setName("Long->B64 $num_s");
+ $this->addTest($test);
+ }
+
+ $test = new Tests_Auth_OpenID_RandRange($lib);
+ $test->setName('Big number randrange');
+ $this->addTest($test);
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/Tests/Auth/OpenID/CryptUtil.php b/Tests/Auth/OpenID/CryptUtil.php
index af05cea..14ff4ae 100644
--- a/Tests/Auth/OpenID/CryptUtil.php
+++ b/Tests/Auth/OpenID/CryptUtil.php
@@ -16,26 +16,7 @@
require_once('PHPUnit.php');
require_once('Auth/OpenID/CryptUtil.php');
-/**
- * Computes the maximum integer value for this PHP installation.
- *
- * @return int $max_int_value The maximum integer value for this
- * PHP installation
- */
-function Tests_Auth_OpenID_maxint()
-{
- /* assumes largest integer is of form 2^n - 1 */
- $to_test = pow(2, 16);
- while (1) {
- $last = $to_test;
- $to_test = 2 * $to_test;
- if (($to_test < $last) || (!is_int($to_test))) {
- return($last + ($last - 1));
- }
- }
-}
-
-class Tests_Auth_OpenID_ByteOps extends PHPUnit_TestCase {
+class Tests_Auth_OpenID_CryptUtil extends PHPUnit_TestCase {
function test_length()
{
$cases = array(1, 10, 255);
@@ -71,189 +52,4 @@ class Tests_Auth_OpenID_ByteOps extends PHPUnit_TestCase {
}
}
-class Tests_Auth_OpenID_BinLongConvertRnd extends PHPUnit_TestCase {
- var $lib;
- var $max;
-
- function Tests_Auth_OpenID_BinLongConvertRnd(&$lib, $max)
- {
- $this->lib =& $lib;
- $this->max = $max;
- }
-
- function runTest()
- {
- $n = $this->lib->init(0);
- foreach (range(0, 9) as $i) {
- $rnd = Auth_OpenID_randrange($this->max);
- $n = $this->lib->add($n, $rnd);
- }
- $s = Auth_OpenID_longToBinary($n);
- $this->assertTrue(is_string($s));
- $n_prime = Auth_OpenID_binaryToLong($s);
- $this->assertEquals($this->lib->cmp($n, $n_prime), 0);
- }
-}
-
-class Tests_Auth_OpenID_BinLongConvert extends PHPUnit_TestCase {
- var $lib;
- var $bin;
- var $lng;
-
- function Tests_Auth_OpenID_BinLongConvert(&$lib, $bin, $lng)
- {
- $this->lib =& $lib;
- $this->bin = $bin;
- $this->lng = $lng;
- }
-
- function runTest()
- {
- $n_prime = Auth_OpenID_binaryToLong($this->bin);
- $s_prime = Auth_OpenID_longToBinary($this->lng);
- $this->assertEquals($this->lib->cmp($this->lng, $n_prime), 0);
- $this->assertTrue($this->bin == $s_prime);
- }
-}
-
-class Tests_Auth_OpenID_Base64ToLong extends PHPUnit_TestCase {
- var $num;
- var $b64;
- var $lib;
-
- function Tests_Auth_OpenID_Base64ToLong(&$lib, $b64, $num)
- {
- $this->lib = $lib;
- $this->b64 = $b64;
- $this->num = $num;
- }
-
- function runTest()
- {
- $actual = Auth_OpenID_base64ToLong($this->b64);
- $this->assertTrue($this->lib->cmp($this->num, $actual) == 0);
- }
-}
-
-class Tests_Auth_OpenID_LongToBase64 extends Tests_Auth_OpenID_Base64ToLong {
- function Tests_Auth_OpenID_LongToBase64(&$lib, $b64, $num)
- {
- $this->lib = $lib;
- $this->b64 = $b64;
- $this->num = $num;
- }
-
- function runTest()
- {
- $actual = Auth_OpenID_longToBase64($this->num);
- $this->assertEquals($this->b64, $actual);
- }
-}
-
-class Tests_Auth_OpenID_RandRange extends PHPUnit_TestCase {
- function Tests_Auth_OpenID_RandRange(&$lib)
- {
- $this->lib =& $lib;
- }
-
- function runTest()
- {
- $stop = $this->lib->pow(2, 128);
- $a = Auth_OpenID_randrange($stop);
- $b = Auth_OpenID_randrange($stop);
-
- $this->assertFalse($this->lib->cmp($b, $a) == 0, "Same: $a $b");
-
- $n = $this->lib->init(Tests_Auth_OpenID_maxint());
- $n = $this->lib->add($n, 1);
-
- // Make sure that we can generate random numbers that are
- // larger than platform int size
- $result = Auth_OpenID_randrange($n);
-
- // What can we say about the result?
- }
-}
-
-class Tests_Auth_OpenID_CryptUtil extends PHPUnit_TestSuite {
- function _parseBase64Data()
- {
- $lines = file_get_contents('Tests/n2b64', true);
- $lines = explode("\n", $lines);
-
- $data = array();
- foreach ($lines as $line) {
- if (!$line) {
- continue;
- }
- list($b64, $ascii) = explode(' ', $line);
- $data[$b64] = $ascii;
- }
- return $data;
- }
-
- function Tests_Auth_OpenID_CryptUtil($name)
- {
- $this->setName($name);
-
- if (!defined('Auth_OpenID_NO_MATH_SUPPORT')) {
- $this->addTestSuite('Tests_Auth_OpenID_BigInt');
-
- $lib =& Auth_OpenID_getMathLib();
- $max = Tests_Auth_OpenID_maxint();
- $upper = defined('Tests_Auth_OpenID_thorough') ? 499 : 3;
-
- foreach (range(0, $upper) as $iteration) {
- $test = new Tests_Auth_OpenID_BinLongConvertRnd($lib, $max);
- $test->setName("BinLongConvertRnd " . strval($iteration));
- $this->addTest($test);
- }
-
- $cases = array(
- "\x00" => 0,
- "\x01" => 1,
- "\x00\xFF" => 255,
- "\x00\x80" => 128,
- "\x00\x81" => 129,
- "\x00\x80\x00" => 32768,
- "OpenID is cool" => "1611215304203901150134421257416556"
- );
-
- foreach ($cases as $bin => $lng_m) {
- $lng = $lib->init($lng_m);
- $test = new Tests_Auth_OpenID_BinLongConvert($lib, $bin, $lng);
- $test->setName('BinLongConvert ' . bin2hex($bin));
- $this->addTest($test);
- }
-
- $count = defined('Tests_Auth_OpenID_thorough') ? -1 : 2;
- $data = $this->_parseBase64Data();
- foreach ($data as $b64 => $num_s) {
- // Only test the first few unless thorough is defined
- if (strlen($num_s) > 5) {
- if ($count == 0) {
- break;
- } else {
- $count -= 1;
- }
- }
- $num = $lib->init($num_s);
- $test = new Tests_Auth_OpenID_Base64ToLong($lib, $b64, $num);
- $test->setName("B64->Long $num_s");
- $this->addTest($test);
-
- $test = new Tests_Auth_OpenID_LongToBase64($lib, $b64, $num);
- $test->setName("Long->B64 $num_s");
- $this->addTest($test);
- }
-
- $test = new Tests_Auth_OpenID_RandRange($lib);
- $test->setName('Big number randrange');
- $this->addTest($test);
- }
-
- $this->addTestSuite('Tests_Auth_OpenID_ByteOps');
- }
-}
-
?> \ No newline at end of file
diff --git a/Tests/TestDriver.php b/Tests/TestDriver.php
index 2b0314b..50e1d29 100644
--- a/Tests/TestDriver.php
+++ b/Tests/TestDriver.php
@@ -64,14 +64,15 @@ function global_require_once($name)
$_test_dir = 'Tests/Auth/OpenID/';
$_test_names = array(
- 'KVForm',
+ 'Association',
+ 'BigMath',
+ 'Consumer',
'CryptUtil',
- 'OIDUtil',
'DiffieHellman',
'HMACSHA1',
- 'Association',
+ 'KVForm',
+ 'OIDUtil',
'Parse',
- 'Consumer',
'StoreTest'
);