Convert Figma logo to code with AI

bitcoin-core logosecp256k1

Optimized C library for EC operations on curve secp256k1

2,048
993
2,048
149

Top Related Projects

Fast Elliptic Curve Cryptography in plain javascript

Quick Overview

The bitcoin-core/secp256k1 repository is an optimized C library for elliptic curve operations on the secp256k1 curve. This curve is used in Bitcoin's public key cryptography and digital signature algorithms. The library provides high-performance implementations of various cryptographic operations essential for Bitcoin and other cryptocurrencies.

Pros

  • Extremely optimized for performance, making it ideal for high-throughput cryptographic operations
  • Extensively tested and audited, ensuring reliability and security
  • Designed with side-channel attack resistance in mind
  • Provides a clean API for easy integration into other projects

Cons

  • Limited to operations on the secp256k1 curve, not a general-purpose cryptographic library
  • Requires careful use and understanding of cryptographic principles to implement securely
  • May have a steeper learning curve compared to higher-level cryptographic libraries

Code Examples

  1. Creating and verifying a signature:
#include <secp256k1.h>

// Create a context
secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);

// Generate a private key
unsigned char seckey[32];
secp256k1_keypair keypair;
secp256k1_keypair_create(ctx, &keypair, seckey);

// Sign a message
unsigned char msg[32] = {...};  // 32-byte message to sign
secp256k1_ecdsa_signature signature;
secp256k1_ecdsa_sign(ctx, &signature, msg, seckey, NULL, NULL);

// Verify the signature
secp256k1_pubkey pubkey;
secp256k1_keypair_pub(ctx, &pubkey, &keypair);
int result = secp256k1_ecdsa_verify(ctx, &signature, msg, &pubkey);
  1. Performing key exchange:
#include <secp256k1.h>

// Generate two key pairs
secp256k1_keypair keypair1, keypair2;
secp256k1_keypair_create(ctx, &keypair1, seckey1);
secp256k1_keypair_create(ctx, &keypair2, seckey2);

// Perform ECDH
unsigned char shared_secret[32];
secp256k1_pubkey pubkey2;
secp256k1_keypair_pub(ctx, &pubkey2, &keypair2);
secp256k1_ecdh(ctx, shared_secret, &pubkey2, seckey1, NULL, NULL);
  1. Generating a public key:
#include <secp256k1.h>

// Generate a private key
unsigned char seckey[32];
secp256k1_pubkey pubkey;

// Create the public key
secp256k1_ec_pubkey_create(ctx, &pubkey, seckey);

// Serialize the public key
unsigned char output[65];
size_t outputlen = 65;
secp256k1_ec_pubkey_serialize(ctx, output, &outputlen, &pubkey, SECP256K1_EC_UNCOMPRESSED);

Getting Started

To use the secp256k1 library in your project:

  1. Clone the repository:

    git clone https://github.com/bitcoin-core/secp256k1.git
    
  2. Build the library:

    cd secp256k1
    ./autogen.sh
    ./configure
    make
    make check
    
  3. Include the header in your C code:

    #include <secp256k1.h>
    
  4. Link against the built library when compiling your project.

Remember to create and destroy the context appropriately in your application:

secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
// Use the context...
secp256k1_context_destroy(

Competitor Comparisons

Fast Elliptic Curve Cryptography in plain javascript

Pros of elliptic

  • Written in JavaScript, making it easily integrable into web and Node.js applications
  • Supports a wider range of elliptic curves, including secp256k1, p192, p224, p384, p521
  • More flexible and customizable for various use cases beyond cryptocurrency

Cons of elliptic

  • Generally slower performance compared to secp256k1's optimized C implementation
  • May have a larger attack surface due to its broader feature set
  • Less specialized for Bitcoin-specific use cases

Code Comparison

secp256k1:

static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) {
    unsigned char c[32];
    secp256k1_scalar sn, u1, u2;
    secp256k1_fe xr;
    secp256k1_gej pubkeyj;
    secp256k1_gej pr;

elliptic:

ECDSA.prototype.verify = function verify(msg, signature, key, enc) {
  msg = this._truncateToN(new BN(msg, 16));
  key = this.keyFromPublic(key, enc);
  signature = new Signature(signature, 'hex');

  // Perform primitive values validation

Both libraries implement ECDSA signature verification, but secp256k1 uses low-level C operations for optimized performance, while elliptic uses higher-level JavaScript constructs for better readability and flexibility.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

libsecp256k1

Dependencies: None irc.libera.chat #secp256k1

High-performance high-assurance C library for digital signatures and other cryptographic primitives on the secp256k1 elliptic curve.

This library is intended to be the highest quality publicly available library for cryptography on the secp256k1 curve. However, the primary focus of its development has been for usage in the Bitcoin system and usage unlike Bitcoin's may be less well tested, verified, or suffer from a less well thought out interface. Correct usage requires some care and consideration that the library is fit for your application's purpose.

Features:

  • secp256k1 ECDSA signing/verification and key generation.
  • Additive and multiplicative tweaking of secret/public keys.
  • Serialization/parsing of secret keys, public keys, signatures.
  • Constant time, constant memory access signing and public key generation.
  • Derandomized ECDSA (via RFC6979 or with a caller provided function.)
  • Very efficient implementation.
  • Suitable for embedded systems.
  • No runtime dependencies.
  • Optional module for public key recovery.
  • Optional module for ECDH key exchange.
  • Optional module for Schnorr signatures according to BIP-340.
  • Optional module for ElligatorSwift key exchange according to BIP-324.

Implementation details

  • General
    • No runtime heap allocation.
    • Extensive testing infrastructure.
    • Structured to facilitate review and analysis.
    • Intended to be portable to any system with a C89 compiler and uint64_t support.
    • No use of floating types.
    • Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.")
  • Field operations
    • Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1).
      • Using 5 52-bit limbs
      • Using 10 26-bit limbs (including hand-optimized assembly for 32-bit ARM, by Wladimir J. van der Laan).
        • This is an experimental feature that has not received enough scrutiny to satisfy the standard of quality of this library but is made available for testing and review by the community.
  • Scalar operations
    • Optimized implementation without data-dependent branches of arithmetic modulo the curve's order.
      • Using 4 64-bit limbs (relying on __int128 support in the compiler).
      • Using 8 32-bit limbs.
  • Modular inverses (both field elements and scalars) based on safegcd with some modifications, and a variable-time variant (by Peter Dettman).
  • Group operations
    • Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7).
    • Use addition between points in Jacobian and affine coordinates where possible.
    • Use a unified addition/doubling formula where necessary to avoid data-dependent branches.
    • Point/x comparison without a field inversion by comparison in the Jacobian coordinate space.
  • Point multiplication for verification (aP + bG).
    • Use wNAF notation for point multiplicands.
    • Use a much larger window for multiples of G, using precomputed multiples.
    • Use Shamir's trick to do the multiplication with the public key and the generator simultaneously.
    • Use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones.
  • Point multiplication for signing
    • Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions.
    • Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains)
      • Access the table with branch-free conditional moves so memory access is uniform.
      • No data-dependent branches
    • Optional runtime blinding which attempts to frustrate differential power analysis.
    • The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally.

Building with Autotools

$ ./autogen.sh
$ ./configure
$ make
$ make check  # run the test suite
$ sudo make install  # optional

To compile optional modules (such as Schnorr signatures), you need to run ./configure with additional flags (such as --enable-module-schnorrsig). Run ./configure --help to see the full list of available flags.

Building with CMake (experimental)

To maintain a pristine source tree, CMake encourages to perform an out-of-source build by using a separate dedicated build tree.

Building on POSIX systems

$ mkdir build && cd build
$ cmake ..
$ cmake --build .
$ ctest  # run the test suite
$ sudo cmake --install .  # optional

To compile optional modules (such as Schnorr signatures), you need to run cmake with additional flags (such as -DSECP256K1_ENABLE_MODULE_SCHNORRSIG=ON). Run cmake .. -LH to see the full list of available flags.

Cross compiling

To alleviate issues with cross compiling, preconfigured toolchain files are available in the cmake directory. For example, to cross compile for Windows:

$ cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-w64-mingw32.toolchain.cmake

To cross compile for Android with NDK (using NDK's toolchain file, and assuming the ANDROID_NDK_ROOT environment variable has been set):

$ cmake .. -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=28

Building on Windows

To build on Windows with Visual Studio, a proper generator must be specified for a new build tree.

The following example assumes using of Visual Studio 2022 and CMake v3.21+.

In "Developer Command Prompt for VS 2022":

>cmake -G "Visual Studio 17 2022" -A x64 -S . -B build
>cmake --build build --config RelWithDebInfo

Usage examples

Usage examples can be found in the examples directory. To compile them you need to configure with --enable-examples.

To compile the Schnorr signature and ECDH examples, you also need to configure with --enable-module-schnorrsig and --enable-module-ecdh.

Benchmark

If configured with --enable-benchmark (which is the default), binaries for benchmarking the libsecp256k1 functions will be present in the root directory after the build.

To print the benchmark result to the command line:

$ ./bench_name

To create a CSV file for the benchmark result :

$ ./bench_name | sed '2d;s/ \{1,\}//g' > bench_name.csv

Reporting a vulnerability

See SECURITY.md

Contributing to libsecp256k1

See CONTRIBUTING.md