go-blockchain/crypto/bridge.h

177 lines
9.9 KiB
C
Raw Permalink Normal View History

// SPDX-Licence-Identifier: EUPL-1.2
// Stable C API for go-blockchain CGo bindings.
// Go code calls ONLY these functions — no C++ types cross this boundary.
#ifndef CRYPTONOTE_BRIDGE_H
#define CRYPTONOTE_BRIDGE_H
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
// ── Hashing ───────────────────────────────────────────────
void bridge_fast_hash(const uint8_t *data, size_t len, uint8_t hash[32]);
// ── Scalar Operations ────────────────────────────────────
// Reduce a 32-byte scalar modulo the Ed25519 group order l.
void cn_sc_reduce32(uint8_t key[32]);
// ── Key Operations ────────────────────────────────────────
int cn_generate_keys(uint8_t pub[32], uint8_t sec[32]);
int cn_secret_to_public(const uint8_t sec[32], uint8_t pub[32]);
int cn_check_key(const uint8_t pub[32]);
// ── Key Derivation ────────────────────────────────────────
int cn_generate_key_derivation(const uint8_t pub[32], const uint8_t sec[32],
uint8_t derivation[32]);
int cn_derive_public_key(const uint8_t derivation[32], uint64_t index,
const uint8_t base[32], uint8_t derived[32]);
int cn_derive_secret_key(const uint8_t derivation[32], uint64_t index,
const uint8_t base[32], uint8_t derived[32]);
// ── Key Images ────────────────────────────────────────────
int cn_generate_key_image(const uint8_t pub[32], const uint8_t sec[32],
uint8_t image[32]);
int cn_validate_key_image(const uint8_t image[32]);
// ── Standard Signatures ───────────────────────────────────
int cn_generate_signature(const uint8_t hash[32], const uint8_t pub[32],
const uint8_t sec[32], uint8_t sig[64]);
int cn_check_signature(const uint8_t hash[32], const uint8_t pub[32],
const uint8_t sig[64]);
// ── Ring Signatures (NLSAG) ──────────────────────────────
int cn_generate_ring_signature(const uint8_t hash[32], const uint8_t image[32],
const uint8_t *pubs, size_t pubs_count,
const uint8_t sec[32], size_t sec_index,
uint8_t *sigs);
int cn_check_ring_signature(const uint8_t hash[32], const uint8_t image[32],
const uint8_t *pubs, size_t pubs_count,
const uint8_t *sigs);
// ── Point Helpers ─────────────────────────────────────────
// Multiply a curve point by the cofactor 8 (for clearing small subgroup component).
int cn_point_mul8(const uint8_t pk[32], uint8_t result[32]);
// Premultiply by 1/8 (cofactor inverse). Stored form on-chain.
int cn_point_div8(const uint8_t pk[32], uint8_t result[32]);
// Subtract two curve points: result = a - b.
int cn_point_sub(const uint8_t a[32], const uint8_t b[32], uint8_t result[32]);
// ── CLSAG Verification (HF4+) ────────────────────────────
// Ring entries are flat arrays of 32-byte public keys per entry:
// GG: [stealth_addr(32) | amount_commitment(32)] per entry = 64 bytes
// GGX: [stealth(32) | commitment(32) | blinded_asset_id(32)] = 96 bytes
// GGXXG: [stealth(32) | commitment(32) | blinded_asset_id(32) | concealing(32)] = 128 bytes
// Signature layout (flat):
// GG: c(32) | r[ring_size*32] | K1(32) = 64 + ring_size*32
// GGX: c(32) | r_g[ring_size*32] | r_x[ring_size*32] | K1(32) | K2(32) = 96 + ring_size*64
// GGXXG: c(32) | r_g[ring_size*32] | r_x[ring_size*32] | K1(32) | K2(32) | K3(32) | K4(32) = 160 + ring_size*64
size_t cn_clsag_gg_sig_size(size_t ring_size);
int cn_clsag_gg_generate(const uint8_t hash[32], const uint8_t *ring,
size_t ring_size, const uint8_t pseudo_out[32],
const uint8_t ki[32], const uint8_t secret_x[32],
const uint8_t secret_f[32], size_t secret_index,
uint8_t *sig);
int cn_clsag_gg_verify(const uint8_t hash[32], const uint8_t *ring,
size_t ring_size, const uint8_t pseudo_out[32],
const uint8_t ki[32], const uint8_t *sig);
size_t cn_clsag_ggx_sig_size(size_t ring_size);
int cn_clsag_ggx_verify(const uint8_t hash[32], const uint8_t *ring,
size_t ring_size, const uint8_t pseudo_out_commitment[32],
const uint8_t pseudo_out_asset_id[32],
const uint8_t ki[32], const uint8_t *sig);
size_t cn_clsag_ggxxg_sig_size(size_t ring_size);
int cn_clsag_ggxxg_verify(const uint8_t hash[32], const uint8_t *ring,
size_t ring_size, const uint8_t pseudo_out_commitment[32],
const uint8_t pseudo_out_asset_id[32],
const uint8_t extended_commitment[32],
const uint8_t ki[32], const uint8_t *sig);
// ── Range Proofs (BPP — Bulletproofs++) ──────────────────
// Verifies a BPP range proof (1 delta). Used for zc_outs_range_proof in
// post-HF4 transactions. proof is the wire-serialised bpp_signature:
// varint(len(L)) + L[]*32 + varint(len(R)) + R[]*32
// + A0(32) + A(32) + B(32) + r(32) + s(32) + delta(32)
// commitments is a flat array of 32-byte public keys — the
// amount_commitments_for_rp_aggregation (E'_j, premultiplied by 1/8).
// Uses bpp_crypto_trait_ZC_out (generators UGX, N=64, values_max=32).
// Returns 0 on success, 1 on verification failure or deserialisation error.
int cn_bpp_verify(const uint8_t *proof, size_t proof_len,
const uint8_t *commitments, size_t num_commitments);
// ── Range Proofs (BPPE — Bulletproofs++ Enhanced) ────────
// Verifies a BPPE range proof (2 deltas). Used for Zarcanum PoS E_range_proof.
// proof is the wire-serialised bppe_signature:
// varint(len(L)) + L[]*32 + varint(len(R)) + R[]*32
// + A0(32) + A(32) + B(32) + r(32) + s(32) + delta_1(32) + delta_2(32)
// commitments is a flat array of 32-byte public keys (premultiplied by 1/8).
// Uses bpp_crypto_trait_Zarcanum (N=128, values_max=16).
// Returns 0 on success, 1 on verification failure or deserialisation error.
int cn_bppe_verify(const uint8_t *proof, size_t proof_len,
const uint8_t *commitments, size_t num_commitments);
// ── BGE One-out-of-Many ───────────────────────────────────
// Verifies a BGE one-out-of-many proof. proof is wire-serialised BGE_proof:
// A(32) + B(32) + varint(len(Pk)) + Pk[]*32
// + varint(len(f)) + f[]*32 + y(32) + z(32)
// ring is a flat array of 32-byte public keys. context is a 32-byte hash.
// Returns 0 on success, 1 on verification failure or deserialisation error.
int cn_bge_verify(const uint8_t context[32], const uint8_t *ring,
size_t ring_size, const uint8_t *proof, size_t proof_len);
// ── Generic Double Schnorr ────────────────────────────────
// Generates a generic_double_schnorr_sig from zarcanum.h.
// a_is_x selects the generator pair:
// 0 -> (G, G)
// 1 -> (X, G)
// proof must point to a 96-byte buffer.
int cn_double_schnorr_generate(int a_is_x, const uint8_t hash[32],
const uint8_t secret_a[32],
const uint8_t secret_b[32],
uint8_t *proof, size_t proof_len);
// Verifies a generic_double_schnorr_sig from zarcanum.h.
// a_is_x selects the generator pair:
// 0 -> (G, G)
// 1 -> (X, G)
// Returns 0 on success, 1 on verification failure or deserialisation error.
int cn_double_schnorr_verify(int a_is_x, const uint8_t hash[32],
const uint8_t a[32], const uint8_t b[32],
const uint8_t *proof, size_t proof_len);
// ── Zarcanum PoS ──────────────────────────────────────────
// Legacy compatibility wrapper for the historical proof-only API.
int cn_zarcanum_verify(const uint8_t hash[32], const uint8_t *proof,
size_t proof_len);
// Full Zarcanum verification entrypoint.
// ring is a flat array of 128-byte CLSAG_GGXXG ring members:
// [stealth(32) | amount_commitment(32) | blinded_asset_id(32) | concealing(32)]
// Returns 0 on success, 1 on verification failure or deserialisation error.
int cn_zarcanum_verify_full(const uint8_t m[32], const uint8_t kernel_hash[32],
const uint8_t *ring, size_t ring_size,
const uint8_t last_pow_block_id_hashed[32],
const uint8_t stake_ki[32],
uint64_t pos_difficulty,
const uint8_t *proof, size_t proof_len);
// ── RandomX PoW Hashing ──────────────────────────────────
// key/key_size: RandomX cache key (e.g. "LetheanRandomXv1")
// input/input_size: block header hash (32 bytes) + nonce (8 bytes LE)
// output: 32-byte hash result
// Returns 0 on success.
int bridge_randomx_hash(const uint8_t* key, size_t key_size,
const uint8_t* input, size_t input_size,
uint8_t* output);
#ifdef __cplusplus
}
#endif
#endif // CRYPTONOTE_BRIDGE_H