Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:05

0001 // nbtheory.h - originally written and placed in the public domain by Wei Dai

0002 
0003 /// \file nbtheory.h

0004 /// \brief Classes and functions  for number theoretic operations

0005 
0006 #ifndef CRYPTOPP_NBTHEORY_H
0007 #define CRYPTOPP_NBTHEORY_H
0008 
0009 #include "cryptlib.h"
0010 #include "integer.h"
0011 #include "algparam.h"
0012 
0013 NAMESPACE_BEGIN(CryptoPP)
0014 
0015 /// \brief The Small Prime table

0016 /// \param size number of elements in the table

0017 /// \return prime table with /p size elements

0018 /// \details GetPrimeTable() obtains pointer to small prime table and provides the size of the table.

0019 ///  /p size is an out parameter.

0020 CRYPTOPP_DLL const word16 * CRYPTOPP_API GetPrimeTable(unsigned int &size);
0021 
0022 // ************ primality testing ****************

0023 
0024 /// \brief Generates a provable prime

0025 /// \param rng a RandomNumberGenerator to produce random material

0026 /// \param bits the number of bits in the prime number

0027 /// \return Integer() meeting Maurer's tests for primality

0028 CRYPTOPP_DLL Integer CRYPTOPP_API MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits);
0029 
0030 /// \brief Generates a provable prime

0031 /// \param rng a RandomNumberGenerator to produce random material

0032 /// \param bits the number of bits in the prime number

0033 /// \return Integer() meeting Mihailescu's tests for primality

0034 /// \details Mihailescu's methods performs a search using algorithmic progressions.

0035 CRYPTOPP_DLL Integer CRYPTOPP_API MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int bits);
0036 
0037 /// \brief Tests whether a number is a small prime

0038 /// \param p a candidate prime to test

0039 /// \return true if p is a small prime, false otherwise

0040 /// \details Internally, the library maintains a table of the first 32719 prime numbers

0041 ///   in sorted order. IsSmallPrime searches the table and returns true if p is

0042 ///   in the table.

0043 CRYPTOPP_DLL bool CRYPTOPP_API IsSmallPrime(const Integer &p);
0044 
0045 /// \brief Tests whether a number is divisible by a small prime

0046 /// \return true if p is divisible by some prime less than bound.

0047 /// \details TrialDivision() returns <tt>true</tt> if <tt>p</tt> is divisible by some prime less

0048 ///   than <tt>bound</tt>. <tt>bound</tt> should not be greater than the largest entry in the

0049 ///   prime table, which is 32719.

0050 CRYPTOPP_DLL bool CRYPTOPP_API TrialDivision(const Integer &p, unsigned bound);
0051 
0052 /// \brief Tests whether a number is divisible by a small prime

0053 /// \return true if p is NOT divisible by small primes.

0054 /// \details SmallDivisorsTest() returns <tt>true</tt> if <tt>p</tt> is NOT divisible by some

0055 ///   prime less than 32719.

0056 CRYPTOPP_DLL bool CRYPTOPP_API SmallDivisorsTest(const Integer &p);
0057 
0058 /// \brief Determine if a number is probably prime

0059 /// \param n the number to test

0060 /// \param b the base to exponentiate

0061 /// \return true if the number n is probably prime, false otherwise.

0062 /// \details IsFermatProbablePrime raises <tt>b</tt> to the <tt>n-1</tt> power and checks if

0063 ///   the result is congruent to 1 modulo <tt>n</tt>.

0064 /// \details These is no reason to use IsFermatProbablePrime, use IsStrongProbablePrime or

0065 ///   IsStrongLucasProbablePrime instead.

0066 /// \sa IsStrongProbablePrime, IsStrongLucasProbablePrime

0067 CRYPTOPP_DLL bool CRYPTOPP_API IsFermatProbablePrime(const Integer &n, const Integer &b);
0068 
0069 /// \brief Determine if a number is probably prime

0070 /// \param n the number to test

0071 /// \return true if the number n is probably prime, false otherwise.

0072 /// \details These is no reason to use IsLucasProbablePrime, use IsStrongProbablePrime or

0073 ///   IsStrongLucasProbablePrime instead.

0074 /// \sa IsStrongProbablePrime, IsStrongLucasProbablePrime

0075 CRYPTOPP_DLL bool CRYPTOPP_API IsLucasProbablePrime(const Integer &n);
0076 
0077 /// \brief Determine if a number is probably prime

0078 /// \param n the number to test

0079 /// \param b the base to exponentiate

0080 /// \return true if the number n is probably prime, false otherwise.

0081 CRYPTOPP_DLL bool CRYPTOPP_API IsStrongProbablePrime(const Integer &n, const Integer &b);
0082 
0083 /// \brief Determine if a number is probably prime

0084 /// \param n the number to test

0085 /// \return true if the number n is probably prime, false otherwise.

0086 CRYPTOPP_DLL bool CRYPTOPP_API IsStrongLucasProbablePrime(const Integer &n);
0087 
0088 /// \brief Determine if a number is probably prime

0089 /// \param rng a RandomNumberGenerator to produce random material

0090 /// \param n the number to test

0091 /// \param rounds the number of tests to perform

0092 /// \details This is the Rabin-Miller primality test, i.e. repeating the strong probable prime

0093 ///   test for several rounds with random bases

0094 /// \sa <A HREF="https://crypto.stackexchange.com/q/17707/10496">Trial divisions before

0095 ///   Miller-Rabin checks?</A> on Crypto Stack Exchange

0096 CRYPTOPP_DLL bool CRYPTOPP_API RabinMillerTest(RandomNumberGenerator &rng, const Integer &n, unsigned int rounds);
0097 
0098 /// \brief Verifies a number is probably prime

0099 /// \param p a candidate prime to test

0100 /// \return true if p is a probable prime, false otherwise

0101 /// \details IsPrime() is suitable for testing candidate primes when creating them. Internally,

0102 ///   IsPrime() utilizes SmallDivisorsTest(), IsStrongProbablePrime() and IsStrongLucasProbablePrime().

0103 CRYPTOPP_DLL bool CRYPTOPP_API IsPrime(const Integer &p);
0104 
0105 /// \brief Verifies a number is probably prime

0106 /// \param rng a RandomNumberGenerator for randomized testing

0107 /// \param p a candidate prime to test

0108 /// \param level the level of thoroughness of testing

0109 /// \return true if p is a strong probable prime, false otherwise

0110 /// \details VerifyPrime() is suitable for testing candidate primes created by others. Internally,

0111 ///   VerifyPrime() utilizes IsPrime() and one-round RabinMillerTest(). If the candidate passes and

0112 ///   level is greater than 1, then 10 round RabinMillerTest() primality testing is performed.

0113 CRYPTOPP_DLL bool CRYPTOPP_API VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level = 1);
0114 
0115 /// \brief Application callback to signal suitability of a cabdidate prime

0116 class CRYPTOPP_DLL PrimeSelector
0117 {
0118 public:
0119     virtual ~PrimeSelector() {}
0120     const PrimeSelector *GetSelectorPointer() const {return this;}
0121     virtual bool IsAcceptable(const Integer &candidate) const =0;
0122 };
0123 
0124 /// \brief Finds a random prime of special form

0125 /// \param p an Integer reference to receive the prime

0126 /// \param max the maximum value

0127 /// \param equiv the equivalence class based on the parameter mod

0128 /// \param mod the modulus used to reduce the equivalence class

0129 /// \param pSelector pointer to a PrimeSelector function for the application to signal suitability

0130 /// \return true if and only if FirstPrime() finds a prime and returns the prime through p. If FirstPrime()

0131 ///   returns false, then no such prime exists and the value of p is undefined

0132 /// \details FirstPrime() uses a fast sieve to find the first probable prime

0133 ///   in <tt>{x | p<=x<=max and x%mod==equiv}</tt>

0134 CRYPTOPP_DLL bool CRYPTOPP_API FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector);
0135 
0136 CRYPTOPP_DLL unsigned int CRYPTOPP_API PrimeSearchInterval(const Integer &max);
0137 
0138 CRYPTOPP_DLL AlgorithmParameters CRYPTOPP_API MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength);
0139 
0140 // ********** other number theoretic functions ************

0141 
0142 /// \brief Calculate the greatest common divisor

0143 /// \param a the first term

0144 /// \param b the second term

0145 /// \return the greatest common divisor if one exists, 0 otherwise.

0146 inline Integer GCD(const Integer &a, const Integer &b)
0147     {return Integer::Gcd(a,b);}
0148 
0149 /// \brief Determine relative primality

0150 /// \param a the first term

0151 /// \param b the second term

0152 /// \return true if <tt>a</tt> and <tt>b</tt> are relatively prime, false otherwise.

0153 inline bool RelativelyPrime(const Integer &a, const Integer &b)
0154     {return Integer::Gcd(a,b) == Integer::One();}
0155 
0156 /// \brief Calculate the least common multiple

0157 /// \param a the first term

0158 /// \param b the second term

0159 /// \return the least common multiple of <tt>a</tt> and <tt>b</tt>.

0160 inline Integer LCM(const Integer &a, const Integer &b)
0161     {return a/Integer::Gcd(a,b)*b;}
0162 
0163 /// \brief Calculate multiplicative inverse

0164 /// \param a the number to test

0165 /// \param b the modulus

0166 /// \return an Integer <tt>(a ^ -1) % n</tt> or 0 if none exists.

0167 /// \details EuclideanMultiplicativeInverse returns the multiplicative inverse of the Integer

0168 ///   <tt>*a</tt> modulo the Integer <tt>b</tt>. If no Integer exists then Integer 0 is returned.

0169 inline Integer EuclideanMultiplicativeInverse(const Integer &a, const Integer &b)
0170     {return a.InverseMod(b);}
0171 
0172 
0173 /// \brief Chinese Remainder Theorem

0174 /// \param xp the first number, mod p

0175 /// \param p the first prime modulus

0176 /// \param xq the second number, mod q

0177 /// \param q the second prime modulus

0178 /// \param u inverse of p mod q

0179 /// \return the CRT value of the parameters

0180 /// \details CRT uses the Chinese Remainder Theorem to calculate <tt>x</tt> given

0181 ///   <tt>x mod p</tt> and <tt>x mod q</tt>, and <tt>u</tt> the inverse of <tt>p mod q</tt>.

0182 CRYPTOPP_DLL Integer CRYPTOPP_API CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u);
0183 
0184 /// \brief Calculate the Jacobi symbol

0185 /// \param a the first term

0186 /// \param b the second term

0187 /// \return the Jacobi symbol.

0188 /// \details Jacobi symbols are calculated using the following rules:

0189 ///  -# if <tt>b</tt> is prime, then <tt>Jacobi(a, b)</tt>, then return 0

0190 ///  -# if <tt>a%b</tt>==0 AND <tt>a</tt> is quadratic residue <tt>mod b</tt>, then return 1

0191 ///  -# return -1 otherwise

0192 /// \details Refer to a number theory book for what Jacobi symbol means when <tt>b</tt> is not prime.

0193 CRYPTOPP_DLL int CRYPTOPP_API Jacobi(const Integer &a, const Integer &b);
0194 
0195 /// \brief Calculate the Lucas value

0196 /// \return the Lucas value

0197 /// \details Lucas() calculates the Lucas function <tt>V_e(p, 1) mod n</tt>.

0198 CRYPTOPP_DLL Integer CRYPTOPP_API Lucas(const Integer &e, const Integer &p, const Integer &n);
0199 
0200 /// \brief Calculate the inverse Lucas value

0201 /// \return the inverse Lucas value

0202 /// \details InverseLucas() calculates <tt>x</tt> such that <tt>m==Lucas(e, x, p*q)</tt>,

0203 ///   <tt>p q</tt> primes, <tt>u</tt> is inverse of <tt>p mod q</tt>.

0204 CRYPTOPP_DLL Integer CRYPTOPP_API InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u);
0205 
0206 /// \brief Modular multiplication

0207 /// \param x the first term

0208 /// \param y the second term

0209 /// \param m the modulus

0210 /// \return an Integer <tt>(x * y) % m</tt>.

0211 inline Integer ModularMultiplication(const Integer &x, const Integer &y, const Integer &m)
0212     {return a_times_b_mod_c(x, y, m);}
0213 
0214 /// \brief Modular exponentiation

0215 /// \param x the base

0216 /// \param e the exponent

0217 /// \param m the modulus

0218 /// \return an Integer <tt>(a ^ b) % m</tt>.

0219 inline Integer ModularExponentiation(const Integer &x, const Integer &e, const Integer &m)
0220     {return a_exp_b_mod_c(x, e, m);}
0221 
0222 /// \brief Extract a modular square root

0223 /// \param a the number to extract square root

0224 /// \param p the prime modulus

0225 /// \return the modular square root if it exists

0226 /// \details ModularSquareRoot returns <tt>x</tt> such that <tt>x*x%p == a</tt>, <tt>p</tt> prime

0227 CRYPTOPP_DLL Integer CRYPTOPP_API ModularSquareRoot(const Integer &a, const Integer &p);
0228 
0229 /// \brief Extract a modular root

0230 /// \return a modular root if it exists

0231 /// \details ModularRoot returns <tt>x</tt> such that <tt>a==ModularExponentiation(x, e, p*q)</tt>,

0232 ///   <tt>p</tt> <tt>q</tt> primes, and <tt>e</tt> relatively prime to <tt>(p-1)*(q-1)</tt>,

0233 ///   <tt>dp=d%(p-1)</tt>, <tt>dq=d%(q-1)</tt>, (d is inverse of <tt>e mod (p-1)*(q-1)</tt>)

0234 ///   and <tt>u=inverse of p mod q</tt>.

0235 CRYPTOPP_DLL Integer CRYPTOPP_API ModularRoot(const Integer &a, const Integer &dp, const Integer &dq, const Integer &p, const Integer &q, const Integer &u);
0236 
0237 /// \brief Solve a Modular Quadratic Equation

0238 /// \param r1 the first residue

0239 /// \param r2 the second residue

0240 /// \param a the first coefficient

0241 /// \param b the second coefficient

0242 /// \param c the third constant

0243 /// \param p the prime modulus

0244 /// \return true if solutions exist

0245 /// \details SolveModularQuadraticEquation() finds <tt>r1</tt> and <tt>r2</tt> such that <tt>ax^2 +

0246 ///   bx + c == 0 (mod p)</tt> for x in <tt>{r1, r2}</tt>, <tt>p</tt> prime.

0247 CRYPTOPP_DLL bool CRYPTOPP_API SolveModularQuadraticEquation(Integer &r1, Integer &r2, const Integer &a, const Integer &b, const Integer &c, const Integer &p);
0248 
0249 /// \brief Estimate work factor

0250 /// \param bitlength the size of the number, in bits

0251 /// \return the estimated work factor, in operations

0252 /// \details DiscreteLogWorkFactor returns log base 2 of estimated number of operations to

0253 ///   calculate discrete log or factor a number.

0254 CRYPTOPP_DLL unsigned int CRYPTOPP_API DiscreteLogWorkFactor(unsigned int bitlength);
0255 
0256 /// \brief Estimate work factor

0257 /// \param bitlength the size of the number, in bits

0258 /// \return the estimated work factor, in operations

0259 /// \details FactoringWorkFactor returns log base 2 of estimated number of operations to

0260 ///   calculate discrete log or factor a number.

0261 CRYPTOPP_DLL unsigned int CRYPTOPP_API FactoringWorkFactor(unsigned int bitlength);
0262 
0263 // ********************************************************

0264 
0265 /// \brief Generator of prime numbers of special forms

0266 class CRYPTOPP_DLL PrimeAndGenerator
0267 {
0268 public:
0269     /// \brief Construct a PrimeAndGenerator

0270     PrimeAndGenerator() {}
0271 
0272     /// \brief Construct a PrimeAndGenerator

0273     /// \param delta +1 or -1

0274     /// \param rng a RandomNumberGenerator derived class

0275     /// \param pbits the number of bits in the prime p

0276     /// \details PrimeAndGenerator() generates a random prime p of the form <tt>2*q+delta</tt>, where delta is 1 or -1 and q is

0277     ///   also prime. Internally the constructor calls <tt>Generate(delta, rng, pbits, pbits-1)</tt>.

0278     /// \pre <tt>pbits > 5</tt>

0279     /// \warning This PrimeAndGenerator() is slow because primes of this form are harder to find.

0280     PrimeAndGenerator(signed int delta, RandomNumberGenerator &rng, unsigned int pbits)
0281         {Generate(delta, rng, pbits, pbits-1);}
0282 
0283     /// \brief Construct a PrimeAndGenerator

0284     /// \param delta +1 or -1

0285     /// \param rng a RandomNumberGenerator derived class

0286     /// \param pbits the number of bits in the prime p

0287     /// \param qbits the number of bits in the prime q

0288     /// \details PrimeAndGenerator() generates a random prime p of the form <tt>2*r*q+delta</tt>, where q is also prime.

0289     ///    Internally the constructor calls <tt>Generate(delta, rng, pbits, qbits)</tt>.

0290     /// \pre <tt>qbits > 4 && pbits > qbits</tt>

0291     PrimeAndGenerator(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned qbits)
0292         {Generate(delta, rng, pbits, qbits);}
0293 
0294     /// \brief Generate a Prime and Generator

0295     /// \param delta +1 or -1

0296     /// \param rng a RandomNumberGenerator derived class

0297     /// \param pbits the number of bits in the prime p

0298     /// \param qbits the number of bits in the prime q

0299     /// \details Generate() generates a random prime p of the form <tt>2*r*q+delta</tt>, where q is also prime.

0300     void Generate(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned qbits);
0301 
0302     /// \brief Retrieve first prime

0303     /// \return Prime() returns the prime p.

0304     const Integer& Prime() const {return p;}
0305 
0306     /// \brief Retrieve second prime

0307     /// \return SubPrime() returns the prime q.

0308     const Integer& SubPrime() const {return q;}
0309 
0310     /// \brief Retrieve the generator

0311     /// \return Generator() returns the generator g.

0312     const Integer& Generator() const {return g;}
0313 
0314 private:
0315     Integer p, q, g;
0316 };
0317 
0318 NAMESPACE_END
0319 
0320 #endif