//
// LiDIA - a library for computational number theory
//   Copyright (c) 1994, 1995 by the LiDIA Group
//
// File        : poly_multiplier.h
// Author      : Victor Shoup, Thomas Pfahler (TPf)
// Last change : TPf, Feb 29, 1996, initial version
//             

#ifndef LIDIA_POLY_MULTIPLIER__H
#define LIDIA_POLY_MULTIPLIER__H


#ifndef HEADBANGER


#if defined(HAVE_MAC_DIRS) || defined(__MWERKS__)

#include <LiDIA:Fp_polynomial.h>
#include <LiDIA:Fp_polynomial_fft.h>
#include <LiDIA:poly_modulus.h>

#else

#include <LiDIA/Fp_polynomial.h>
#include <LiDIA/Fp_polynomial_fft.h>
#include <LiDIA/poly_modulus.h>

#endif


// If you need to compute a * b % f for a fixed b, but for many a's
// (for example, computing powers of b modulo f), it is
// much more efficient to first build a poly_multiplier B for b,
// and then use the routine below.

class poly_multiplier
{
    const poly_modulus* mod;
//public:
    Fp_polynomial pol_b;
    bool UseFFT;
    fft_rep B1;
    fft_rep B2;

public:
    poly_multiplier() : mod(0)
    { //pol_b.assign_zero(); //modulus not set
    };

    poly_multiplier(const poly_multiplier& B)
    { if (B.mod != 0) build(B.multiplier(), *mod); }

    poly_multiplier(const Fp_polynomial& b, const poly_modulus& F)
    { build(b, F); }

    void build(const Fp_polynomial& b, const poly_modulus& F);

    poly_multiplier & operator =(const poly_multiplier &B)
    {
	if (B.mod != 0) build(B.multiplier(), *B.mod);
	return *this;
    }

    inline bool uses(const poly_modulus& F) const
    { return (&F == mod); }

    inline const Fp_polynomial& multiplier() const
    { return pol_b; }

    friend void multiply(Fp_polynomial& x, const Fp_polynomial& a, 
			const poly_multiplier& B, const poly_modulus& F);
    // x = (a * b) % f


    friend void update_map(base_vector<bigint>& x, const base_vector<bigint>& a,
			const poly_multiplier& B, const poly_modulus& F);
    //see compose.c
    /* computes (a, b), (a, (b*X)%f), ..., (a, (b*X^{n-1})%f),
	where ( , ) denotes the vector inner product.
	This is really a "transposed" MulMod by B.
    */

};



#endif

#endif


