Balance Commitment Format

Balance Commitment Format - Technical Specification

This document specifies the balance commitment format used for proving value conservation in Roru Protocol transactions.

Balance Proof Architecture

Purpose

Balance commitments prove that:

  • Input values equal output values

  • No value is created or destroyed

  • All values are within valid ranges

  • Transaction is balanced

Commitment Structure

Balance Commitment Format:

pub struct BalanceCommitment {
    pub input_commitment: Commitment,   // Sum of input commitments
    pub output_commitment: Commitment,  // Sum of output commitments
    pub public_value: Option<i64>,      // Public value (if any)
    pub proof: BalanceProof,            // Zero-knowledge proof
}

Commitment Calculation

Input Commitment

Input Commitment Formula:

C_in = Σ(C_i) for all input notes i

Where each C_i is a Pedersen commitment to note i.

Implementation:

fn calculate_input_commitment(inputs: &[Note]) -> Commitment {
    inputs.iter()
        .map(|note| commit_note(note))
        .sum()
}

Output Commitment

Output Commitment Formula:

C_out = Σ(C_j) for all output notes j

Implementation:

fn calculate_output_commitment(outputs: &[Note]) -> Commitment {
    outputs.iter()
        .map(|note| commit_note(note))
        .sum()
}

Balance Equation

Balance Verification:

C_in = C_out + C_fee

Where:

  • C_in = sum of input commitments

  • C_out = sum of output commitments

  • C_fee = fee commitment (if applicable)

Zero-Knowledge Balance Proof

Proof Circuit

Balance Circuit:

  • Proves input sum = output sum

  • Hides individual values

  • Verifies range constraints

  • Ensures no overflow

Circuit Constraints:

// Input sum constraint
let input_sum = inputs.iter().sum();
// Output sum constraint
let output_sum = outputs.iter().sum();
// Balance constraint
assert!(input_sum == output_sum + fee);
// Range constraints
for value in inputs {
    assert!(value < MAX_VALUE);
}
for value in outputs {
    assert!(value < MAX_VALUE);
}

Proof Generation

Generation Process:

  1. Construct witness

  2. Execute circuit

  3. Generate proof

  4. Verify proof

Generation Code:

fn generate_balance_proof(
    inputs: &[Note],
    outputs: &[Note],
    fee: u64,
) -> BalanceProof {
    let witness = BalanceWitness {
        input_values: inputs.iter().map(|n| n.value).collect(),
        output_values: outputs.iter().map(|n| n.value).collect(),
        input_randomness: inputs.iter().map(|n| n.randomness).collect(),
        output_randomness: outputs.iter().map(|n| n.randomness).collect(),
        fee,
    };
    
    execute_balance_circuit(&witness)
}

Public Values

Public Value Support

Public Value Format:

pub struct PublicValue {
    pub amount: i64,        // Can be negative (refund)
    pub asset_id: AssetId,
}

Public Value Handling

Use Cases:

  • Public fees

  • Public refunds

  • Transparent operations

  • Compliance requirements

Balance with Public Values:

C_in + C_public_in = C_out + C_public_out + C_fee

Range Constraints

Value Ranges

Valid Range:

  • Minimum: 0

  • Maximum: 2^64 - 1

  • No negative values (except public)

  • No overflow

Range Proof

Range Proof Circuit:

  • Proves value in range [0, 2^64)

  • Efficient proof size

  • Fast verification

Range Proof Implementation:

fn prove_range(value: u64, randomness: Scalar) -> RangeProof {
    // Prove value is in valid range
    // Using range proof circuit
    generate_range_proof(value, randomness)
}

Fee Handling

Fee Commitment

Fee Format:

pub struct FeeCommitment {
    pub amount: u64,
    pub commitment: Commitment,
}

Fee Calculation

Fee Structure:

  • Base fee

  • Size-based fee

  • Priority fee (optional)

  • Total fee

Fee Commitment:

fn commit_fee(fee: u64) -> Commitment {
    commit_value(fee, generate_randomness())
}

Batch Balance Verification

Batch Operations

Batch Format:

pub struct BatchBalanceCommitment {
    pub transactions: Vec<BalanceCommitment>,
    pub batch_proof: BatchProof,
}

Batch Verification

Verification Process:

  1. Verify individual proofs

  2. Verify batch proof

  3. Check aggregate balance

  4. Validate all constraints

Batch Verification Code:

fn verify_batch(batch: &BatchBalanceCommitment) -> bool {
    // Verify all individual proofs
    for tx in &batch.transactions {
        if !verify_balance_proof(tx) {
            return false;
        }
    }
    
    // Verify batch proof
    verify_batch_proof(&batch.batch_proof)
}

Homomorphic Properties

Additive Homomorphism

Property:

Commit(a) + Commit(b) = Commit(a + b)

Application:

  • Efficient balance verification

  • Batch operations

  • Aggregate proofs

Implementation

Homomorphic Addition:

fn add_commitments(c1: Commitment, c2: Commitment) -> Commitment {
    c1 + c2  // Point addition on curve
}

Performance

Efficiency

Operations:

  • Commitment calculation: O(n) where n is number of notes

  • Proof generation: O(1) circuit execution

  • Proof verification: O(1)

  • Batch verification: O(1) per transaction

Sizes:

  • Balance commitment: 64 bytes

  • Balance proof: ~1-2 KB

  • Batch proof: ~2-3 KB

Security

Security Properties

Binding:

  • Cannot change values without changing commitment

  • Cryptographically secure

  • Prevents fraud

Hiding:

  • Values hidden in commitments

  • Zero-knowledge proofs

  • No information leakage

Conclusion

Balance commitments provide:

  • Correctness: Proves value conservation

  • Privacy: Hides individual values

  • Efficiency: Fast verification

  • Flexibility: Supports various scenarios

  • Security: Cryptographic guarantees

Understanding balance commitments is essential for transaction validation.

Last updated