UltrafastSecp256k1 3.50.0
Ultra high-performance secp256k1 elliptic curve cryptography library
Loading...
Searching...
No Matches
batch_verify.hpp
Go to the documentation of this file.
1#ifndef SECP256K1_BATCH_VERIFY_HPP
2#define SECP256K1_BATCH_VERIFY_HPP
3#pragma once
4
5// ============================================================================
6// Batch Verification for ECDSA and Schnorr (BIP-340) on secp256k1
7// ============================================================================
8// Verifies N signatures in one multi-scalar multiplication, yielding
9// ~2-3x speedup over N individual verifications for large batches.
10//
11// Method (Schnorr):
12// For signatures (R_i, s_i) on messages m_i with pubkeys P_i:
13// Pick random weights a_i, verify:
14// sum(a_i * s_i) * G == sum(a_i * R_i) + sum(a_i * e_i * P_i)
15//
16// Method (ECDSA):
17// For signatures (r_i, s_i) on messages z_i with pubkeys Q_i:
18// Pick random weights a_i, w_i = s_i^{-1}, verify:
19// sum(a_i * z_i * w_i) * G + sum(a_i * r_i * w_i * Q_i) has x == r_i
20// (ECDSA batch is less efficient than Schnorr batch due to the structure)
21//
22// If batch verification fails, falls back to individual verification to
23// identify the invalid signature(s).
24// ============================================================================
25
26#include <array>
27#include <cstddef>
28#include <cstdint>
29#include <vector>
30#include "secp256k1/ecdsa.hpp"
31#include "secp256k1/schnorr.hpp"
32
33namespace secp256k1 {
34
35// -- Schnorr Batch Verification -----------------------------------------------
36
38 std::array<std::uint8_t, 32> pubkey_x; // X-only public key
39 std::array<std::uint8_t, 32> message; // 32-byte message
41};
42
44 const SchnorrXonlyPubkey* pubkey; // Parsed x-only pubkey; must outlive the batch call
45 std::array<std::uint8_t, 32> message; // 32-byte message
47};
48
49// Verify a batch of Schnorr signatures.
50// Returns true if ALL signatures are valid.
51// Uses random linear combination for efficiency.
52//
53// Performance: ~2-3x faster than N individual schnorr_verify() calls.
54bool schnorr_batch_verify(const SchnorrBatchEntry* entries, std::size_t n);
55bool schnorr_batch_verify(const std::vector<SchnorrBatchEntry>& entries);
56bool schnorr_batch_verify(const SchnorrBatchCachedEntry* entries, std::size_t n);
57bool schnorr_batch_verify(const std::vector<SchnorrBatchCachedEntry>& entries);
58
59// -- ECDSA Batch Verification -------------------------------------------------
60
62 std::array<std::uint8_t, 32> msg_hash; // 32-byte message hash
63 fast::Point public_key; // Full public key point
65};
66
67// Verify a batch of ECDSA signatures.
68// Returns true if ALL signatures are valid.
69//
70// NOTE: ECDSA batch verification is less efficient than Schnorr due to
71// requiring per-signature modular inversions. Speedup is ~1.5-2x.
72bool ecdsa_batch_verify(const ECDSABatchEntry* entries, std::size_t n);
73bool ecdsa_batch_verify(const std::vector<ECDSABatchEntry>& entries);
74
75// -- Identify Invalid Signatures ----------------------------------------------
76
77// After a batch fails, identify which signature(s) are invalid.
78// Returns indices of invalid entries.
79std::vector<std::size_t> schnorr_batch_identify_invalid(
80 const SchnorrBatchEntry* entries, std::size_t n);
81
82std::vector<std::size_t> schnorr_batch_identify_invalid(
83 const SchnorrBatchCachedEntry* entries, std::size_t n);
84
85std::vector<std::size_t> ecdsa_batch_identify_invalid(
86 const ECDSABatchEntry* entries, std::size_t n);
87
88} // namespace secp256k1
89
90#endif // SECP256K1_BATCH_VERIFY_HPP
bool schnorr_batch_verify(const SchnorrBatchEntry *entries, std::size_t n)
std::vector< std::size_t > schnorr_batch_identify_invalid(const SchnorrBatchEntry *entries, std::size_t n)
bool ecdsa_batch_verify(const ECDSABatchEntry *entries, std::size_t n)
std::vector< std::size_t > ecdsa_batch_identify_invalid(const ECDSABatchEntry *entries, std::size_t n)
std::array< std::uint8_t, 32 > msg_hash
std::array< std::uint8_t, 32 > message
const SchnorrXonlyPubkey * pubkey
std::array< std::uint8_t, 32 > message
std::array< std::uint8_t, 32 > pubkey_x