UltrafastSecp256k1/docs/wiki/API-Reference.md
vano be528aef66 audit: add AUDIT_COVERAGE.md + ASCII cleanup + CT fixes
- Add comprehensive AUDIT_COVERAGE.md documenting all 46 audit modules
  across 8 sections with ~1M+ total assertions
- Pure ASCII cleanup: remove all Unicode from source/cmake/script files
  (box-drawing, arrows, Greek, emoji, BOM, Georgian in comments)
- CT fix: RISC-V is_zero_mask (seqz+neg inline asm)
- CT fix: ct_compare general path (snez)
- All 188 files updated for ASCII-only compliance (Section 17 rule)
- Verified: 46/46 audit PASS on X64, ARM64, RISC-V (QEMU + Mars HW)
- Verified: 24/24 CTest PASS on X64
2026-02-25 19:14:21 +04:00

16 KiB

API Reference

Complete API documentation for UltrafastSecp256k1.

For the full detailed reference, see docs/API_REFERENCE.md.


CPU API

Namespace: secp256k1::fast

Headers:

#include <secp256k1/field.hpp>    // FieldElement
#include <secp256k1/scalar.hpp>   // Scalar
#include <secp256k1/point.hpp>    // Point, KPlan, Selftest
#include <secp256k1/ecdsa.hpp>    // ECDSA sign/verify
#include <secp256k1/schnorr.hpp>  // Schnorr BIP-340 sign/verify
#include <secp256k1/ecdh.hpp>     // ECDH key exchange
#include <secp256k1/bip32.hpp>    // BIP-32 HD derivation
#include <secp256k1/address.hpp>  // Address generation (P2PKH, P2WPKH, P2TR)
#include <secp256k1/wif.hpp>      // WIF encode/decode
#include <secp256k1/sha256.hpp>   // SHA-256 (SHA-NI accelerated)

FieldElement

256-bit field element for secp256k1 (mod p where p = 2^256 - 2^32 - 977).

Construction

Method Description
FieldElement::zero() Zero element
FieldElement::one() One element
FieldElement::from_uint64(val) From 64-bit integer
FieldElement::from_limbs(arr) From 4x64-bit array (little-endian)
FieldElement::from_bytes(arr) From 32 bytes (big-endian)
FieldElement::from_hex(str) From hex string (64 chars)

Arithmetic

Operator/Method Description
a + b Addition
a - b Subtraction
a * b Multiplication
a.square() Squaring (a^2)
a.inverse() Modular inverse (a^-1)
a += b In-place addition
a -= b In-place subtraction
a *= b In-place multiplication
a.square_inplace() In-place squaring
a.inverse_inplace() In-place inverse

Serialization

Method Description
a.to_bytes() To 32 bytes (big-endian)
a.to_bytes_into(ptr) To buffer (no allocation)
a.to_hex() To hex string
a.limbs() Raw limb access

Comparison

Operator Description
a == b Equality
a != b Inequality

Scalar

256-bit scalar for secp256k1 (mod n, the group order).

Construction

Method Description
Scalar::zero() Zero
Scalar::one() One
Scalar::from_uint64(val) From 64-bit integer
Scalar::from_limbs(arr) From 4x64-bit array
Scalar::from_bytes(arr) From 32 bytes (big-endian)
Scalar::from_hex(str) From hex string

Arithmetic

Operator Description
a + b Addition (mod n)
a - b Subtraction (mod n)
a * b Multiplication (mod n)

Utility

Method Description
s.is_zero() Check if zero
s.bit(i) Get i-th bit
s.to_naf() NAF encoding
s.to_wnaf(w) wNAF encoding

Point

Elliptic curve point on secp256k1 (Jacobian coordinates internally).

Construction

Method Description
Point::generator() Generator point G
Point::infinity() Point at infinity
Point::from_affine(x, y) From affine coordinates
Point::from_hex(x_hex, y_hex) From hex strings

Point Operations

Method Description
p.add(q) Point addition (p + q)
p.dbl() Point doubling (2p)
p.scalar_mul(k) Scalar multiplication (k*p)
p.negate() Negation (-p)

Optimized Operations

Method Description
p.scalar_mul_with_plan(plan) Fixed-K multiplication (fastest)
p.next() p + G
p.prev() p - G
p.add_mixed_inplace(x, y) Mixed Jacobian+Affine addition (7M + 4S)

In-Place Operations

Method Description
p.add_inplace(q) p += q
p.sub_inplace(q) p -= q
p.dbl_inplace() p = 2p
p.negate_inplace() p = -p
p.next_inplace() p += G
p.prev_inplace() p -= G

Serialization

Method Description
p.x() Affine x-coordinate
p.y() Affine y-coordinate
p.to_compressed() 33-byte compressed format
p.to_uncompressed() 65-byte uncompressed format
p.x_first_half() First 16 bytes of x
p.x_second_half() Last 16 bytes of x

Properties

Method Description
p.is_infinity() Check if point at infinity
p.X(), p.Y(), p.z() Raw Jacobian coordinates

KPlan

Pre-computed plan for fixed-K scalar multiplication.

// Create plan once
Scalar K = Scalar::from_hex("...");
KPlan plan = KPlan::from_scalar(K);

// Use for multiple Q values (reuses cached GLV decomposition + wNAF)
Point R1 = Q1.scalar_mul_with_plan(plan);
Point R2 = Q2.scalar_mul_with_plan(plan);

Selftest

#include "secp256k1/selftest.hpp"
using namespace secp256k1::fast;

// Quick startup check
Selftest(true, SelftestMode::smoke);

// Full CI suite
Selftest(true, SelftestMode::ci);

// Nightly stress test with custom seed
Selftest(true, SelftestMode::stress, 0xDEADBEEF);

ECDSA (RFC 6979)

Header: #include <secp256k1/ecdsa.hpp>

Functions

Function Description
ecdsa_sign(msg_hash, seckey) Sign with RFC 6979 deterministic nonces, low-S normalization
ecdsa_verify(msg_hash, pubkey, sig) Verify ECDSA signature
ecdsa_sign_recoverable(msg_hash, seckey) Sign with recovery ID (for EIP-155)
ecdsa_recover(msg_hash, sig, recid) Recover public key from signature

Example

#include <secp256k1/ecdsa.hpp>
using namespace secp256k1::fast;

// Sign
uint8_t msg_hash[32] = { /* SHA-256 of message */ };
Scalar seckey = Scalar::from_hex("...");
auto [sig_r, sig_s] = ecdsa_sign(msg_hash, seckey);

// Verify
Point pubkey = Point::generator().scalar_mul(seckey);
bool valid = ecdsa_verify(msg_hash, pubkey, sig_r, sig_s);

Performance (x86-64)

Operation Time
ECDSA Sign 8.5 us
ECDSA Verify 23.6 us

Schnorr (BIP-340)

Header: #include <secp256k1/schnorr.hpp>

Functions

Function Description
schnorr_sign(msg, seckey, aux_rand) BIP-340 Schnorr sign with tagged hashing
schnorr_verify(msg, pubkey_x, sig) BIP-340 Schnorr verify with x-only pubkey

Example

#include <secp256k1/schnorr.hpp>
using namespace secp256k1::fast;

uint8_t msg[32] = { /* message hash */ };
uint8_t aux[32] = { /* auxiliary randomness */ };
Scalar seckey = Scalar::from_hex("...");
auto sig = schnorr_sign(msg, seckey, aux);

// Verify with x-only pubkey (32 bytes)
auto pubkey_x = Point::generator().scalar_mul(seckey).x().to_bytes();
bool valid = schnorr_verify(msg, pubkey_x, sig);

Performance (x86-64)

Operation Time
Schnorr Sign 6.8 us
Schnorr Verify 24.0 us

ECDH

Header: #include <secp256k1/ecdh.hpp>

Functions

Function Description
ecdh_raw(seckey, pubkey) Raw ECDH shared point
ecdh_xonly(seckey, pubkey) x-coordinate only (32 bytes)
ecdh_compressed(seckey, pubkey) SHA-256(compressed shared point)

Example

#include <secp256k1/ecdh.hpp>
using namespace secp256k1::fast;
namespace ct = secp256k1::ct;

Scalar alice_sk = Scalar::from_hex("...");
Point bob_pk = Point::from_hex("...", "...");

// Use CT for secret-dependent operations!
Point shared = ct::scalar_mul(bob_pk, alice_sk);
auto secret = shared.x().to_bytes();  // 32-byte shared secret

Performance (x86-64)

Operation Time
ECDH 23.9 us

BIP-32 HD Derivation

Header: #include <secp256k1/bip32.hpp>

Functions

Function Description
bip32_from_seed(seed, seed_len) Master key from seed
bip32_derive_child(parent, index) Derive child key (hardened if index >= 0x80000000)
bip32_serialize(key, version) Serialize to xprv/xpub

Derivation Paths

Supports all standard BIP-44 paths for 27 blockchains:


Address Generation

Header: #include <secp256k1/address.hpp>

Functions

Function Description
address_p2pkh(pubkey, version) Pay-to-Public-Key-Hash (Base58Check)
address_p2wpkh(pubkey, hrp) Pay-to-Witness-Public-Key-Hash (Bech32)
address_p2tr(pubkey_x, hrp) Pay-to-Taproot (Bech32m)
address_eip55(pubkey) Ethereum EIP-55 checksummed address

SHA-256

Header: #include <secp256k1/sha256.hpp>

Hardware-accelerated when SHA-NI is available.

Function Description
sha256(data, len) Single-shot SHA-256
sha256_hmac(key, data) HMAC-SHA-256

Constant-Time (CT) API

Namespace: secp256k1::ct

Headers:

#include <secp256k1/ct/ops.hpp>    // Low-level CT primitives
#include <secp256k1/ct/field.hpp>  // CT field arithmetic
#include <secp256k1/ct/scalar.hpp> // CT scalar arithmetic
#include <secp256k1/ct/point.hpp>  // CT point operations

All CT functions operate on the same types as fast:: (FieldElement, Scalar, Point). Both namespaces are always compiled -- no flags or #ifdef needed.


CT Primitives (ct/ops.hpp)

Low-level building blocks. Every function has a data-independent execution trace.

Function Description
value_barrier(v) Compiler optimization barrier
is_zero_mask(v) Returns 0xFFF...F if v == 0, else 0
is_nonzero_mask(v) Returns 0xFFF...F if v != 0, else 0
eq_mask(a, b) Returns 0xFFF...F if a == b, else 0
bool_to_mask(flag) Converts bool to all-ones/all-zeros mask
lt_mask(a, b) Returns all-ones if a < b (unsigned)
cmov64(dst, src, mask) CT conditional move (64-bit)
cmov256(dst, src, mask) CT conditional move (4x64-bit)
cswap256(a, b, mask) CT conditional swap (4x64-bit)
ct_select(a, b, mask) Returns a if mask=all-ones, else b
ct_lookup(table, count, stride, index, out) CT table lookup (scans all entries)
ct_lookup_256(table, count, index, out) CT lookup for 256-bit entries

CT Field Operations (ct/field.hpp)

Function Description
field_add(a, b) CT addition mod p
field_sub(a, b) CT subtraction mod p
field_mul(a, b) CT multiplication mod p
field_sqr(a) CT squaring mod p
field_neg(a) CT negation mod p
field_inv(a) CT inverse (addition-chain Fermat, fixed 255 sqr + 14 mul)
field_cmov(r, a, mask) CT conditional move
field_cswap(a, b, mask) CT conditional swap
field_select(a, b, mask) CT select: a if mask=1s, else b
field_cneg(a, mask) CT conditional negate
field_is_zero(a) CT zero check -> mask
field_eq(a, b) CT equality -> mask
field_normalize(a) CT reduce to canonical form

CT Scalar Operations (ct/scalar.hpp)

Function Description
scalar_add(a, b) CT addition mod n
scalar_sub(a, b) CT subtraction mod n
scalar_neg(a) CT negation mod n
scalar_cmov(r, a, mask) CT conditional move
scalar_cswap(a, b, mask) CT conditional swap
scalar_select(a, b, mask) CT select
scalar_cneg(a, mask) CT conditional negate
scalar_is_zero(a) CT zero check -> mask
scalar_eq(a, b) CT equality -> mask
scalar_bit(a, index) CT bit access (reads all limbs)
scalar_window(a, pos, width) CT w-bit window extraction

CT Point Operations (ct/point.hpp)

Function Description
point_add_complete(p, q) Complete addition (handles all cases branchlessly)
point_dbl(p) CT doubling
point_neg(p) CT negation
point_cmov(r, a, mask) CT conditional move
point_select(a, b, mask) CT select
point_table_lookup(table, size, index) CT table lookup (scans all entries)
scalar_mul(p, k) CT scalar multiplication (GLV + effective-affine)
generator_mul(k) CT generator multiplication (k*G, precomputed table)
point_is_on_curve(p) CT curve membership check -> mask
point_eq(a, b) CT point equality -> mask

CTJacobianPoint

Internal representation with uint64_t infinity flag (for branchless operations):

struct CTJacobianPoint {
    FieldElement x, y, z;
    std::uint64_t infinity;  // 0 = normal, 0xFFF...F = infinity

    static CTJacobianPoint from_point(const Point& p) noexcept;
    Point to_point() const noexcept;
    static CTJacobianPoint make_infinity() noexcept;
};

Stable C ABI (ufsecp)

Header: #include "ufsecp.h"

Starting with v3.4.0, UltrafastSecp256k1 ships a stable C ABI designed for FFI bindings (C#, Python, Rust, Go, Java, Node.js, etc.). 45 exported functions.

Context Management

ufsecp_ctx* ctx = NULL;
ufsecp_ctx_create(&ctx);
// ... use ctx ...
ufsecp_ctx_destroy(ctx);

API Categories

Category Functions
Context ctx_create, ctx_destroy, selftest, last_error
Keys keygen, seckey_verify, pubkey_create, pubkey_parse, pubkey_serialize
ECDSA ecdsa_sign, ecdsa_verify, ecdsa_sign_der, ecdsa_verify_der, ecdsa_recover
Schnorr schnorr_sign, schnorr_verify
SHA-256 sha256 (SHA-NI accelerated)
ECDH ecdh_compressed, ecdh_xonly, ecdh_raw
BIP-32 bip32_from_seed, bip32_derive_child, bip32_serialize
Address address_p2pkh, address_p2wpkh, address_p2tr
WIF wif_encode, wif_decode
Tweak pubkey_tweak_add, pubkey_tweak_mul
Version version, abi_version, version_string

Quick Example (C)

#include "ufsecp.h"

ufsecp_ctx* ctx = NULL;
ufsecp_ctx_create(&ctx);

unsigned char seckey[32], pubkey[33];
ufsecp_keygen(ctx, seckey, pubkey);

unsigned char msg[32] = { /* SHA-256 hash */ };
unsigned char sig[64];
ufsecp_ecdsa_sign(ctx, seckey, msg, sig);

int valid = 0;
ufsecp_ecdsa_verify(ctx, pubkey, 33, msg, sig, &valid);

ufsecp_ctx_destroy(ctx);

CUDA API

Namespace: secp256k1::cuda

Header: #include <secp256k1.cuh>

Data Structures

struct FieldElement { uint64_t limbs[4]; };
struct Scalar { uint64_t limbs[4]; };
struct JacobianPoint { FieldElement x, y, z; bool infinity; };
struct AffinePoint { FieldElement x, y; };

Device Functions

Function Description
field_add(a, b, r) r = a + b
field_sub(a, b, r) r = a - b
field_mul(a, b, r) r = a * b
field_sqr(a, r) r = a^2
field_inv(a, r) r = a^-1
jacobian_add(p, q, r) r = p + q
jacobian_double(p, r) r = 2p
scalar_mul(p, k, r) r = k*p
jacobian_to_affine(p, r) Convert to affine

GPU Signature Operations (v3.6.0+)

#include <ecdsa.cuh>
#include <schnorr.cuh>
#include <recovery.cuh>

// ECDSA (RFC 6979, low-S, Shamir + GLV)
__device__ bool ecdsa_sign(msg_hash, privkey, sig);
__device__ bool ecdsa_verify(msg_hash, pubkey, sig);
__device__ bool ecdsa_sign_recoverable(msg_hash, privkey, sig);
__device__ bool ecdsa_recover(msg_hash, sig, pubkey);

// Schnorr BIP-340 (tagged hash midstates)
__device__ bool schnorr_sign(privkey, msg, aux, sig);
__device__ bool schnorr_verify(pubkey_x, msg, sig);

Hash Functions

#include <hash160.cuh>

__device__ void hash160_compressed(const uint8_t pubkey[33], uint8_t hash[20]);
__device__ void hash160_uncompressed(const uint8_t pubkey[65], uint8_t hash[20]);

See Also