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.
251## 4. Avoiding modulus operations253So far, there are two places where we compute a remainder of big numbers modulo *M*: at the end of254`div2n` in every `update_de`, and at the very end of `modinv` after potentially negating *d* due to the255sign of *f*. These are relatively expensive operations when done generically.257To deal with the modulus operation in `div2n`, we simply stop requiring *d* and *e* to be in range258*[0,M)* all the time. Let's start by inlining `div2n` into `update_de`, and dropping the modulus259operation at the end:261```python262def update_de(d, e, t, M, Mi):263"""Multiply matrix t/2^N with [d, e] mod M, given Mi=1/M mod 2^N."""264u, v, q, r = t265cd, ce = u*d + v*e, q*d + r*e266# Cancel out bottom N bits of cd and ce.267md = -((Mi * cd) % 2**N)268me = -((Mi * ce) % 2**N)269cd += md * M270ce += me * M271# And cleanly divide by 2**N.272return cd >> N, ce >> N273```275Let's look at bounds on the ranges of these numbers. It can be shown that *|u|+|v|* and *|q|+|r|*276never exceed *2<sup>N</sup>* (see paragraph 8.3 in the paper), and thus a multiplication with *t* will have277outputs whose absolute values are at most *2<sup>N</sup>* times the maximum absolute input value. In case the278inputs *d* and *e* are in *(-M,M)*, which is certainly true for the initial values *d=0* and *e=1* assuming279*M > 1*, the multiplication results in numbers in range *(-2<sup>N</sup>M,2<sup>N</sup>M)*. Subtracting less than *2<sup>N</sup>*280times *M* to cancel out *N* bits brings that up to *(-2<sup>N+1</sup>M,2<sup>N</sup>M)*, and281dividing by *2<sup>N</sup>* at the end takes it to *(-2M,M)*. Another application of `update_de` would take that282to *(-3M,2M)*, and so forth. This progressive expansion of the variables' ranges can be283counteracted by incrementing *d* and *e* by *M* whenever they're negative:285```python286...287if d < 0:288d += M289if e < 0:290e += M291cd, ce = u*d + v*e, q*d + r*e292# Cancel out bottom N bits of cd and ce.293...294```296With inputs in *(-2M,M)*, they will first be shifted into range *(-M,M)*, which means that the297output will again be in *(-2M,M)*, and this remains the case regardless of how many `update_de`298invocations there are. In what follows, we will try to make this more efficient.300Note that increasing *d* by *M* is equal to incrementing *cd* by *u M* and *ce* by *q M*. Similarly,301increasing *e* by *M* is equal to incrementing *cd* by *v M* and *ce* by *r M*. So we could instead write:303```python304...305cd, ce = u*d + v*e, q*d + r*e306# Perform the equivalent of incrementing d, e by M when they're negative.307if d < 0:308cd += u*M309ce += q*M310if e < 0:311cd += v*M312ce += r*M313# Cancel out bottom N bits of cd and ce.314md = -((Mi * cd) % 2**N)315me = -((Mi * ce) % 2**N)316cd += md * M317ce += me * M318...319```321Now note that we have two steps of corrections to *cd* and *ce* that add multiples of *M*: this322increment, and the decrement that cancels out bottom bits. The second one depends on the first323one, but they can still be efficiently combined by only computing the bottom bits of *cd* and *ce*324at first, and using that to compute the final *md*, *me* values:326```python327def update_de(d, e, t, M, Mi):328"""Multiply matrix t/2^N with [d, e], modulo M."""329u, v, q, r = t330md, me = 0, 0331# Compute what multiples of M to add to cd and ce.332if d < 0:333md += u334me += q335if e < 0:336md += v337me += r338# Compute bottom N bits of t*[d,e] + M*[md,me].339cd, ce = (u*d + v*e + md*M) % 2**N, (q*d + r*e + me*M) % 2**N340# Correct md and me such that the bottom N bits of t*[d,e] + M*[md,me] are zero.341md -= (Mi * cd) % 2**N342me -= (Mi * ce) % 2**N343# Do the full computation.344cd, ce = u*d + v*e + md*M, q*d + r*e + me*M345# And cleanly divide by 2**N.346return cd >> N, ce >> N347```349One last optimization: we can avoid the *md M* and *me M* multiplications in the bottom bits of *cd*350and *ce* by moving them to the *md* and *me* correction:352```python353...354# Compute bottom N bits of t*[d,e].355cd, ce = (u*d + v*e) % 2**N, (q*d + r*e) % 2**N356# Correct md and me such that the bottom N bits of t*[d,e]+M*[md,me] are zero.357# Note that this is not the same as {md = (-Mi * cd) % 2**N} etc. That would also result in N358# zero bottom bits, but isn't guaranteed to be a reduction of [0,2^N) compared to the359# previous md and me values, and thus would violate our bounds analysis.360md -= (Mi*cd + md) % 2**N361me -= (Mi*ce + me) % 2**N362...363```365The resulting function takes *d* and *e* in range *(-2M,M)* as inputs, and outputs values in the same366range. That also means that the *d* value at the end of `modinv` will be in that range, while we want367a result in *[0,M)*. To do that, we need a normalization function. It's easy to integrate the368conditional negation of *d* (based on the sign of *f*) into it as well:370```python371def normalize(sign, v, M):372"""Compute sign*v mod M, where v is in range (-2*M,M); output in [0,M)."""373assert sign == 1 or sign == -1374# v in (-2*M,M)375if v < 0:376v += M377# v in (-M,M). Now multiply v with sign (which can only be 1 or -1).378if sign == -1:379v = -v380# v in (-M,M)381if v < 0:382v += M383# v in [0,M)384return v385```387And calling it in `modinv` is simply:389```python390...391return normalize(f, d, M)392```395## 5. Constant-time operation397The primary selling point of the algorithm is fast constant-time operation. What code flow still398depends on the input data so far?400- the number of iterations of the while *g ≠ 0* loop in `modinv`401- the branches inside `divsteps_n_matrix`402- the sign checks in `update_de`403- the sign checks in `normalize`405To make the while loop in `modinv` constant time it can be replaced with a constant number of406iterations. The paper proves (Theorem 11.2) that *741* divsteps are sufficient for any *256*-bit407inputs, and [safegcd-bounds](https://github.com/sipa/safegcd-bounds) shows that the slightly better bound *724* is408sufficient even. Given that every loop iteration performs *N* divsteps, it will run a total of409*⌈724/N⌉* times.411To deal with the branches in `divsteps_n_matrix` we will replace them with constant-time bitwise412operations (and hope the C compiler isn't smart enough to turn them back into branches; see413`ctime_tests.c` for automated tests that this isn't the case). To do so, observe that a414divstep can be written instead as (compare to the inner loop of `gcd` in section 1).416```python417x = -f if delta > 0 else f # set x equal to (input) -f or f418if g & 1:419g += x # set g to (input) g-f or g+f420if delta > 0:421delta = -delta422f += g # set f to (input) g (note that g was set to g-f before)423delta += 1424g >>= 1425```427To convert the above to bitwise operations, we rely on a trick to negate conditionally: per the428definition of negative numbers in two's complement, (*-v == ~v + 1*) holds for every number *v*. As429*-1* in two's complement is all *1* bits, bitflipping can be expressed as xor with *-1*. It follows430that *-v == (v ^ -1) - (-1)*. Thus, if we have a variable *c* that takes on values *0* or *-1*, then431*(v ^ c) - c* is *v* if *c=0* and *-v* if *c=-1*.433Using this we can write:435```python436x = -f if delta > 0 else f437```439in constant-time form as:441```python442c1 = (-delta) >> 63443# Conditionally negate f based on c1:444x = (f ^ c1) - c1445```447To use that trick, we need a helper mask variable *c1* that resolves the condition *δ>0* to *-1*448(if true) or *0* (if false). We compute *c1* using right shifting, which is equivalent to dividing by449the specified power of *2* and rounding down (in Python, and also in C under the assumption of a typical two's complement system; see450`assumptions.h` for tests that this is the case). Right shifting by *63* thus maps all451numbers in range *[-2<sup>63</sup>,0)* to *-1*, and numbers in range *[0,2<sup>63</sup>)* to *0*.453Using the facts that *x&0=0* and *x&(-1)=x* (on two's complement systems again), we can write:455```python456if g & 1:457g += x458```460as:462```python463# Compute c2=0 if g is even and c2=-1 if g is odd.464c2 = -(g & 1)465# This masks out x if g is even, and leaves x be if g is odd.466g += x & c2467```469Using the conditional negation trick again we can write:471```python472if g & 1:473if delta > 0:474delta = -delta475```477as:479```python480# Compute c3=-1 if g is odd and delta>0, and 0 otherwise.481c3 = c1 & c2482# Conditionally negate delta based on c3:483delta = (delta ^ c3) - c3484```486Finally:488```python489if g & 1:490if delta > 0:491f += g492```494becomes:496```python497f += g & c3498```500It turns out that this can be implemented more efficiently by applying the substitution
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.