/* Creates an odd BigInt with the specified number of digits. * Returns it by reference in the "number" parameter. */ void PrimeGenerator::makePrimeCandidate(BigInt &number, unsigned long int digitCount) { PrimeGenerator::MakeRandom(number, digitCount); //make the number odd if (!number.IsOdd()) number.SetDigit(0, number.GetDigit(0) + 1); //make sure the leading digit is not a zero if (number.GetDigit(number.Length() - 1) == 0) number.SetDigit(number.Length() - 1, (std::rand() % 9) + 1); }
/* Generates a random number such as 1 <= number < 'top'. * Returns it by reference in the 'number' parameter. */ void PrimeGenerator::makeRandom(BigInt &number, const BigInt &top) { //randomly select the number of digits for the random number unsigned long int newDigitCount = (rand() % top.Length()) + 1; MakeRandom(number, newDigitCount); //make sure number < top while (number >= top) MakeRandom(number, newDigitCount); }
/* Transforms a BigInt cyphertext into a std::string cyphertext. */ string RSA::decode(const BigInt &message) { string decoded; // The special symbol '1' we added to the beginning of the encoded message // will now be positioned at message[message.Length() - 1], and // message.Length() -1 must be divisible by 3 without remainder. Thus we // can ignore the special symbol by only using digits in the range // from message[0] to message[message.Length() - 2]. for (unsigned long int i(0); i < message.Length() / 3; i++) { // Decode the characters using the ASCII values in the BigInt digits. char ASCII = 100 * char(message.GetDigit(i * 3)); ASCII += 10 * char(message.GetDigit(i * 3 + 1)); decoded.push_back(ASCII + char(message.GetDigit(i * 3 + 2))); } return decoded; }
/* Returns a probable prime number "digitCount" digits long, * with a probability of at least 1 - 4^(-k) that it is prime. */ BigInt PrimeGenerator::Generate(unsigned long int digitCount, unsigned long int k) { if (digitCount < 3) throw "Error PRIMEGENERATOR00: Primes less than 3 digits long " "not supported."; BigInt primeCandidate; PrimeGenerator::makePrimeCandidate(primeCandidate, digitCount); while (!isProbablePrime(primeCandidate, k)) { //select the next odd number and try again primeCandidate = primeCandidate + 2; if (primeCandidate.Length() != digitCount) PrimeGenerator::makePrimeCandidate(primeCandidate, digitCount); } return primeCandidate; }