26bool ranges_overlap(
const void* lhs, std::size_t lhs_size,
const void* rhs, std::size_t rhs_size)
noexcept {
27 if (lhs_size == 0 || rhs_size == 0 || lhs ==
nullptr || rhs ==
nullptr) {
31 const auto lhs_addr =
reinterpret_cast<std::uintptr_t
>(lhs);
32 const auto rhs_addr =
reinterpret_cast<std::uintptr_t
>(rhs);
33 if (lhs_addr <= rhs_addr) {
34 return (rhs_addr - lhs_addr) < lhs_size;
36 return (lhs_addr - rhs_addr) < rhs_size;
43 return Bytes(data, data + size);
51 std::fill(std::begin(out->public_key), std::end(out->public_key), 0);
59 std::fill(std::begin(out->xonly_public_key), std::end(out->xonly_public_key), 0);
64 UInt256::from_hex(
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
69 static const UInt256 value = [] {
79 out.reserve(prefix.size() + message.size());
80 out.insert(out.end(), prefix.begin(), prefix.end());
81 out.insert(out.end(), message.begin(), message.end());
86 if (secret_key ==
nullptr) {
92 "parse_secret_key:purify_validate_secret_key");
99 if (public_key ==
nullptr) {
105 "parse_public_key:purify_validate_public_key");
112 const std::array<unsigned char, PURIFY_PUBLIC_KEY_BYTES> bytes = value.
to_bytes_be();
113 std::copy(bytes.begin(), bytes.end(), out);
117 const std::array<unsigned char, PURIFY_FIELD_ELEMENT_BYTES> bytes = value.
to_bytes_be();
118 std::copy(bytes.begin(), bytes.end(), out);
124 "derive_public_key_from_secret:mul_secret_affine_p1");
126 "derive_public_key_from_secret:mul_secret_affine_p2");
127 return pack_public(p1.x.to_uint256(), p2.x.to_uint256());
138 if (out ==
nullptr) {
162 const unsigned char* seed,
167 const unsigned char* seed_input = seed;
169 if (out ==
nullptr) {
174 seed_input = seed_copy.data();
198 if (out_public_key ==
nullptr) {
220 if (out ==
nullptr) {
232 std::array<unsigned char, PURIFY_SECRET_KEY_BYTES> packed_secret_bytes = packed_secret->to_bytes_be();
233 purify::Bytes ikm(packed_secret_bytes.begin(), packed_secret_bytes.end());
234#if PURIFY_USE_LEGACY_FIELD_HASHES
235 std::optional<purify::UInt256>
scalar =
239 std::optional<purify::UInt256>
scalar = purify::tagged_hash_to_int<4>(
245 if (!
scalar.has_value()) {
250 const std::array<unsigned char, PURIFY_BIP340_SECRET_KEY_BYTES> scalar_bytes =
scalar->to_bytes_be();
251 std::copy(scalar_bytes.begin(), scalar_bytes.end(), out->
secret_key);
252 if (secp_context ==
nullptr) {
265 const unsigned char* message,
266 size_t message_len) {
267 if (out_field_element ==
nullptr) {
270 if (message_len != 0 && message ==
nullptr) {
purify_error_code purify_generate_key(purify_generated_key *out)
Generates one random Purify keypair.
purify_error_code purify_generate_key_from_seed(purify_generated_key *out, const unsigned char *seed, size_t seed_len)
Deterministically derives one Purify keypair from seed material.
purify_error_code purify_eval(unsigned char out_field_element[PURIFY_FIELD_ELEMENT_BYTES], const unsigned char secret_key[PURIFY_SECRET_KEY_BYTES], const unsigned char *message, size_t message_len)
Evaluates the Purify PRF for one packed secret and message.
purify_error_code purify_derive_public_key(unsigned char out_public_key[PURIFY_PUBLIC_KEY_BYTES], const unsigned char secret_key[PURIFY_SECRET_KEY_BYTES])
Derives the packed public key corresponding to one packed Purify secret.
purify_error_code purify_derive_bip340_key(purify_bip340_key *out, const unsigned char secret_key[PURIFY_SECRET_KEY_BYTES], purify_secp_context *secp_context)
Derives one canonical BIP340 keypair from one packed Purify secret.
Result< AffinePoint > mul_secret_affine(const JacobianPoint &point, const UInt256 &scalar) const
Multiplies a public point by a secret scalar using exception-free complete formulas.
Purify result carrier that either holds a value or an error.
bool has_value() const noexcept
Field element modulo the backend scalar field used by this implementation.
std::array< unsigned char, 32 > to_bytes_be() const
Serializes the field element in big-endian form.
Reusable BIP340-style tagged SHA-256 helper.
purify_error_code purify_core_sample_secret_key(unsigned char out_secret_key[PURIFY_SECRET_KEY_BYTES])
purify_error_code purify_core_seed_secret_key(unsigned char out_secret_key[PURIFY_SECRET_KEY_BYTES], const unsigned char *seed, size_t seed_len)
Elliptic-curve helpers, fixed parameters, and hash-to-curve utilities for Purify.
Library-level error taxonomy used to classify Purify failures.
#define PURIFY_ASSIGN_OR_RETURN(lhs, expr, context)
Evaluates an expected-like expression, binds the value to lhs, and propagates errors.
void write_field_element(const FieldElement &value, unsigned char *out)
void clear_generated_key(purify_generated_key *out) noexcept
const UInt256 & secp256k1_order()
void clear_bip340_key(purify_bip340_key *out) noexcept
void write_uint512(const UInt512 &value, unsigned char *out)
Bytes copy_bytes(const unsigned char *data, std::size_t size)
bool ranges_overlap(const void *lhs, std::size_t lhs_size, const void *rhs, std::size_t rhs_size) noexcept
Bytes tagged_message(std::string_view prefix, const Bytes &message)
Result< UInt512 > parse_public_key(const unsigned char *public_key)
Result< UInt512 > derive_public_key_from_secret(const UInt512 &secret)
Result< UInt512 > parse_secret_key(const unsigned char *secret_key)
const UInt256 & secp256k1_order_minus_one()
constexpr ErrorCode from_core_error_code(purify_error_code code) noexcept
constexpr purify_error_code to_core_error_code(ErrorCode code) noexcept
void secure_clear_bytes(void *data, std::size_t size) noexcept
constexpr Unexpected< Error > unexpected_error(ErrorCode code, const char *context=nullptr)
Constructs an unexpected Error value from a machine-readable code.
Bytes bytes_from_ascii(std::string_view input)
Encodes an ASCII string as a byte vector.
const EllipticCurve & curve1()
Returns the first Purify curve instance.
std::vector< unsigned char > Bytes
Dynamically sized byte string used for messages, serialized witnesses, and proofs.
const JacobianPoint & generator1()
Returns the fixed generator for the first curve.
UInt512 pack_public(const UInt256 &x1, const UInt256 &x2)
Packs two x-coordinates into the reference 512-bit public-key encoding.
Result< std::pair< UInt256, UInt256 > > unpack_secret(const UInt512 &z)
Splits a packed private key into its two per-curve secret scalars.
Result< JacobianPoint > hash_to_curve(const Bytes &data, const EllipticCurve &curve)
Hashes arbitrary data onto the supplied curve by rejection sampling x-coordinates.
const EllipticCurve & curve2()
Returns the second Purify curve instance.
const JacobianPoint & generator2()
Returns the fixed generator for the second curve.
FieldElement combine(const FieldElement &x1, const FieldElement &x2)
Applies the Purify curve-combination map to two x-coordinates.
Public C core for Purify key validation, key derivation, key generation, and evaluation.
#define PURIFY_SECRET_KEY_BYTES
#define PURIFY_PUBLIC_KEY_BYTES
purify_error_code
Machine-readable status code returned by the Purify C core.
@ PURIFY_ERROR_MISSING_VALUE
@ PURIFY_ERROR_INTERNAL_MISMATCH
@ PURIFY_ERROR_BACKEND_REJECTED_INPUT
purify_error_code purify_validate_secret_key(const unsigned char secret_key[PURIFY_SECRET_KEY_BYTES])
Validates one packed Purify secret key.
#define PURIFY_FIELD_ELEMENT_BYTES
purify_error_code purify_validate_public_key(const unsigned char public_key[PURIFY_PUBLIC_KEY_BYTES])
Validates one packed Purify public key.
int purify_bip340_key_from_seckey(purify_secp_context *context, unsigned char seckey32[32], unsigned char xonly_pubkey32[32])
Canonicalizes a valid secp256k1 secret key for BIP340 and derives its x-only public key.
Secret-owning Purify key material wrappers.
static BigUInt from_bytes_be(const unsigned char *data, std::size_t size)
Parses a big-endian byte string into the fixed-width integer.
void sub_assign(const BigUInt &other)
Subtracts another fixed-width integer in place.
static BigUInt from_hex(std::string_view hex)
Parses a hexadecimal string with the precondition that the value fits exactly.
static BigUInt one()
Returns the multiplicative identity.
std::array< unsigned char, Words *8 > to_bytes_be() const
Serializes the value to a fixed-width big-endian byte array.
Canonical BIP340 keypair derived from one packed Purify secret.
unsigned char secret_key[PURIFY_BIP340_SECRET_KEY_BYTES]
unsigned char xonly_public_key[PURIFY_BIP340_XONLY_PUBKEY_BYTES]
Seed/public-key bundle returned by the C core key-generation entry points.
unsigned char secret_key[PURIFY_SECRET_KEY_BYTES]
unsigned char public_key[PURIFY_PUBLIC_KEY_BYTES]