Example #1
0
 /**
  * Generate a random number
  *
  * @param optional Integer $min
  * @param optional Integer $max
  * @return BigInteger
  * @access public
  */
 function random($min = false, $max = false)
 {
     if ($min === false) {
         $min = new BigInteger(0);
     }
     if ($max === false) {
         $max = new BigInteger(0x7fffffff);
     }
     $compare = $max->compare($min);
     if (!$compare) {
         return $this->_normalize($min);
     } else {
         if ($compare < 0) {
             // if $min is bigger then $max, swap $min and $max
             $temp = $max;
             $max = $min;
             $min = $temp;
         }
     }
     static $one;
     if (!isset($one)) {
         $one = new BigInteger(1);
     }
     $max = $max->subtract($min->subtract($one));
     $size = strlen(ltrim($max->toBytes(), chr(0)));
     /*
         doing $random % $max doesn't work because some numbers will be more likely to occur than others.
         eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145
         would produce 5 whereas the only value of random that could produce 139 would be 139. ie.
         not all numbers would be equally likely. some would be more likely than others.
     
         creating a whole new random number until you find one that is within the range doesn't work
         because, for sufficiently small ranges, the likelihood that you'd get a number within that range
         would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability
         would be pretty high that $random would be greater than $max.
     
         phpseclib works around this using the technique described here:
     
         http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string
     */
     $random_max = new BigInteger(chr(1) . str_repeat("", $size), 256);
     $random = $this->_random_number_helper($size);
     list($max_multiple) = $random_max->divide($max);
     $max_multiple = $max_multiple->multiply($max);
     while ($random->compare($max_multiple) >= 0) {
         $random = $random->subtract($max_multiple);
         $random_max = $random_max->subtract($max_multiple);
         $random = $random->bitwise_leftShift(8);
         $random = $random->add($this->_random_number_helper(1));
         $random_max = $random_max->bitwise_leftShift(8);
         list($max_multiple) = $random_max->divide($max);
         $max_multiple = $max_multiple->multiply($max);
     }
     list(, $random) = $random->divide($max);
     return $this->_normalize($random->add($min));
 }
Example #2
0
 /**
  * Prepare a number for use in Montgomery Modular Reductions
  *
  * @see _montgomery()
  * @see _slidingWindow()
  * @access private
  * @param Array $x
  * @param Array $n
  * @return Array
  */
 function _prepMontgomery($x, $n)
 {
     $lhs = new BigInteger();
     $lhs->value = array_merge($this->_array_repeat(0, count($n)), $x);
     $rhs = new BigInteger();
     $rhs->value = $n;
     list(, $temp) = $lhs->divide($rhs);
     return $temp->value;
 }