Line | Count | Source (jump to first uncovered line) |
1 | | // nbtheory.h - originally written and placed in the public domain by Wei Dai |
2 | | |
3 | | /// \file nbtheory.h |
4 | | /// \brief Classes and functions for number theoretic operations |
5 | | |
6 | | #ifndef CRYPTOPP_NBTHEORY_H |
7 | | #define CRYPTOPP_NBTHEORY_H |
8 | | |
9 | | #include "cryptlib.h" |
10 | | #include "integer.h" |
11 | | #include "algparam.h" |
12 | | |
13 | | NAMESPACE_BEGIN(CryptoPP) |
14 | | |
15 | | /// \brief The Small Prime table |
16 | | /// \param size number of elements in the table |
17 | | /// \return prime table with /p size elements |
18 | | /// \details GetPrimeTable() obtains pointer to small prime table and provides the size of the table. |
19 | | /// /p size is an out parameter. |
20 | | CRYPTOPP_DLL const word16 * CRYPTOPP_API GetPrimeTable(unsigned int &size); |
21 | | |
22 | | // ************ primality testing **************** |
23 | | |
24 | | /// \brief Generates a provable prime |
25 | | /// \param rng a RandomNumberGenerator to produce random material |
26 | | /// \param bits the number of bits in the prime number |
27 | | /// \return Integer() meeting Maurer's tests for primality |
28 | | CRYPTOPP_DLL Integer CRYPTOPP_API MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits); |
29 | | |
30 | | /// \brief Generates a provable prime |
31 | | /// \param rng a RandomNumberGenerator to produce random material |
32 | | /// \param bits the number of bits in the prime number |
33 | | /// \return Integer() meeting Mihailescu's tests for primality |
34 | | /// \details Mihailescu's methods performs a search using algorithmic progressions. |
35 | | CRYPTOPP_DLL Integer CRYPTOPP_API MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int bits); |
36 | | |
37 | | /// \brief Tests whether a number is a small prime |
38 | | /// \param p a candidate prime to test |
39 | | /// \return true if p is a small prime, false otherwise |
40 | | /// \details Internally, the library maintains a table of the first 32719 prime numbers |
41 | | /// in sorted order. IsSmallPrime searches the table and returns true if p is |
42 | | /// in the table. |
43 | | CRYPTOPP_DLL bool CRYPTOPP_API IsSmallPrime(const Integer &p); |
44 | | |
45 | | /// \brief Tests whether a number is divisible by a small prime |
46 | | /// \return true if p is divisible by some prime less than bound. |
47 | | /// \details TrialDivision() returns <tt>true</tt> if <tt>p</tt> is divisible by some prime less |
48 | | /// than <tt>bound</tt>. <tt>bound</tt> should not be greater than the largest entry in the |
49 | | /// prime table, which is 32719. |
50 | | CRYPTOPP_DLL bool CRYPTOPP_API TrialDivision(const Integer &p, unsigned bound); |
51 | | |
52 | | /// \brief Tests whether a number is divisible by a small prime |
53 | | /// \return true if p is NOT divisible by small primes. |
54 | | /// \details SmallDivisorsTest() returns <tt>true</tt> if <tt>p</tt> is NOT divisible by some |
55 | | /// prime less than 32719. |
56 | | CRYPTOPP_DLL bool CRYPTOPP_API SmallDivisorsTest(const Integer &p); |
57 | | |
58 | | /// \brief Determine if a number is probably prime |
59 | | /// \param n the number to test |
60 | | /// \param b the base to exponentiate |
61 | | /// \return true if the number n is probably prime, false otherwise. |
62 | | /// \details IsFermatProbablePrime raises <tt>b</tt> to the <tt>n-1</tt> power and checks if |
63 | | /// the result is congruent to 1 modulo <tt>n</tt>. |
64 | | /// \details These is no reason to use IsFermatProbablePrime, use IsStrongProbablePrime or |
65 | | /// IsStrongLucasProbablePrime instead. |
66 | | /// \sa IsStrongProbablePrime, IsStrongLucasProbablePrime |
67 | | CRYPTOPP_DLL bool CRYPTOPP_API IsFermatProbablePrime(const Integer &n, const Integer &b); |
68 | | |
69 | | /// \brief Determine if a number is probably prime |
70 | | /// \param n the number to test |
71 | | /// \return true if the number n is probably prime, false otherwise. |
72 | | /// \details These is no reason to use IsLucasProbablePrime, use IsStrongProbablePrime or |
73 | | /// IsStrongLucasProbablePrime instead. |
74 | | /// \sa IsStrongProbablePrime, IsStrongLucasProbablePrime |
75 | | CRYPTOPP_DLL bool CRYPTOPP_API IsLucasProbablePrime(const Integer &n); |
76 | | |
77 | | /// \brief Determine if a number is probably prime |
78 | | /// \param n the number to test |
79 | | /// \param b the base to exponentiate |
80 | | /// \return true if the number n is probably prime, false otherwise. |
81 | | CRYPTOPP_DLL bool CRYPTOPP_API IsStrongProbablePrime(const Integer &n, const Integer &b); |
82 | | |
83 | | /// \brief Determine if a number is probably prime |
84 | | /// \param n the number to test |
85 | | /// \return true if the number n is probably prime, false otherwise. |
86 | | CRYPTOPP_DLL bool CRYPTOPP_API IsStrongLucasProbablePrime(const Integer &n); |
87 | | |
88 | | /// \brief Determine if a number is probably prime |
89 | | /// \param rng a RandomNumberGenerator to produce random material |
90 | | /// \param n the number to test |
91 | | /// \param rounds the number of tests to perform |
92 | | /// \details This is the Rabin-Miller primality test, i.e. repeating the strong probable prime |
93 | | /// test for several rounds with random bases |
94 | | /// \sa <A HREF="https://crypto.stackexchange.com/q/17707/10496">Trial divisions before |
95 | | /// Miller-Rabin checks?</A> on Crypto Stack Exchange |
96 | | CRYPTOPP_DLL bool CRYPTOPP_API RabinMillerTest(RandomNumberGenerator &rng, const Integer &n, unsigned int rounds); |
97 | | |
98 | | /// \brief Verifies a number is probably prime |
99 | | /// \param p a candidate prime to test |
100 | | /// \return true if p is a probable prime, false otherwise |
101 | | /// \details IsPrime() is suitable for testing candidate primes when creating them. Internally, |
102 | | /// IsPrime() utilizes SmallDivisorsTest(), IsStrongProbablePrime() and IsStrongLucasProbablePrime(). |
103 | | CRYPTOPP_DLL bool CRYPTOPP_API IsPrime(const Integer &p); |
104 | | |
105 | | /// \brief Verifies a number is probably prime |
106 | | /// \param rng a RandomNumberGenerator for randomized testing |
107 | | /// \param p a candidate prime to test |
108 | | /// \param level the level of thoroughness of testing |
109 | | /// \return true if p is a strong probable prime, false otherwise |
110 | | /// \details VerifyPrime() is suitable for testing candidate primes created by others. Internally, |
111 | | /// VerifyPrime() utilizes IsPrime() and one-round RabinMillerTest(). If the candidate passes and |
112 | | /// level is greater than 1, then 10 round RabinMillerTest() primality testing is performed. |
113 | | CRYPTOPP_DLL bool CRYPTOPP_API VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level = 1); |
114 | | |
115 | | /// \brief Application callback to signal suitability of a candidate prime |
116 | | class CRYPTOPP_DLL PrimeSelector |
117 | | { |
118 | | public: |
119 | 0 | virtual ~PrimeSelector() {} |
120 | 0 | const PrimeSelector *GetSelectorPointer() const {return this;} |
121 | | virtual bool IsAcceptable(const Integer &candidate) const =0; |
122 | | }; |
123 | | |
124 | | /// \brief Finds a random prime of special form |
125 | | /// \param p an Integer reference to receive the prime |
126 | | /// \param max the maximum value |
127 | | /// \param equiv the equivalence class based on the parameter mod |
128 | | /// \param mod the modulus used to reduce the equivalence class |
129 | | /// \param pSelector pointer to a PrimeSelector function for the application to signal suitability |
130 | | /// \return true if and only if FirstPrime() finds a prime and returns the prime through p. If FirstPrime() |
131 | | /// returns false, then no such prime exists and the value of p is undefined |
132 | | /// \details FirstPrime() uses a fast sieve to find the first probable prime |
133 | | /// in <tt>{x | p<=x<=max and x%mod==equiv}</tt> |
134 | | CRYPTOPP_DLL bool CRYPTOPP_API FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector); |
135 | | |
136 | | CRYPTOPP_DLL unsigned int CRYPTOPP_API PrimeSearchInterval(const Integer &max); |
137 | | |
138 | | CRYPTOPP_DLL AlgorithmParameters CRYPTOPP_API MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength); |
139 | | |
140 | | // ********** other number theoretic functions ************ |
141 | | |
142 | | /// \brief Calculate the greatest common divisor |
143 | | /// \param a the first term |
144 | | /// \param b the second term |
145 | | /// \return the greatest common divisor if one exists, 0 otherwise. |
146 | | inline Integer GCD(const Integer &a, const Integer &b) |
147 | 458 | {return Integer::Gcd(a,b);} |
148 | | |
149 | | /// \brief Determine relative primality |
150 | | /// \param a the first term |
151 | | /// \param b the second term |
152 | | /// \return true if <tt>a</tt> and <tt>b</tt> are relatively prime, false otherwise. |
153 | | inline bool RelativelyPrime(const Integer &a, const Integer &b) |
154 | 0 | {return Integer::Gcd(a,b) == Integer::One();} |
155 | | |
156 | | /// \brief Calculate the least common multiple |
157 | | /// \param a the first term |
158 | | /// \param b the second term |
159 | | /// \return the least common multiple of <tt>a</tt> and <tt>b</tt>. |
160 | | inline Integer LCM(const Integer &a, const Integer &b) |
161 | 307 | {return a/Integer::Gcd(a,b)*b;} |
162 | | |
163 | | /// \brief Calculate multiplicative inverse |
164 | | /// \param a the number to test |
165 | | /// \param b the modulus |
166 | | /// \return an Integer <tt>(a ^ -1) % n</tt> or 0 if none exists. |
167 | | /// \details EuclideanMultiplicativeInverse returns the multiplicative inverse of the Integer |
168 | | /// <tt>*a</tt> modulo the Integer <tt>b</tt>. If no Integer exists then Integer 0 is returned. |
169 | | inline Integer EuclideanMultiplicativeInverse(const Integer &a, const Integer &b) |
170 | 0 | {return a.InverseMod(b);} |
171 | | |
172 | | |
173 | | /// \brief Chinese Remainder Theorem |
174 | | /// \param xp the first number, mod p |
175 | | /// \param p the first prime modulus |
176 | | /// \param xq the second number, mod q |
177 | | /// \param q the second prime modulus |
178 | | /// \param u inverse of p mod q |
179 | | /// \return the CRT value of the parameters |
180 | | /// \details CRT uses the Chinese Remainder Theorem to calculate <tt>x</tt> given |
181 | | /// <tt>x mod p</tt> and <tt>x mod q</tt>, and <tt>u</tt> the inverse of <tt>p mod q</tt>. |
182 | | CRYPTOPP_DLL Integer CRYPTOPP_API CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u); |
183 | | |
184 | | /// \brief Calculate the Jacobi symbol |
185 | | /// \param a the first term |
186 | | /// \param b the second term |
187 | | /// \return the Jacobi symbol. |
188 | | /// \details Jacobi symbols are calculated using the following rules: |
189 | | /// -# if <tt>b</tt> is prime, then <tt>Jacobi(a, b)</tt>, then return 0 |
190 | | /// -# if <tt>a%b</tt>==0 AND <tt>a</tt> is quadratic residue <tt>mod b</tt>, then return 1 |
191 | | /// -# return -1 otherwise |
192 | | /// \details Refer to a number theory book for what Jacobi symbol means when <tt>b</tt> is not prime. |
193 | | CRYPTOPP_DLL int CRYPTOPP_API Jacobi(const Integer &a, const Integer &b); |
194 | | |
195 | | /// \brief Calculate the Lucas value |
196 | | /// \return the Lucas value |
197 | | /// \details Lucas() calculates the Lucas function <tt>V_e(p, 1) mod n</tt>. |
198 | | CRYPTOPP_DLL Integer CRYPTOPP_API Lucas(const Integer &e, const Integer &p, const Integer &n); |
199 | | |
200 | | /// \brief Calculate the inverse Lucas value |
201 | | /// \return the inverse Lucas value |
202 | | /// \details InverseLucas() calculates <tt>x</tt> such that <tt>m==Lucas(e, x, p*q)</tt>, |
203 | | /// <tt>p q</tt> primes, <tt>u</tt> is inverse of <tt>p mod q</tt>. |
204 | | CRYPTOPP_DLL Integer CRYPTOPP_API InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u); |
205 | | |
206 | | /// \brief Modular multiplication |
207 | | /// \param x the first term |
208 | | /// \param y the second term |
209 | | /// \param m the modulus |
210 | | /// \return an Integer <tt>(x * y) % m</tt>. |
211 | | inline Integer ModularMultiplication(const Integer &x, const Integer &y, const Integer &m) |
212 | 0 | {return a_times_b_mod_c(x, y, m);} |
213 | | |
214 | | /// \brief Modular exponentiation |
215 | | /// \param x the base |
216 | | /// \param e the exponent |
217 | | /// \param m the modulus |
218 | | /// \return an Integer <tt>(a ^ b) % m</tt>. |
219 | | inline Integer ModularExponentiation(const Integer &x, const Integer &e, const Integer &m) |
220 | 0 | {return a_exp_b_mod_c(x, e, m);} |
221 | | |
222 | | /// \brief Extract a modular square root |
223 | | /// \param a the number to extract square root |
224 | | /// \param p the prime modulus |
225 | | /// \return the modular square root if it exists |
226 | | /// \details ModularSquareRoot returns <tt>x</tt> such that <tt>x*x%p == a</tt>, <tt>p</tt> prime |
227 | | CRYPTOPP_DLL Integer CRYPTOPP_API ModularSquareRoot(const Integer &a, const Integer &p); |
228 | | |
229 | | /// \brief Extract a modular root |
230 | | /// \return a modular root if it exists |
231 | | /// \details ModularRoot returns <tt>x</tt> such that <tt>a==ModularExponentiation(x, e, p*q)</tt>, |
232 | | /// <tt>p</tt> <tt>q</tt> primes, and <tt>e</tt> relatively prime to <tt>(p-1)*(q-1)</tt>, |
233 | | /// <tt>dp=d%(p-1)</tt>, <tt>dq=d%(q-1)</tt>, (d is inverse of <tt>e mod (p-1)*(q-1)</tt>) |
234 | | /// and <tt>u=inverse of p mod q</tt>. |
235 | | CRYPTOPP_DLL Integer CRYPTOPP_API ModularRoot(const Integer &a, const Integer &dp, const Integer &dq, const Integer &p, const Integer &q, const Integer &u); |
236 | | |
237 | | /// \brief Solve a Modular Quadratic Equation |
238 | | /// \param r1 the first residue |
239 | | /// \param r2 the second residue |
240 | | /// \param a the first coefficient |
241 | | /// \param b the second coefficient |
242 | | /// \param c the third constant |
243 | | /// \param p the prime modulus |
244 | | /// \return true if solutions exist |
245 | | /// \details SolveModularQuadraticEquation() finds <tt>r1</tt> and <tt>r2</tt> such that <tt>ax^2 + |
246 | | /// bx + c == 0 (mod p)</tt> for x in <tt>{r1, r2}</tt>, <tt>p</tt> prime. |
247 | | CRYPTOPP_DLL bool CRYPTOPP_API SolveModularQuadraticEquation(Integer &r1, Integer &r2, const Integer &a, const Integer &b, const Integer &c, const Integer &p); |
248 | | |
249 | | /// \brief Estimate work factor |
250 | | /// \param bitlength the size of the number, in bits |
251 | | /// \return the estimated work factor, in operations |
252 | | /// \details DiscreteLogWorkFactor returns log base 2 of estimated number of operations to |
253 | | /// calculate discrete log or factor a number. |
254 | | CRYPTOPP_DLL unsigned int CRYPTOPP_API DiscreteLogWorkFactor(unsigned int bitlength); |
255 | | |
256 | | /// \brief Estimate work factor |
257 | | /// \param bitlength the size of the number, in bits |
258 | | /// \return the estimated work factor, in operations |
259 | | /// \details FactoringWorkFactor returns log base 2 of estimated number of operations to |
260 | | /// calculate discrete log or factor a number. |
261 | | CRYPTOPP_DLL unsigned int CRYPTOPP_API FactoringWorkFactor(unsigned int bitlength); |
262 | | |
263 | | // ******************************************************** |
264 | | |
265 | | /// \brief Generator of prime numbers of special forms |
266 | | class CRYPTOPP_DLL PrimeAndGenerator |
267 | | { |
268 | | public: |
269 | | /// \brief Construct a PrimeAndGenerator |
270 | 0 | PrimeAndGenerator() {} |
271 | | |
272 | | /// \brief Construct a PrimeAndGenerator |
273 | | /// \param delta +1 or -1 |
274 | | /// \param rng a RandomNumberGenerator derived class |
275 | | /// \param pbits the number of bits in the prime p |
276 | | /// \details PrimeAndGenerator() generates a random prime p of the form <tt>2*q+delta</tt>, where delta is 1 or -1 and q is |
277 | | /// also prime. Internally the constructor calls <tt>Generate(delta, rng, pbits, pbits-1)</tt>. |
278 | | /// \pre <tt>pbits > 5</tt> |
279 | | /// \warning This PrimeAndGenerator() is slow because primes of this form are harder to find. |
280 | | PrimeAndGenerator(signed int delta, RandomNumberGenerator &rng, unsigned int pbits) |
281 | 0 | {Generate(delta, rng, pbits, pbits-1);} |
282 | | |
283 | | /// \brief Construct a PrimeAndGenerator |
284 | | /// \param delta +1 or -1 |
285 | | /// \param rng a RandomNumberGenerator derived class |
286 | | /// \param pbits the number of bits in the prime p |
287 | | /// \param qbits the number of bits in the prime q |
288 | | /// \details PrimeAndGenerator() generates a random prime p of the form <tt>2*r*q+delta</tt>, where q is also prime. |
289 | | /// Internally the constructor calls <tt>Generate(delta, rng, pbits, qbits)</tt>. |
290 | | /// \pre <tt>qbits > 4 && pbits > qbits</tt> |
291 | | PrimeAndGenerator(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned qbits) |
292 | 0 | {Generate(delta, rng, pbits, qbits);} |
293 | | |
294 | | /// \brief Generate a Prime and Generator |
295 | | /// \param delta +1 or -1 |
296 | | /// \param rng a RandomNumberGenerator derived class |
297 | | /// \param pbits the number of bits in the prime p |
298 | | /// \param qbits the number of bits in the prime q |
299 | | /// \details Generate() generates a random prime p of the form <tt>2*r*q+delta</tt>, where q is also prime. |
300 | | void Generate(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned qbits); |
301 | | |
302 | | /// \brief Retrieve first prime |
303 | | /// \return Prime() returns the prime p. |
304 | 0 | const Integer& Prime() const {return p;} |
305 | | |
306 | | /// \brief Retrieve second prime |
307 | | /// \return SubPrime() returns the prime q. |
308 | 0 | const Integer& SubPrime() const {return q;} |
309 | | |
310 | | /// \brief Retrieve the generator |
311 | | /// \return Generator() returns the generator g. |
312 | 0 | const Integer& Generator() const {return g;} |
313 | | |
314 | | private: |
315 | | Integer p, q, g; |
316 | | }; |
317 | | |
318 | | NAMESPACE_END |
319 | | |
320 | | #endif |