---
abstract: 'The family of left-to-right algorithms reduces input numbers by repeatedly subtracting the smaller number, or multiple of the smaller number, from the larger number. This paper describes how to extend any such algorithm to compute the Jacobi symbol, using a single table lookup per reduction. For both quadratic time algorithms (Euclid, Lehmer) and subquadratic algorithms (Knuth, Schönhage, Möller), the additional cost is linear, roughly one table lookup per quotient in the quotient sequence. This method was used for the 2010 rewrite of the Jacobi symbol computation in .'
author:
- Niels Möller
bibliography:
- 'ref.bib'
date: 2019
title: Efficient computation of the Jacobi symbol
---

Introduction
============

The Legendre symbol and its generalizations, the Jacobi symbol and the Kronecker symbol, are important functions in number theory. For simplicity, in this paper we focus on computation of the Jacobi symbol, since the Kronecker symbol can be computed by the same function with a little preprocessing of the inputs.

Jacobi and GCD
--------------

Two quadratic algorithms for computing the Kronecker symbol (and hence also the Jacobi symbol) are described as Algorithm 1.4.10 and 1.4.12 in [@cohen]. These algorithms run in quadratic time, and consists of a series of reduction steps, related to Euclid’s algorithm and the binary algorithm, respectively. Both Kronecker algorithms share one property with the binary algorithm: The reduction steps examine the current pair of numbers in both ends. They examine the least significant end to cast out powers of two, and they examine the most significant end to determine a quotient (like in Euclid’s algorithm) or to determine which number is largest (like in the binary algorithm).

Fast, subquadratic, algorithms work by divide-and-conquer, where a substantial piece of the work is done by examining only one half of the input numbers. Fast left-to-right is related to fast algorithms for computing the continued fraction expansion [@schoenhage:1971; @knuth:algorithms]. These are left-to-right algorithms, in that they process the input from the most significant end. The binary recursive algorithm [@stehle] is a right-to-left algorithm, in that it processes inputs from the least significant end. The asymptotic running times of these algorithms are $O(M(n) \log n)$, where $M(n)$ denotes the time needed to multiply two $n$-bit numbers. The algorithm used in recent versions of the library [@gmp] is a variant of Schönhage’s algorithm [@moller-sgcd].

It is possible to compute the Jacobi symbol in subquadratic time, with the same asymptotic complexity as . One algorithm is described in [@bach-shallit] (solution to exercise 5.52), which says:

> This complexity bound is part of the “folklore” and has apparently never appeared in print. The basic idea can be found in Gauss \[1876\]. Our presentation is based on that in Bachmann \[1902\]. H. W. Lenstra, Jr. also informed us of this idea; he attributes it to A. Schönhage.

Since the quadratic algorithms for the Jacobi symbol examines the data at both ends, some reorganization is necessary to construct a divide-and-conquer algorithm that processes data from one end. The binary algorithm has the same problem. In the binary recursive algorithm, this is handled by using a slightly different reduction step using 2-adic division.

Recently, the binary recursive algorithm has been extended to compute the Jacobi symbol [@brent:jacobi]. The main difference to the corresponding algorithm is that it needs the intermediate reduced values to be non-negative, and to ensure this the binary quotients must be chosen in the range $1 \leq q < 2^{k+1}$ rather than $|q| < 2^k$. As a result, the algorithm is slower than the algorithm by a small constant factor.

Main contribution
-----------------

This paper describes a fairly simple extension to a wide class of left-to-right algorithms, including Lehmer’s algorithm and the subquadratic algorithm in [@moller-sgcd], which computes the Jacobi symbol using only $O(n)$ extra time and $O(1)$ extra space[^1]. This indicates that also for the fastest algorithms for large inputs, the cost is essentially the same for computing the and computing the Jacobi symbol.[^2]

Like the algorithm described in [@bach-shallit], the computation is related to the quotient sequence. The updates of the Jacobi symbol are somewhat different, instead following an unpublished algorithm by Schönhage [@schoenhage-brent-communication] for computing the Jacobi symbol from the quotient sequence modulo four. In the algorithms in , the quotients are not always applied in a single step; instead, there is a series of reductions of the form $a {\leftarrow}a
- m b$, where $m$ is a positive number equal to or less than the correct quotient ${\lfloor a/b \rfloor}$. In the corresponding Jacobi algorithms, the Jacobi sign is updated for each such partial quotient. Most of the partial quotients are determined from truncated inputs where the least significant parts of the numbers are ignored. The least significant two bits, needed for the Jacobi computation, must therefore be maintained separately.

Notation
--------

The time needed to multiply two $n$-bit numbers is denoted $M(n)$, where $M(n) = O(n \log n)$ for the fastest known algorithms. [^3]

The Jacobi symbol is denoted $(a | b)$. We use the convention that $[\text{condition}]$ means the function that is one when the condition is true, otherwise 0, e.g., $(0 | b) = [b = 1]$.

Left-to-right GCD
=================

In this paper, we will not describe the details of fast algorithms. Instead we will consider Algorithm \[alg:gcd\], which is a generic left-to-right algorithm, with a basic reduction step where a multiple of the smaller number is subtracted from the larger number. We also describe the main idea of fast instantiations of this algorithm.

In: $a, b > 0$ $a \geq b$ $a {\leftarrow}a - m b$, with $1 \leq m \leq {\lfloor a/b \rfloor}$ $a = 0$ $b$ $b {\leftarrow}b - m a$, with $1 \leq m \leq {\lfloor b/a \rfloor}$ $b = 0$ $a$

This algorithm terminates after a finite number of steps, since in each iteration $\max(a,b)$ is reduced, until $a = b$ and the algorithm terminates. It returns the correct value, since $\GCD(a,b)$ is unchanged by each reduction step.

The running time of an instantiation of this algorithm depends on the choice of $m$ in each step, and on the amount of computation done in each step. E.g., if $m = 1$, the worst case number of iterations in exponential. Euclid’s algorithm is a special case where, in each step, $m$ is the correct quotient of the current numbers.

The faster algorithms implements an iteration that depends only on some of the most significant bits of $a$ and $b$: These bits determine which of $a$ and $b$ is largest, and they also suffice for computing an $m$ which is close to the quotient ${\lfloor a/b \rfloor}$ or ${\lfloor b/a \rfloor}$. Furthermore, one can compute an initial part of the sequence of reductions based on the most significant parts of $a$ and $b$, collect the reductions into a transformation matrix, and apply all the reductions at once to the least significant parts of $a$ and $b$ later on. This saves a lot of time, since it omits computing all the intermediate $a$ and $b$ to full precision. If one repeatedly chops off one or two of the most significant words, one gets Lehmer’s algorithm, and by chopping numbers in half, one can construct a divide-and-conquer algorithm with subquadratic complexity.

We will extend this generic algorithm to also compute the Jacobi symbol. To do that, we need to investigate how the basic reduction $a
- m b$ affects the Jacobi symbol. When we have sorted this out, in the next section, the result is easily applied to all variants of Algorithm \[alg:gcd\].

Left-to-right Jacobi
====================

In this section, we summarize the properties of the Jacobi symbol we use, derive the update rules needed for our left-to-right algorithm. Finally, we give the resulting algorithm and prove its correctness.

Jacobi symbol properties
------------------------

The Jacobi symbol $(a | b)$ is defined for $b$ odd and positive, and arbitrary $a$. We work primarily with non-negative $a$, and make use of the following properties of the Jacobi symbol.

Assume that $a$ is positive and that $b$ is odd and positive. Then

(i) \[it:zero\] $(0 | b) = [b = 1]$.

(ii) \[it:negation\] $(a | b) = (-1)^{(b-1)/2} (-a | b)$

(iii) \[it:reciprocity\] If both $a$ and $b$ are odd, then $$(a | b) = (-1)^{(a-1)(b-1)/4} (b | a)$$

(iv) \[it:odd-reduction\] $(a | b) = (a - m b | b)$ for any $m$.

(v) \[it:even-reduction-4\] If $a = 0 \pmod 4$ and $1 \leq m \leq {\lfloor b/a \rfloor}$, then $$(a | b) = (a | b - ma)$$

(vi) \[it:even-reduction-2\] If $a = 2 \pmod 4$ and $1 \leq m \leq {\lfloor b/a \rfloor}$, then $$(a | b) = (-1)^{m(b-1)/2 + m(m-1)/2} (a | b - ma)$$

For  to  we refer to standard textbooks. The final two are not so well-known, and their use for Jacobi computation is suggested by Schönhage [@schoenhage-brent-communication]. To prove them, assume that $a$ is even and $a < b$. Then $$\begin{aligned}
    (a | b) &= (a - b | b) && \text{By \eqref{it:odd-reduction}}\\
    &= (-1)^{(b-1)/2} (b - a | b) && \text{By \eqref{it:negation}} \\
    &= (-1)^{(b-1)/2 + (b-1)(b-a-1)/4} (b | b-a) &&\text{By \eqref{it:reciprocity}}\\
    &= (-1)^{(b-1)/2 + (b-1)(b-a-1)/4}(a | b-a) && \text{By \eqref{it:odd-reduction}}
  \end{aligned}$$ Since $b^2 - 1$ is divisible by 8 for any odd $b$, we get a resulting exponent, modulo two, of $$(b-1)/2 + (b-1)(b-a-1)/4 = a (b-1)/4$$ If $a = 0 \pmod 4$, this exponent is even and hence there is no sign change. And this continues to hold if the subtraction is repeated, which proves . Next, consider the case $a
  = 2 \pmod 4$. Then $a/2 = 1 \pmod 2$, and repeating the subtraction $m$ times gives the exponent $$\begin{gathered}
    a \{(b-1) + (b-a-1) + \cdots + (b - (m-1) a - 1)\} / 4 \\
    = m(b-1)/2 + m(m-1)/2 \pmod 2
  \end{gathered}$$ which proves .

Finally, note that in these formulas, all the signs are determined by the least significant two bits of $a$, $b$ and $m$.

The new algorithm
-----------------

The algorithm works with two non-negative integers $a$ and $b$, where multiples of the smaller one is subtracted from the larger. To compute the Jacobi symbol we maintain these additional state variables: $$\begin{aligned}
e &\in {\mathbb{Z}}_2 && \text{Current sign is $(-1)^e$} \\
\alpha &\in {\mathbb{Z}}_4 && \text{Least significant bits of $a$} \\
\beta &\in {\mathbb{Z}}_4 && \text{Least significant bits of $b$} \\
d &\in {\mathbb{Z}}_2 && \text{Index of denominator}\end{aligned}$$

The value of $d$ is one if the most recent reduction subtracted $b$ from $a$, and zero if it subtracted $a$ from $b$. We collect these four variables as the state $S = (e, \alpha, \beta, d)$. The state is updated by the function , Algorithm \[alg:jupdate\].

In: $d' \in {\mathbb{Z}}_2$, $m \in {\mathbb{Z}}_4$, $S = (e, \alpha, \beta, d)$ $d \neq d'$ and both $\alpha$ and $\beta$ are odd $e {\leftarrow}e + (\alpha - 1)(\beta - 1)/4$ Reciprocity $d {\leftarrow}d'$ $d = 1$ $\beta = 2$ $e {\leftarrow}e + m (\alpha - 1)/2 + m (m-1)/2$ $\alpha {\leftarrow}\alpha - m \beta$ $\alpha = 2$ $e {\leftarrow}e + m (\beta - 1)/2 + m (m-1)/2$ $\beta {\leftarrow}\beta - m \alpha$ $S' = (e, \alpha, \beta, d)$

Since the inputs of this function are nine bits, and the outputs are six bits, it’s clear it can be implemented using a lookup table consisting of $2^9$ six-bit entries, which fits in 512 bytes if entries are padded to byte boundaries.[^4]

Algorithm \[alg:jacobi\] extends the generic left-to-right algorithm to compute the Jacobi symbol. The main loop of this algorithm differs from Algorithm \[alg:gcd\] only by the calls to for each reduction step.

In: $a, b > 0$, $b$ odd Out: The Jacobi symbol $(a | b)$ State: $S = (e, \alpha, \beta, d)$ \[li:jacobi-init\] $S {\leftarrow}(0, a \bmod 4, b \bmod 4, 1)$ $a \geq b$ \[li:update-a\] $a {\leftarrow}a - m b$, with $1 \leq m \leq {\lfloor a/b \rfloor}$ \[li:jacobi-update-a\] $S {\leftarrow}\proc{jupdate}(S, 1, m \bmod 4)$ $a = 0$ $[b = 1] (-1)^e$ $b {\leftarrow}b - m a$, with $1 \leq m \leq {\lfloor b/a \rfloor}$ \[li:jacobi-update-b\] $S {\leftarrow}\proc{jupdate}(S, 0, m \bmod 4)$ $b = 0$ $[a = 1] (-1)^e$

Correctness
-----------

Let $a_0$ and $b_0$ denote the original inputs to Algorithm \[alg:jacobi\]. Since the reduction steps and the stop condition are the same as in Algorithm \[alg:gcd\], it terminates after a finite number of steps. We now prove that it returns $(a_0 | b_0)$.

Algorithm \[alg:jacobi\] clearly maintains $\alpha = a \bmod 4$ and $\beta = b \bmod 4$. We next prove that the following holds at the start of each iteration:

If $d = 0$ we have $$(a_0 | b_0) = (-1)^e \times
  \begin{cases}
    (b | a) & \text{$\alpha$ odd} \\
    (a | b) & \text{$\alpha$ even}
  \end{cases}$$ and if $d = 1$ we have $$\label{eq:invariant-1}
  (a_0 | b_0) = (-1)^e \times
  \begin{cases}
    (a | b) & \text{$\beta$ odd} \\
    (b | a) & \text{$\beta$ even}
  \end{cases}$$ This clearly holds at the start of the loop, to prove that it is maintained, consider the case $a \geq b$ (the case $a < b$ is analogous). Let $a$, $b$ (unchanged) and $S = (e, \alpha, \beta, d)$ denote the values of the variables before line \[li:update-a\]. There are a couple of different cases, depending on the state:

-   If $\beta$ is odd and either $\alpha$ is even or $d = 1$, then $(a_0 |
      b_0) = (-1)^e (a | b) = (-1)^e (a - m b | b)$.

-   If $\alpha$ and $\beta$ are both odd and $d = 0$, then $(a_0 | b_0) =
      (-1)^e (b | a) = (-1)^{e + (a-1)(b-1)/4} (a - m b | b)$.

-   If $\beta = 0 \pmod 4$, then $(a_0 | b_0) = (-1)^e (b |
      a) = (-1)^e (b | a - m b)$.

-   If $\beta = 2 \pmod 4$, then $(a_0 | b_0) = (-1)^e (b |
      a) = (-1)^{e + m(a-1)/2 + m(m-1)/2} (b | a - m b)$.

In each case, the call to makes the appropriate change to $e$, and Eq.  holds after the iteration.

Results
=======

The algorithm was implemented in -5.1.0, released 2012. In benchmarks at the time, comparing the old binary algorithm to the new Jacobi extension of Lehmer’s algorithm (both $O(n^2)$), the new algorithm computed Jacobi symbols about twice as fast for moderate size numbers (around 2000 bits), and 10 times faster for numbers of size of 500000 bits. For even larger numbers, the Jacobi extension of subquadratic brought even greater speedups.

Acknowledgments {#acknowledgments .unnumbered}
===============

The author wishes to thank Richard Brent for providing valuable background material and for encouraging the writing of this paper.

[^1]: The size of the additional state to be maintained is $O(1)$. But in a practical implementation, which does not store this state in a global variable, either the state or a pointer to it will be copied into each activation record, which for a subquadratic recursive divide-and-conquer algorithm costs $O(\log n)$ extra space rather than $O(1)$

[^2]: Even though we cannot rule out the existence of a left-to-right algorithm which is a constant factor faster than Jacobi. Such an algorithm would lie outside the class of “generic left-to-right algorithms” we describe in this paper, e.g., it might use intermediate reduced values of varying signs and quotients that are rounded towards the nearest integer rather than towards $-\infty$.

[^3]: Multiplication in is based on the more practical Schönhage-Strassen algorithm, with asymptotic complexity $O(n \log n \log \log n)$.

[^4]: One quarter of the entries in this table corresponds to invalid inputs, since at least one of $\alpha$ and $\beta$ is always odd. If we also note that the value of $d$ is needed only when $\alpha = \beta = 3$, the state can be encoded into only 26 values, and then the table can be compacted to only 208 entries.
