Assessment reports>Penumbra>Threat Model>The value-balance mechanism

The value-balance mechanism

Penumbra uses additively homomorphic commitments in the style of Zcash Sapling to ensure that the balances contributed by actions within a transaction sum to zero, with the capability to hide intermediate amounts. The IsAction trait, which all actions implement, contains a function fn balance_commitment(&self) -> balance::Commitment;, which determines the value (potentially of multiple assets) that each action credits or debits from the transaction balance and whether that value is transparent or hidden. Balance commitments are group elements in the Decaf377 elliptic curve, whose order is slightly less than , and are of the form , where

  • is a random blinding value (which is zero for transparent commitments)

  • is a generator that is the Elligator encoding of the Blake2b hash of the string decaf377-rdsa-binding

  • is the (possibly negative) value associated with asset i in commitment j

  • is a generator depending on asset i's ID (the Elligator encoding of the Poseidon hash of the Blake2b hash of the string penumbra.value.generator and the asset's numeric ID)

These commitments have several important properties:

  • Summing them as curve points produces a commitment to the sum of the balances.

  • If is random, knowledge of does not reveal anything about .

  • If all of are zero, can be used as an ECDSA public key to check signatures signed with knowledge of

  • If some of are nonzero, a malicious signer can only produce a signature for by finding some such that and signing with , but finding such a requires solving the discrete logarithm problem.

  • Statements involving their components can be efficiently proved in zero knowledge by providing and as witnesses to the circuits.

The first property is used by Transaction::binding_verification_key to produce a commitment to the sum of the transaction's actions' balances. The third property is used by Transaction::check_stateless's valid_binding_signature check to ensure that the transaction's balance sums to zero by checking the signature produced in TransactionPlanner::apply_auth_data, where the synthetic_blinding_factor used to construct the binding_signing_key corresponds to .

In order for this to correctly represent value, each action's implementation must ensure that no unconstrained attacker-controlled values are included in the determination of the balance commitment and that overflow modulo the order of the group is not possible. Each action must ensure that the amounts contributed to the value balance are accurately tracked, whether that be through external state (like the nullifier set/state commitment tree) or by having a mix of negative and positive of different assets within the action's balance commitment.

For a more detailed treatment of the single-asset case, see section 4.13, "Balance and Binding Signature (Sapling)", of the Zcash protocol specification (https://zips.z.cash/protocol/protocol.pdf).

Zellic © 2025Back to top ↑