UltrafastSecp256k1 3.68.0
Ultra high-performance secp256k1 elliptic curve cryptography library
Loading...
Searching...
No Matches
ellswift.hpp
Go to the documentation of this file.
1#ifndef SECP256K1_ELLSWIFT_HPP
2#define SECP256K1_ELLSWIFT_HPP
3#pragma once
4
5// ============================================================================
6// ElligatorSwift encoding for secp256k1 (BIP-324)
7// ============================================================================
8// Implements the ElligatorSwift encoding as specified in BIP-324, which uses
9// a variant of the Elligator Squared technique to encode secp256k1 public keys
10// as uniformly random-looking 64-byte strings.
11//
12// The encoding is:
13// ellswift_encode(pubkey) -> 64 bytes (u || t), indistinguishable from random
14// ellswift_decode(64 bytes) -> pubkey (x-only)
15//
16// For BIP-324 ECDH:
17// ellswift_xdh(our_ell64, their_ell64, our_privkey, initiator) -> 32-byte secret
18//
19// Reference: BIP-324, https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki
20// ============================================================================
21
22#include <array>
23#include <cstdint>
24#include <cstddef>
25#include "secp256k1/point.hpp"
26#include "secp256k1/scalar.hpp"
27#include "secp256k1/field.hpp"
28
29namespace secp256k1 {
30
31using fast::Scalar;
32using fast::Point;
33using fast::FieldElement;
34
35// -- ElligatorSwift encoding/decoding -----------------------------------------
36
37// Decode a 64-byte ElligatorSwift encoding to an x-coordinate.
38// Returns the x-coordinate of the encoded point.
39FieldElement ellswift_decode(const std::uint8_t encoding[64]) noexcept;
40
41// Create a 64-byte ElligatorSwift encoding from a private key.
42// Generates a uniformly random-looking 64 bytes that encodes privkey * G.
43// Uses OS CSPRNG for the randomness needed by the encoding.
44std::array<std::uint8_t, 64> ellswift_create(const Scalar& privkey);
45
46// Auxrnd variant: mixes auxrnd32 into the encoding RNG (matches libsecp256k1
47// secp256k1_ellswift_create auxrnd32 semantics). When auxrnd32 is NULL,
48// falls back to pure CSPRNG (identical to the single-argument overload).
49// Callers SHOULD pass a fresh 32-byte random value so that the same private
50// key produces a different encoding on each call — required by BIP-324 to
51// prevent key-identity leakage across connections.
52std::array<std::uint8_t, 64> ellswift_create(const Scalar& privkey,
53 const std::uint8_t* auxrnd32);
54
55// Fast variant: uses the precomputed fixed-base table (non-CT generator mul).
56// Suitable for ephemeral keys (BIP-324 session keys) where CT is not required.
57std::array<std::uint8_t, 64> ellswift_create_fast(const Scalar& privkey);
58
59// Fast XDH variant: uses non-CT variable-base scalar_mul for the ECDH step.
60// Suitable for BIP-324 ephemeral session keys where CT is not required.
61std::array<std::uint8_t, 32> ellswift_xdh_fast(
62 const std::uint8_t ell_a64[64],
63 const std::uint8_t ell_b64[64],
64 const Scalar& our_privkey,
65 bool initiating) noexcept;
66
67// Encode an existing x-coordinate as a 64-byte ElligatorSwift encoding.
68// rnd32: 32 bytes of randomness that determine which of the many valid
69// encodings is selected. Must not be a deterministic function of x.
70// Used by secp256k1_ellswift_encode (encode an existing pubkey).
71std::array<std::uint8_t, 64> ellswift_encode_x(const FieldElement& x,
72 const std::uint8_t rnd32[32]);
73
74// -- ElligatorSwift ECDH (BIP-324) --------------------------------------------
75
76// Perform x-only ECDH using ElligatorSwift-encoded public keys.
77// Both ell_a64 and ell_b64 are 64-byte ElligatorSwift encodings.
78// our_privkey is our secret key.
79// initiating: true if we are the connection initiator (determines key order).
80// Returns 32-byte shared secret (SHA256-based).
81std::array<std::uint8_t, 32> ellswift_xdh(
82 const std::uint8_t ell_a64[64],
83 const std::uint8_t ell_b64[64],
84 const Scalar& our_privkey,
85 bool initiating) noexcept;
86
87} // namespace secp256k1
88
89#endif // SECP256K1_ELLSWIFT_HPP
FieldElement ellswift_decode(const std::uint8_t encoding[64]) noexcept
std::array< std::uint8_t, 32 > ellswift_xdh(const std::uint8_t ell_a64[64], const std::uint8_t ell_b64[64], const Scalar &our_privkey, bool initiating) noexcept
std::array< std::uint8_t, 64 > ellswift_create_fast(const Scalar &privkey)
std::array< std::uint8_t, 64 > ellswift_create(const Scalar &privkey)
std::array< std::uint8_t, 64 > ellswift_encode_x(const FieldElement &x, const std::uint8_t rnd32[32])
std::array< std::uint8_t, 32 > ellswift_xdh_fast(const std::uint8_t ell_a64[64], const std::uint8_t ell_b64[64], const Scalar &our_privkey, bool initiating) noexcept