Skip to content

Conversation

@robknight
Copy link

@robknight robknight commented Feb 24, 2025

Currently calling Poseidon::new() loads the constants from scratch each time, converting them from string representation to field elements. There's ~1.8MB of constants, so this takes some time - tens of milliseconds in native and over 200ms in Wasm.

However, this process really only needs to be done once, so we can statically initialize the constants and avoid paying this cost multiple times. This greatly speeds up signing PODs in parcnet-pod:

image

I've also added a second commit, which looks like a huge change but isn't that big: it breaks up the constants into separate crates, enabled by features, so that it's possible to include only those constants which are required. For example, PODs only require the poseidon-1, poseidon-2, and poseidon-5 constants, and the rest are dead weight. This cuts the WASM build for parcnet-pod down from 1.7MB to 473KB. I do appreciate that this is a slightly scarier refactor, though, so we might want to discuss the implications.

Copy link
Owner

@arnaucube arnaucube left a comment

Choose a reason for hiding this comment

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

This a very nice improvement!!

Comment on lines +139 to +141
if t_idx >= self.constants.c.len() {
return Err(format!("No constants available for input length {}. Enable the appropriate feature flag.", inp.len()));
}
Copy link
Owner

Choose a reason for hiding this comment

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

I tried using the lib externally, importing only the feature poseidon-2, and it breaks because the self.constants.c.len() is always 1 (same happens for the other poseidon sizes).

Copy link
Owner

Choose a reason for hiding this comment

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

Maybe a way to catch this for the future, might be splitting the test into a test for each size, and adding feature conditionals to the tests; something like

    #[test]
    #[cfg(feature = "poseidon-2")]
    fn test_poseidon2() {
        // ...
    }

    #[test]
    #[cfg(feature = "poseidon-3")]
    fn test_poseidon3() {
        // ...
    }
   // ...

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants