
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%  polymodulus.tex       LiDIA documentation
%%
%%  This file contains the documentation of the class poly_modulus
%%
%%  Copyright   (c)   1996   by  LiDIA-Group 
%%
%%  Authors: Thomas Pfahler
%%

\begin{lidia_man}
\markright{\BF{poly\_modulus, poly\_multiplier}}

\NAME
	\BF{poly\_modulus}  \DOTFILL  class for efficient computations modulo\\
		polynomials over finite prime fields \\
	\BF{poly\_multiplier}  \DOTFILL  class for efficient multiplications modulo\\
		polynomials over finite prime fields


\ABSTRACT
	If you need to do a lot of arithmetic modulo a fixed \BF{Fp\_polynomial} 
	\MATH{f}, build a \BF{poly\_modulus} \MATH{F} for \MATH{f}. This 
	pre-computes information about \MATH{f} that speeds up the computation 
	a great deal, especially for large polynomials.

	If you need to compute the product \MATH{a \CDOT b \pmod{f}} for a fixed 
	\BF{Fp\_polynomial} \MATH{b}, but for many \BF{Fp\_polynomial}s \MATH{a} 
	(for example, when computing powers of \MATH{b} modulo \MATH{f}),
	it is much more efficient to first build a \BF{poly\_multiplier} \MATH{B}
	for \MATH{b}, and then use the multiplication routine below.


\DESCRIPTION

	The pre-computations for variables of type \BF{poly\_modulus} as well 
	as for variables of type \BF{poly\_multiplier} consist of evaluating 
	FFT-representations. For further description, see \cite{ShoupGF}.
	However, if the degree of the polynomials involved is small,
	pre-computations are not necessary. In this case, arithmetic with
	\BF{poly\_modulus} or \BF{poly\_multiplier} is not faster than
	modular arithmetic without pre-conditioning.

\bigskip

\CONS

\fcode{ct}{poly\_modulus}{}{
	no initialization is done; you must call the member--function \TT{build} 
	(see below) before using this \BF{poly\_modulus} in one of the arithmetical
	functions.}

\fcode{ct}{poly\_modulus}{const Fp\_polynomial \& f}{
    initializes for computations modulo \MATH{f}.}

\fcode{dt}{\MATH{\sim}poly\_modulus}{}{}

\bigskip

\fcode{ct}{poly\_multiplier}{}{
  	no initialization is done. The member--function \TT{build} (see below) must be called
	before this instance can be used for multiplications.}

\fcode{ct}{poly\_multiplier}{const Fp\_polynomial \& b\k const poly\_modulus \& F}{
  	initializes for multiplications with \MATH{b} modulo \MATH{F.modulus()}.}

\fcode{dt}{\MATH{\sim}poly\_multiplier}{}{}


\BASIC

	Let \MATH{F} be of type \BF{poly\_modulus}.
	Let \MATH{B} be of type \BF{poly\_multiplier}.

\fcode{void }{F.build}{const Fp\_polynomial \& f}{
  	initializes for computations modulo \MATH{f}.}

\fcode{void }{B.build}{const Fp\_polynomial \& b\k const poly\_modulus \& F}{
  	initializes for multiplications with \MATH{b} modulo \MATH{F.modulus()}.\\
	If \MATH{b.degree \ge F.modulus().degree()}, the lidia\_error\_handler is 
	invoked.}


\ACCS
	
	Let \MATH{F} be of type \BF{poly\_modulus}.
	Let \MATH{B} be of type \BF{poly\_multiplier}.

\cfcode{const Fp\_polynomial \& }{F.modulus}{}{
  	returns a constant reference to the polynomial for which \MATH{F}
	was build.}

\cfcode{const Fp\_polynomial \& }{B.multiplier}{}{
  	returns a constant reference to the polynomial for which \MATH{B}
	was build.}


\ARTH

	As described in the section \BF{Fp\_polynomial}, each polynomial has
	its own modulus \MATH{p} of type \BF{bigint}. The same is true for
	\BF{poly\_modulus} and \BF{poly\_multiplier} for they are only
	additional representations of polynomials over finite prime fields.\\
	Therefore, if the moduli of the ``const'' arguments are not the same,
	the lidia\_error\_handler is invoked.\\
	The ``resulting'' polynomial receives the modulus of the ``input'' 
	polynomials.

\medskip


\fcode{void }{remainder}{Fp\_polynomial \& g\k const Fp\_polynomial \& a\k const poly\_modulus \& F}{
  	\MATH{ g \equiv a \pmod{F.modulusl()}}.\\
	No restrictions on \MATH{a.degree()}.}

\fcode{void }{multiply}{Fp\_polynomial \& g\k const Fp\_polynomial \& a\k const Fp\_polynomial \& b\k const poly\_modulus \& F}{
	\MATH{g \equiv a \CDOT b \pmod{F.modulus()}}.\\
	If \MATH{a.degree()} or \MATH{b.degree() \ge F.modulus().degree()},
	the lidia\_error\_handler is invoked.}

\fcode{void }{multiply}{Fp\_polynomial \& g\k const Fp\_polynomial \& a\k const
poly\_multiplier \& B\k const poly\_modulus \& F}{
	\MATH{g \equiv a \CDOT B.multiplier() \pmod{F.modulus()}}.\\
	If \MATH{B} is not initialized with \MATH{F} or \MATH{a.degree() \ge 
	F.modulus().degree()}, the lidia\_error\_handler is invoked.}
	  
\fcode{void }{square}{Fp\_polynomial \& g\k const Fp\_polynomial \& a\k const poly\_modulus \& F}{
	\MATH{g \equiv a^2 \pmod{F.modulus()}}.\\
	If \MATH{a.degree() \ge F.modulus().degree()}, the lidia\_error\_handler 
	is invoked.}

\fcode{void }{power}{Fp\_polynomial \& g\k const Fp\_polynomial \& a\k const bigint \& e\k const poly\_modulus \& F}{
	\MATH{g \equiv a^e \pmod{F.modulus()}}.\\
	If \MATH{e < 0}, the lidia\_error\_handler is invoked.}

\fcode{void }{power\_x}{Fp\_polynomial \& g\k const bigint \& e\k const poly\_modulus \& F}{
	\MATH{g \equiv x^e \pmod{F.modulus()}}.\\
	If \MATH{e < 0}, the lidia\_error\_handler is invoked.}

\fcode{void }{power\_x\_plus\_a}{Fp\_polynomial \& g\k const bigint \& a\k const bigint \& e\k const poly\_modulus \& F}{
	\MATH{g \equiv (x + a)^e \pmod{F.modulus()}}.\\
	If \MATH{e < 0}, the lidia\_error\_handler is invoked.}


\medskip

\HIGH
\fcode{void }{min\_poly}{Fp\_polynomial \& h\k const Fp\_polynomial \& g\k lidia\_size\_t m\k const poly\_modulus \& F}{
        computes the monic minimal polynomial \MATH{h} of
        (\MATH{g} mod \MATH{F.modulus()}).
        \MATH{m} is an upper bound on the degree of the minimal polynomial.
        The algorithm is probabilistic, always returns a divisor of
        the minimal polynomial, and returns a proper divisor with
        probability at most \MATH{m/g.modulus()}.}

\fcode{void }{checked\_min\_poly}{Fp\_polynomial \& h\k const Fp\_polynomial \& g\k lidia\_size\_t m\k const poly\_modulus \& F}{
        same as \MATH{min\_poly}, but guarantees that result is correct.}

\fcode{void }{irred\_poly}{Fp\_polynomial \& h\k const Fp\_polynomial \& g\k lidia\_size\_t m\k const poly\_modulus \& F}{
        same as \MATH{min\_poly}, but assumes that \MATH{F.modulus()}
        is irreducible (or at least that the minimal polynomial of \MATH{g} is
        itself irreducible).\\
        The algorithm is deterministic (and hence is always correct).}

\fcode{void }{compose}{Fp\_polynomial \& c\k const Fp\_polynomial \& g\k const Fp\_polynomial \& h\k const poly\_modulus \& F}{
	\MATH{c = g(h)} modulo \MATH{F.modulus()}.}


\fcode{void }{trace\_map}{Fp\_polynomial \& w\k const Fp\_polynomial \& a\k
lidia\_size\_t d\k const poly\_modulus \& F\k const Fp\_polynomial \& b}{
	\MATH{w = \SUM{i=0}{d-1}{a^{q^i}}} mod \MATH{F.modulus()}.\\
	It is assumed that \MATH{d \GE 0}, \MATH{q} is a power of
	\MATH{F.modulus().modulus()}, and \MATH{b = x^q} modulo
	\MATH{F.modulus()}, otherwise the behaviour of this function is
	undefined.}
		  

\fcode{void }{power\_compose}{Fp\_polynomial \& w\k const Fp\_polynomial \& b\k lidia\_size\_t d\k const poly\_modulus \& F}{
	\MATH{w = x^{q^d}} mod \MATH{F.modulus()}.\\
	It is assumed that \MATH{d \GE 0}, \MATH{q} is a power of
	\MATH{F.modulus().modulus()}, and \MATH{b = x^q} modulo
	\MATH{F.modulus()}, otherwise the behaviour of this function is
	undefined.}


\medskip

\SEEALSO

	\BF{Fp\_polynomial}


\EXAMPLES
\begin{verbatim}
    #include <LiDIA/Fp_polynomial.h>
    #include <LiDIA/poly_modulus.h>
    #include <LiDIA/poly_multiplier.h>

    main()
    {
        Fp_polynomial a, b, f, x, y, z;
        poly_modulus F;
        poly_multiplier B;

        cout << "Please enter a : "; cin >> a;
        cout << "Please enter b : "; cin >> b;
        cout << "Please enter f : "; cin >> f;

        multiply_mod(x, a, b, f);

        F.build(f);
        multiply(y, a, b, F);

        B.build(b, F);
        multiply(z, a, B, F);

        //now, x == y == z

        cout << "a * b  mod  f  =  ";
        x.pretty_print(cout);
        cout << "\n";
    }
\end{verbatim}

	example:

\begin{verbatim}
    Please enter a : x^4 + 2 mod 97
    Please enter b : x^3 + 1 mod 97
    Please enter f : x^5 - 1 mod 97

    a * b  mod  f  = x^4 + 2*x^3 + x^2 + 2 mod 97
\end{verbatim}

\AUTHOR
	Victor Shoup (original author) \\
	Thomas Pfahler

\end{lidia_man}
