[RFC] Improve Mantle Transaction hash
This RFC follows an older schema and will be updated when time allows.
Authors: Thomas Lavaur Approvals (research): Marcin Pawlowski Approvals (engineering): Daniel Sanchez Quiros, Youngjoon Lee
Motivation
As Mantle Transactions grow (notably with large CHANNEL_INSCRIBE Operations), computing ZkHash over the whole transaction becomes a noticeable cost during transaction construction and verification. This RFC proposes a small change that preserves the use of ZkHash while reducing the amount of data hashed inside the circuit.
Proposal
In version [1.2.0] Mantle, the Mantle Transaction hash is defined as the ZkHash of the entire Mantle Transaction, excluding the Ledger Transaction proof and the Operation proofs.
Currently we perform a zero-knowledge hashing on a Mantle Transaction (without proofs):
tx_hash = ZkHash(mantle_tx_without_proofs).
However, execution of this hashing algorithm is time consuming and grows with the size of the input. Therefore, we propose instead hashing the Mantle Transaction using the classic hash defined in [1.0.2] Common Cryptographic Components, then hashing the result with ZkHash:
tx_hash = ZkHash(classic_hash(mantle_tx_without_proofs)),
where classic_hash() is the classic hash defined in [1.0.2] Common Cryptographic Components.
Justification
The proposed change speeds up computation of the Mantle Transaction hash by moving most of the work out of ZkHash and into a classic hash, while still committing to the result inside ZkHash. This becomes an issue as Mantle Transactions grow, since hashing can take a substantial amount of time (for example, if the transaction contains a large CHANNEL_INSCRIBE Operation).
Here we show the difference of computation speed for Mantle Transactions encoding and hashing containing a single Ledger Transaction and a single Inscription varying the size of the inscription to make the transaction longer.
+--------------+-----------------------+------------------+-------------------------------+---------------------------+
| payload_size | blake2b_poseidon2_avg | poseidon2_avg | poseidon2 / blake2b_poseidon2 | blake2b+poseidon2 faster |
+--------------+-----------------------+------------------+-------------------------------+---------------------------+
| 64 | 10.84 us | 65.89 us | 6.08x | 83.55% |
| 256 | 10.40 us | 62.14 us | 5.98x | 83.26% |
| 1,024 | 10.89 us | 142.30 us | 13.07x | 92.35% |
| 4,096 | 13.02 us | 561.00 us | 43.09x | 97.68% |
| 65,536 | 71.34 us | 8.851 ms | 124.07x | 99.19% |
| 524,288 | 657.20 us | 70.69 ms | 107.56x | 99.07% |
| 1,048,576 | 1.315 ms | 143.30 ms | 108.97x | 99.08% |
| 2,097,152 | 2.652 ms | 283.90 ms | 107.05x | 99.07% |
| 4,194,304 | 5.981 ms | 563.70 ms | 94.25x | 98.94% |
+--------------+-----------------------+------------------+-------------------------------+---------------------------+
We can clearly see that combining the classic and zk hashes yields a significant improvement. The material used for the benchmarks is the following:
- CPU : 13th Gen Intel(R) Core(TM) i9-13980HX (24 cores / 32 threads)
- RAM : 32GB - Speed: 5600 MT/s
- Motherboard: Micro-Star International Co., Ltd. MS-17S1
- OS : Ubuntu 22.04.5 LTS
- Kernel : 6.8.0-59-generic
The code of the benchmarks can be found here.
Specifications Update
- [v1.2.1] Mantle Specification