Bitcoin Core source code. libsecp256k1. A highly secure implementation of secp256k1 operations, used as a benchmark for signature testing and verification.

03.09.2026

Bitcoin Core source code. libsecp256k1. A highly secure implementation of secp256k1 operations, used as a benchmark for signature testing and verification.

The library  libsecp256k1 is an open-source reference C module designed for cryptographic operations on the elliptic curve $secp256k1$ ($y^2 \equiv x^3 + 7 \pmod p$) in the Bitcoin Core ecosystem. Unlike general-purpose libraries (such as OpenSSL),  libsecp256k1 it is optimized exclusively for a single curve with strict requirements for constant runtime, no runtime heap allocation, and a minimized side-channel attack surface.

1. Architectural principles and basic parameters of the secp256k1 curve

The curve $secp256k1$ is defined over a finite field $\mathbb{F}_p$ by an equation in Weierstrass form:

\[ y^2 \equiv x^3 + 7 \pmod p \] \[ p = 2^{256} – 2^{32} – 977 = 2^{256} – 0 ext{x}1000003D1 \] \[ n = ext{0xFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141} \] \[ h = 1 \]

Key engineering principles for implementation:

  • Zero Runtime Allocations:  All runtime structures, contexts ( secp256k1_context), and precomputation tables are allocated on the stack or statically initialized by the caller.
  • Constant-Time Execution:  Branching ( if/else) and lookup tables (LUTs) with indices that depend on secret data (nonce $k$, private key $d$) are prohibited.
  • Defensive programming:  Limiting APIs to high-level abstractions (“Be difficult to use insecurely”).

Archived cryptanalytic precedent:  In 2013, a vulnerability in the pseudorandom generator (PRNG) in Android Java SecureRandom led to the duplication of ephemeral keys $k$ in Bitcoin wallets. Attackers instantly recovered private keys using the formula $d = (s_1 k – e_1) \cdot r^{-1} \pmod n$. Implementation of a derandomized RFC 6979 signature  libsecp256k1 completely eliminated the dependence on an external OS entropy source.

2. Basic field arithmetic (Field Arithmetic: 5×52-bit and 10×26-bit)

To represent 256-bit numbers of the $\mathbb{F}_p$ field, the library uses a redundant radix representation:

  • 64-bit platforms:  5 elements (limbs) of 52 bits.
  • 32-bit platforms:  10 elements (limbs) of 26 bits (including hand-written assembler inserts for ARM).
/* Определение 5x52-bit представления поля (secp256k1_fe) */
typedef struct {
    uint64_t n[5];
} secp256k1_fe;

/* Редукция псевдо-Мерсенновского модуля p = 2^256 - 0x1000003D1 */
/* Число 0x1000003D1 разбивается на константы для сложения старших переносов */

The redundancy of the bits allows multiple additions and multiplications to be performed without immediate full reduction, minimizing expensive carry propagation operations.

Archived cryptanalytic precedent:  In 2023, an optimization was discovered during builds with Clang compilers >= 14 that translated conditional memory moves into instructions with data-dependent timing. The  libsecp256k1 v0.3.1 code was quickly corrected with memory barriers to ensure strict constant-time at the instruction level (CVE-2019-25003 / LLVM backend fixes).

3. Modular inversion and the SafeGCD algorithm

To calculate the inverses of $x^{-1} \pmod p$ and $s^{-1} \pmod n$,  the safegcdlibsecp256k1  algorithm   (developed by Daniel J. Bernstein and Bo-Yin Yang, adapted by Peter Dettman) is used.

\[ \delta_{i+1} = egin{cases} 1 — \delta_i, & ext{if } \delta_i > 0 ext{ and } f_i \equiv 1 \pmod 2 \ 1 + \delta_i, & ext{otherwise} \end{cases} \] \[ (f_{i+1}, g_{i+1}) = ext{TransitionMatrix}(\delta_i, f_i, g_i) \]

The classic Euclidean algorithm contains loops and branches dependent on the values ​​of the input bits, creating a critical vulnerability to timing attacks. SafeGCD performs a strictly fixed number of iterations (590 steps for 256 bits) with a constant number of operations at each step.

Archived cryptanalytic precedent:  The “LadderLeak” and “Just a Little Bit More” attacks (van de Pol, Smart, Yarom) demonstrated that leaking even 1-2 bits of each $k$ via modular inversion cache timing allows one to recover the master key using the LLL/Hidden Number Problem (HNP) lattice reduction algorithm. SafeGCD completely mitigates this attack vector.

4. Group operations and Jacobi projective coordinates

To eliminate the need to calculate the modular inversion at each step of adding up the curve points, the calculations are converted into Jacobi coordinates:

\[ (X, Y, Z) \implies (x, y) = \left( rac{X}{Z^2}, rac{Y}{Z^3} ight) \] \[ Y^2 \equiv X^3 + 7 Z^6 \pmod p \]

Features of implementation in  libsecp256k1:

  • Specialized doubling and addition formulas that take into account $a = 0$ in the secp256k1 equation.
  • Unified addition/doubling formulas that eliminate branching in borderline cases (when points are equal or mutually opposite).
  • Comparison of coordinates $X_1/Z_1^2 \equiv X_2/Z_2^2 \iff X_1 Z_2^2 \equiv X_2 Z_1^2 \pmod p$ without modular division.
/* Функция сложения точек в смешанных координатах (Jacobian + Affine) */
static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge);

Archived Cryptanalytic Case:  Invalid Curve Attack in ECDH Protocols: If a party receives an unverified point $(x, y)$ that does not lie on $y^2 = x^3 + 7$, the attacker chooses a curve point of low order $n’$, computes the shared secret, and recovers the private key using the CRT (Chinese Remainder Theorem).  libsecp256k1 Strong verification of the point’s location on the curve and a check of order $nP = \mathcal{O}$ are built into the API.

5. Scalar multiplication and GLV endomorphism

The curve $secp256k1$ has an effective Gaitem-Lambert-Vanston (GLV) endomorphism:

\[ \phi(P) = \lambda P = ( eta x, y) \] \[ \lambda^3 \equiv 1 \pmod n, \quad eta^3 \equiv 1 \pmod p \]

During verification, the scalar $k$ is split into $k_1, k_2 pprox 128 ext{ bits}$:

\[ k \cdot P = k_1 \cdot P + k_2 \cdot \phi(P) \]

To verify signatures, Shamir’s Trick and the $w ext{NAF}$ (width-$w$ Non-Adjacent Form) representation are used, which speeds up the $aG + bP$ verification by 25–30%.

Operation modeMultiplication algorithmTime constancyApplication
Signing (Secret Data)Power Table 16 + Branch-free CMOV + Base Randomization (Blinding)Strict Constant-Timesecp256k1_ecdsa_signschnorrsig_sign
Verification (Public Data)GLV decomposition + wNAF + Shamir’s TrickVariable-Time (optimized for network bandwidth)secp256k1_ecdsa_verifyschnorrsig_verify

Archived cryptanalytic precedent:  In 2023, Hertzbleed’s research showed that dynamic processor frequency scheduling (DVFS) converts power consumption differences into timing leaks. To prevent attacks on the deterministic nonce, $k$  libsecp256k1 recommends passing an additional 32-byte entropy in the argument  ndata (BIP-340 / RFC 6979 with extra entropy).

6. Cryptographic modules: ECDSA, Schnorr (BIP-340), MuSig2 (BIP-327)

In addition to the traditional ECDSA, the library contains modern protocols:

  • BIP-340 (Schnorr Signatures):  The linearity of the structure allows for aggregation of keys and signatures, and prevents malleability by fixing the 32-byte $x$-only public key.
  • BIP-327 (MuSig2):  A two-round multisig protocol that is resistant to Wagner attacks on the Generalized Birthday Problem (k-tree) by hashing two nonces $R_1, R_2$.
  • BIP-324 (ElligatorSwift):  Uniform public key encoding to protect Bitcoin node p2p traffic from DPI and censorship.
/* Сборка с включением всех передовых модулей */
cmake -B build \
  -DSECP256K1_ENABLE_MODULE_SCHNORRSIG=ON \
  -DSECP256K1_ENABLE_MODULE_MUSIG=ON \
  -DSECP256K1_ENABLE_MODULE_ELLSWIFT=ON \
  -DSECP256K1_ENABLE_MODULE_RECOVERY=ON
cmake --build build
ctest --test-dir build

Conclusion

The library  libsecp256k1 sets the highest standard in cryptographic engineering, combining mathematical optimizations of the Weierstrass curve with protection against the full range of known cryptanalytic attacks (timing, cache, invalid curve, CRT, LLL/HNP, DPA). The implementation serves as a global benchmark for testing and verifying signatures in decentralized systems.

Bibliography

Bitcoin Core source code. libsecp256k1: Highly secure implementation of secp256k1 operations:  https://goolg.ru/bitcoin-core-source-code-libsecp256k1-highly-secure-implementation-of-secp256k1-operations/

  1. Nguyen, P. Q., & Shparlinski, I. E. (2002). The Insecurity of the Digital Signature Algorithm with Partially Known Nonces.  Journal of Cryptology , 15(3), 151–176.[reference:44][reference:45]
  2. Nguyen, P. Q., & Shparlinski, I. E. (2003). The Insecurity of the Elliptic Curve Digital Signature Algorithm with Partially Known Nonces.  Designs, Codes and Cryptography , 30(2), 151–176.[reference:46]
  3. Boneh, D., & Venkatesan, R. (1996). Hardness of Computing the Most Significant Bits of Secret Keys in Diffie-Hellman and Related Schemes.  Crypto ’96 .[reference:47]
  4. Howgrave-Graham, N., & Smart, N. P. (1999). Lattice Attacks on Digital Signature Schemes.  Designs, Codes and Cryptography , 23(3), 283–290.[reference:48]
  5. Leadbitter, P. J., & Smart, N. P. (2002). Cryptanalysis of MQV with Partially Known Nonces.  IACR ePrint 2002. [reference:49]