ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
BigMath.php
Go to the documentation of this file.
1 <?php
2 
21 require_once 'Auth/OpenID/CryptUtil.php';
22 
26 require_once 'Auth/OpenID.php';
27 
45  function longToBinary($long)
46  {
47  $cmp = $this->cmp($long, 0);
48  if ($cmp < 0) {
49  $msg = __FUNCTION__ . " takes only positive integers.";
50  trigger_error($msg, E_USER_ERROR);
51  return null;
52  }
53 
54  if ($cmp == 0) {
55  return "\x00";
56  }
57 
58  $bytes = array();
59 
60  while ($this->cmp($long, 0) > 0) {
61  array_unshift($bytes, $this->mod($long, 256));
62  $long = $this->div($long, pow(2, 8));
63  }
64 
65  if ($bytes && ($bytes[0] > 127)) {
66  array_unshift($bytes, 0);
67  }
68 
69  $string = '';
70  foreach ($bytes as $byte) {
71  $string .= pack('C', $byte);
72  }
73 
74  return $string;
75  }
76 
86  function binaryToLong($str)
87  {
88  if ($str === null) {
89  return null;
90  }
91 
92  // Use array_merge to return a zero-indexed array instead of a
93  // one-indexed array.
94  $bytes = array_merge(unpack('C*', $str));
95 
96  $n = $this->init(0);
97 
98  if ($bytes && ($bytes[0] > 127)) {
99  trigger_error("bytesToNum works only for positive integers.",
100  E_USER_WARNING);
101  return null;
102  }
103 
104  foreach ($bytes as $byte) {
105  $n = $this->mul($n, pow(2, 8));
106  $n = $this->add($n, $byte);
107  }
108 
109  return $n;
110  }
111 
112  function base64ToLong($str)
113  {
114  $b64 = base64_decode($str);
115 
116  if ($b64 === false) {
117  return false;
118  }
119 
120  return $this->binaryToLong($b64);
121  }
122 
123  function longToBase64($str)
124  {
125  return base64_encode($this->longToBinary($str));
126  }
127 
142  function rand($stop)
143  {
144  static $duplicate_cache = array();
145 
146  // Used as the key for the duplicate cache
147  $rbytes = $this->longToBinary($stop);
148 
149  if (array_key_exists($rbytes, $duplicate_cache)) {
150  list($duplicate, $nbytes) = $duplicate_cache[$rbytes];
151  } else {
152  if ($rbytes[0] == "\x00") {
153  $nbytes = Auth_OpenID::bytes($rbytes) - 1;
154  } else {
155  $nbytes = Auth_OpenID::bytes($rbytes);
156  }
157 
158  $mxrand = $this->pow(256, $nbytes);
159 
160  // If we get a number less than this, then it is in the
161  // duplicated range.
162  $duplicate = $this->mod($mxrand, $stop);
163 
164  if (count($duplicate_cache) > 10) {
165  $duplicate_cache = array();
166  }
167 
168  $duplicate_cache[$rbytes] = array($duplicate, $nbytes);
169  }
170 
171  do {
172  $bytes = "\x00" . Auth_OpenID_CryptUtil::getBytes($nbytes);
173  $n = $this->binaryToLong($bytes);
174  // Keep looping if this value is in the low duplicated range
175  } while ($this->cmp($n, $duplicate) < 0);
176 
177  return $this->mod($n, $stop);
178  }
179 }
180 
191  var $type = 'bcmath';
192 
193  function add($x, $y)
194  {
195  return bcadd($x, $y);
196  }
197 
198  function sub($x, $y)
199  {
200  return bcsub($x, $y);
201  }
202 
203  function pow($base, $exponent)
204  {
205  return bcpow($base, $exponent);
206  }
207 
208  function cmp($x, $y)
209  {
210  return bccomp($x, $y);
211  }
212 
213  function init($number, $base = 10)
214  {
215  return $number;
216  }
217 
218  function mod($base, $modulus)
219  {
220  return bcmod($base, $modulus);
221  }
222 
223  function mul($x, $y)
224  {
225  return bcmul($x, $y);
226  }
227 
228  function div($x, $y)
229  {
230  return bcdiv($x, $y);
231  }
232 
238  function _powmod($base, $exponent, $modulus)
239  {
240  $square = $this->mod($base, $modulus);
241  $result = 1;
242  while($this->cmp($exponent, 0) > 0) {
243  if ($this->mod($exponent, 2)) {
244  $result = $this->mod($this->mul($result, $square), $modulus);
245  }
246  $square = $this->mod($this->mul($square, $square), $modulus);
247  $exponent = $this->div($exponent, 2);
248  }
249  return $result;
250  }
251 
252  function powmod($base, $exponent, $modulus)
253  {
254  if (function_exists('bcpowmod')) {
255  return bcpowmod($base, $exponent, $modulus);
256  } else {
257  return $this->_powmod($base, $exponent, $modulus);
258  }
259  }
260 
261  function toString($num)
262  {
263  return $num;
264  }
265 }
266 
277  var $type = 'gmp';
278 
279  function add($x, $y)
280  {
281  return gmp_add($x, $y);
282  }
283 
284  function sub($x, $y)
285  {
286  return gmp_sub($x, $y);
287  }
288 
289  function pow($base, $exponent)
290  {
291  return gmp_pow($base, $exponent);
292  }
293 
294  function cmp($x, $y)
295  {
296  return gmp_cmp($x, $y);
297  }
298 
299  function init($number, $base = 10)
300  {
301  return gmp_init($number, $base);
302  }
303 
304  function mod($base, $modulus)
305  {
306  return gmp_mod($base, $modulus);
307  }
308 
309  function mul($x, $y)
310  {
311  return gmp_mul($x, $y);
312  }
313 
314  function div($x, $y)
315  {
316  return gmp_div_q($x, $y);
317  }
318 
319  function powmod($base, $exponent, $modulus)
320  {
321  return gmp_powm($base, $exponent, $modulus);
322  }
323 
324  function toString($num)
325  {
326  return gmp_strval($num);
327  }
328 }
329 
344 {
345  $result = array();
346 
347  if (!defined('Auth_OpenID_BUGGY_GMP')) {
348  $result[] =
349  array('modules' => array('gmp', 'php_gmp'),
350  'extension' => 'gmp',
351  'class' => 'Auth_OpenID_GmpMathWrapper');
352  }
353 
354  $result[] = array('modules' => array('bcmath', 'php_bcmath'),
355  'extension' => 'bcmath',
356  'class' => 'Auth_OpenID_BcMathWrapper');
357 
358  return $result;
359 }
360 
365 {
366  $loaded = false;
367 
368  $hasDl = function_exists('dl');
369  foreach ($exts as $extension) {
370  if (extension_loaded($extension['extension'])) {
371  return $extension;
372  }
373  }
374 
375  return false;
376 }
377 
401 {
402  // The instance of Auth_OpenID_MathWrapper that we choose to
403  // supply will be stored here, so that subseqent calls to this
404  // method will return a reference to the same object.
405  static $lib = null;
406 
407  if (isset($lib)) {
408  return $lib;
409  }
410 
412  $null = null;
413  return $null;
414  }
415 
416  // If this method has not been called before, look at
417  // Auth_OpenID_math_extensions and try to find an extension that
418  // works.
420  if ($ext === false) {
421  $tried = array();
422  foreach (Auth_OpenID_math_extensions() as $extinfo) {
423  $tried[] = $extinfo['extension'];
424  }
425  $triedstr = implode(", ", $tried);
426 
428 
429  $result = null;
430  return $result;
431  }
432 
433  // Instantiate a new wrapper
434  $class = $ext['class'];
435  $lib = new $class();
436 
437  return $lib;
438 }
439 
441 {
442  if (!defined('Auth_OpenID_NO_MATH_SUPPORT')) {
443  define('Auth_OpenID_NO_MATH_SUPPORT', true);
444  }
445 }
446 
448 {
449  return defined('Auth_OpenID_NO_MATH_SUPPORT');
450 }
451 
452