You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							90 lines
						
					
					
						
							3.2 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							90 lines
						
					
					
						
							3.2 KiB
						
					
					
				
								// Number theoretic operations.
							 | 
						|
								
							 | 
						|
								#ifndef _CL_NUMTHEORY_H
							 | 
						|
								#define _CL_NUMTHEORY_H
							 | 
						|
								
							 | 
						|
								#include "cln/number.h"
							 | 
						|
								#include "cln/integer.h"
							 | 
						|
								#include "cln/modinteger.h"
							 | 
						|
								#include "cln/condition.h"
							 | 
						|
								
							 | 
						|
								namespace cln {
							 | 
						|
								
							 | 
						|
								// jacobi(a,b) returns the Jacobi symbol
							 | 
						|
								//                       (  a  )
							 | 
						|
								//                       ( --- )
							 | 
						|
								//                       (  b  )
							 | 
						|
								// a, b must be integers, b > 0, b odd. The result is 0 iff gcd(a,b) > 1.
							 | 
						|
								  extern int jacobi (sint32 a, sint32 b);
							 | 
						|
								  extern int jacobi (const cl_I& a, const cl_I& b);
							 | 
						|
								
							 | 
						|
								// isprobprime(n), n integer > 0,
							 | 
						|
								// returns true when n is probably prime.
							 | 
						|
								// This is pretty quick, but no caching is done.
							 | 
						|
								  extern cl_boolean isprobprime (const cl_I& n);
							 | 
						|
								
							 | 
						|
								// nextprobprime(x) returns the smallest probable prime >= x.
							 | 
						|
								  extern const cl_I nextprobprime (const cl_R& x);
							 | 
						|
								
							 | 
						|
								#if 0
							 | 
						|
								// primitive_root(R) of R = Z/pZ, with p a probable prime,
							 | 
						|
								// returns
							 | 
						|
								//   either a generator of (Z/pZ)^*, assuming p is prime, or
							 | 
						|
								//   a proof that p is not prime, maybe even a non-trivial factor of p.
							 | 
						|
								struct primitive_root_t {
							 | 
						|
									cl_composite_condition* condition;
							 | 
						|
									cl_MI gen;
							 | 
						|
									// Constructors.
							 | 
						|
									primitive_root_t (cl_composite_condition* c) : condition (c) {}
							 | 
						|
									primitive_root_t (const cl_MI& g) : condition (NULL), gen (g) {}
							 | 
						|
								};
							 | 
						|
								extern const primitive_root_t primitive_root (const cl_modint_ring& R);
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								// sqrt_mod_p(R,x) where x is an element of R = Z/pZ, with p a probable prime,
							 | 
						|
								// returns
							 | 
						|
								//   either the square roots of x in R, assuming p is prime, or
							 | 
						|
								//   a proof that p is not prime, maybe even a non-trivial factor of p.
							 | 
						|
								struct sqrt_mod_p_t {
							 | 
						|
									cl_composite_condition* condition;
							 | 
						|
									// If no condition:
							 | 
						|
									int solutions; // 0,1,2
							 | 
						|
									cl_I factor; // zero or non-trivial factor of p
							 | 
						|
									cl_MI solution[2]; // max. 2 solutions
							 | 
						|
									// Constructors.
							 | 
						|
									sqrt_mod_p_t () {}
							 | 
						|
									sqrt_mod_p_t (cl_composite_condition* c) : condition (c) {}
							 | 
						|
									sqrt_mod_p_t (int s) : condition (NULL), solutions (s) {}
							 | 
						|
									sqrt_mod_p_t (int s, const cl_MI& x0) : condition (NULL), solutions (s)
							 | 
						|
										{ solution[0] = x0; }
							 | 
						|
									sqrt_mod_p_t (int s, const cl_MI& x0, const cl_MI& x1) : condition (NULL), solutions (s)
							 | 
						|
										{ solution[0] = x0; solution[1] = x1; }
							 | 
						|
								};
							 | 
						|
								extern const sqrt_mod_p_t sqrt_mod_p (const cl_modint_ring& R, const cl_MI& x);
							 | 
						|
								
							 | 
						|
								// cornacchia1(d,p) solves x^2 + d*y^2 = p.
							 | 
						|
								// cornacchia4(d,p) solves x^2 + d*y^2 = 4*p.
							 | 
						|
								// d is an integer > 0, p is a probable prime.
							 | 
						|
								// It returns
							 | 
						|
								//   either a nonnegative solution (x,y), if it exists, assuming p is prime, or
							 | 
						|
								//   a proof that p is not prime, maybe even a non-trivial factor of p.
							 | 
						|
								struct cornacchia_t {
							 | 
						|
									cl_composite_condition* condition;
							 | 
						|
									// If no condition:
							 | 
						|
									int solutions; // 0,1
							 | 
						|
									// If solutions=1 and d > 4 (d > 64 for cornacchia4):
							 | 
						|
									// All solutions are (x,y), (-x,y), (x,-y), (-x,-y).
							 | 
						|
									cl_I solution_x; // x >= 0
							 | 
						|
									cl_I solution_y; // y >= 0
							 | 
						|
									// Constructors.
							 | 
						|
									cornacchia_t () {}
							 | 
						|
									cornacchia_t (cl_composite_condition* c) : condition (c) {}
							 | 
						|
									cornacchia_t (int s) : condition (NULL), solutions (s) {}
							 | 
						|
									cornacchia_t (int s, const cl_I& x, const cl_I& y) : condition (NULL), solutions (s), solution_x (x), solution_y (y) {}
							 | 
						|
								};
							 | 
						|
								extern const cornacchia_t cornacchia1 (const cl_I& d, const cl_I& p);
							 | 
						|
								extern const cornacchia_t cornacchia4 (const cl_I& d, const cl_I& p);
							 | 
						|
								
							 | 
						|
								}  // namespace cln
							 | 
						|
								
							 | 
						|
								#endif /* _CL_NUMTHEORY_H */
							 |