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.
1// Copyright (c) 2017-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <crypto/muhash.h>7#include <crypto/chacha20.h>8#include <crypto/common.h>9#include <hash.h>10#include <span.h>11#include <uint256.h>12#include <util/check.h>14#include <bit>15#include <cstring>16#include <limits>18namespace {20using limb_t = Num3072::limb_t;21using signed_limb_t = Num3072::signed_limb_t;22using double_limb_t = Num3072::double_limb_t;23using signed_double_limb_t = Num3072::signed_double_limb_t;24constexpr int LIMB_SIZE = Num3072::LIMB_SIZE;25constexpr int SIGNED_LIMB_SIZE = Num3072::SIGNED_LIMB_SIZE;26constexpr int LIMBS = Num3072::LIMBS;27constexpr int SIGNED_LIMBS = Num3072::SIGNED_LIMBS;28constexpr int FINAL_LIMB_POSITION = 3072 / SIGNED_LIMB_SIZE;29constexpr int FINAL_LIMB_MODULUS_BITS = 3072 % SIGNED_LIMB_SIZE;30constexpr limb_t MAX_LIMB = (limb_t)(-1);31constexpr limb_t MAX_SIGNED_LIMB = (((limb_t)1) << SIGNED_LIMB_SIZE) - 1;32/** 2^3072 - 1103717, the largest 3072-bit safe prime number, is used as the modulus. */33constexpr limb_t MAX_PRIME_DIFF = 1103717;34/** The modular inverse of (2**3072 - MAX_PRIME_DIFF) mod (MAX_SIGNED_LIMB + 1). */35constexpr limb_t MODULUS_INVERSE = limb_t(0x70a1421da087d93);38/** Extract the lowest limb of [c0,c1,c2] into n, and left shift the number by 1 limb. */39inline void extract3(limb_t& c0, limb_t& c1, limb_t& c2, limb_t& n)40{41n = c0;42c0 = c1;43c1 = c2;44c2 = 0;45}47/** [c0,c1] = a * b */48inline void mul(limb_t& c0, limb_t& c1, const limb_t& a, const limb_t& b)49{50double_limb_t t = (double_limb_t)a * b;51c1 = t >> LIMB_SIZE;52c0 = t;53}55/* [c0,c1,c2] += n * [d0,d1,d2]. c2 is 0 initially */56inline void mulnadd3(limb_t& c0, limb_t& c1, limb_t& c2, limb_t& d0, limb_t& d1, limb_t& d2, const limb_t& n)57{58double_limb_t t = (double_limb_t)d0 * n + c0;59c0 = t;60t >>= LIMB_SIZE;61t += (double_limb_t)d1 * n + c1;62c1 = t;63t >>= LIMB_SIZE;64c2 = t + d2 * n;65}67/* [c0,c1] *= n */68inline void muln2(limb_t& c0, limb_t& c1, const limb_t& n)69{70double_limb_t t = (double_limb_t)c0 * n;71c0 = t;72t >>= LIMB_SIZE;73t += (double_limb_t)c1 * n;74c1 = t;75}77/** [c0,c1,c2] += a * b */78inline void muladd3(limb_t& c0, limb_t& c1, limb_t& c2, const limb_t& a, const limb_t& b)79{80double_limb_t t = (double_limb_t)a * b;81limb_t th = t >> LIMB_SIZE;82limb_t tl = t;84c0 += tl;85th += (c0 < tl) ? 1 : 0;86c1 += th;87c2 += (c1 < th) ? 1 : 0;88}90/**91* Add limb a to [c0,c1]: [c0,c1] += a. Then extract the lowest92* limb of [c0,c1] into n, and left shift the number by 1 limb.93* */94inline void addnextract2(limb_t& c0, limb_t& c1, const limb_t& a, limb_t& n)95{96limb_t c2 = 0;98// add99c0 += a;100if (c0 < a) {101c1 += 1;103// Handle case when c1 has overflown104if (c1 == 0) c2 = 1;105}107// extract108n = c0;109c0 = c1;110c1 = c2;111}113} // namespace115/** Indicates whether d is larger than the modulus. */116bool Num3072::IsOverflow() const117{118if (this->limbs[0] <= std::numeric_limits<limb_t>::max() - MAX_PRIME_DIFF) return false;119for (int i = 1; i < LIMBS; ++i) {120if (this->limbs[i] != std::numeric_limits<limb_t>::max()) return false;121}122return true;123}125void Num3072::FullReduce()126{127limb_t c0 = MAX_PRIME_DIFF;128limb_t c1 = 0;129for (int i = 0; i < LIMBS; ++i) {130addnextract2(c0, c1, this->limbs[i], this->limbs[i]);131}132}134namespace {135/** A type representing a number in signed limb representation. */136struct Num3072Signed137{138/** The represented value is sum(limbs[i]*2^(SIGNED_LIMB_SIZE*i), i=0..SIGNED_LIMBS-1).139* Note that limbs may be negative, or exceed 2^SIGNED_LIMB_SIZE-1. */140signed_limb_t limbs[SIGNED_LIMBS];142/** Construct a Num3072Signed with value 0. */143Num3072Signed()144{145memset(limbs, 0, sizeof(limbs));146}148/** Convert a Num3072 to a Num3072Signed. Output will be normalized and in149* range 0..2^3072-1. */150void FromNum3072(const Num3072& in)151{152double_limb_t c = 0;153int b = 0, outpos = 0;154for (int i = 0; i < LIMBS; ++i) {155c += double_limb_t{in.limbs[i]} << b;156b += LIMB_SIZE;157while (b >= SIGNED_LIMB_SIZE) {158limbs[outpos++] = limb_t(c) & MAX_SIGNED_LIMB;159c >>= SIGNED_LIMB_SIZE;160b -= SIGNED_LIMB_SIZE;161}162}163Assume(outpos == SIGNED_LIMBS - 1);164limbs[SIGNED_LIMBS - 1] = c;165c >>= SIGNED_LIMB_SIZE;166Assume(c == 0);167}169/** Convert a Num3072Signed to a Num3072. Input must be in range 0..modulus-1. */170void ToNum3072(Num3072& out) const171{172double_limb_t c = 0;173int b = 0, outpos = 0;174for (int i = 0; i < SIGNED_LIMBS; ++i) {175c += double_limb_t(limbs[i]) << b;176b += SIGNED_LIMB_SIZE;177if (b >= LIMB_SIZE) {178out.limbs[outpos++] = c;179c >>= LIMB_SIZE;180b -= LIMB_SIZE;181}182}183Assume(outpos == LIMBS);184Assume(c == 0);185}187/** Take a Num3072Signed in range 1-2*2^3072..2^3072-1, and:188* - optionally negate it (if negate is true)189* - reduce it modulo the modulus (2^3072 - MAX_PRIME_DIFF)190* - produce output with all limbs in range 0..2^SIGNED_LIMB_SIZE-1191*/192void Normalize(bool negate)193{194// Add modulus if this was negative. This brings the range of *this to 1-2^3072..2^3072-1.195signed_limb_t cond_add = limbs[SIGNED_LIMBS-1] >> (LIMB_SIZE-1); // -1 if this is negative; 0 otherwise196limbs[0] += signed_limb_t(-MAX_PRIME_DIFF) & cond_add;197limbs[FINAL_LIMB_POSITION] += (signed_limb_t(1) << FINAL_LIMB_MODULUS_BITS) & cond_add;198// Next negate all limbs if negate was set. This does not change the range of *this.199signed_limb_t cond_negate = -signed_limb_t(negate); // -1 if this negate is true; 0 otherwise200for (int i = 0; i < SIGNED_LIMBS; ++i) {201limbs[i] = (limbs[i] ^ cond_negate) - cond_negate;202}203// Perform carry (make all limbs except the top one be in range 0..2^SIGNED_LIMB_SIZE-1).204for (int i = 0; i < SIGNED_LIMBS - 1; ++i) {205limbs[i + 1] += limbs[i] >> SIGNED_LIMB_SIZE;206limbs[i] &= MAX_SIGNED_LIMB;207}208// Again add modulus if *this was negative. This brings the range of *this to 0..2^3072-1.209cond_add = limbs[SIGNED_LIMBS-1] >> (LIMB_SIZE-1); // -1 if this is negative; 0 otherwise210limbs[0] += signed_limb_t(-MAX_PRIME_DIFF) & cond_add;211limbs[FINAL_LIMB_POSITION] += (signed_limb_t(1) << FINAL_LIMB_MODULUS_BITS) & cond_add;212// Perform another carry. Now all limbs are in range 0..2^SIGNED_LIMB_SIZE-1.213for (int i = 0; i < SIGNED_LIMBS - 1; ++i) {214limbs[i + 1] += limbs[i] >> SIGNED_LIMB_SIZE;215limbs[i] &= MAX_SIGNED_LIMB;216}217}218};220/** 2x2 transformation matrix with signed_limb_t elements. */221struct SignedMatrix222{223signed_limb_t u, v, q, r;224};226/** Compute the transformation matrix for SIGNED_LIMB_SIZE divsteps.227*228* eta: initial eta value229* f: bottom SIGNED_LIMB_SIZE bits of initial f value230* g: bottom SIGNED_LIMB_SIZE bits of initial g value231* out: resulting transformation matrix, scaled by 2^SIGNED_LIMB_SIZE232* return: eta value after SIGNED_LIMB_SIZE divsteps233*/234inline limb_t ComputeDivstepMatrix(signed_limb_t eta, limb_t f, limb_t g, SignedMatrix& out)235{236/** inv256[i] = -1/(2*i+1) (mod 256) */237static const uint8_t NEGINV256[128] = {2380xFF, 0x55, 0x33, 0x49, 0xC7, 0x5D, 0x3B, 0x11, 0x0F, 0xE5, 0xC3, 0x59,2390xD7, 0xED, 0xCB, 0x21, 0x1F, 0x75, 0x53, 0x69, 0xE7, 0x7D, 0x5B, 0x31,2400x2F, 0x05, 0xE3, 0x79, 0xF7, 0x0D, 0xEB, 0x41, 0x3F, 0x95, 0x73, 0x89,2410x07, 0x9D, 0x7B, 0x51, 0x4F, 0x25, 0x03, 0x99, 0x17, 0x2D, 0x0B, 0x61,2420x5F, 0xB5, 0x93, 0xA9, 0x27, 0xBD, 0x9B, 0x71, 0x6F, 0x45, 0x23, 0xB9,2430x37, 0x4D, 0x2B, 0x81, 0x7F, 0xD5, 0xB3, 0xC9, 0x47, 0xDD, 0xBB, 0x91,2440x8F, 0x65, 0x43, 0xD9, 0x57, 0x6D, 0x4B, 0xA1, 0x9F, 0xF5, 0xD3, 0xE9,2450x67, 0xFD, 0xDB, 0xB1, 0xAF, 0x85, 0x63, 0xF9, 0x77, 0x8D, 0x6B, 0xC1,2460xBF, 0x15, 0xF3, 0x09, 0x87, 0x1D, 0xFB, 0xD1, 0xCF, 0xA5, 0x83, 0x19,2470x97, 0xAD, 0x8B, 0xE1, 0xDF, 0x35, 0x13, 0x29, 0xA7, 0x3D, 0x1B, 0xF1,2480xEF, 0xC5, 0xA3, 0x39, 0xB7, 0xCD, 0xAB, 0x01249};250// Coefficients of returned SignedMatrix; starts off as identity matrix. */
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.