Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
751zeros = min(i, count_trailing_zeros(g))752eta, i = eta - zeros, i - zeros753g, u, v = g >> zeros, u << zeros, v << zeros754if i == 0:755break756if eta < 0:757eta, f, u, v, g, q, r = -eta, g, q, r, -f, -u, -v758limit = min(min(eta + 1, i), 4)759w = (g * NEGINV16[(f & 15) // 2]) % (2**limit)760g, q, r = g + w*f, q + w*u, r + w*v761return eta, (u, v, q, r)763def modinv_var(M, Mi, x):764"""Compute the modular inverse of x mod M, given Mi = 1/M mod 2^N."""765eta, f, g, d, e = -1, M, x, 0, 1766while g != 0:767eta, t = divsteps_n_matrix_var(eta, f % 2**N, g % 2**N)768f, g = update_fg(f, g, t)769d, e = update_de(d, e, t, M, Mi)770return normalize(f, d, Mi)771```773## 8. From GCDs to Jacobi symbol775We can also use a similar approach to calculate Jacobi symbol *(x | M)* by keeping track of an776extra variable *j*, for which at every step *(x | M) = j (g | f)*. As we update *f* and *g*, we777make corresponding updates to *j* using778[properties of the Jacobi symbol](https://en.wikipedia.org/wiki/Jacobi_symbol#Properties):779* *((g/2) | f)* is either *(g | f)* or *-(g | f)*, depending on the value of *f mod 8* (negating if it's *3* or *5*).780* *(f | g)* is either *(g | f)* or *-(g | f)*, depending on *f mod 4* and *g mod 4* (negating if both are *3*).782These updates depend only on the values of *f* and *g* modulo *4* or *8*, and can thus be applied783very quickly, as long as we keep track of a few additional bits of *f* and *g*. Overall, this784calculation is slightly simpler than the one for the modular inverse because we no longer need to785keep track of *d* and *e*.787However, one difficulty of this approach is that the Jacobi symbol *(a | n)* is only defined for788positive odd integers *n*, whereas in the original safegcd algorithm, *f, g* can take negative789values. We resolve this by using the following modified steps:791```python792# Before793if delta > 0 and g & 1:794delta, f, g = 1 - delta, g, (g - f) // 2796# After797if delta > 0 and g & 1:798delta, f, g = 1 - delta, g, (g + f) // 2799```801The algorithm is still correct, since the changed divstep, called a "posdivstep" (see section 8.4802and E.5 in the paper) preserves *gcd(f, g)*. However, there's no proof that the modified algorithm803will converge. The justification for posdivsteps is completely empirical: in practice, it appears804that the vast majority of nonzero inputs converge to *f=g=gcd(f<sub>0</sub>, g<sub>0</sub>)* in a805number of steps proportional to their logarithm.807Note that:808- We require inputs to satisfy *gcd(x, M) = 1*, as otherwise *f=1* is not reached.809- We require inputs *x &neq; 0*, because applying posdivstep with *g=0* has no effect.810- We need to update the termination condition from *g=0* to *f=1*.812We account for the possibility of nonconvergence by only performing a bounded number of813posdivsteps, and then falling back to square-root based Jacobi calculation if a solution has not814yet been found.816The optimizations in sections 3-7 above are described in the context of the original divsteps, but817in the C implementation we also adapt most of them (not including "avoiding modulus operations",818since it's not necessary to track *d, e*, and "constant-time operation", since we never calculate819Jacobi symbols for secret data) to the posdivsteps version.
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.