purify
C++ Purify implementation with native circuit and BPP support
Loading...
Searching...
No Matches
legacy.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
14#pragma once
15
16#include <array>
17#include <cstdint>
18#include <span>
19#include <utility>
20
21#include "purify/api.hpp"
22
24
25using Scalar32 = std::array<unsigned char, 32>;
26using XOnly32 = std::array<unsigned char, 32>;
27using Signature64 = std::array<unsigned char, 64>;
28
30struct TopicProofCache;
31struct Signature;
32struct NonceProof;
33struct ProvenSignature;
34
42struct PublicKey {
43 static constexpr std::size_t kSerializedSize = 96;
44
47
52 [[nodiscard]] Bytes serialize() const;
53
59 [[nodiscard]] static Result<PublicKey> deserialize(std::span<const unsigned char> serialized,
60 purify_secp_context* secp_context);
61
67 [[nodiscard]] static Result<PublicKey> from_secret(const SecretKey& secret,
68 purify_secp_context* secp_context);
69
76 [[nodiscard]] Result<bool> verify_signature(std::span<const unsigned char> message,
77 const Signature& signature,
78 purify_secp_context* secp_context) const;
79
88 std::span<const unsigned char> message,
89 const NonceProof& nonce_proof,
90 purify_secp_context* secp_context,
91 ExperimentalBulletproofBackendCache* circuit_cache = nullptr) const;
92
101 const MessageProofCache& cache,
102 const NonceProof& nonce_proof,
103 purify_secp_context* secp_context,
104 ExperimentalBulletproofBackendCache* circuit_cache = nullptr) const;
105
114 std::span<const unsigned char> topic,
115 const NonceProof& nonce_proof,
116 purify_secp_context* secp_context,
117 ExperimentalBulletproofBackendCache* circuit_cache = nullptr) const;
118
127 const TopicProofCache& cache,
128 const NonceProof& nonce_proof,
129 purify_secp_context* secp_context,
130 ExperimentalBulletproofBackendCache* circuit_cache = nullptr) const;
131
140 std::span<const unsigned char> message,
141 const ProvenSignature& signature,
142 purify_secp_context* secp_context,
143 ExperimentalBulletproofBackendCache* circuit_cache = nullptr) const;
144
153 const MessageProofCache& cache,
154 const ProvenSignature& signature,
155 purify_secp_context* secp_context,
156 ExperimentalBulletproofBackendCache* circuit_cache = nullptr) const;
157
167 std::span<const unsigned char> message,
168 std::span<const unsigned char> topic,
169 const ProvenSignature& signature,
170 purify_secp_context* secp_context,
171 ExperimentalBulletproofBackendCache* circuit_cache = nullptr) const;
172
182 const TopicProofCache& cache,
183 std::span<const unsigned char> message,
184 const ProvenSignature& signature,
185 purify_secp_context* secp_context,
186 ExperimentalBulletproofBackendCache* circuit_cache = nullptr) const;
187};
188
190struct Nonce {
191 static constexpr std::size_t kSerializedSize = 32;
192
194
195 [[nodiscard]] Bytes serialize() const;
196 [[nodiscard]] static Result<Nonce> deserialize(std::span<const unsigned char> serialized,
197 purify_secp_context* secp_context);
198};
199
201struct Signature {
202 static constexpr std::size_t kSerializedSize = 64;
203
205
206 [[nodiscard]] Nonce nonce() const;
207 [[nodiscard]] Scalar32 s() const;
208 [[nodiscard]] Bytes serialize() const;
209 [[nodiscard]] static Result<Signature> deserialize(std::span<const unsigned char> serialized,
210 purify_secp_context* secp_context);
211};
212
224
225 [[nodiscard]] Result<Bytes> serialize(purify_secp_context* secp_context) const;
226 [[nodiscard]] static Result<NonceProof> deserialize(std::span<const unsigned char> serialized,
227 purify_secp_context* secp_context);
228};
229
234
235 [[nodiscard]] Result<Bytes> serialize(purify_secp_context* secp_context) const;
236 [[nodiscard]] static Result<ProvenSignature> deserialize(std::span<const unsigned char> serialized,
237 purify_secp_context* secp_context);
238};
239
261
283
285
293public:
294 enum class Scope : std::uint8_t {
295 Message,
296 Topic,
297 };
298
299 PreparedNonce(const PreparedNonce&) = delete;
301
302 PreparedNonce(PreparedNonce&& other) noexcept;
303 PreparedNonce& operator=(PreparedNonce&& other) noexcept;
305
310 [[nodiscard]] const Nonce& public_nonce() const noexcept {
311 return nonce_;
312 }
313
320 [[nodiscard]] Scalar32 scalar() const {
321 return scalar_;
322 }
323
333 [[nodiscard]] static PreparedNonce from_parts(Scope scope, const Scalar32& scalar, const Nonce& nonce,
335
342 [[nodiscard]] Result<Signature> sign_message(const Bip340Key& signer,
343 std::span<const unsigned char> message,
344 purify_secp_context* secp_context) &&;
345
352 [[nodiscard]] Result<Signature> sign_topic_message(const Bip340Key& signer,
353 std::span<const unsigned char> message,
354 purify_secp_context* secp_context) &&;
355
356private:
359
360 void clear() noexcept;
361
362 Scope scope_{Scope::Message};
363 Scalar32 scalar_{};
364 Nonce nonce_{};
365 XOnly32 signer_pubkey_{};
366 XOnly32 binding_digest_{};
367};
368
377public:
380
384
389 [[nodiscard]] const Nonce& public_nonce() const noexcept {
390 return prepared_.public_nonce();
391 }
392
397 [[nodiscard]] const NonceProof& proof() const noexcept {
398 return proof_;
399 }
400
405 [[nodiscard]] Scalar32 scalar() const {
406 return prepared_.scalar();
407 }
408
415 [[nodiscard]] static PreparedNonceWithProof from_parts(PreparedNonce prepared, NonceProof proof);
416
423 [[nodiscard]] Result<ProvenSignature> sign_message(const SecretKey& secret,
424 std::span<const unsigned char> message,
425 purify_secp_context* secp_context) &&;
426
433 [[nodiscard]] Result<ProvenSignature> sign_topic_message(const SecretKey& secret,
434 std::span<const unsigned char> message,
435 purify_secp_context* secp_context) &&;
436
437private:
439 : prepared_(std::move(prepared)), proof_(std::move(proof)) {}
440
441 PreparedNonce prepared_;
442 NonceProof proof_;
443};
444
445class KeyPair {
446public:
447 KeyPair(const KeyPair&) = delete;
448 KeyPair& operator=(const KeyPair&) = delete;
449 KeyPair(KeyPair&& other) noexcept = default;
450 KeyPair& operator=(KeyPair&& other) noexcept = default;
451 ~KeyPair() = default;
452
458 [[nodiscard]] static Result<KeyPair> from_secret(const SecretKey& secret,
459 purify_secp_context* secp_context);
460
466 [[nodiscard]] static Result<KeyPair> from_secret(SecretKey&& secret,
467 purify_secp_context* secp_context);
468
473 [[nodiscard]] const PublicKey& public_key() const noexcept {
474 return public_key_;
475 }
476
482 [[nodiscard]] Result<PreparedNonce> prepare_message_nonce(std::span<const unsigned char> message,
483 purify_secp_context* secp_context) const;
484
491 std::span<const unsigned char> message,
492 purify_secp_context* secp_context) const;
493
500 const MessageProofCache& cache,
501 purify_secp_context* secp_context) const;
502
508 [[nodiscard]] Result<PreparedNonce> prepare_topic_nonce(std::span<const unsigned char> topic,
509 purify_secp_context* secp_context) const;
510
517 std::span<const unsigned char> topic,
518 purify_secp_context* secp_context) const;
519
526 const TopicProofCache& cache,
527 purify_secp_context* secp_context) const;
528
534 [[nodiscard]] Result<Signature> sign_message(std::span<const unsigned char> message,
535 purify_secp_context* secp_context) const;
536
543 [[nodiscard]] Result<Signature> sign_message_with_prepared(std::span<const unsigned char> message,
544 PreparedNonce&& prepared,
545 purify_secp_context* secp_context) const;
546
554 std::span<const unsigned char> message,
555 PreparedNonceWithProof&& prepared,
556 purify_secp_context* secp_context) const;
557
564 [[nodiscard]] Result<Signature> sign_with_topic(std::span<const unsigned char> message,
565 std::span<const unsigned char> topic,
566 purify_secp_context* secp_context) const;
567
574 [[nodiscard]] Result<Signature> sign_with_prepared_topic(std::span<const unsigned char> message,
575 PreparedNonce&& prepared,
576 purify_secp_context* secp_context) const;
577
585 std::span<const unsigned char> message,
586 PreparedNonceWithProof&& prepared,
587 purify_secp_context* secp_context) const;
588
595 std::span<const unsigned char> message,
596 purify_secp_context* secp_context) const;
597
604 const MessageProofCache& cache,
605 purify_secp_context* secp_context) const;
606
614 std::span<const unsigned char> message,
615 std::span<const unsigned char> topic,
616 purify_secp_context* secp_context) const;
617
625 std::span<const unsigned char> message,
626 const TopicProofCache& cache,
627 purify_secp_context* secp_context) const;
628
629private:
631 : secret_(std::move(secret)), public_key_(std::move(public_key)) {}
632
633 SecretKey secret_;
634 PublicKey public_key_{};
635};
636
637} // namespace purify::puresign
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
Caller-owned cache for reusable legacy Bulletproof backend resources keyed by gate count.
Public-key-agnostic native verifier-circuit template.
Move-only packed Purify secret stored in dedicated heap memory.
Definition secret.hpp:52
Result< Signature > sign_with_prepared_topic(std::span< const unsigned char > message, PreparedNonce &&prepared, purify_secp_context *secp_context) const
Signs a message using an already prepared topic-bound nonce.
Definition legacy.cpp:845
Result< Signature > sign_message_with_prepared(std::span< const unsigned char > message, PreparedNonce &&prepared, purify_secp_context *secp_context) const
Signs a message using an already prepared message-bound nonce.
Definition legacy.cpp:825
static Result< KeyPair > from_secret(const SecretKey &secret, purify_secp_context *secp_context)
Derives a signing key pair from one packed Purify secret.
Definition legacy.cpp:779
Result< Signature > sign_with_topic(std::span< const unsigned char > message, std::span< const unsigned char > topic, purify_secp_context *secp_context) const
Signs a message using a topic-bound deterministic nonce.
Definition legacy.cpp:838
Result< PreparedNonce > prepare_message_nonce(std::span< const unsigned char > message, purify_secp_context *secp_context) const
Deterministically prepares a message-bound nonce.
Definition legacy.cpp:789
Result< PreparedNonceWithProof > prepare_message_nonce_with_proof(std::span< const unsigned char > message, purify_secp_context *secp_context) const
Deterministically prepares a message-bound nonce together with its proof.
Definition legacy.cpp:794
Result< PreparedNonce > prepare_topic_nonce(std::span< const unsigned char > topic, purify_secp_context *secp_context) const
Deterministically prepares a topic-bound nonce.
Definition legacy.cpp:804
KeyPair & operator=(const KeyPair &)=delete
KeyPair & operator=(KeyPair &&other) noexcept=default
Result< PreparedNonceWithProof > prepare_topic_nonce_with_proof(std::span< const unsigned char > topic, purify_secp_context *secp_context) const
Deterministically prepares a topic-bound nonce together with its proof.
Definition legacy.cpp:809
KeyPair(const KeyPair &)=delete
Result< Signature > sign_message(std::span< const unsigned char > message, purify_secp_context *secp_context) const
Signs a message with a deterministically derived message-bound nonce.
Definition legacy.cpp:819
KeyPair(KeyPair &&other) noexcept=default
Result< ProvenSignature > sign_message_with_prepared_proof(std::span< const unsigned char > message, PreparedNonceWithProof &&prepared, purify_secp_context *secp_context) const
Signs a message using an already prepared message-bound nonce proof bundle.
Definition legacy.cpp:832
Result< ProvenSignature > sign_with_topic_proof(std::span< const unsigned char > message, std::span< const unsigned char > topic, purify_secp_context *secp_context) const
Signs a message with a topic-bound nonce proof.
Definition legacy.cpp:872
const PublicKey & public_key() const noexcept
Returns the public key bundle associated with this signer.
Definition legacy.hpp:473
Result< ProvenSignature > sign_message_with_proof(std::span< const unsigned char > message, purify_secp_context *secp_context) const
Signs a message and returns the signature bundled with its nonce proof.
Definition legacy.cpp:858
Result< ProvenSignature > sign_with_prepared_topic_proof(std::span< const unsigned char > message, PreparedNonceWithProof &&prepared, purify_secp_context *secp_context) const
Signs a message using an already prepared topic-bound nonce proof bundle.
Definition legacy.cpp:852
Move-only prepared nonce bundled with its public statement proof.
Definition legacy.hpp:376
Result< ProvenSignature > sign_topic_message(const SecretKey &secret, std::span< const unsigned char > message, purify_secp_context *secp_context) &&
Consumes this topic-bound prepared proof bundle and signs the message.
Definition legacy.cpp:375
Scalar32 scalar() const
Explicitly exports the secret nonce scalar from the wrapped prepared nonce.
Definition legacy.hpp:405
const Nonce & public_nonce() const noexcept
Returns the public nonce proved by this bundle.
Definition legacy.hpp:389
Result< ProvenSignature > sign_message(const SecretKey &secret, std::span< const unsigned char > message, purify_secp_context *secp_context) &&
Consumes this message-bound prepared proof bundle and signs the message.
Definition legacy.cpp:362
const NonceProof & proof() const noexcept
Returns the public nonce proof carried by this bundle.
Definition legacy.hpp:397
static PreparedNonceWithProof from_parts(PreparedNonce prepared, NonceProof proof)
Bundles a prepared nonce with its matching public nonce proof.
Definition legacy.cpp:358
PreparedNonceWithProof(const PreparedNonceWithProof &)=delete
PreparedNonceWithProof & operator=(PreparedNonceWithProof &&other) noexcept=default
PreparedNonceWithProof & operator=(const PreparedNonceWithProof &)=delete
PreparedNonceWithProof(PreparedNonceWithProof &&other) noexcept=default
Move-only prepared nonce bound to either a message or a topic.
Definition legacy.hpp:292
static PreparedNonce from_parts(Scope scope, const Scalar32 &scalar, const Nonce &nonce, const XOnly32 &signer_pubkey, const XOnly32 &binding_digest)
Builds a prepared nonce from already-derived nonce components.
Definition legacy.cpp:268
Scalar32 scalar() const
Explicitly exports the secret nonce scalar.
Definition legacy.hpp:320
const Nonce & public_nonce() const noexcept
Returns the public nonce corresponding to this prepared secret nonce scalar.
Definition legacy.hpp:310
Result< Signature > sign_message(const Bip340Key &signer, std::span< const unsigned char > message, purify_secp_context *secp_context) &&
Consumes this message-bound nonce and signs the matching message.
Definition legacy.cpp:300
PreparedNonce & operator=(const PreparedNonce &)=delete
Result< Signature > sign_topic_message(const Bip340Key &signer, std::span< const unsigned char > message, purify_secp_context *secp_context) &&
Consumes this topic-bound nonce and signs a message under that topic binding.
Definition legacy.cpp:330
PreparedNonce(const PreparedNonce &)=delete
std::array< unsigned char, 32 > Scalar32
Definition legacy.hpp:25
std::array< unsigned char, 32 > XOnly32
Definition legacy.hpp:26
std::array< unsigned char, 64 > Signature64
Definition legacy.hpp:27
std::vector< unsigned char > Bytes
Dynamically sized byte string used for messages, serialized witnesses, and proofs.
Definition common.hpp:99
Scope scope
Definition bppp.cpp:118
Nonce nonce
Definition bppp.cpp:120
XOnly32 signer_pubkey
Definition bppp.cpp:121
XOnly32 binding_digest
Definition bppp.cpp:122
Canonical BIP340 keypair derived deterministically from a packed Purify secret.
Definition api.hpp:38
Experimental single-proof wrapper over the imported legacy Bulletproof circuit backend.
Cacheable message-bound nonce-proof template.
Definition legacy.hpp:247
NativeBulletproofCircuitTemplate circuit_template
Definition legacy.hpp:250
static Result< MessageProofCache > build(std::span< const unsigned char > message)
Builds a reusable verifier template for one exact message.
Definition legacy.cpp:771
ExperimentalBulletproofBackendCache backend_cache
Definition legacy.hpp:252
Public nonce together with its experimental Purify statement proof.
Definition legacy.hpp:221
ExperimentalBulletproofProof proof
Definition legacy.hpp:223
static Result< NonceProof > deserialize(std::span< const unsigned char > serialized, purify_secp_context *secp_context)
Definition legacy.cpp:141
Result< Bytes > serialize(purify_secp_context *secp_context) const
Definition legacy.cpp:117
Public BIP340 nonce point in x-only form.
Definition legacy.hpp:190
static Result< Nonce > deserialize(std::span< const unsigned char > serialized, purify_secp_context *secp_context)
Definition legacy.cpp:71
static constexpr std::size_t kSerializedSize
Definition legacy.hpp:191
Bytes serialize() const
Definition legacy.cpp:67
Standard signature bundled with the public nonce proof it relied on.
Definition legacy.hpp:231
static Result< ProvenSignature > deserialize(std::span< const unsigned char > serialized, purify_secp_context *secp_context)
Definition legacy.cpp:189
Result< Bytes > serialize(purify_secp_context *secp_context) const
Definition legacy.cpp:169
Public key bundle pairing a Purify packed public key with its derived BIP340 x-only key.
Definition legacy.hpp:42
static constexpr std::size_t kSerializedSize
Definition legacy.hpp:43
Result< bool > verify_message_signature_with_proof(std::span< const unsigned char > message, const ProvenSignature &signature, purify_secp_context *secp_context, ExperimentalBulletproofBackendCache *circuit_cache=nullptr) const
Verifies a message signature bundled with its nonce proof.
Definition legacy.cpp:741
Result< bool > verify_message_nonce_proof(std::span< const unsigned char > message, const NonceProof &nonce_proof, purify_secp_context *secp_context, ExperimentalBulletproofBackendCache *circuit_cache=nullptr) const
Verifies a message-bound nonce proof against this public key.
Definition legacy.cpp:715
Result< bool > verify_signature(std::span< const unsigned char > message, const Signature &signature, purify_secp_context *secp_context) const
Verifies a plain BIP340 signature against this bundle's x-only public key.
Definition legacy.cpp:710
Bytes serialize() const
Serializes this public-key bundle into its fixed-size wire format.
Definition legacy.cpp:39
static Result< PublicKey > from_secret(const SecretKey &secret, purify_secp_context *secp_context)
Derives both public identities from one packed Purify secret.
Definition legacy.cpp:706
Result< bool > verify_topic_signature_with_proof(std::span< const unsigned char > message, std::span< const unsigned char > topic, const ProvenSignature &signature, purify_secp_context *secp_context, ExperimentalBulletproofBackendCache *circuit_cache=nullptr) const
Verifies a topic-bound signature bundled with its nonce proof.
Definition legacy.cpp:755
Result< bool > verify_topic_nonce_proof(std::span< const unsigned char > topic, const NonceProof &nonce_proof, purify_secp_context *secp_context, ExperimentalBulletproofBackendCache *circuit_cache=nullptr) const
Verifies a topic-bound nonce proof against this public key.
Definition legacy.cpp:728
static Result< PublicKey > deserialize(std::span< const unsigned char > serialized, purify_secp_context *secp_context)
Parses a serialized public-key bundle.
Definition legacy.cpp:48
Standard 64-byte BIP340 signature.
Definition legacy.hpp:201
static constexpr std::size_t kSerializedSize
Definition legacy.hpp:202
static Result< Signature > deserialize(std::span< const unsigned char > serialized, purify_secp_context *secp_context)
Definition legacy.cpp:102
Bytes serialize() const
Definition legacy.cpp:98
Scalar32 s() const
Definition legacy.cpp:92
Cacheable topic-bound nonce-proof template.
Definition legacy.hpp:269
NativeBulletproofCircuitTemplate circuit_template
Definition legacy.hpp:272
ExperimentalBulletproofBackendCache backend_cache
Definition legacy.hpp:274
static Result< TopicProofCache > build(std::span< const unsigned char > topic)
Builds a reusable verifier template for one exact topic.
Definition legacy.cpp:775