Skip to content

Add bn254 support and expose poseidon/poseidon2 host functions#1667

Merged
leighmcculloch merged 17 commits intomainfrom
release/v25-preview
Jan 12, 2026
Merged

Add bn254 support and expose poseidon/poseidon2 host functions#1667
leighmcculloch merged 17 commits intomainfrom
release/v25-preview

Conversation

@mootz12
Copy link
Copy Markdown
Contributor

@mootz12 mootz12 commented Jan 5, 2026

What

Why

Expose new crypto functions for protocol 25

Known limitations

Only the raw host function exposure for Poseidon/Poseidon2 has been added in this PR. The more elaborate setup for sponge, parameters, hash function wrappers will be done in a separate repo here

jayz22 and others added 8 commits November 11, 2025 11:54
### What

This is the same PR as
#1613, but onto
`p25-preview` branch instead of `master`, so that it doesn't interfere
with any potential p24 patch work.

All comments have been addressed in the original PR.

---------

Co-authored-by: Siddharth Suresh <siddharth@stellar.org>
Co-authored-by: Leigh <351529+leighmcculloch@users.noreply.github.com>
### What

Implements Poseidon, Poseidon:
- two new hash functions under `Crypto` which performs
Poseidon/Poseidon2 hashing. Underneath they wrap the permutation host
function call with a sponge implementation
- provide reference parameters for Poseidon/Poseidon2 for bn254
- results match both circom (for Poseidon) and noir (for Poseidon2) with
test cases
- also expose the two permutation host functions in `CryptoHazmat`, to
support custom sponge implementation / parameter sets.

### Why

[TODO: Why this change is being made. Include any context required to
understand the why.]

### Known limitations

For Poseidon only supports `hash2` (t=3, hashing two inputs into one
output) for now.
Only support BN254 for now.
To add support for the rest, need to generate and import those
parameters, which will be done in a followup.
Marked as draft because we need to fix the tests.
Implement `Neg` trait for `G1Affine`. This is useful for verifying
Groth16 proofs.

### What

- Introduce an `Fq` newtype wrapping `BytesN<FP_SERIALIZED_SIZE>` as the
BN254 base field element
- Implement `Neg` for `Fq`
- Implement `Neg` for `G1Affine` by:

### Why

- We need this operation to make cheaper groth16 verification on the
bn254 curve. BLS has implemented this feature as well.

### Known limitations

- Negation is implemented only for G1Affine; G2Affine and other types
(e.g. projective representations) do not yet have Neg implementations.

---------

Co-authored-by: Siddharth Suresh <siddharth@stellar.org>
### What

Merge main into v25-preview

---------

Co-authored-by: Leigh <351529+leighmcculloch@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
### What

This is just #1644 with
cleaner history.

---------

Co-authored-by: Nando Vieira <me@fnando.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
### What

Update typenames and add the contracttype mapping.
Co-authored-by: Leigh <351529+leighmcculloch@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@leighmcculloch
Copy link
Copy Markdown
Member

leighmcculloch commented Jan 5, 2026

Can we name the title of this PR, and its description with the crypto features being merged so that the git history on main captures what the features are being introduced? We can probably lift details from the PRs that were merged into the v25 branch. The final commit is written using the PR title and description.

@leighmcculloch
Copy link
Copy Markdown
Member

@jayz22 Should this wait on #1663 merging first? Or can that go to main separately?

@mootz12 mootz12 changed the title Release/v25 preview Add bn254, Poseidon, and Poseidon2 support Jan 5, 2026
@jayz22
Copy link
Copy Markdown
Contributor

jayz22 commented Jan 5, 2026

@jayz22 Should this wait on #1663 merging first? Or can that go to main separately?

@leighmcculloch yeah, let's merge that one first, since it contains a few additions/improvements to the Poseidon(2).

@socket-security
Copy link
Copy Markdown

socket-security bot commented Jan 5, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedsoroban-env-host@​23.0.1 ⏵ 25.0.086100100100100
Updatedsoroban-env-common@​23.0.1 ⏵ 25.0.091 +1100100100100
Updatedstellar-xdr@​23.0.0 ⏵ 25.0.093 +1100100100100
Updatedsoroban-env-guest@​23.0.1 ⏵ 25.0.010010093100100

View full report

@teddav
Copy link
Copy Markdown

teddav commented Jan 5, 2026

@jayz22 Could we add more constants to the Poseidon config? With the current parameters (T = 3 and the constants) in poseidon_params, hashing is limited to just two inputs. Supporting more inputs would be much more useful.
Since the number of inputs scales with the number of constants, we probably don’t want to make poseidon_params.rs too heavy. That said, supporting around 5–6 inputs feels like a good balance and should cover most protocol use cases.

EDIT: i just saw that you have an open PR with T=4, can we add a few more? :) Happy to review the PR if needed

@jayz22
Copy link
Copy Markdown
Contributor

jayz22 commented Jan 5, 2026

@jayz22 Could we add more constants to the Poseidon config? With the current parameters (T = 3 and the constants) in poseidon_params, hashing is limited to just two inputs. Supporting more inputs would be much more useful. Since the number of inputs scales with the number of constants, we probably don’t want to make poseidon_params.rs too heavy. That said, supporting around 5–6 inputs feels like a good balance and should cover most protocol use cases.

EDIT: i just saw that you have an open PR with T=4, can we add a few more? :) Happy to review the PR if needed

@teddav thanks for your interest in trying the Poseidon!
In the second PR I've added Poseidon parameters for t up to 4 (hashing 3 inputs). This should be a good starting point, but happy to consider adding more. (it's mostly takes time to properly generate/validate the parameters for both bn and bls and test them against circom/noir).

Also to point out, there is no hard rule between number of inputs and internal state size. I.e. you can use a sponge with internal t=4 and hash input length of 100, internally the sponge alternate between absorb and permute until the entire input is consumed. I.e. you can do the following

    // initialize a config with rate=2 (t=3)
    let config = PoseidonConfig::new(&self.env, field_type, 2);
    poseidon_sponge::hash(&self.env, inputs, config)

jayz22 and others added 2 commits January 7, 2026 18:16
…1663)

##  Summary

This PR provides comprehensive Poseidon and Poseidon2 hash function
implementations for both BN254 and BLS12-381 curves, with extensive
parameter coverage and test validation against external reference
implementations.

##  Changes

###  Convenience Hash Methods

- Added poseidon_hash<N>() - matches
https://github.com/iden3/circomlib/blob/35e54ea21da3e8762557234298dbb553c175ea8d/circuits/poseidon.circom
- Added poseidon2_hash<N>() - matches
https://github.com/noir-lang/noir/blob/abfee1f54b20984172ba23482f4af160395cfba5/noir_stdlib/src/hash/poseidon2.nr

###  Poseidon Parameters (poseidon_params.rs)

- BN254: MDS matrix and round constants for t=2, t=3, t=4 (validated
against circomlib)
- BLS12-381: MDS matrix and round constants for t=2, t=3, t=4 (validated
against reference Sage script and
[poseidon-bls12381-circom](https://github.com/jmagan/poseidon-bls12381-circom))

###  Poseidon2 Parameters (poseidon2_params.rs)

- BN254: Diagonal matrix (MAT_DIAG) and round constants for t=2, t=3,
t=4
  - BLS12-381: Diagonal matrix and round constants for t=2, t=3, t=4
- Parameters generated using reference Sage script and validated against
reference test vectors (generated by the script)

###  Sponge Implementations

- PoseidonSponge and Poseidon2Sponge with configurable parameters via
PoseidonConfig and Poseidon2Config
  - Proper capacity/rate handling matching reference implementations

###  Test Coverage

- Poseidon (BN254) - hash_n validated against circomlib
- Poseidon (BLS12-381) - hash_n validated against
poseidon-bls12381-circom
- Poseidon2 (BN254) - hash validated against barretenberg, permutation
validated against reference test vectors
- Poseidon2 (BLS12-381) - permutation validated against reference test
vectors
Copy link
Copy Markdown
Member

@leighmcculloch leighmcculloch left a comment

Choose a reason for hiding this comment

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

I thought all the changes in this pr were already reviewed on other PRs before merging to the v25-preview, but upon review of the PRs, not all of them were reviewed or approved.

I took a look through and noted a few minor things, comments inline. cc @jayz22

Can folks from the core team who are familiar with the crypto being added please do a full review? cc @stellar/contract-committers

The changes should ideally be reviewed by someone who wasn't the author. The authors were @jayz22 @Oghma @sisuresh. But @sisuresh's changes were all reviewed, so the reviewer just needs to be someone other than @jayz22 @Oghma.

jayz22 and others added 3 commits January 12, 2026 10:05
### What

Remove Poseidon, Poseidon2 code from the sdk.

### Why

To prepare for migrating this into a separate repo, for independent
review/audit/release cadence from the regular sdk.
@leighmcculloch leighmcculloch added this pull request to the merge queue Jan 12, 2026
@leighmcculloch leighmcculloch removed this pull request from the merge queue due to a manual request Jan 12, 2026
@jayz22 jayz22 changed the title Add bn254, Poseidon, and Poseidon2 support P25 - Add bn254 support and expose poseidon/poseidon2 host functions Jan 12, 2026
@jayz22 jayz22 changed the title P25 - Add bn254 support and expose poseidon/poseidon2 host functions Add bn254 support and expose poseidon/poseidon2 host functions Jan 12, 2026
@leighmcculloch leighmcculloch added this pull request to the merge queue Jan 12, 2026
Merged via the queue into main with commit ecad5ad Jan 12, 2026
190 of 204 checks passed
@leighmcculloch leighmcculloch deleted the release/v25-preview branch January 12, 2026 23:54
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.

6 participants