UltrafastSecp256k1 3.50.0
Ultra high-performance secp256k1 elliptic curve cryptography library
Loading...
Searching...
No Matches
adaptor.hpp
Go to the documentation of this file.
1#ifndef SECP256K1_ADAPTOR_HPP
2#define SECP256K1_ADAPTOR_HPP
3#pragma once
4
5// ============================================================================
6// Adaptor Signatures for secp256k1
7// ============================================================================
8// Adaptor signatures enable atomic protocols like:
9// - Atomic swaps (cross-chain)
10// - Discreet Log Contracts (DLCs)
11// - Payment channel protocols
12//
13// Protocol:
14// 1. Signer creates pre-signature sigma~ w.r.t. adaptor point T = t*G
15// 2. Verifier checks pre-signature validity against T
16// 3. Once signer learns secret t, they adapt sigma~ -> valid signature sigma
17// 4. Verifier extracts t from (sigma~, sigma)
18//
19// Works with both ECDSA and Schnorr signatures.
20// ============================================================================
21
22#include <array>
23#include <cstdint>
24#include <utility>
25#include "secp256k1/scalar.hpp"
26#include "secp256k1/point.hpp"
27#include "secp256k1/schnorr.hpp"
28#include "secp256k1/ecdsa.hpp"
29
30namespace secp256k1 {
31
32// -- Schnorr Adaptor Signatures -----------------------------------------------
33
34// Pre-signature (adaptor signature) for Schnorr
36 fast::Point R_hat; // R^ = k*G (before adapting with T)
37 fast::Scalar s_hat; // s = k - e*x (partial, needs adapting)
38 bool needs_negation; // Whether R^+T has even y (BIP-340)
39};
40
41// Create Schnorr adaptor pre-signature
42// Signs message but locks the result: needs adaptor secret t to complete.
43// adaptor_point: T = t*G (public adaptor point)
44// private_key: signer's private key
45// msg: 32-byte message
46// aux_rand: 32 bytes auxiliary randomness
49 const std::array<std::uint8_t, 32>& msg,
50 const fast::Point& adaptor_point,
51 const std::array<std::uint8_t, 32>& aux_rand);
52
53// Verify a Schnorr adaptor pre-signature
54// Checks: s*G == R^ - e*P (where e = H(R^+T, P, m))
56 const std::array<std::uint8_t, 32>& pubkey_x,
57 const std::array<std::uint8_t, 32>& msg,
58 const fast::Point& adaptor_point);
59
60// Adapt pre-signature with secret t to produce valid Schnorr signature
61// sigma = (R^+T, s+t)
64 const fast::Scalar& adaptor_secret);
65
66// Extract adaptor secret t from pre-signature and completed signature
67// t = s - s (mod n)
68std::pair<fast::Scalar, bool>
70 const SchnorrSignature& sig);
71
72// -- ECDSA Adaptor Signatures -------------------------------------------------
73
74// Pre-signature for ECDSA adaptor
76 fast::Point R_hat; // R^ = k*G
77 fast::Scalar s_hat; // Encrypted signature scalar
78 fast::Scalar r; // r = x-coord of (R^ + T)
79};
80
81// Create ECDSA adaptor pre-signature
84 const std::array<std::uint8_t, 32>& msg_hash,
85 const fast::Point& adaptor_point);
86
87// Verify ECDSA adaptor pre-signature
89 const fast::Point& public_key,
90 const std::array<std::uint8_t, 32>& msg_hash,
91 const fast::Point& adaptor_point);
92
93// Adapt ECDSA pre-signature to valid signature with adaptor secret
96 const fast::Scalar& adaptor_secret);
97
98// Extract adaptor secret from ECDSA pre-sig and completed sig
99std::pair<fast::Scalar, bool>
101 const ECDSASignature& sig);
102
103} // namespace secp256k1
104
105#endif // SECP256K1_ADAPTOR_HPP
bool schnorr_adaptor_verify(const SchnorrAdaptorSig &pre_sig, const std::array< std::uint8_t, 32 > &pubkey_x, const std::array< std::uint8_t, 32 > &msg, const fast::Point &adaptor_point)
SchnorrAdaptorSig schnorr_adaptor_sign(const fast::Scalar &private_key, const std::array< std::uint8_t, 32 > &msg, const fast::Point &adaptor_point, const std::array< std::uint8_t, 32 > &aux_rand)
ECDSAAdaptorSig ecdsa_adaptor_sign(const fast::Scalar &private_key, const std::array< std::uint8_t, 32 > &msg_hash, const fast::Point &adaptor_point)
ECDSASignature ecdsa_adaptor_adapt(const ECDSAAdaptorSig &pre_sig, const fast::Scalar &adaptor_secret)
std::pair< fast::Scalar, bool > ecdsa_adaptor_extract(const ECDSAAdaptorSig &pre_sig, const ECDSASignature &sig)
std::pair< fast::Scalar, bool > schnorr_adaptor_extract(const SchnorrAdaptorSig &pre_sig, const SchnorrSignature &sig)
SchnorrSignature schnorr_adaptor_adapt(const SchnorrAdaptorSig &pre_sig, const fast::Scalar &adaptor_secret)
bool ecdsa_adaptor_verify(const ECDSAAdaptorSig &pre_sig, const fast::Point &public_key, const std::array< std::uint8_t, 32 > &msg_hash, const fast::Point &adaptor_point)