FLINT3.7.0-dev
Algorithm

Kronecker substitution

Cost
One integer product of about (ℓ1+ℓ2)(2β+lg⁡ℓ2)(\ell_1 + \ell_2)(2\beta + \lg \ell_2) bits (KS), or two (KS2) or four (KS4) products of a half or a quarter of that size, plus O(ℓ1+ℓ2)O(\ell_1 + \ell_2) word operations.

Kronecker substitution reduces polynomial multiplication to integer multiplication. The coefficients of each factor are written into the bits of one large integer, with enough space between them that the coefficients of the product do not overlap, and one integer product yields all coefficients of the polynomial product. The idea goes back to Kronecker [Kro1882]; Schönhage used it to multiply polynomials with integer and complex coefficients [Sch1982], and it is discussed in [GG2003, §8.4] and [Ber2008]. Its strength is that it inherits all the work that has gone into integer multiplication: FLINT's and GMP's basecase and Toom–Cook code, and the FFTs.

Harvey [Har2009a] observed that evaluating at several points, ±2b\pm 2^b and ±2−b\pm 2^{-b}, replaces the single integer product by two or four products of a half or a quarter of the size. Since integer multiplication costs more than linear time, this is faster. FLINT's implementations of these variants, KS2 and KS4, come from Harvey's zn_poly library.

Throughout, ff and gg have lengths ℓ1≥ℓ2\ell_1 \ge \ell_2 and coefficients in [0,n)[0, n), h=fgh = fg has length ℓ1+ℓ2−1\ell_1 + \ell_2 - 1, and β\beta is the bit length of nn (NMOD_BITS). We write hkh_k for the coefficients of the product of ff and gg as polynomials with integer coefficients. Each is a sum of at most ℓ2\ell_2 products, so

0≤hk≤ℓ2(n−1)2<22β+⌈log⁡2ℓ2⌉.0 \le h_k \le \ell_2 (n - 1)^2 < 2^{2\beta + \lceil \log_2 \ell_2 \rceil}.

All three methods compute the integers hkh_k exactly and reduce them modulo nn at the end, with one-, two- or three-word reductions (NMOD_RED, NMOD2_RED2, NMOD_RED3).

Plain Kronecker substitution#

Lemma 1. Let b≥1b \ge 1 and let h(x)=∑hkxkh(x) = \sum h_k x^k have integer coefficients 0≤hk<2b0 \le h_k < 2^b. Then hkh_k is the integer formed by bits bk,…,bk+b−1bk, \ldots, bk + b - 1 of h(2b)h(2^b).

Proof. The binary expansions of the terms hk2bkh_k 2^{bk} occupy disjoint bit ranges, so their sum is formed without carries.

Algorithm 1: KS

Input: ff, gg as above.

Output: fg mod nfg \bmod n.

  1. Choose bb with ℓ2(n−1)2<2b\ell_2 (n - 1)^2 < 2^b.
  2. Form the integers F=f(2b)F = f(2^b) and G=g(2b)G = g(2^b) by writing the coefficients into bb-bit fields (bit packing).
  3. Compute the integer product H=FGH = FG.
  4. Read the hkh_k from the bb-bit fields of HH (bit unpacking) and reduce each modulo nn.

Correctness is Lemma 1 applied to the integer polynomial fgfg, since FG=(fg)(2b)FG = (fg)(2^b). The integers FF and GG have about ℓ1b\ell_1 b and ℓ2b\ell_2 b bits, so the cost is one integer product of (ℓ1+ℓ2)b(\ell_1 + \ell_2) b bits plus linear work. The field size b≈2β+log⁡2ℓ2b \approx 2\beta + \log_2 \ell_2 grows only logarithmically with the length, but for small moduli a large part of each field holds the bits of the sums rather than of the inputs, which is the waste that KS2 and KS4 reduce.

_nmod_poly_mulmid_KS, which implements the full, low and middle products by substitution, takes b=2β+⌊log⁡2ℓ2⌋+1b = 2\beta + \lfloor \log_2 \ell_2 \rfloor + 1, and if this fits in a word replaces it by the exact bit length of ℓ2(n−1)2\ell_2 (n-1)^2. It packs with _nmod_poly_bit_pack, multiplies with flint_mpn_mul (or flint_mpn_sqr for squares) and extracts only the requested range of coefficients with _nmod_poly_bit_unpack, which reduces each field of one to three words. Before packing it drops the low coefficients of the operands that cannot contribute to the requested range, but otherwise it forms the whole integer product.

Evaluation at 2b2^b and −2b-2^b (KS2)#

Write h(x)=he(x2)+xho(x2)h(x) = h_e(x^2) + x h_o(x^2) for the even and odd parts, and similarly for ff and gg. Let B=2bB = 2^b.

Lemma 2. h(B)+h(−B)=2he(B2)h(B) + h(-B) = 2 h_e(B^2) and h(B)−h(−B)=2Bho(B2)h(B) - h(-B) = 2 B h_o(B^2). If the coefficients of hh are less than B2B^2, the coefficients of heh_e and hoh_o are the 2b2b-bit fields of he(B2)h_e(B^2) and ho(B2)h_o(B^2).

Proof. The identities follow from (−B)k=(−1)kBk(-B)^k = (-1)^k B^k. The second statement is Lemma 1 with 2b2b in place of bb.

With bb about half the field size of KS, KS2 computes two integer products f(B)g(B)f(B) g(B) and f(−B)g(−B)f(-B) g(-B), each of about (ℓ1+ℓ2)b(\ell_1 + \ell_2) b bits, half the size of the single product of KS. The evaluations are cheap: fe(B2)f_e(B^2) and Bfo(B2)B f_o(B^2) are packings of the even and odd coefficients into 2b2b-bit fields, the second shifted by bb bits, and f(±B)f(\pm B) is their sum or difference. Since f(−B)f(-B) may be negative, FLINT stores absolute values and tracks the sign of the product.

Algorithm 2: KS2

Input: ff, gg as above, ℓ2≥2\ell_2 \ge 2.

Output: fg mod nfg \bmod n.

  1. c←2β+⌈log⁡2ℓ2⌉c \gets 2\beta + \lceil \log_2 \ell_2 \rceil, b←⌈c/2⌉b \gets \lceil c / 2 \rceil, B←2bB \gets 2^b.
  2. Pack fe(B2)f_e(B^2), Bfo(B2)B f_o(B^2), ge(B2)g_e(B^2) and Bgo(B2)B g_o(B^2) (_nmod_poly_KS2_pack); form f(±B)f(\pm B) and g(±B)g(\pm B) with an addition and a signed subtraction each.
  3. P←f(B)g(B)P \gets f(B) g(B), M←f(−B)g(−B)M \gets f(-B) g(-B).
  4. Unpack the 2b2b-bit fields of (P+M)/2(P + M)/2 to obtain heh_e, and of (P−M)/(2B)(P - M)/(2B) to obtain hoh_o (_nmod_poly_KS2_unpack); reduce modulo nn into the even and odd positions of the output (_nmod_poly_KS2_reduce).

The bound hk<2c≤B2h_k < 2^c \le B^2 makes Lemma 2 applicable. For a square only two integer squarings are needed.

Adding the reciprocal points ±2−b\pm 2^{-b} (KS4)#

The reversal rev⁡(f)(x)=xℓ1−1f(1/x)\operatorname{rev}(f)(x) = x^{\ell_1 - 1} f(1/x) satisfies rev⁡(fg)=rev⁡(f)rev⁡(g)\operatorname{rev}(fg) = \operatorname{rev}(f) \operatorname{rev}(g), so evaluating reversed polynomials at BB amounts to evaluating at 1/B1/B in integer arithmetic. KS4 runs the KS2 evaluation twice, on f,gf, g and on their reversals, with bb about a quarter of the field size of KS. Now a coefficient of heh_e may have up to 4b4b bits while the fields of he(B2)h_e(B^2) are only 2b2b bits wide, so neighbouring coefficients overlap. The low halves of the coefficients can be read from the normal evaluation, starting at the low end, and the high halves from the reversed one, starting at the high end.

Theorem 3 (Recovery from two overlapping evaluations). Let D≥4D \ge 4 and let c0,…,cm−1c_0, \ldots, c_{m-1} be integers with ci=αi+Dβic_i = \alpha_i + D \beta_i, 0≤αi<D0 \le \alpha_i < D and 0≤βi≤D−20 \le \beta_i \le D - 2. Let

X=∑i=0m−1ciDi,Y=∑i=0m−1ciDm−1−i,X = \sum_{i=0}^{m-1} c_i D^i, \qquad Y = \sum_{i=0}^{m-1} c_i D^{m-1-i},

with base-DD digits xpx_p and ypy_p for 0≤p≤m0 \le p \le m. Set α−1=β−1=κ0=0\alpha_{-1} = \beta_{-1} = \kappa_0 = 0. Then for i=0,1,…,m−1i = 0, 1, \ldots, m-1,

αi=(xi−βi−1−κi) mod D,κi+1=[ xi<βi−1+κi ],\alpha_i = (x_i - \beta_{i-1} - \kappa_i) \bmod D, \qquad \kappa_{i+1} = [\, x_i < \beta_{i-1} + \kappa_i \,],
βi=((ym−i−αi−1) mod D)−[ ym−1−i<αi ],\beta_i = \bigl((y_{m-i} - \alpha_{i-1}) \bmod D\bigr) - [\, y_{m-1-i} < \alpha_i \,],

where [⋅][\cdot] is 1 if the condition holds and 0 otherwise. In particular the cic_i are determined by XX and YY and are computed in increasing order of ii with O(m)O(m) digit operations.

Proof. Digits of XX. Coefficient cic_i contributes αi\alpha_i to position ii and βi\beta_i to position i+1i + 1. Let κi\kappa_i be the carry into position ii. Then αi+βi−1+κi=xi+Dκi+1\alpha_i + \beta_{i-1} + \kappa_i = x_i + D \kappa_{i+1}; the left side is at most 2D−22D - 2, so carries are 0 or 1. Reducing modulo DD gives αi\alpha_i, and κi+1=1\kappa_{i+1} = 1 exactly when the subtraction xi−βi−1−κix_i - \beta_{i-1} - \kappa_i borrows.

Digits of YY. Here cic_i contributes αi\alpha_i to position p=m−1−ip = m - 1 - i and βi\beta_i to position p+1p + 1. Let λp\lambda_p be the carry into position pp. Position pp receives αi+βi+1+λp\alpha_i + \beta_{i+1} + \lambda_p (with βm=0\beta_m = 0). Since βi+1+λp≤D−1\beta_{i+1} + \lambda_p \le D - 1, this sum reaches DD, which makes λp+1=1\lambda_{p+1} = 1, exactly when its residue ypy_p is less than αi\alpha_i. Position p+1=m−ip + 1 = m - i receives αi−1+βi+λp+1\alpha_{i-1} + \beta_i + \lambda_{p+1}, hence (ym−i−αi−1) mod D=βi+λp+1(y_{m-i} - \alpha_{i-1}) \bmod D = \beta_i + \lambda_{p+1}, with no wrap-around because βi+λp+1≤D−1\beta_i + \lambda_{p+1} \le D - 1. Subtracting λp+1=[ym−1−i<αi]\lambda_{p+1} = [y_{m-1-i} < \alpha_i] gives βi\beta_i. Each step needs only βi−1\beta_{i-1} and αi\alpha_i, which are known by then.

In KS4, D=22bD = 2^{2b}, the cic_i are the coefficients of heh_e (and then of hoh_o), XX is he(B2)h_e(B^2) from the normal evaluation and YY is the corresponding value from the reversed one. The hypothesis on βi\beta_i holds with FLINT's choice of bb:

Proposition 4. Let c=2β+kc = 2\beta + k with k=⌈log⁡2ℓ2⌉k = \lceil \log_2 \ell_2 \rceil, b=⌈c/4⌉b = \lceil c/4 \rceil and D=22bD = 2^{2b}, as in _nmod_poly_mul_KS4. Then every hjh_j satisfies ⌊hj/D⌋≤D−2\lfloor h_j / D \rfloor \le D - 2.

Proof. Since n−1≤2β−1n - 1 \le 2^\beta - 1 and ℓ2≤2k\ell_2 \le 2^k,

hj≤2k(22β−2β+1+1)=2c−2k(2β+1−1).h_j \le 2^k (2^{2\beta} - 2^{\beta + 1} + 1) = 2^c - 2^k (2^{\beta+1} - 1).

If 4b=c4b = c, then D2=2cD^2 = 2^c and D=2β+k/2<2k(2β+1−1)D = 2^{\beta + k/2} < 2^k (2^{\beta+1} - 1), so hj<D2−Dh_j < D^2 - D, which is the claim. If 4b>c4b > c, then hj<2c≤D2/2h_j < 2^c \le D^2/2, so ⌊hj/D⌋<D/2≤D−2\lfloor h_j / D \rfloor < D/2 \le D - 2.

Algorithm 3: KS4

Input: ff, gg as above, ℓ2≥2\ell_2 \ge 2.

Output: fg mod nfg \bmod n.

  1. c←2β+⌈log⁡2ℓ2⌉c \gets 2\beta + \lceil \log_2 \ell_2 \rceil, b←⌈c/4⌉b \gets \lceil c / 4 \rceil, B←2bB \gets 2^b.
  2. As in Algorithm 2, compute f(±B)g(±B)f(\pm B) g(\pm B) and from them 2he(B2)2 h_e(B^2) and 2Bho(B2)2 B h_o(B^2).
  3. Do the same with rev⁡(f)\operatorname{rev}(f) and rev⁡(g)\operatorname{rev}(g). This gives the even and odd parts of rev⁡(h)\operatorname{rev}(h) at B2B^2, which are the reversals of heh_e and hoh_o, exchanged if the length of hh is even (FLINT compensates with shifts by bb bits).
  4. Split the four integers into 2b2b-bit digits and apply Theorem 3 to obtain the even and the odd coefficients, reducing each modulo nn (_nmod_poly_KS2_recover_reduce).

Cost#

Let I(N)I(N) be the cost of multiplying two NN-bit integers and let N=(ℓ1+ℓ2)cN = (\ell_1 + \ell_2) c be the size of the product formed by KS. Up to linear terms,

KS: I(N),KS2: 2 I(N/2),KS4: 4 I(N/4).\text{KS: } I(N), \qquad \text{KS2: } 2\, I(N/2), \qquad \text{KS4: } 4\, I(N/4).

Since II grows faster than linearly, KS4 is the fastest for large NN. The gain is large where integer multiplication is quadratic or Toom–Cook, and shrinks to a modest constant factor in the FFT range [Har2009a]. The linear overhead (more packing, signed additions and the recovery) is larger for KS2 and KS4, so plain KS is preferred for short products; the crossovers used by _nmod_poly_mul are given in Cutoffs. For truncated and middle products, substitution offers no saving beyond shortening the operands, since the whole integer product is formed.

Use in FLINT#

void _nmod_poly_mul_KS(nn_ptr out, nn_srcptr in1, slong len1, nn_srcptr in2, slong len2, nmod_t mod)
void _nmod_poly_mul_KS2(nn_ptr res, nn_srcptr op1, slong n1, nn_srcptr op2, slong n2, nmod_t mod)
void _nmod_poly_mul_KS4(nn_ptr res, nn_srcptr op1, slong n1, nn_srcptr op2, slong n2, nmod_t mod)
void _nmod_poly_mulmid_KS(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong nlo, slong nhi, nmod_t mod)

Referenced from#

References#

  • [Kro1882] L. Kronecker, "Grundzüge einer arithmetischen Theorie der algebraischen Grössen", Journal für die reine und angewandte Mathematik 92 (1882), 1–122
  • [Sch1982] A. Schönhage, "Asymptotically fast algorithms for the numerical multiplication and division of polynomials with complex coefficients", Computer Algebra (EUROCAM '82), LNCS 144 (1982), 3–15
  • [GG2003] J. von zur Gathen and J. Gerhard, Modern Computer Algebra, second edition, Cambridge University Press (2003)
  • [Ber2008] D. J. Bernstein, "Fast multiplication and its applications", in Algorithmic Number Theory, MSRI Publications 44 (2008), 325–384
  • [Har2009a] D. Harvey, "Faster polynomial multiplication via multipoint Kronecker substitution", Journal of Symbolic Computation 44:10 (2009), 1502–1510
Cite this page

The FLINT team, “Kronecker substitution,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/polynomials/kronecker.html (generated 2026-11-02).