UltrafastSecp256k1 3.50.0
Ultra high-performance secp256k1 elliptic curve cryptography library
Loading...
Searching...
No Matches
recovery.hpp
Go to the documentation of this file.
1#ifndef SECP256K1_RECOVERY_HPP
2#define SECP256K1_RECOVERY_HPP
3
4// ============================================================================
5// ECDSA Public Key Recovery -- secp256k1
6// ============================================================================
7// Given an ECDSA signature (r, s) and the message hash, recover the public key
8// that was used to create the signature. Up to 4 candidates exist; the
9// recovery ID (recid = 0..3) selects which one.
10//
11// BIP-137 / Ethereum use recovery IDs (v) to enable address derivation from
12// transaction signatures without transmitting the public key.
13//
14// Usage:
15// // Sign with recovery
16// auto [sig, recid] = ecdsa_sign_recoverable(msg_hash, private_key);
17//
18// // Recover public key
19// auto [pk, ok] = ecdsa_recover(msg_hash, sig, recid);
20// if (ok) { ... pk is the recovered public key ... }
21// ============================================================================
22
23#include <array>
24#include <cstdint>
25#include <utility>
26#include "secp256k1/ecdsa.hpp"
27#include "secp256k1/point.hpp"
28#include "secp256k1/scalar.hpp"
29
30namespace secp256k1 {
31
32using fast::Scalar;
33using fast::Point;
34
35// -- Recoverable Signature ----------------------------------------------------
36
39 int recid; // 0-3: recovery ID
40};
41
42// -- Sign with Recovery ID ----------------------------------------------------
43// Like ecdsa_sign() but also returns the recovery ID needed for recovery.
44// recid encodes:
45// bit 0: parity of R.y (0 = even, 1 = odd)
46// bit 1: whether R.x overflowed the curve order (almost never; r = R.x mod n
47// and R.x could be >= n but < p, happens with probability ~2^-128)
49 const std::array<std::uint8_t, 32>& msg_hash,
50 const Scalar& private_key);
51
52// -- Public Key Recovery ------------------------------------------------------
53// Recovers the public key from a signature and message hash.
54// Returns {Point, bool} where bool indicates success.
55// Fails if:
56// - r or s is zero
57// - R point is not on the curve
58// - Recovered point is infinity
59std::pair<Point, bool> ecdsa_recover(
60 const std::array<std::uint8_t, 32>& msg_hash,
61 const ECDSASignature& sig,
62 int recid);
63
64// -- Compact Recovery Serialization -------------------------------------------
65// 65-byte format: [recid_byte] [r: 32 bytes] [s: 32 bytes]
66// recid_byte = 27 + recid + (compressed ? 4 : 0)
67std::array<std::uint8_t, 65> recoverable_to_compact(
68 const RecoverableSignature& rsig,
69 bool compressed = true);
70
71// Parse 65-byte compact recoverable signature
72// Returns {RecoverableSignature, bool} where bool indicates success
73std::pair<RecoverableSignature, bool> recoverable_from_compact(
74 const std::array<std::uint8_t, 65>& data);
75
76} // namespace secp256k1
77
78#endif // SECP256K1_RECOVERY_HPP
std::array< std::uint8_t, 65 > recoverable_to_compact(const RecoverableSignature &rsig, bool compressed=true)
RecoverableSignature ecdsa_sign_recoverable(const std::array< std::uint8_t, 32 > &msg_hash, const Scalar &private_key)
std::pair< RecoverableSignature, bool > recoverable_from_compact(const std::array< std::uint8_t, 65 > &data)
std::pair< Point, bool > ecdsa_recover(const std::array< std::uint8_t, 32 > &msg_hash, const ECDSASignature &sig, int recid)