Skip to content

feat: add field element based sign/verify with Poseidon2 sponge for bn254#810

Open
devon1209 wants to merge 3 commits intoConsensys:masterfrom
devon1209:feat/bn254-poseidon2-fieldHasher
Open

feat: add field element based sign/verify with Poseidon2 sponge for bn254#810
devon1209 wants to merge 3 commits intoConsensys:masterfrom
devon1209:feat/bn254-poseidon2-fieldHasher

Conversation

@devon1209
Copy link
Copy Markdown
Contributor

@devon1209 devon1209 commented Feb 23, 2026

Description

Adds field-element-based EdDSA signing/verification (SignField/VerifyField) to bn254, using a Poseidon2 sponge hash that produces outputs identical to gnark's in-circuit Poseidon2 hash (std/hash/poseidon2).

Currently, gnark-crypto's off-chain EdDSA (Sign/Verify) uses hash.Hash (byte-based), while gnark's in-circuit EdDSA uses hash.FieldHasher (field-element-based). Even with the same Poseidon2 permutation, these produce different hash values.

Fixes #809

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)

How has this been tested?

Please describe the tests that you ran or implemented to verify your changes. Provide instructions so we can reproduce.

  • go test ./ecc/bn254/fr/poseidon2
  • go test ./ecc/bn254/twistededwards/eddsa

How has this been benchmarked?

Please describe the benchmarks that you ran to verify your changes.

  • Not run (not requested)

Checklist:

  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • I did not modify files generated from templates
  • golangci-lint does not output errors locally
  • New and existing unit tests pass locally with my changes

Note

Medium Risk
Touches cryptographic hashing and signature code paths; while changes are additive and well-tested, any mismatch in sponge parameters/domain separation could break compatibility or introduce subtle security issues.

Overview
Adds a BN254 Poseidon2 field-element sponge hash (SpongeHash) plus a small NewFieldHasher wrapper, using HorizenLabs t=4/8/12/16 parameters, an IV derived from input length, and multi-block absorption so off-chain hashing matches gnark’s in-circuit Poseidon2 sponge domain.

Extends BN254 EdDSA with field-element message signing and verification via SignField/VerifyField and a FieldHasher interface, including explicit domain separation for the deterministic nonce to avoid reuse with the existing byte-based Sign API. Adds unit tests covering sponge determinism/width selection/multiblock/panic behavior and an end-to-end Poseidon2-backed SignField/VerifyField test; generator templates are updated so the BN254 code is produced consistently.

Written by Cursor Bugbot for commit 425c297. This will update automatically on new commits. Configure here.

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

@devon1209 devon1209 marked this pull request as draft February 24, 2026 02:24
@devon1209 devon1209 marked this pull request as ready for review February 25, 2026 04:27
@ivokub
Copy link
Copy Markdown
Collaborator

ivokub commented Mar 9, 2026

Thanks for the contribution. I'll take a bit time to review -- perhaps it is better to add some generic hash.FieldHasher interface in the hash package as well, but I'd like to think about it a bit more to ensure that we have nice aligning interfaces with gnark.

@devon1209
Copy link
Copy Markdown
Contributor Author

@ivokub Thank you for taking a look. I also had some thoughts on how to best align the interfaces, so it would be nice if there is an improvement.

@ivokub
Copy link
Copy Markdown
Collaborator

ivokub commented Mar 9, 2026

@ivokub Thank you for taking a look. I also had some thoughts on how to best align the interfaces, so it would be nice if there is an improvement.

Yeah, it has backfired on us as well several times due to mismatching hashes (also on edge cases where there are some leading zeros etc) and there is also significant memory overhead due to needing to allocate bytes for mapping field elements and then back.

Now with generics it could perhaps actually even work out. Before generics all solutions were ugly, but would have to iterate a few times to get it just right

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.

feat: add field element based sign/verify with Poseidon2 sponge for bn254

2 participants