1 | initial version |

For integer polynomials, FLINT is used to do the multiplication. We look at the `_mul_`

method since in Sage, `__mul__`

is used to handle coercion and then dispatches to `_mul_`

.

```
sage: R.<x> = ZZ[]
sage: x._mul_??
...
cpdef RingElement _mul_(self, RingElement right):
r"""
Returns self multiplied by right.
EXAMPLES::
sage: R.<x> = PolynomialRing(ZZ)
sage: (x - 2)*(x^2 - 8*x + 16)
x^3 - 10*x^2 + 32*x - 32
"""
cdef Polynomial_integer_dense_flint x = self._new()
sig_on()
fmpz_poly_mul(x.__poly, self.__poly,
(<Polynomial_integer_dense_flint>right).__poly)
sig_off()
return x
```

You can do a similar check to see that FLINT's `fmpq_poly_mul`

is used for polynomials over the rationals.

The univariate polynomials over finite fields different based on the size of the field. For example, for small primes, FLINT is used:

```
sage: R.<x> = GF(next_prime(2^5))[]
sage: type(x)
<type 'sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint'>
```

But for larger primes, NTL is used:

```
sage: R.<x> = GF(next_prime(2^64))[]
sage: type(x)
<type 'sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_p'>
```

To find out the exact algorithm / heuristics used, you'll need to delve into those packages.

Copyright Sage, 2010. Some rights reserved under creative commons license. Content on this site is licensed under a Creative Commons Attribution Share Alike 3.0 license.