purify
C++ Purify implementation with native circuit and BPP support
Loading...
Searching...
No Matches
common.hpp
Go to the documentation of this file.
1// Copyright (c) 2026 Judica, Inc.
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or https://opensource.org/license/mit/.
4
10#pragma once
11
12#include <algorithm>
13#include <array>
14#include <cassert>
15#include <bit>
16#include <cctype>
17#include <charconv>
18#include <cstdint>
19#include <iomanip>
20#include <map>
21#include <memory>
22#include <limits>
23#include <optional>
24#include <ostream>
25#include <span>
26#include <sstream>
27#include <string>
28#include <string_view>
29#include <tuple>
30#include <unordered_map>
31#include <unordered_set>
32#include <utility>
33#include <vector>
34
35#include "purify/error.hpp"
36#include "purify/secp_bridge.h"
37
38#ifndef PURIFY_USE_LEGACY_FIELD_HASHES
39#define PURIFY_USE_LEGACY_FIELD_HASHES 0
40#endif
41
42namespace purify {
43
45 void operator()(purify_secp_context* context) const noexcept {
47 }
48};
49
50using SecpContextPtr = std::unique_ptr<purify_secp_context, SecpContextDeleter>;
51
55
56inline Status require_secp_context(const purify_secp_context* context, const char* error_context) {
57 if (context == nullptr) {
58 return unexpected_error(ErrorCode::MissingValue, error_context);
59 }
60 return {};
61}
62
63[[nodiscard]] inline bool checked_add_size(std::size_t lhs, std::size_t rhs, std::size_t& out) noexcept {
64 if (rhs > std::numeric_limits<std::size_t>::max() - lhs) {
65 return false;
66 }
67 out = lhs + rhs;
68 return true;
69}
70
71[[nodiscard]] inline bool checked_mul_size(std::size_t lhs, std::size_t rhs, std::size_t& out) noexcept {
72 if (lhs != 0 && rhs > std::numeric_limits<std::size_t>::max() / lhs) {
73 return false;
74 }
75 out = lhs * rhs;
76 return true;
77}
78
79[[nodiscard]] inline bool size_fits_u32(std::size_t value) noexcept {
80 return value <= static_cast<std::size_t>(std::numeric_limits<std::uint32_t>::max());
81}
82
83[[nodiscard]] inline bool size_fits_u64(std::size_t value) noexcept {
84 return value <= static_cast<std::size_t>(std::numeric_limits<std::uint64_t>::max());
85}
86
87[[nodiscard]] inline Result<std::uint64_t> narrow_size_to_u64(std::size_t value, const char* context) {
88 if (!size_fits_u64(value)) {
90 }
91 return static_cast<std::uint64_t>(value);
92}
93
94[[nodiscard]] inline bool is_power_of_two_size(std::size_t value) noexcept {
95 return value != 0 && (value & (value - 1)) == 0;
96}
97
99using Bytes = std::vector<unsigned char>;
100
106template <typename T>
107inline void best_effort_reserve_add(std::vector<T>& out, std::size_t lhs, std::size_t rhs) {
108 std::size_t reserve_size = 0;
109 if (checked_add_size(lhs, rhs, reserve_size)) {
110 out.reserve(reserve_size);
111 }
112}
113
114template <typename T>
115inline void best_effort_reserve_mul(std::vector<T>& out, std::size_t lhs, std::size_t rhs) {
116 std::size_t reserve_size = 0;
117 if (checked_mul_size(lhs, rhs, reserve_size)) {
118 out.reserve(reserve_size);
119 }
120}
121
128template <std::size_t MinSize, typename T>
130public:
131 static constexpr std::size_t min_size = MinSize;
132 using element_type = T;
133
134 template <std::size_t Extent>
135 requires(Extent != std::dynamic_extent && Extent >= MinSize)
136 constexpr explicit SpanAtLeast(std::span<T, Extent> span) noexcept : span_(span) {}
137
138 [[nodiscard]] static Result<SpanAtLeast> try_from(std::span<T> span) {
139 if (span.size() < MinSize) {
140 return unexpected_error(ErrorCode::RangeViolation, "SpanAtLeast::try_from:too_short");
141 }
142 return SpanAtLeast(span);
143 }
144
145 [[nodiscard]] constexpr std::span<T> span() const noexcept {
146 return span_;
147 }
148
149 [[nodiscard]] constexpr const T* data() const noexcept {
150 return span_.data();
151 }
152
153 [[nodiscard]] constexpr std::size_t size() const noexcept {
154 return span_.size();
155 }
156
157 [[nodiscard]] constexpr auto begin() const noexcept {
158 return span_.begin();
159 }
160
161 [[nodiscard]] constexpr auto end() const noexcept {
162 return span_.end();
163 }
164
165 [[nodiscard]] constexpr operator std::span<T>() const noexcept {
166 return span_;
167 }
168
169private:
170 constexpr explicit SpanAtLeast(std::span<T> span) noexcept : span_(span) {}
171
172 std::span<T> span_;
173};
174
175} // namespace purify
Purify result carrier that either holds a value or an error.
Definition expected.hpp:64
Checked span wrapper that guarantees a minimum runtime length.
Definition common.hpp:129
constexpr std::size_t size() const noexcept
Definition common.hpp:153
constexpr auto begin() const noexcept
Definition common.hpp:157
constexpr SpanAtLeast(std::span< T, Extent > span) noexcept
Definition common.hpp:136
constexpr const T * data() const noexcept
Definition common.hpp:149
constexpr auto end() const noexcept
Definition common.hpp:161
static Result< SpanAtLeast > try_from(std::span< T > span)
Definition common.hpp:138
constexpr std::span< T > span() const noexcept
Definition common.hpp:145
static constexpr std::size_t min_size
Definition common.hpp:131
Library-level error taxonomy used to classify Purify failures.
Definition api.hpp:21
Status require_secp_context(const purify_secp_context *context, const char *error_context)
Definition common.hpp:56
constexpr Unexpected< Error > unexpected_error(ErrorCode code, const char *context=nullptr)
Constructs an unexpected Error value from a machine-readable code.
Definition error.hpp:293
bool size_fits_u64(std::size_t value) noexcept
Definition common.hpp:83
bool is_power_of_two_size(std::size_t value) noexcept
Definition common.hpp:94
Result< std::uint64_t > narrow_size_to_u64(std::size_t value, const char *context)
Definition common.hpp:87
bool checked_mul_size(std::size_t lhs, std::size_t rhs, std::size_t &out) noexcept
Definition common.hpp:71
std::unique_ptr< purify_secp_context, SecpContextDeleter > SecpContextPtr
Definition common.hpp:50
SecpContextPtr make_secp_context() noexcept
Definition common.hpp:52
void best_effort_reserve_mul(std::vector< T > &out, std::size_t lhs, std::size_t rhs)
Definition common.hpp:115
std::vector< unsigned char > Bytes
Dynamically sized byte string used for messages, serialized witnesses, and proofs.
Definition common.hpp:99
bool size_fits_u32(std::size_t value) noexcept
Definition common.hpp:79
void best_effort_reserve_add(std::vector< T > &out, std::size_t lhs, std::size_t rhs)
Reserve capacity when the size arithmetic fits, otherwise skip the hint.
Definition common.hpp:107
bool checked_add_size(std::size_t lhs, std::size_t rhs, std::size_t &out) noexcept
Definition common.hpp:63
Narrow C ABI exposing secp256k1 scalar and HMAC helpers to the C++ headers.
void purify_secp_context_destroy(purify_secp_context *context)
Destroys a context returned by purify_secp_context_create.
Definition bppp_bridge.c:69
purify_secp_context * purify_secp_context_create(void)
Creates one reusable secp256k1 context for the Purify bridge and public APIs.
Definition bppp_bridge.c:46
void operator()(purify_secp_context *context) const noexcept
Definition common.hpp:45