|
mpt-crypto
Confidential Multi-Purpose Tokens Cryptographic Library
|
Aggregated Bulletproof Range Proofs (Logarithmic Size). More...
#include "secp256k1_mpt.h"#include <openssl/sha.h>#include <openssl/rand.h>#include <string.h>#include <assert.h>#include <stdlib.h>#include <secp256k1.h>
Go to the source code of this file.
Macros | |
| #define | BP_VALUE_BITS 64 |
| #define | BP_TOTAL_BITS(m) |
| #define | SER_PT(P) |
Functions | |
| static size_t | bp_ipa_rounds (size_t total_bits) |
| static int | generate_random_scalar (const secp256k1_context *ctx, unsigned char *scalar_bytes) |
| static int | compute_amount_point (const secp256k1_context *ctx, secp256k1_pubkey *mG, uint64_t amount) |
| static int | add_term (const secp256k1_context *ctx, secp256k1_pubkey *acc, int *acc_inited, const secp256k1_pubkey *term) |
| static void | secp256k1_mpt_scalar_sub (unsigned char *res, const unsigned char *a, const unsigned char *b) |
| int | secp256k1_bulletproof_ipa_dot (const secp256k1_context *ctx, unsigned char *out, const unsigned char *a, const unsigned char *b, size_t n) |
| int | secp256k1_bulletproof_add_point_to_accumulator (const secp256k1_context *ctx, secp256k1_pubkey *acc, const secp256k1_pubkey *term) |
| int | secp256k1_bulletproof_ipa_msm (const secp256k1_context *ctx, secp256k1_pubkey *r_out, const secp256k1_pubkey *points, const unsigned char *scalars, size_t n) |
| static int | msm_try_add (const secp256k1_context *ctx, secp256k1_pubkey *acc, int *acc_inited, const secp256k1_pubkey *points, const unsigned char *scalars, size_t n) |
| void | scalar_vector_mul (const secp256k1_context *ctx, unsigned char res[][32], unsigned char a[][32], unsigned char b[][32], size_t n) |
| void | scalar_vector_add (const secp256k1_context *ctx, unsigned char res[][32], unsigned char a[][32], unsigned char b[][32], size_t n) |
| void | scalar_vector_powers (const secp256k1_context *ctx, unsigned char res[][32], const unsigned char *y, size_t n) |
| static void | scalar_pow_u32 (const secp256k1_context *ctx, unsigned char y_pow_out[32], const unsigned char y[32], unsigned int i) |
| static void | compute_z_pows_j2 (const secp256k1_context *ctx, unsigned char(*z_j2)[32], const unsigned char z[32], size_t m) |
| static int | secp256k1_bulletproof_point_scalar_mul (const secp256k1_context *ctx, secp256k1_pubkey *r_out, const secp256k1_pubkey *p_in, const unsigned char *s_scalar) |
| static void | compute_delta_scalars (const secp256k1_context *ctx, unsigned char(*y_block_sum)[32], unsigned char two_sum[32], const unsigned char y[32], size_t m) |
| static int | pubkey_equal (const secp256k1_context *ctx, const secp256k1_pubkey *a, const secp256k1_pubkey *b) |
| int | fold_generators (const secp256k1_context *ctx, secp256k1_pubkey *final_point, const secp256k1_pubkey *generators, const unsigned char *u_flat, const unsigned char *uinv_flat, size_t n, size_t rounds, int is_H) |
| int | apply_ipa_folding_to_P (const secp256k1_context *ctx, secp256k1_pubkey *P, const secp256k1_pubkey *L_vec, const secp256k1_pubkey *R_vec, const unsigned char *u_flat, const unsigned char *uinv_flat, size_t rounds) |
| int | secp256k1_bulletproof_ipa_compute_LR (const secp256k1_context *ctx, secp256k1_pubkey *L, secp256k1_pubkey *R, const unsigned char *a_L, const unsigned char *a_R, const unsigned char *b_L, const unsigned char *b_R, const secp256k1_pubkey *G_L, const secp256k1_pubkey *G_R, const secp256k1_pubkey *H_L, const secp256k1_pubkey *H_R, const secp256k1_pubkey *U, const unsigned char *ux, size_t half_n) |
| int | secp256k1_bulletproof_ipa_compress_step (const secp256k1_context *ctx, unsigned char *a, unsigned char *b, secp256k1_pubkey *G, secp256k1_pubkey *H, size_t half_n, const unsigned char *x, const unsigned char *x_inv) |
| static int | scalar_is_zero (const unsigned char s[32]) |
| int | derive_ipa_binding_challenge (const secp256k1_context *ctx, unsigned char *ux_out, const unsigned char *commit_inp_32, const unsigned char *dot_32) |
| int | derive_ipa_round_challenge (const secp256k1_context *ctx, unsigned char u_out[32], const unsigned char last_challenge[32], const secp256k1_pubkey *L, const secp256k1_pubkey *R) |
| int | secp256k1_bulletproof_run_ipa_prover (const secp256k1_context *ctx, const secp256k1_pubkey *g, secp256k1_pubkey *G_vec, secp256k1_pubkey *H_vec, unsigned char *a_vec, unsigned char *b_vec, size_t n, const unsigned char ipa_transcript_id[32], const unsigned char ux_scalar[32], secp256k1_pubkey *L_out, secp256k1_pubkey *R_out, size_t max_rounds, size_t *rounds_out, unsigned char a_final[32], unsigned char b_final[32]) |
| static int | ipa_verify_explicit (const secp256k1_context *ctx, const secp256k1_pubkey *G_vec, const secp256k1_pubkey *H_vec, const secp256k1_pubkey *U, const secp256k1_pubkey *P_in, const secp256k1_pubkey *L_vec, const secp256k1_pubkey *R_vec, size_t n, const unsigned char a_final[32], const unsigned char b_final[32], const unsigned char ux[32], const unsigned char ipa_transcript_id[32]) |
| int | secp256k1_bulletproof_compute_vectors_block (const secp256k1_context *ctx, uint64_t value, size_t block_index, unsigned char *al, unsigned char *ar, unsigned char *sl, unsigned char *sr) |
| int | secp256k1_bulletproof_create_commitment (const secp256k1_context *ctx, secp256k1_pubkey *commitment_C, uint64_t value, const unsigned char *blinding_factor, const secp256k1_pubkey *pk_base) |
| Computes a Pedersen Commitment: C = value*G + blinding_factor*Pk_base. | |
| int | secp256k1_bulletproof_prove_agg (const secp256k1_context *ctx, unsigned char *proof_out, size_t *proof_len, const uint64_t *values, const unsigned char *blindings_flat, size_t m, const secp256k1_pubkey *pk_base, const unsigned char *context_id) |
| int | secp256k1_bulletproof_verify_agg (const secp256k1_context *ctx, const secp256k1_pubkey *G_vec, const secp256k1_pubkey *H_vec, const unsigned char *proof, size_t proof_len, const secp256k1_pubkey *commitment_C_vec, size_t m, const secp256k1_pubkey *pk_base, const unsigned char *context_id) |
Aggregated Bulletproof Range Proofs (Logarithmic Size).
This module implements non-interactive zero-knowledge range proofs based on the Bulletproofs protocol (Bünz et al., 2018). It allows a prover to demonstrate that a committed value lies within the range \( [0, 2^{64}) \) without revealing the value itself.
Protocol Overview: The implementation follows the standard single-value and aggregated Bulletproof logic:
Aggregation: This implementation supports aggregating \( m \) proofs into a single verification process. The total vector length is \( n = 64 \cdot m \). Aggregation significantly reduces the on-chain footprint compared to \( m \) individual proofs.
Fiat-Shamir Transcript: The non-interactive challenge generation follows a strict dependency chain to ensure binding and special soundness:
Dependencies:
Definition in file bulletproof_aggregated.c.
| #define BP_TOTAL_BITS | ( | m | ) |
Definition at line 50 of file bulletproof_aggregated.c.
| #define BP_VALUE_BITS 64 |
Definition at line 47 of file bulletproof_aggregated.c.
| #define SER_PT | ( | P | ) |
|
static |
Safely adds a point to an accumulator (acc += term). Handles uninitialized accumulators by assignment instead of addition.
Definition at line 102 of file bulletproof_aggregated.c.

| int apply_ipa_folding_to_P | ( | const secp256k1_context * | ctx, |
| secp256k1_pubkey * | P, | ||
| const secp256k1_pubkey * | L_vec, | ||
| const secp256k1_pubkey * | R_vec, | ||
| const unsigned char * | u_flat, | ||
| const unsigned char * | uinv_flat, | ||
| size_t | rounds ) |
Definition at line 442 of file bulletproof_aggregated.c.


|
inlinestatic |
|
static |
Computes the point M = amount * G. Internal helper used by commitment construction.
Definition at line 81 of file bulletproof_aggregated.c.

|
static |
Computes per-block y-power sums for aggregated Bulletproofs. For block j (0-based): y_block_sum[j] = sum_{i=0}^{63} y^{64*j + i} Also computes: two_sum = sum_{i=0}^{63} 2^i These are used by the caller to construct delta(y, z).
Definition at line 335 of file bulletproof_aggregated.c.


|
static |
z_j2 = z^(j+2) for j = 0..m-1 (small exponent)
Definition at line 303 of file bulletproof_aggregated.c.


| int derive_ipa_binding_challenge | ( | const secp256k1_context * | ctx, |
| unsigned char * | ux_out, | ||
| const unsigned char * | commit_inp_32, | ||
| const unsigned char * | dot_32 ) |
Definition at line 690 of file bulletproof_aggregated.c.


| int derive_ipa_round_challenge | ( | const secp256k1_context * | ctx, |
| unsigned char | u_out[32], | ||
| const unsigned char | last_challenge[32], | ||
| const secp256k1_pubkey * | L, | ||
| const secp256k1_pubkey * | R ) |
Derive u = H(last_challenge || L || R) reduced to a valid scalar. IMPORTANT: use the SAME exact logic in verifier.
Definition at line 724 of file bulletproof_aggregated.c.


| int fold_generators | ( | const secp256k1_context * | ctx, |
| secp256k1_pubkey * | final_point, | ||
| const secp256k1_pubkey * | generators, | ||
| const unsigned char * | u_flat, | ||
| const unsigned char * | uinv_flat, | ||
| size_t | n, | ||
| size_t | rounds, | ||
| int | is_H ) |
u_flat and uinv_flat are arrays of length (rounds * 32): u_j = u_flat + 32*j u_j_inv = uinv_flat + 32*j
Definition at line 381 of file bulletproof_aggregated.c.


|
static |
Generates a secure 32-byte random scalar. Returns 1 on success, 0 on failure.
Definition at line 65 of file bulletproof_aggregated.c.

|
static |
Definition at line 874 of file bulletproof_aggregated.c.


|
static |
Definition at line 224 of file bulletproof_aggregated.c.


|
static |
Compare two secp256k1 public keys for equality.
Definition at line 373 of file bulletproof_aggregated.c.

|
static |
Definition at line 672 of file bulletproof_aggregated.c.

|
static |
Compute y^i for small i.
Definition at line 285 of file bulletproof_aggregated.c.


| void scalar_vector_add | ( | const secp256k1_context * | ctx, |
| unsigned char | res[][32], | ||
| unsigned char | a[][32], | ||
| unsigned char | b[][32], | ||
| size_t | n ) |
Computes component-wise: result[i] = a[i] + b[i]
Definition at line 255 of file bulletproof_aggregated.c.

| void scalar_vector_mul | ( | const secp256k1_context * | ctx, |
| unsigned char | res[][32], | ||
| unsigned char | a[][32], | ||
| unsigned char | b[][32], | ||
| size_t | n ) |
Computes component-wise: result[i] = a[i] * b[i] (Hadamard product)
Definition at line 245 of file bulletproof_aggregated.c.

| void scalar_vector_powers | ( | const secp256k1_context * | ctx, |
| unsigned char | res[][32], | ||
| const unsigned char * | y, | ||
| size_t | n ) |
Fills a vector with powers of a scalar: [1, y, y^2, ..., y^{n-1}]
Definition at line 266 of file bulletproof_aggregated.c.


| int secp256k1_bulletproof_add_point_to_accumulator | ( | const secp256k1_context * | ctx, |
| secp256k1_pubkey * | acc, | ||
| const secp256k1_pubkey * | term ) |
Internal helper for multi-scalar multiplication. Adds a point to the accumulator.
Definition at line 166 of file bulletproof_aggregated.c.
| int secp256k1_bulletproof_compute_vectors_block | ( | const secp256k1_context * | ctx, |
| uint64_t | value, | ||
| size_t | block_index, | ||
| unsigned char * | al, | ||
| unsigned char * | ar, | ||
| unsigned char * | sl, | ||
| unsigned char * | sr ) |
Phase 1, Step 3 (Aggregated): Compute al, ar, sl, sr vectors for ONE value block inside an aggregated proof.
The caller is responsible for:
Block layout: bits for value j occupy indices: [BP_VALUE_BITS * j .. BP_VALUE_BITS * j + BP_VALUE_BITS - 1]
Definition at line 998 of file bulletproof_aggregated.c.

| int secp256k1_bulletproof_create_commitment | ( | const secp256k1_context * | ctx, |
| secp256k1_pubkey * | commitment_C, | ||
| uint64_t | value, | ||
| const unsigned char * | blinding_factor, | ||
| const secp256k1_pubkey * | pk_base ) |
Computes a Pedersen Commitment: C = value*G + blinding_factor*Pk_base.
Computes the Pedersen Commitment: C = value*G + blinding_factor*Pk_base.
Definition at line 1061 of file bulletproof_aggregated.c.


| int secp256k1_bulletproof_ipa_compress_step | ( | const secp256k1_context * | ctx, |
| unsigned char * | a, | ||
| unsigned char * | b, | ||
| secp256k1_pubkey * | G, | ||
| secp256k1_pubkey * | H, | ||
| size_t | half_n, | ||
| const unsigned char * | x, | ||
| const unsigned char * | x_inv ) |
One IPA compression step (in-place).
Input vectors are length (2*half_n): a[0..2*half_n-1], b[0..2*half_n-1], G[0..2*half_n-1], H[0..2*half_n-1]
After return, the first half contains folded vectors: a'[0..half_n-1], b'[0..half_n-1], G'[0..half_n-1], H'[0..half_n-1]
Formulas (matching prover/verifier conventions): a'[i] = aL[i]*x + aR[i]*x_inv b'[i] = bL[i]*x_inv + bR[i]*x G'[i] = GL[i]*x_inv + GR[i]*x H'[i] = HL[i]*x + HR[i]*x_inv
Definition at line 607 of file bulletproof_aggregated.c.


| int secp256k1_bulletproof_ipa_compute_LR | ( | const secp256k1_context * | ctx, |
| secp256k1_pubkey * | L, | ||
| secp256k1_pubkey * | R, | ||
| const unsigned char * | a_L, | ||
| const unsigned char * | a_R, | ||
| const unsigned char * | b_L, | ||
| const unsigned char * | b_R, | ||
| const secp256k1_pubkey * | G_L, | ||
| const secp256k1_pubkey * | G_R, | ||
| const secp256k1_pubkey * | H_L, | ||
| const secp256k1_pubkey * | H_R, | ||
| const secp256k1_pubkey * | U, | ||
| const unsigned char * | ux, | ||
| size_t | half_n ) |
Computes the cross-term commitments L and R. L = <a_L, G_R> + <b_R, H_L> + c_L * ux * g R = <a_R, G_L> + <b_L, H_R> + c_R * ux * g ctx The context. L Output: Commitment point L_j. R Output: Commitment point R_j. half_n Length of the input vector halves. g The blinding generator point (Pk_base in our case). return 1 on success, 0 on failure.
Definition at line 511 of file bulletproof_aggregated.c.


| int secp256k1_bulletproof_ipa_dot | ( | const secp256k1_context * | ctx, |
| unsigned char * | out, | ||
| const unsigned char * | a, | ||
| const unsigned char * | b, | ||
| size_t | n ) |
Computes the modular dot product c = <a, b> = sum(a[i] * b[i]) mod q. This function calculates the inner product of two scalar vectors. ctx The context. out Output 32-byte scalar (the inner product result). a Input scalar vector A (n * 32 bytes). b Input scalar vector B (n * 32 bytes). n The length of the vectors. 1 on success, 0 on failure.
Definition at line 144 of file bulletproof_aggregated.c.


| int secp256k1_bulletproof_ipa_msm | ( | const secp256k1_context * | ctx, |
| secp256k1_pubkey * | r_out, | ||
| const secp256k1_pubkey * | points, | ||
| const unsigned char * | scalars, | ||
| size_t | n ) |
Computes Multiscalar Multiplication (MSM): R = sum(s[i] * P[i]). ctx The context. r_out Output point (the sum R). points Array of N input points (secp256k1_pubkey). scalars Flat array of N 32-byte scalars. n The number of terms (N). return 1 on success, 0 on failure. NOTE: This MSM is used only for Bulletproofs where all scalars are public. It is NOT constant-time with respect to scalars and MUST NOT be used for secret-key operations.
Definition at line 190 of file bulletproof_aggregated.c.


|
static |
Point = Scalar * Point (using public API)
Definition at line 317 of file bulletproof_aggregated.c.
| int secp256k1_bulletproof_prove_agg | ( | const secp256k1_context * | ctx, |
| unsigned char * | proof_out, | ||
| size_t * | proof_len, | ||
| const uint64_t * | values, | ||
| const unsigned char * | blindings_flat, | ||
| size_t | m, | ||
| const secp256k1_pubkey * | pk_base, | ||
| const unsigned char * | context_id ) |
Generates an aggregated Bulletproof for m values.
This function constructs a range proof asserting that all m values are within the [0, 2^64) range. The proof is serialized into proof_out.
Inputs:
Outputs:
Returns 1 on success, 0 on failure.
Definition at line 1114 of file bulletproof_aggregated.c.

| int secp256k1_bulletproof_run_ipa_prover | ( | const secp256k1_context * | ctx, |
| const secp256k1_pubkey * | g, | ||
| secp256k1_pubkey * | G_vec, | ||
| secp256k1_pubkey * | H_vec, | ||
| unsigned char * | a_vec, | ||
| unsigned char * | b_vec, | ||
| size_t | n, | ||
| const unsigned char | ipa_transcript_id[32], | ||
| const unsigned char | ux_scalar[32], | ||
| secp256k1_pubkey * | L_out, | ||
| secp256k1_pubkey * | R_out, | ||
| size_t | max_rounds, | ||
| size_t * | rounds_out, | ||
| unsigned char | a_final[32], | ||
| unsigned char | b_final[32] ) |
Runs the Inner Product Argument (IPA) prover. Recursively folds vectors G, H, a, and b into a single final term, producing log2(n) pairs of cross-term commitments (stored in L_out/R_out). Returns 1 on success, 0 on failure.
Definition at line 759 of file bulletproof_aggregated.c.


| int secp256k1_bulletproof_verify_agg | ( | const secp256k1_context * | ctx, |
| const secp256k1_pubkey * | G_vec, | ||
| const secp256k1_pubkey * | H_vec, | ||
| const unsigned char * | proof, | ||
| size_t | proof_len, | ||
| const secp256k1_pubkey * | commitment_C_vec, | ||
| size_t | m, | ||
| const secp256k1_pubkey * | pk_base, | ||
| const unsigned char * | context_id ) |
Verifies an aggregated Bulletproof range proof for m commitments.
Checks that the values committed in commitment_C_vec are all within the [0, 2^64) range.
Usage Notes:
Serialized Proof Format:
Total Size: 292 + (66 * rounds) bytes, where rounds = log2(64 * m).
Returns 1 if valid, 0 otherwise.
Definition at line 1715 of file bulletproof_aggregated.c.

|
static |
Computes modular subtraction of two scalars: res = a - b (mod q).
Definition at line 124 of file bulletproof_aggregated.c.

