//
// LMath.hxx
//
// some basic number theoretical algorithms
//
// Copyright (C) 1996-7 by Leonard Janke (janke@unixg.ubc.ca)

#ifndef _LMATH_HXX
#define _LMATH_HXX

#include <linteger/linteger.hxx>
#include <prng/prng.hxx>

class LMath
{
public:
  static void LongDivide(const LInteger& dividend, const LInteger& divisor, 
			 LInteger& quotient, LInteger& remainder);
  static LInteger Sqrt(const LInteger& n);

  static LInteger ModExp(const LInteger& g, const LInteger& x, 
			 const LInteger& n);
  static LInteger CRTModExp(const LInteger& g, const LInteger& x, 
			    const LInteger& p, const LInteger& q);

  static LInteger GCD(const LInteger& x, const LInteger& y);
  static LInteger ExtendedEuclid(const LInteger& x, const LInteger& y, 
                                 LInteger& u, LInteger& v);
  static LInteger InvertUnit(const LInteger& x, const LInteger& n);
  static LInteger ChineseRemainderTheorem(const LInteger& x_p, 
                                          const LInteger& p,
					  const LInteger& x_q,
					  const LInteger& q);

  static int Composite(const LInteger& x, PRNG& prng);
  static LInteger RandomProbablePrime(const int numBits, PRNG& prng, 
				      int (*PreProcess)(LInteger&)=NULL,
				      const int fewerBits=0, 
				      const int RabinMillerIterations=20);
};

#endif
