The question, first
On-chain verification of Merkle proofs over an arithmetization-oriented hash is a real cost centre; rollup withdrawal proofs, storage proofs, anything that verifies a ZK-friendly tree in Solidity. Poseidon is the de facto choice and costs ~18,229 gas per 2-to-1 hash at a saturated optimizer in the maintained poseidon-solidity implementation.
I have a design that measures 14,232 gas for the same operation, a 1.28× improvement, and I want to know whether that margin is interesting enough to anyone here to be worth pursuing toward something standardisable; or whether the answer is “the gas isn’t the bottleneck, don’t bother.”
This is a request for feedback on whether the direction matters, not an EIP and not a proposal to adopt anything. The design is new and has had no external cryptanalysis. Do not deploy it.
What it is, briefly
Ashlar is an AO hash whose degree engine is a Feistel chain of field squarings rather than a power map. The motivating observation is an accounting one: a rank-1 constraint has total degree at most 2, so a zero-dimensional CICO ideal presented by C of them has quotient dimension at most 2^C. Squaring attains that ceiling — one bit of ideal degree per constraint, against 0.774 for x^5 and 0.702 for x^7.
The consequence in circuit terms: 191 measured R1CS constraints for a width-3 2-to-1 hash on BN254, against derived counts of 243 for Poseidon and 240 for Poseidon2. The consequence on-chain is the gas number above.
- Artifact, Solidity contracts, and Paper: GitHub - aryaethn/ashlar: Ashlar: an arithmetization-oriented hash from an R1CS-optimal squaring degree engine — paper, artifact manifest, and validation campaign · GitHub
- Cryptanalysis discussion: ethresear.ch thread
The gas measurement, in full
All contracts were gated on-chain against frozen test vectors before any gas number was taken. Foundry 1.7.1, solc 0.8.24, Cancun.
optimizer_runs |
Ashlar | Poseidon t=3 | Poseidon2 t=4 | Keccak-256 |
|---|---|---|---|---|
| 200 | 18,552 | 30,485 | 26,813 | 418 |
| 1,000 | 18,040 | 30,485 | 26,813 | 418 |
| 5,000 | 14,232 | 30,485 | 26,807 | 418 |
| 10,000 | 14,232 | 18,229 | 19,639 | 418 |
| 200,000 | 14,232 | 18,229 | 19,639 | 418 |
Three things I want to be upfront about, because each of them could reasonably
change your read:
- The ranking depends on the optimizer setting. At
runs=200the gap looks like 1.64×; at saturation it is 1.28×. Saturation is the deployment-realistic setting for a hash library, so 1.28× is the number I stand behind — but if you saw 1.64× quoted somewhere, that is the low-optimizer artifact and I am not going to defend it. - Keccak is ~34× cheaper and always will be. This matters only where you need a hash that is also cheap inside a proof.
- The Poseidon2 row is width 4, because no maintained width-3 Solidity Poseidon2 implementation existed when I measured. That is not an apples-to-apples row and I would not lean on it.
The arithmetic floor for the Ashlar contract is 326 mulmod + 395 addmod + 2 mod = 5,778 gas, so the measured 14,232 carries 2.46× overhead in stack, memory and dispatch. Someone better at Yul than me could probably close a meaningful part of that gap, which is one concrete thing I would like help with.
Where it is worse
I would rather you hear this from me:
- Native Goldilocks is 4.09× slower than Poseidon2 at width 12. If your workload is dominated by native hashing in a STARK prover rather than by constraints or gas, this is the wrong design.
- Native BN254 is ~11% slower than Poseidon2.
- Plonkish is a trade, not a win — one gate choice costs 1.26× more rows than Poseidon; another beats it at 58 rows but consumes the entire degree-9 budget, so any other gate in the circuit that would exceed 9 doubles the extended-domain blowup for everything.
- AIR cost was not measured and I rank nothing there.
What would actually need to be true
If anyone thinks this is worth pursuing, the honest prerequisites are, in order:
- External cryptanalysis. Nothing here has been independently reviewed. The paper proves an active-S-box count and a structural degree for the bare engine, and explicitly does not claim a lower bound on the cost of solving CICO or the algebraic security of the deployed mode. The multi-output ideal degree of the full permutation is open. A hash with no external analysis has no business in a standard.
- A second independent implementation, ideally by someone who was not involved, built from the normative pseudocode in the appendix alone. The appendix is written to make that possible and there is a conformance check that verifies it reproduces the frozen vectors without importing the reference.
- A real use case that is gas-bound rather than prover-bound, because the design deliberately trades native speed for constraints and gas.
Only after all three would an EIP or an ERC-style registry entry make sense, and I am not proposing one.
What I am asking
- Is a 1.28× on-chain AO hash improvement worth anyone’s attention, or is the gas cost of Merkle verification no longer where the pain is?
- Is there a deployment where the constraint count (191 vs 243) matters more than the native speed regression?
- Would anyone want to try to beat 2.46× overhead on the Yul contract? The contract and its gas harness are in the repo.
- Is Primordial Soup the right category for this, or should it sit purely on ethresear.ch until it has external analysis?
Genuinely open to “not interesting, here’s why.”