Synopsis
A vector commitment is a construction that produces a constant-size, binding commitment to an indexed vector of elements and short membership and/or non-membership proofs for any indices & elements in the vector. This specification enumerates the functions and properties required of commitment constructions used in the IBC protocol. In particular, commitments utilised in IBC are required to be positionally binding: they must be able to prove existence or nonexistence of values at specific positions (indices).Motivation
In order to provide a guarantee of a particular state transition having occurred on one chain which can be verified on another chain, IBC requires an efficient cryptographic construction to prove inclusion or non-inclusion of particular values at particular paths in state.Definitions
The manager of a vector commitment is the actor with the ability and responsibility to add or remove items from the commitment. Generally this will be the state machine of a blockchain. The prover is the actor responsible for generating proofs of inclusion or non-inclusion of particular elements. Generally this will be a relayer (see ICS 18). The verifier is the actor who checks proofs in order to verify that the manager of the commitment did or did not add a particular element. Generally this will be an IBC handler (module implementing IBC) running on another chain. Commitments are instantiated with particular path and value types, which are assumed to be arbitrary serialisable data. A negligible function is a function that grows more slowly than the reciprocal of every positive polynomial, as defined here.Desired Properties
This document only defines desired properties, not a concrete implementation — see “Properties” below.Technical Specification
Below we define a behaviour and an overview of datatypes. For data type definition look at cosmos/ics23 repository.Datatypes
A commitment construction MUST specify the following datatypes, which are otherwise opaque (need not be introspected) but MUST be serialisable:Commitment State
ACommitmentState is the full state of the commitment, which will be stored by the manager.
Commitment Root
ACommitmentRoot commits to a particular commitment state and should be constant-size.
In certain commitment constructions with constant-size states, CommitmentState and CommitmentRoot may be the same type.
Commitment Path
ACommitmentPath is the path used to verify commitment proofs, which can be an arbitrary structured object (defined by a commitment type). It must be computed by applyPrefix (defined below).
Prefix
ACommitmentPrefix defines a store prefix of the commitment proof. It is applied to the path before the path is passed to the proof verification functions.
applyPrefix constructs a new commitment path from the arguments. It interprets the path argument in the context of the prefix argument.
For two (prefix, path) tuples, applyPrefix(prefix, path) MUST return the same key only if the tuple elements are equal.
applyPrefix MUST be implemented per Path, as Path can have different concrete structures. applyPrefix MAY accept multiple CommitmentPrefix types.
The CommitmentPath returned by applyPrefix does not need to be serialisable (e.g. it might be a list of tree node identifiers), but it does need an equality comparison.
removePrefix is the inverse operation of applyPrefix, i.e. it returns the bytestring key without the store prefix.
Proof
ACommitmentProof demonstrates membership or non-membership for an element or set of elements, verifiable in conjunction with a known commitment root. Proofs should be succinct.
Required functions
A commitment construction MUST provide the following functions, defined over paths as serialisable objects and values as byte arrays:Initialisation
Thegenerate function initialises the state of the commitment from an initial (possibly empty) map of paths to values.
Root calculation
ThecalculateRoot function calculates a constant-size commitment to the commitment state which can be used to verify proofs.
Adding & removing elements
Theset function sets a path to a value in the commitment.
remove function removes a path and associated value from a commitment.
Proof generation
ThecreateMembershipProof function generates a proof that a particular commitment path has been set to a particular value in a commitment.
createNonMembershipProof function generates a proof that a commitment path has not been set to any value in a commitment.
Proof verification
TheverifyMembership function verifies a proof that a path has been set to a particular value in a commitment.
verifyNonMembership function verifies a proof that a path has not been set to any value in a commitment.
Optional functions
A commitment construction MAY provide the following functions: ThebatchVerifyMembership function verifies a proof that many paths have been set to specific values in a commitment.
batchVerifyNonMembership function verifies a proof that many paths have not been set to any value in a commitment.
verifyMembership and verifyNonMembership respectively (efficiency may vary):
Properties & Invariants
Commitments MUST be complete, sound, and position binding. These properties are defined with respect to a security parameterk, which MUST be agreed upon by the manager, prover, and verifier (and often will be constant for the commitment algorithm).
Completeness
Commitment proofs MUST be complete: path => value mappings which have been added to the commitment can always be proved to have been included, and paths which have not been included can always be proved to have been excluded, except with probability negligible ink.
For any prefix prefix and any path path last set to a value value in the commitment acc,
prefix and any path path not set in the commitment acc, for all values of proof and all values of value,
Soundness
Commitment proofs MUST be sound: path => value mappings which have not been added to the commitment cannot be proved to have been included, or paths which have been added to the commitment excluded, except with probability negligible in a configurable security parameterk.
For any prefix prefix and any path path last set to a value value in the commitment acc, for all values of proof,
prefix and any path path not set in the commitment acc, for all values of proof and all values of value,
b may be proven by showing the existence of key a and key c in addition to proving that these two keys are neighbors in the commitment.
Position binding
Commitment proofs MUST be position binding: a given commitment path can only map to one value, and a commitment proof cannot prove that the same path opens to a different value except with probability negligible in k. For any prefixprefix and any path path set in the commitment acc, there is one value for which:
otherValue where value !== otherValue, for all values of proof,
Backwards Compatibility
Not applicable.Forwards Compatibility
Commitment algorithms are expected to be fixed. New algorithms can be introduced by versioning connections and channels.Example Implementations
- Implementations of ICS 23 in Go and Rust can be found in cosmos/ics23 repository.
History
Security definitions are mostly sourced from these papers (and simplified somewhat):- Vector Commitments and their Applications
- Commitments with Applications to Anonymity-Preserving Revocation
- Batching Techniques for Commitments with Applications to IOPs and Stateless Blockchains