-
Notifications
You must be signed in to change notification settings - Fork 266
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: added poseidon2 hash function to barretenberg/crypto #3118
Conversation
Benchmark resultsNo metrics with a significant change found. Detailed resultsAll benchmarks are run on txs on the This benchmark source data is available in JSON format on S3 here. Values are compared against data from master at commit L2 block published to L1Each column represents the number of txs on an L2 block published to L1.
L2 chain processingEach column represents the number of blocks on the L2 chain where each block has 16 txs.
Circuits statsStats on running time and I/O sizes collected for every circuit run across all benchmarks.
MiscellaneousTransaction sizes based on how many contracts are deployed in the tx.
|
Since the poseidon code is not comformant with the reference implementation, it probably makes sense to thoroughly review the changes outside of the poseidon2 module and the API of poseidon2. Once we make poseidon2 conformant with a chosen reference implementation using test vectors, then it will become glaringly obvious if the implementation is "correct". @zac-williamson what are your thoughts? |
Would also say that while its not conformant we likely don't want to integrate it into other parts of the system as it may cause breaking changes once we make it conformant |
I think this works and should be plan A, but it works only as long as we can get independent test vectors. The best I can find use |
Yes I agree. I think we should get all of the hash structures implemented and working (i.e. have stuff in the stdlib, ideally also have ACIR opcodes working), but to not actually use Poseidon downstream until we've made it conformant |
params use sage script derived from hoizen labs implementation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally looks good to me. Had several questions and some nits.
barretenberg/cpp/src/barretenberg/crypto/poseidon2/poseidon2_cpp_params.sage
Outdated
Show resolved
Hide resolved
barretenberg/cpp/src/barretenberg/crypto/poseidon2/CMakeLists.txt
Outdated
Show resolved
Hide resolved
barretenberg/cpp/src/barretenberg/crypto/poseidon2/poseidon2_permutation.hpp
Show resolved
Hide resolved
barretenberg/cpp/src/barretenberg/crypto/poseidon2/poseidon2_permutation.hpp
Show resolved
Hide resolved
barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp
Show resolved
Hide resolved
cache_size += 1; | ||
} else if (mode == Mode::SQUEEZE) { | ||
// If we're in squeeze mode, switch to absorb mode and add the input into the cache. | ||
// N.B. I don't think this code path can be reached?! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like a call to squeeze() and then absorb() will hit this condition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but it does seem like we would not like to ever have an absorb AFTER a squeeze. Maybe we could throw an error in this case?
barretenberg/cpp/src/barretenberg/crypto/poseidon2/poseidon2_permutation.hpp
Outdated
Show resolved
Hide resolved
auto new_output_elements = perform_duplex(); | ||
mode = Mode::SQUEEZE; | ||
for (size_t i = 0; i < rate; ++i) { | ||
cache[i] = new_output_elements[i]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we populate the cache with the same elements in state?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is because we return cache elements as our output, but this seems like a weird way to do things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cache
contains data that has yet to be included in the sponge, and state
is the active data in the sponge.
state
acts as a mutable data structure and cache
doesn't. I think this is a safer way to structure the code as perform_duplex
mutates state
cache_size = rate; | ||
} | ||
// By this point, we should have a non-empty cache. Pop one item off the top of the cache and return it. | ||
FF result = cache[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not just return cache[cache_size-1]? and avoid this shifting process?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cache
is not a local variable but is a member of the Sponge class. It's state is important. We must remove the element that we are returning from the cache. Just returning cache[cache_size - 1]
will not have the same behavior.
with regards to the manual action of shifting cache
, we could have used a std::vector
to define cache
and used the pop
method, but I wanted to use a fixed-size array to represent cache
so that indexing the array out of bounds would more easily be caught by the compiler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant returning cache[cache_size-1]
and also decrementing cache_size
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just thoroughness when developing the code. I wanted to rule out stale data in cache
being a source of bugs.
Can we try using an existing implementation with t=3, and modify it so that it uses t=4? |
return output; | ||
} | ||
|
||
template <size_t out_len> static std::array<FF, out_len> hash_fixed_length(std::span<FF> input) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't see how there's a differentiation between fixed length and variable length here. It seems like we only have fixed length hashing since we only take in field elements of 254 bits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the length refers to the number of field elements being hashed, not the number of bits in a field element.
Variable-length means that we are computing the hash of a dynamically-sized nubmer of field elements (i.e. the length varies from one hash to the next)
Fixed-length hash means we are computing the hash of a fixed-size nubmer of inputs (i.e. the length does not vary from one hash to the next)
A fixed-length hash is more efficient if we can get away with it, as we do not need to include the size of the hash in the preimage data being hashed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it, seems like we are only doing variable length hashing then right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for now. Merkle membership hashes will likely use fixed length
Yes I think we can do this. |
🤖 I have created a release *beep* *boop* --- <details><summary>aztec-packages: 0.16.1</summary> ## [0.16.1](aztec-packages-v0.16.0...aztec-packages-v0.16.1) (2023-11-28) ### Features * Added poseidon2 hash function to barretenberg/crypto ([#3118](#3118)) ([d47782b](d47782b)) * Aztec CI files in Noir ([#3430](#3430)) ([1621f3a](1621f3a)) * Persistent archiver store ([#3410](#3410)) ([4735bde](4735bde)), closes [#3361](#3361) ### Bug Fixes * **ci:** Don't leave DRY_DEPLOY unset ([#3449](#3449)) ([454e316](454e316)) * **ci:** Publishing dockerhub manifests ([#3451](#3451)) ([a59e7f0](a59e7f0)) * Hotfix noir sync ([#3436](#3436)) ([c4e4745](c4e4745)) ### Miscellaneous * **docs:** Core concepts page in getting-started ([#3401](#3401)) ([1a62f73](1a62f73)) * Point acir tests at noir master branch ([#3440](#3440)) ([106e690](106e690)) ### Documentation * Further updates to the gas and fees whitepaper ([#3448](#3448)) ([4152ba6](4152ba6)) * Updates to gas and fees yellow paper ([#3438](#3438)) ([5f0e1ca](5f0e1ca)) </details> <details><summary>barretenberg.js: 0.16.1</summary> ## [0.16.1](barretenberg.js-v0.16.0...barretenberg.js-v0.16.1) (2023-11-28) ### Miscellaneous * **barretenberg.js:** Synchronize aztec-packages versions </details> <details><summary>barretenberg: 0.16.1</summary> ## [0.16.1](barretenberg-v0.16.0...barretenberg-v0.16.1) (2023-11-28) ### Features * Added poseidon2 hash function to barretenberg/crypto ([#3118](#3118)) ([d47782b](d47782b)) ### Miscellaneous * Point acir tests at noir master branch ([#3440](#3440)) ([106e690](106e690)) </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Preliminary work to add Poseidon2 hash function as a standard library primitive (https://eprint.iacr.org/2023/323.pdf) Adds Poseidon2 to crypto module, following paper + specification at https://github.com/C2SP/C2SP/blob/792c1254124f625d459bfe34417e8f6bdd02eb28/poseidon-sponge.md --------- Co-authored-by: lucasxia01 <[email protected]>
🤖 I have created a release *beep* *boop* --- <details><summary>aztec-packages: 0.16.1</summary> ## [0.16.1](AztecProtocol/aztec-packages@aztec-packages-v0.16.0...aztec-packages-v0.16.1) (2023-11-28) ### Features * Added poseidon2 hash function to barretenberg/crypto ([#3118](AztecProtocol/aztec-packages#3118)) ([d47782b](AztecProtocol/aztec-packages@d47782b)) * Aztec CI files in Noir ([#3430](AztecProtocol/aztec-packages#3430)) ([1621f3a](AztecProtocol/aztec-packages@1621f3a)) * Persistent archiver store ([#3410](AztecProtocol/aztec-packages#3410)) ([4735bde](AztecProtocol/aztec-packages@4735bde)), closes [#3361](AztecProtocol/aztec-packages#3361) ### Bug Fixes * **ci:** Don't leave DRY_DEPLOY unset ([#3449](AztecProtocol/aztec-packages#3449)) ([454e316](AztecProtocol/aztec-packages@454e316)) * **ci:** Publishing dockerhub manifests ([#3451](AztecProtocol/aztec-packages#3451)) ([a59e7f0](AztecProtocol/aztec-packages@a59e7f0)) * Hotfix noir sync ([#3436](AztecProtocol/aztec-packages#3436)) ([c4e4745](AztecProtocol/aztec-packages@c4e4745)) ### Miscellaneous * **docs:** Core concepts page in getting-started ([#3401](AztecProtocol/aztec-packages#3401)) ([1a62f73](AztecProtocol/aztec-packages@1a62f73)) * Point acir tests at noir master branch ([#3440](AztecProtocol/aztec-packages#3440)) ([106e690](AztecProtocol/aztec-packages@106e690)) ### Documentation * Further updates to the gas and fees whitepaper ([#3448](AztecProtocol/aztec-packages#3448)) ([4152ba6](AztecProtocol/aztec-packages@4152ba6)) * Updates to gas and fees yellow paper ([#3438](AztecProtocol/aztec-packages#3438)) ([5f0e1ca](AztecProtocol/aztec-packages@5f0e1ca)) </details> <details><summary>barretenberg.js: 0.16.1</summary> ## [0.16.1](AztecProtocol/aztec-packages@barretenberg.js-v0.16.0...barretenberg.js-v0.16.1) (2023-11-28) ### Miscellaneous * **barretenberg.js:** Synchronize aztec-packages versions </details> <details><summary>barretenberg: 0.16.1</summary> ## [0.16.1](AztecProtocol/aztec-packages@barretenberg-v0.16.0...barretenberg-v0.16.1) (2023-11-28) ### Features * Added poseidon2 hash function to barretenberg/crypto ([#3118](AztecProtocol/aztec-packages#3118)) ([d47782b](AztecProtocol/aztec-packages@d47782b)) ### Miscellaneous * Point acir tests at noir master branch ([#3440](AztecProtocol/aztec-packages#3440)) ([106e690](AztecProtocol/aztec-packages@106e690)) </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Preliminary work to add Poseidon2 hash function as a standard library primitive (https://eprint.iacr.org/2023/323.pdf)
Adds Poseidon2 to crypto module, following paper + specification at https://github.com/C2SP/C2SP/blob/792c1254124f625d459bfe34417e8f6bdd02eb28/poseidon-sponge.md
Checklist:
Remove the checklist to signal you've completed it. Enable auto-merge if the PR is ready to merge.