UltrafastSecp256k1 3.50.0
Ultra high-performance secp256k1 elliptic curve cryptography library
Loading...
Searching...
No Matches
context.hpp
Go to the documentation of this file.
1#ifndef SECP256K1_CONTEXT_HPP
2#define SECP256K1_CONTEXT_HPP
3#pragma once
4
5// ============================================================================
6// CurveContext -- Custom Generator Point & Curve Parameters
7// ============================================================================
8// Allows users to:
9// 1. Use a custom generator point G (default: standard secp256k1 G)
10// 2. Define custom curve configurations
11// 3. Override order n, cofactor h, and curve name
12//
13// Design:
14// - Zero overhead for standard secp256k1 (nullptr = use defaults)
15// - constexpr-ready for compile-time known generators
16// - No heap allocation; POD-like structure
17//
18// Usage:
19// // Standard secp256k1 (default)
20// auto pub = secp256k1::derive_public_key(privkey);
21//
22// // Custom generator
23// CurveContext ctx = CurveContext::secp256k1();
24// ctx.generator = my_custom_G;
25// auto pub = secp256k1::derive_public_key(privkey, &ctx);
26// ============================================================================
27
28#include <array>
29#include <cstdint>
30#include <cstring>
31#include <string_view>
32#include "secp256k1/point.hpp"
33#include "secp256k1/scalar.hpp"
34
35namespace secp256k1 {
36
37// -- Curve Context ------------------------------------------------------------
38
40 // Generator point (base point G)
42
43 // Curve order n as raw 32 bytes (big-endian).
44 // Stored as raw bytes because Scalar reduces mod n, so Scalar(n) == 0.
45 // Default: secp256k1 order = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
46 std::array<std::uint8_t, 32> order{};
47
48 // Cofactor h (secp256k1: h = 1)
49 std::uint32_t cofactor = 1;
50
51 // Curve name (for diagnostics / logging)
52 // Fixed buffer to avoid heap allocation
53 char name[32] = {};
54
55 // -- Factory methods --------------------------------------------------
56
57 // Standard secp256k1 context (default parameters)
59 CurveContext ctx;
61 // secp256k1 order n (big-endian bytes)
62 ctx.order = {
63 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
64 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
65 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
66 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41
67 };
68 ctx.cofactor = 1;
69 set_name(ctx, "secp256k1");
70 return ctx;
71 }
72
73 // Create context with custom generator (same curve, different G)
74 static CurveContext with_generator(const fast::Point& custom_G,
75 const char* label = "secp256k1-custom") {
77 ctx.generator = custom_G;
78 set_name(ctx, label);
79 return ctx;
80 }
81
82 // Create from arbitrary parameters
83 // order_n: 32-byte big-endian curve order
85 const std::array<std::uint8_t, 32>& order_n,
86 std::uint32_t h = 1,
87 const char* label = "custom") {
88 CurveContext ctx;
89 ctx.generator = G;
90 ctx.order = order_n;
91 ctx.cofactor = h;
92 set_name(ctx, label);
93 return ctx;
94 }
95
96 // -- Helpers ----------------------------------------------------------
97
98 std::string_view curve_name() const noexcept {
99 return std::string_view(name);
100 }
101
102private:
103 static void set_name(CurveContext& ctx, const char* label) {
104 std::memset(ctx.name, 0, sizeof(ctx.name));
105 std::size_t len = 0;
106 // cppcheck-suppress arrayIndexOutOfBoundsCond ; len is bounded by sizeof(ctx.name)-1
107 while (len < sizeof(ctx.name) - 1 && label[len]) {
108 ctx.name[len] = label[len];
109 ++len;
110 }
111 }
112};
113
114// -- Context-Aware Operations -------------------------------------------------
115
116// Get the effective generator point (custom or default secp256k1 G)
117inline const fast::Point& effective_generator(const CurveContext* ctx = nullptr) {
118 if (ctx) return ctx->generator;
119 // Return standard secp256k1 generator via static singleton
120 static const fast::Point default_G = fast::Point::generator();
121 return default_G;
122}
123
124// Derive public key from private key: pubkey = privkey * G
125// ctx: nullptr = standard secp256k1, or custom context
127 const CurveContext* ctx = nullptr) {
128 return effective_generator(ctx).scalar_mul(private_key);
129}
130
131// Scalar multiplication with context's generator: result = scalar * G
133 const CurveContext* ctx = nullptr) {
134 return effective_generator(ctx).scalar_mul(scalar);
135}
136
137} // namespace secp256k1
138
139#endif // SECP256K1_CONTEXT_HPP
Point scalar_mul(const Scalar &scalar) const
static Point generator()
fast::Point derive_public_key(const fast::Scalar &private_key, const CurveContext *ctx=nullptr)
Definition context.hpp:126
const fast::Point & effective_generator(const CurveContext *ctx=nullptr)
Definition context.hpp:117
fast::Point scalar_mul_G(const fast::Scalar &scalar, const CurveContext *ctx=nullptr)
Definition context.hpp:132
static CurveContext secp256k1_default()
Definition context.hpp:58
std::array< std::uint8_t, 32 > order
Definition context.hpp:46
static CurveContext with_generator(const fast::Point &custom_G, const char *label="secp256k1-custom")
Definition context.hpp:74
fast::Point generator
Definition context.hpp:41
std::string_view curve_name() const noexcept
Definition context.hpp:98
std::uint32_t cofactor
Definition context.hpp:49
static CurveContext custom(const fast::Point &G, const std::array< std::uint8_t, 32 > &order_n, std::uint32_t h=1, const char *label="custom")
Definition context.hpp:84