NOTE: This scheme is FLAWED and can be attacked. The attacker can swap the
data for arbitrary
data'. First they need to compute the
orig=hash(P1|data); fake=hash(P1|data'). They can then swap the original data with the fake one and adjust the kernel offset by
the difference in hash computations. Note that even if kernel offsets did not exist, the same attack could be done by adding and signing
a new kernel that contains the hash difference.
A way to commit to additional UTXO data in the scope of a MW transaction
Let’s say we want to commit to more data than a single Pedersen commitment
v*H + r*G. David Burkett introduced an idea
that uses Bulletproofs to inject a hash in the 20 bytes that are available in the Bulletproof. This however makes the
protocol dependent on the specific range proof implementation Bulletproofs. It would be best if there was a way
to commit to additional data without relying on the range proof implementation. The reason for this is that if an alternative
to Bulletproofs comes, a switch to a different range proof solution would not cause us to lose a way to commit
to additional data.
What it’s trying to solve
This is not about commiting arbitrary data on the chain. This should only be considered when the protocol needs more data than a single Pedersen commitment. Commiting to arbitrary data can be solved with timestamping. Let’s say that the protocol rules requires more than just a single Pedersen commitment for successful validation. For example the Noninteractive approach that David showed requires some additional fields to be a part of the UTXO. The data commitment approach mentioned above is one way to commit to additonal data that’s needed to validate the UTXO and uses Bulletproofs to achieve this.
Commiting to additional data using the transaction kernel
Let’s say we want to commit to some
data with a Mimblewimble UTXO. Along with the Pedersen commitment
P1 = v*H + r*G we also show the
data value which is the data we want to commit to.
This means our UTXO now holds two pieces of information
UTXO = [P1, data].
With the information from the
UTXO, we can compute
P2 = v*H + r*G + hash(P1 | data)*G.
When creating the kernel public key and signature, instead of using
P1 Pedersen commitments we use
P2 which can be computed from the UTXO. This makes the transaction kernel commit to the excess
which is a combination of values of the form
(r+hash(P1 | data))*G instead of just
Only the owner of the Pedersen commitment knows the
r, but everyone can compute the
hash(P1 | data) because the
data are public. Swapping the
data for a different one is
hard because one would need to create a different
data which would produce the same hash
hash(P1 | data) to keep the transaction kernel valid. Finding such data requires finding a hash collision. If someone
wants to spend the commitment they need to know the
r + hash(P1 | data) and since the
data is public, everyone already knows the
hash(P1 | data) part so the only thing an attacker would need to know is
r which is the same requirement as in the current implementation.
This also means that the inflation check formula
sum(outputs) - sum(inputs) needs to use
This does not use any more data than the idea that injects a hash into a Bulletproof. The benefit as mentioned above is that it does not depend on the range proof implementation, but it does require more changes due to the change in the kernel computation which is the downside of this approach.