purify
C++ Purify implementation with native circuit and BPP support
Loading...
Searching...
No Matches
bppp.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 <array>
13#include <cstddef>
14#include <memory>
15#include <span>
16#include <utility>
17#include <vector>
18
19#include "purify/api.hpp"
20
22
23namespace purify::bppp {
24
25namespace detail {
26struct ExperimentalCircuitBackendAccess;
27}
28
30using ScalarBytes = std::array<unsigned char, 32>;
32using PointBytes = std::array<unsigned char, 33>;
34using GeneratorBytes = std::array<unsigned char, 33>;
35
46
55 const ScalarBytes& value,
56 purify_secp_context* secp_context);
57
68 const ScalarBytes& value,
69 purify_secp_context* secp_context,
70 const GeneratorBytes& value_gen,
71 const GeneratorBytes& blind_gen);
72
79 return value.to_bytes_be();
80}
81
87inline std::vector<ScalarBytes> scalar_bytes(const std::vector<FieldElement>& values) {
88 std::vector<ScalarBytes> out;
89 out.reserve(values.size());
90 for (const FieldElement& value : values) {
91 out.push_back(scalar_bytes(value));
92 }
93 return out;
94}
95
99 std::vector<PointBytes> generators;
100 std::vector<ScalarBytes> n_vec;
101 std::vector<ScalarBytes> l_vec;
102 std::vector<ScalarBytes> c_vec;
103};
104
107
111 std::vector<PointBytes> generators;
112 std::vector<ScalarBytes> c_vec;
113 std::size_t n_vec_len = 0;
116};
117
120public:
126
127protected:
129
130private:
131 friend struct detail::ExperimentalCircuitBackendAccess;
132
133 [[nodiscard]] virtual std::shared_ptr<const void> find_public_data_impl(
134 const std::array<unsigned char, 32>& key) const = 0;
135 virtual void insert_public_data_impl(std::array<unsigned char, 32> key,
136 std::shared_ptr<const void> value) = 0;
137 [[nodiscard]] virtual purify_bppp_backend_resources* get_or_create_backend_resources_impl(
138 std::span<const PointBytes> generators,
139 purify_secp_context* secp_context) = 0;
140};
141
143namespace detail {
145 [[nodiscard]] static std::shared_ptr<const void> find_public_data(
146 const ExperimentalCircuitBackend* backend,
147 const std::array<unsigned char, 32>& key);
148 static void insert_public_data(ExperimentalCircuitBackend* backend,
149 std::array<unsigned char, 32> key,
150 std::shared_ptr<const void> value);
151 [[nodiscard]] static purify_bppp_backend_resources* get_or_create_backend_resources(
153 std::span<const PointBytes> generators,
154 purify_secp_context* secp_context);
155};
156} // namespace detail
157
160public:
167
168 [[nodiscard]] bool empty() const noexcept;
169
170private:
171 struct Impl;
172 std::unique_ptr<Impl> impl_;
173
174 [[nodiscard]] std::shared_ptr<const void> find_public_data_impl(
175 const std::array<unsigned char, 32>& key) const override;
176 void insert_public_data_impl(std::array<unsigned char, 32> key,
177 std::shared_ptr<const void> value) override;
178 [[nodiscard]] purify_bppp_backend_resources* get_or_create_backend_resources_impl(
179 std::span<const PointBytes> generators,
180 purify_secp_context* secp_context) override;
181
183};
184
187public:
194
195 void clear();
196 [[nodiscard]] std::size_t size() const noexcept;
207 [[nodiscard]] Result<ExperimentalCircuitCacheLine> clone_line_for_thread(
208 std::span<const PointBytes> generators) const;
210 [[nodiscard]] std::shared_ptr<const void> find_public_data(const std::array<unsigned char, 32>& key) const;
212 void insert_public_data(std::array<unsigned char, 32> key, std::shared_ptr<const void> value);
214 [[nodiscard]] purify_bppp_backend_resources* get_or_create_backend_resources(
215 std::span<const PointBytes> generators,
216 purify_secp_context* secp_context);
217
218private:
219 struct Impl;
220 std::unique_ptr<Impl> impl_;
221
222 [[nodiscard]] std::shared_ptr<const void> find_public_data_impl(
223 const std::array<unsigned char, 32>& key) const override;
224 void insert_public_data_impl(std::array<unsigned char, 32> key,
225 std::shared_ptr<const void> value) override;
226 [[nodiscard]] purify_bppp_backend_resources* get_or_create_backend_resources_impl(
227 std::span<const PointBytes> generators,
228 purify_secp_context* secp_context) override;
229};
230
236Result<NormArgProof> prove_norm_arg(const NormArgInputs& inputs, purify_secp_context* secp_context);
238Result<NormArgProof> prove_norm_arg(NormArgInputs&& inputs, purify_secp_context* secp_context);
240Result<NormArgProof> prove_norm_arg_to_commitment(const NormArgInputs& inputs,
241 const PointBytes& commitment,
242 purify_secp_context* secp_context);
248bool verify_norm_arg(const NormArgProof& proof, purify_secp_context* secp_context);
249
252 PointBytes witness_commitment{};
254};
255
264
273 const NativeBulletproofCircuit& circuit,
274 const BulletproofAssignmentData& assignment,
275 purify_secp_context* secp_context,
276 std::span<const unsigned char> statement_binding = {},
277 ExperimentalCircuitBackend* cache = nullptr);
278
286Result<ExperimentalCircuitNormArgProof> prove_experimental_circuit_norm_arg(
287 const NativeBulletproofCircuit& circuit,
288 const BulletproofAssignmentData& assignment,
289 purify_secp_context* secp_context,
290 std::span<const unsigned char> statement_binding = {},
291 ExperimentalCircuitBackend* cache = nullptr);
292
301Result<ExperimentalCircuitNormArgProof> prove_experimental_circuit_norm_arg_to_commitment(
302 const NativeBulletproofCircuit& circuit,
303 const BulletproofAssignmentData& assignment,
304 const PointBytes& witness_commitment,
305 purify_secp_context* secp_context,
306 std::span<const unsigned char> statement_binding = {},
307 ExperimentalCircuitBackend* cache = nullptr);
308
317 const NativeBulletproofCircuit& circuit,
318 const ExperimentalCircuitNormArgProof& proof,
319 purify_secp_context* secp_context,
320 std::span<const unsigned char> statement_binding = {},
321 ExperimentalCircuitBackend* cache = nullptr);
322
337Result<ExperimentalCircuitZkNormArgProof> prove_experimental_circuit_zk_norm_arg(
338 const NativeBulletproofCircuit& circuit,
339 const BulletproofAssignmentData& assignment,
340 const ScalarBytes& nonce,
341 purify_secp_context* secp_context,
342 std::span<const unsigned char> statement_binding = {},
343 ExperimentalCircuitBackend* cache = nullptr);
344
353 const NativeBulletproofCircuit& circuit,
354 const ExperimentalCircuitZkNormArgProof& proof,
355 purify_secp_context* secp_context,
356 std::span<const unsigned char> statement_binding = {},
357 ExperimentalCircuitBackend* cache = nullptr);
358
366Result<ExperimentalCircuitZkNormArgProof> prove_experimental_circuit_zk_norm_arg_with_public_commitments(
367 const NativeBulletproofCircuit& circuit,
368 const BulletproofAssignmentData& assignment,
369 const ScalarBytes& nonce,
370 std::span<const PointBytes> public_commitments,
371 purify_secp_context* secp_context,
372 std::span<const unsigned char> statement_binding = {},
373 ExperimentalCircuitBackend* cache = nullptr);
374
382 const NativeBulletproofCircuit& circuit,
383 const ExperimentalCircuitZkNormArgProof& proof,
384 std::span<const PointBytes> public_commitments,
385 purify_secp_context* secp_context,
386 std::span<const unsigned char> statement_binding = {},
387 ExperimentalCircuitBackend* cache = nullptr);
388
396
406 const ScalarBytes& blind,
407 purify_secp_context* secp_context);
408
420 const SecretKey& secret,
421 const ScalarBytes& blind,
422 purify_secp_context* secp_context,
423 const GeneratorBytes& value_gen,
424 const GeneratorBytes& blind_gen);
425
426} // namespace purify::bppp
High-level Purify key generation, evaluation, witness generation, and circuit helpers.
Purify result carrier that either holds a value or an error.
Definition expected.hpp:64
Field element modulo the backend scalar field used by this implementation.
Definition numeric.hpp:815
std::array< unsigned char, 32 > to_bytes_be() const
Serializes the field element in big-endian form.
Definition numeric.cpp:84
Move-only packed Purify secret stored in dedicated heap memory.
Definition secret.hpp:52
Common interface for reusable experimental BPPP backend state.
Definition bppp.hpp:119
ExperimentalCircuitBackend(const ExperimentalCircuitBackend &)=delete
ExperimentalCircuitBackend & operator=(const ExperimentalCircuitBackend &)=delete
ExperimentalCircuitBackend(ExperimentalCircuitBackend &&) noexcept=default
friend struct detail::ExperimentalCircuitBackendAccess
Definition bppp.hpp:131
Thread-local clone of one warmed experimental BPPP backend-resource line.
Definition bppp.hpp:159
ExperimentalCircuitCacheLine & operator=(const ExperimentalCircuitCacheLine &)=delete
ExperimentalCircuitCacheLine(const ExperimentalCircuitCacheLine &)=delete
ExperimentalCircuitCacheLine & operator=(ExperimentalCircuitCacheLine &&other) noexcept
ExperimentalCircuitCacheLine(ExperimentalCircuitCacheLine &&other) noexcept
Caller-owned cache for reusable experimental circuit reduction and BPPP backend data.
Definition bppp.hpp:186
ExperimentalCircuitCache & operator=(const ExperimentalCircuitCache &)=delete
ExperimentalCircuitCache(ExperimentalCircuitCache &&other) noexcept
ExperimentalCircuitCache & operator=(ExperimentalCircuitCache &&other) noexcept
ExperimentalCircuitCache(const ExperimentalCircuitCache &)=delete
std::array< unsigned char, 32 > ScalarBytes
Big-endian 32-byte scalar encoding.
Definition bppp.hpp:30
Result< PointBytes > commit_experimental_circuit_witness(const NativeBulletproofCircuit &circuit, const BulletproofAssignmentData &assignment, purify_secp_context *secp_context, std::span< const unsigned char > statement_binding={}, ExperimentalCircuitBackend *cache=nullptr)
Commits to the reduced witness coordinates used by the experimental circuit-to-BPPP reduction.
Definition bppp.cpp:1303
Result< PointBytes > commit_norm_arg(const NormArgInputs &inputs, purify_secp_context *secp_context)
Computes the public BPPP commitment for a standalone norm-argument input bundle.
Definition bppp.cpp:1286
Result< bool > verify_experimental_circuit_norm_arg(const NativeBulletproofCircuit &circuit, const ExperimentalCircuitNormArgProof &proof, purify_secp_context *secp_context, std::span< const unsigned char > statement_binding={}, ExperimentalCircuitBackend *cache=nullptr)
Verifies an experimental transparent circuit proof produced by prove_experimental_circuit_norm_arg.
Definition bppp.cpp:1394
GeneratorBytes base_generator(purify_secp_context *secp_context)
Returns the serialized secp256k1 base generator used as the blind generator.
Definition bppp.cpp:1064
Result< bool > verify_experimental_circuit_zk_norm_arg_with_public_commitments(const NativeBulletproofCircuit &circuit, const ExperimentalCircuitZkNormArgProof &proof, std::span< const PointBytes > public_commitments, purify_secp_context *secp_context, std::span< const unsigned char > statement_binding={}, ExperimentalCircuitBackend *cache=nullptr)
Verifies an experimental masked circuit proof against explicit public commitment points.
Definition bppp.cpp:1770
std::array< unsigned char, 33 > PointBytes
Compressed 33-byte curve-point encoding.
Definition bppp.hpp:32
Result< ExperimentalCircuitZkNormArgProof > prove_experimental_circuit_zk_norm_arg_with_public_commitments(const NativeBulletproofCircuit &circuit, const BulletproofAssignmentData &assignment, const ScalarBytes &nonce, std::span< const PointBytes > public_commitments, purify_secp_context *secp_context, std::span< const unsigned char > statement_binding={}, ExperimentalCircuitBackend *cache=nullptr)
Produces an experimental masked circuit proof bound to explicit public commitment points.
Definition bppp.cpp:1758
GeneratorBytes value_generator_h(purify_secp_context *secp_context)
Returns the serialized alternate generator used for committed values.
Definition bppp.cpp:1073
Result< CommittedPurifyWitness > commit_output_witness(const Bytes &message, const SecretKey &secret, const ScalarBytes &blind, purify_secp_context *secp_context)
Evaluates Purify, derives its witness, and commits to the output using Purify's default generators.
Definition bppp.cpp:1782
Result< std::vector< PointBytes > > create_generators(std::size_t count, purify_secp_context *secp_context)
Expands the BPPP generator list.
Definition bppp.cpp:1083
Result< bool > verify_experimental_circuit_zk_norm_arg(const NativeBulletproofCircuit &circuit, const ExperimentalCircuitZkNormArgProof &proof, purify_secp_context *secp_context, std::span< const unsigned char > statement_binding={}, ExperimentalCircuitBackend *cache=nullptr)
Verifies an experimental masked circuit proof produced by prove_experimental_circuit_zk_norm_arg.
Definition bppp.cpp:1747
std::array< unsigned char, 33 > GeneratorBytes
Serialized generator encoding used by the BPPP bridge.
Definition bppp.hpp:34
Result< PointBytes > pedersen_commit_char(const ScalarBytes &blind, const ScalarBytes &value, purify_secp_context *secp_context)
Computes a Pedersen commitment to an arbitrary 32-byte scalar value using Purify's default generators...
Definition bppp.cpp:1155
ScalarBytes scalar_bytes(const FieldElement &value)
Serializes a Purify field element into the scalar encoding expected by the BPPP bridge.
Definition bppp.hpp:78
Result< ExperimentalCircuitZkNormArgProof > prove_experimental_circuit_zk_norm_arg(const NativeBulletproofCircuit &circuit, const BulletproofAssignmentData &assignment, const ScalarBytes &nonce, purify_secp_context *secp_context, std::span< const unsigned char > statement_binding={}, ExperimentalCircuitBackend *cache=nullptr)
Produces an experimental masked circuit proof over the reduced BPPP relation.
Definition bppp.cpp:1737
std::vector< unsigned char > Bytes
Dynamically sized byte string used for messages, serialized witnesses, and proofs.
Definition common.hpp:99
std::vector< PointBytes > generators
Definition bppp.cpp:471
Nonce nonce
Definition bppp.cpp:120
Columnar witness assignment compatible with the native Bulletproof circuit layout.
Native in-memory representation of a Bulletproof-style arithmetic circuit.
Purify witness bundle together with a Pedersen commitment to the output.
Definition bppp.hpp:390
BulletproofAssignmentData assignment
Definition bppp.hpp:393
Experimental transparent circuit proof backed by the standalone BPPP norm argument.
Definition bppp.hpp:251
Experimental masked circuit proof that hides the reduced witness before the final BPPP argument.
Definition bppp.hpp:257
Inputs required to produce a standalone BPPP norm argument.
Definition bppp.hpp:97
std::vector< ScalarBytes > l_vec
Definition bppp.hpp:101
std::vector< PointBytes > generators
Definition bppp.hpp:99
std::vector< ScalarBytes > n_vec
Definition bppp.hpp:100
std::vector< ScalarBytes > c_vec
Definition bppp.hpp:102
Standalone BPPP norm-argument proof bundle with all verifier-side inputs.
Definition bppp.hpp:109
std::vector< PointBytes > generators
Definition bppp.hpp:111
std::vector< ScalarBytes > c_vec
Definition bppp.hpp:112