/** * Generates a random integer, which will be used to derive a private key * for Diffie-Hellman key exchange. The integer must be less than $stop * * @param BigNum $stop a prime number as a bignum * @return BigNum the random integer as a bignum */ private function generateRandom($stop) { $duplicate_cache = array(); $rand = new Random(); // Used as the key for the duplicate cache $rbytes = $stop->val(256); if (array_key_exists($rbytes, $duplicate_cache)) { list($duplicate, $nbytes) = $duplicate_cache[$rbytes]; } else { if ($rbytes[0] == "") { $nbytes = strlen($rbytes) - 1; } else { $nbytes = strlen($rbytes); } $mxrand = new BigNum(256); $mxrand = $mxrand->pow(new BigNum($nbytes)); // If we get a number less than this, then it is in the // duplicated range. $duplicate = $mxrand->mod($stop); if (count($duplicate_cache) > 10) { $duplicate_cache = array(); } $duplicate_cache[$rbytes] = array($duplicate, $nbytes); } do { $bytes = "" . $rand->bytes($nbytes); $n = new BigNum($bytes, 256); // Keep looping if this value is in the low duplicated range } while ($n->cmp($duplicate) < 0); return $n->mod($stop); }