← index

Add optional UltrafastSecp256k1 backend (opt-in, default unchanged)

An archive of delvingbitcoin.org · view original topic →

vano · #1 ·

Overview

UltrafastSecp256k1 v4.0 is a high-performance secp256k1 engine built for evaluation as an optional secondary backend for Bitcoin Core. The goal is not to replace libsecp256k1, but to make it possible to measure, compare, and selectively enable an alternative implementation under controlled conditions.

This post presents the current state of the project, its integration model, and the evidence gathered through continuous audit infrastructure.

Repository: https://github.com/shrec/UltrafastSecp256k1 Release v4.0.0: https://github.com/shrec/UltrafastSecp256k1/releases/tag/v4.0.0


Integration Model

Integration uses a shim layer that exposes the identical secp256k1.h API surface. Bitcoin Core can be built with the alternative backend using a single CMake flag:

cmake -B build -DSECP256K1_BACKEND=ultrafast
cmake --build build

The default backend remains libsecp256k1 unchanged. All existing Bitcoin Core C++ source files remain unmodified — only the CMake build system references a different library.

Fork demonstrating this integration: https://github.com/shrec/bitcoin/tree/feature/ultrafast-secp256k1-backend

Shim API coverage:


Performance — Bitcoin Core Integration Paths

All numbers from bench_bitcoin (Bitcoin Core’s native benchmark harness) on Intel i5-14400F, GCC 14.2.0, Release+LTO, intel_pstate/no_turbo=1, taskset -c 0, nice -20, 5 runs.

Canonical artifact: docs/BITCOIN_CORE_BENCH_RESULTS.json

Transaction signing:

Benchmark Ultra libsecp256k1 Delta
SignSchnorrWithMerkleRoot 83.9 µs 113.4 µs +35% faster
SignSchnorrWithNullMerkleRoot 84.0 µs 113.0 µs +35% faster
SignTransactionECDSA 149.5 µs 165.1 µs +10% faster
SignTransactionSchnorr 125.4 µs 137.5 µs +10% faster

Script verification:

Benchmark Ultra libsecp256k1 Delta
VerifyScriptP2TR_KeyPath 45.4 µs 46.3 µs +2.0% faster
VerifyScriptP2TR_ScriptPath 76.5 µs 83.8 µs +10% faster
VerifyScriptP2WPKH 46.0 µs 45.8 µs parity (within noise)

Block validation aggregate (ConnectBlock, 2000 unique signatures):

Scenario Ultra libsecp256k1 Delta
All ECDSA 254.3 ms 257.4 ms +1.2% faster
All Schnorr 253.0 ms 255.3 ms +0.9% faster
Mixed (2k Schnorr + 1k ECDSA) 253.9 ms 257.7 ms +1.5% faster

Without LTO: ConnectBlock is ~0.5–1.0% slower than libsecp256k1 due to i-cache pressure from a larger code footprint. LTO is required for Ultra to win the aggregate. This tradeoff is documented in docs/SHIM_KNOWN_DIVERGENCES.md.

Bitcoin Core test suite: 749/749 passing with Ultra backend (GCC 14.2.0, May 2026).


Performance — Constant-Time Signing Primitives

From docs/bench_unified_2026-05-16_gcc14_x86-64.json. CT-vs-CT co-measured in the same run (ratios are TSC-independent):

Operation Ultra CT libsecp256k1 Ratio
CT ECDSA sign 21.6 µs 59.7 µs 1.30× faster
CT Schnorr sign (BIP-340) 18.1 µs 46.5 µs 1.28× faster
Schnorr verify 84.3 µs 84.3 µs equal

Field arithmetic primitives:

Primitive Ultra libsecp256k1 Ratio
field_mul 20.1 ns 26.5 ns 1.32×
field_sqr 18.7 ns 22.3 ns 1.19×
field_inv 1253.9 ns 1506.0 ns 1.20×
field_from_bytes 4.8 ns 13.0 ns 2.71×

Continuous Audit and Assurance (CAAS)

The repository includes a continuous audit infrastructure tracking security regressions across every commit.

Current state at v4.0.0:

Source: docs/SECURITY_AUTONOMY_KPI.json

Audit surfaces include: nonce reuse, side-channel timing (dudect), CT boundary verification, batch verify soundness, MuSig2/FROST protocol attacks, adaptor signatures, DER BIP-66 strict parsing, BIP-340/RFC-6979 known-answer tests, Wycheproof vectors, structure-aware fuzzing, differential testing vs libsecp256k1, and Python-based algebraic property testing.

Security properties enforced:


Benchmarking Methodology

Benchmarks distinguish between:

All claimed improvements include error percentage from nanobench’s internal statistics. Inconclusive results (overlapping ranges) are reported as such. Results are reproducible from the canonical JSON artifacts in the repository.


Reproducibility

Builds are deterministic:


Platform Coverage

CI passing on all platforms as of v4.0.0:

Platform Architecture Compiler
Linux x86-64-v3 GCC 14 / Clang 17
Linux ARM64 GCC 14
Linux RISC-V 64 GCC 14
macOS ARM64 (Apple Silicon) Clang 15
Windows x86-64 MSVC / GCC

Additional: Android ARM64 (NDK), WASM, ESP32, STM32.


Known Limitations


Current Objective

No mandatory integration path is proposed. The current objective is to make an alternative backend available for evaluation on technical grounds, with reproducible evidence, minimal integration surface, and an easy rollback path.

The default backend remains libsecp256k1. All existing behavior is preserved unless the new backend is explicitly enabled at build time.


Reviewer Entry Path

git clone https://github.com/shrec/UltrafastSecp256k1
cd UltrafastSecp256k1
python3 ci/verify_external_audit_bundle.py --allow-commit-mismatch

Key documents:


All performance numbers are from controlled benchmark runs with hard turbo lock. Raw data available in the repository. Canonical benchmark artifact: docs/BITCOIN_CORE_BENCH_RESULTS.json, docs/bench_unified_2026-05-16_gcc14_x86-64.json.

vano · #2 ·

Update (2026-05-17)

Two small things done since the original post:

1. Schnorr verify now accepts any msglen

secp256k1_schnorrsig_verify in the shim was previously restricted to msglen == 32. Updated to match libsecp256k1’s behavior — any length is accepted, with the BIP-340 challenge computed as H_BIP0340/challenge(R.x || P.x || msg[:msglen]). The 32-byte path still uses the optimized fixed-length code.

2. CAAS suite validated against libsecp256k1 itself

As a sanity check on methodology, ran the CAAS Python audit scripts against bitcoin-core/libsecp256k1 directly using a thin reverse bridge shim:

Script Result
Invalid input grammar (27 cases) :white_check_mark: all pass
RFC 6979 spec verifier (202 vectors) :white_check_mark: all match
Nonce bias detector (5,000 samples) :white_check_mark: no bias (p=0.29)
Semantic properties (2,800 checks) :white_check_mark: all pass

libsecp256k1 passes everywhere it implements the feature. BIP-32 cases return advisory skip (rc=77) as expected — libsecp has no BIP-32 module.

This confirms the audit suite is testing actual cryptographic properties rather than implementation-specific behavior. The same suite then passes on UltrafastSecp256k1.