mpt-crypto
Confidential Multi-Purpose Tokens Cryptographic Library
Loading...
Searching...
No Matches
proof_link.c File Reference

Zero-Knowledge Proof Linking ElGamal Ciphertexts and Pedersen Commitments. More...

#include "secp256k1_mpt.h"
#include <openssl/sha.h>
#include <openssl/rand.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
Include dependency graph for proof_link.c:

Go to the source code of this file.

Macros

#define SER_AND_HASH(pk_ptr)

Functions

static int pubkey_equal (const secp256k1_context *ctx, const secp256k1_pubkey *pk1, const secp256k1_pubkey *pk2)
static int generate_random_scalar (const secp256k1_context *ctx, unsigned char *scalar_bytes)
static void build_link_challenge_hash (const secp256k1_context *ctx, unsigned char *e_out, const secp256k1_pubkey *c1, const secp256k1_pubkey *c2, const secp256k1_pubkey *pk, const secp256k1_pubkey *pcm, const secp256k1_pubkey *T1, const secp256k1_pubkey *T2, const secp256k1_pubkey *T3, const unsigned char *context_id)
int secp256k1_elgamal_pedersen_link_prove (const secp256k1_context *ctx, unsigned char *proof, const secp256k1_pubkey *c1, const secp256k1_pubkey *c2, const secp256k1_pubkey *pk, const secp256k1_pubkey *pcm, uint64_t amount, const unsigned char *r, const unsigned char *rho, const unsigned char *context_id)
 Proves the link between an ElGamal ciphertext and a Pedersen commitment.
int secp256k1_elgamal_pedersen_link_verify (const secp256k1_context *ctx, const unsigned char *proof, const secp256k1_pubkey *c1, const secp256k1_pubkey *c2, const secp256k1_pubkey *pk, const secp256k1_pubkey *pcm, const unsigned char *context_id)
 Verifies the link proof between ElGamal and Pedersen commitments.

Detailed Description

Zero-Knowledge Proof Linking ElGamal Ciphertexts and Pedersen Commitments.

This module implements a Sigma protocol to prove that an ElGamal ciphertext and a Pedersen commitment encode the same underlying plaintext value \( m \), without revealing \( m \) or the blinding factors.

Statement: The prover demonstrates knowledge of scalars \( (m, r, \rho) \) such that:

  1. \( C_1 = r \cdot G \) (ElGamal Ephemeral Key)
  2. \( C_2 = m \cdot G + r \cdot P \) (ElGamal Masked Value)
  3. \( PC_m = m \cdot G + \rho \cdot H \) (Pedersen Commitment)

Protocol (Schnorr-style):

  1. Commitment: Prover samples nonces \( k_m, k_r, k_\rho \) and computes:
  • \( T_1 = k_r \cdot G \)
  • \( T_2 = k_m \cdot G + k_r \cdot P \)
  • \( T_3 = k_m \cdot G + k_\rho \cdot H \)
  1. Challenge:

    \[ e = H(\text{"MPT_ELGAMAL_PEDERSEN_LINK"} \parallel C_1 \parallel C_2 \parallel P \parallel PC_m \parallel T_1 \parallel T_2 \parallel T_3 \parallel \dots) \]

  2. Response:
  • \( s_m = k_m + e \cdot m \)
  • \( s_r = k_r + e \cdot r \)
  • \( s_\rho = k_\rho + e \cdot \rho \)
  1. Verification: Verifier checks:
  • \( s_r \cdot G \stackrel{?}{=} T_1 + e \cdot C_1 \)
  • \( s_m \cdot G + s_r \cdot P \stackrel{?}{=} T_2 + e \cdot C_2 \)
  • \( s_m \cdot G + s_\rho \cdot H \stackrel{?}{=} T_3 + e \cdot PC_m \)
      **Security Context:**
    
    This proof prevents "bait-and-switch" attacks where a user sends a valid range proof for a small amount (e.g., 10) but updates the ledger balance with a large or negative amount (e.g., 1,000,000 or -5). It binds the two representations together.
See also
[Spec (ConfidentialMPT_20260201.pdf) Section 3.3.5] Linking ElGamal Ciphertexts and Pedersen Commitments

Definition in file proof_link.c.

Macro Definition Documentation

◆ SER_AND_HASH

#define SER_AND_HASH ( pk_ptr)
Value:
do { \
len = 33; \
secp256k1_ec_pubkey_serialize(ctx, buf, &len, pk_ptr, SECP256K1_EC_COMPRESSED); \
SHA256_Update(&sha, buf, 33); \
} while(0)

Function Documentation

◆ build_link_challenge_hash()

void build_link_challenge_hash ( const secp256k1_context * ctx,
unsigned char * e_out,
const secp256k1_pubkey * c1,
const secp256k1_pubkey * c2,
const secp256k1_pubkey * pk,
const secp256k1_pubkey * pcm,
const secp256k1_pubkey * T1,
const secp256k1_pubkey * T2,
const secp256k1_pubkey * T3,
const unsigned char * context_id )
static

Definition at line 64 of file proof_link.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ generate_random_scalar()

int generate_random_scalar ( const secp256k1_context * ctx,
unsigned char * scalar_bytes )
static

Definition at line 57 of file proof_link.c.

Here is the caller graph for this function:

◆ pubkey_equal()

int pubkey_equal ( const secp256k1_context * ctx,
const secp256k1_pubkey * pk1,
const secp256k1_pubkey * pk2 )
static

Definition at line 53 of file proof_link.c.

Here is the caller graph for this function:

◆ secp256k1_elgamal_pedersen_link_prove()

int secp256k1_elgamal_pedersen_link_prove ( const secp256k1_context * ctx,
unsigned char * proof,
const secp256k1_pubkey * c1,
const secp256k1_pubkey * c2,
const secp256k1_pubkey * pk,
const secp256k1_pubkey * pcm,
uint64_t amount,
const unsigned char * r,
const unsigned char * rho,
const unsigned char * context_id )

Proves the link between an ElGamal ciphertext and a Pedersen commitment.

  • Formal Statement: Knowledge of (m, r, rho) such that: C1 = r*G, C2 = m*G + r*Pk, and PCm = m*G + rho*H.
  • Parameters
    ctxPointer to a secp256k1 context object.
    proof[OUT] Pointer to 195-byte buffer for the proof output.
    c1Pointer to the ElGamal C1 point (r*G).
    c2Pointer to the ElGamal C2 point (m*G + r*Pk).
    pkPointer to the recipient's public key.
    pcmPointer to the Pedersen Commitment (m*G + rho*H).
    amountThe plaintext amount (m).
    rThe 32-byte secret ElGamal blinding factor.
    rhoThe 32-byte secret Pedersen blinding factor.
    context_id32-byte unique transaction context identifier.
    Returns
    1 on success, 0 on failure.

Definition at line 108 of file proof_link.c.

Here is the call graph for this function:

◆ secp256k1_elgamal_pedersen_link_verify()

int secp256k1_elgamal_pedersen_link_verify ( const secp256k1_context * ctx,
const unsigned char * proof,
const secp256k1_pubkey * c1,
const secp256k1_pubkey * c2,
const secp256k1_pubkey * pk,
const secp256k1_pubkey * pcm,
const unsigned char * context_id )

Verifies the link proof between ElGamal and Pedersen commitments.

  • Returns
    1 if the proof is valid, 0 otherwise.

Definition at line 212 of file proof_link.c.

Here is the call graph for this function: