Skip to content

Conversation

@richardpringle
Copy link
Contributor

@richardpringle richardpringle commented Dec 15, 2025

The main change of this PR is the ArithmeticSpongeParams type (found here).

What used to be a Vec<Vec<F>> is now [[F; FULL_ROUNDS]] where FULL_ROUNDS is a const generic of type usize. This means the data can now sit on either the stack or the heap, and is contiguous rather than spread across the heap.

Making this change had wide spread affects to the all the dependent functions, types and traits. Now many of them are generic over a usize. There's really only one file that had logical changes and that's poseidon/src/permutation.rs. Extra allocations were removed and the code was cleaned up a little to now handle the arrays instead of Vecs.

I benchmarked locally and there is small consistent speed up (though that was not the goal).

@dannywillems
Copy link
Member

dannywillems commented Dec 15, 2025

Next steps:

  • check benchmarks
    • this is the first thing to check because the hash function is a critical part of the whole protocol. If we get worse performances, we should abort this task immediately. However, there is a small probability that we get something worse. If we get better performances, we should absolutely documented it, and the CHANGELOG should contain the benchmarks, in addition to this PR.
  • check if updating MinaProtocol/Mina with this version doesn't break
  • as well as o1js
  • fix the different lints
  • clean the history
  • rename ROUNDS into FULL_ROUNDS

Probably as a follow-up:

  • add a new type parameter PARTIAL_ROUNDS as a Poseidon instance contains two types of rounds, so-called "partial" and "full". Our current Poseidon instance do not use any partial rounds, but if we change it in the future, we would need it. As discussed, if the parameter is not used right now, we should not have it in the codebase now.

@richardpringle richardpringle force-pushed the rp/poseidon-arrays branch 3 times, most recently from 5472365 to c846516 Compare December 16, 2025 18:02
Copy link
Contributor Author

@richardpringle richardpringle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these comments are for myself, others are for the reviewer

Comment on lines +125 to +130
state
.iter_mut()
.zip(params.round_constants[0].iter())
.for_each(|(s, x)| {
s.add_assign(x);
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To get the exact same behaviour as before, these should actually be reversed:

Suggested change
state
.iter_mut()
.zip(params.round_constants[0].iter())
.for_each(|(s, x)| {
s.add_assign(x);
});
params
.round_constants[0]
.iter()
.zip(state.iter_mut())
.for_each(|(x, s)| {
s.add_assign(x);
});

In practice though, the round_constants[0] and state are always the same length.

@dannywillems, thoughts? Should I change this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they must be the same length.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dannywillems, should we add an issue to add an assertion here? Could mark it with "good first issue" and hope someone else does it

@richardpringle
Copy link
Contributor Author

Running CI on github.com/mina

@richardpringle richardpringle marked this pull request as ready for review December 22, 2025 17:36
@richardpringle
Copy link
Contributor Author

richardpringle commented Dec 22, 2025

Next steps:

  • check benchmarks

    • this is the first thing to check because the hash function is a critical part of the whole protocol. If we get worse performances, we should abort this task immediately. However, there is a small probability that we get something worse. If we get better performances, we should absolutely documented it, and the CHANGELOG should contain the benchmarks, in addition to this PR.
  • check if updating MinaProtocol/Mina with this version doesn't break

  • as well as o1js

  • fix the different lints

  • clean the history

  • rename ROUNDS into FULL_ROUNDS

Probably as a follow-up:

  • add a new type parameter PARTIAL_ROUNDS as a Poseidon instance contains two types of rounds, so-called "partial" and "full". Our current Poseidon instance do not use any partial rounds, but if we change it in the future, we would need it. As discussed, if the parameter is not used right now, we should not have it in the codebase now.
  • Consistent (small) speedup locally
  • Mina doesn't break, see my comment above.
  • o1js was a little harder to test, but @Trivo25 got things working locally for him. It required a change to the initial memory pages on the web, but that just puts the web inline with nodejs. Not only should the speedup help on wasm-side, but there should be less memory pressure as there are fewer allocations now. @Trivo25 may have been a little concerned about the new memory usage, but it's memory that was always used; now it just exists on initialization instead of being allocated dynamically.
  • lints are fixed
  • history is clean (every commit is formatted and passes the linter - I would bet the tests pass too, but I didn't check that as it's not a requirement)
  • ROUNDS is now FULL_ROUNDS
  • and finally, I will create the PARTIAL_ROUNDS ticket once CI is passing and this PR is approved

params: &ArithmeticSpongeParams<F, FULL_ROUNDS>,
state: &mut [F],
) {
for r in 0..SC::PERM_HALF_ROUNDS_FULL {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess later we can remove PERM_HALF_ROUNDS_FULL from the params.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dannywillems, is there an issue for doing the partial round stuff? We can reference this comment in there

@dannywillems dannywillems merged commit f4f7afa into master Jan 7, 2026
24 checks passed
@dannywillems dannywillems deleted the rp/poseidon-arrays branch January 7, 2026 15:55
@richardpringle
Copy link
Contributor Author

Added a bunch of follow up issues from the comments (mine and @dannywillems's)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants