Skip to content

batched bn254 51 bits RNE multiplier #259

Merged
Bisht13 merged 39 commits into
mainfrom
xr/fmul
Feb 6, 2026
Merged

batched bn254 51 bits RNE multiplier #259
Bisht13 merged 39 commits into
mainfrom
xr/fmul

Conversation

@xrvdg
Copy link
Copy Markdown
Collaborator

@xrvdg xrvdg commented Jan 23, 2026

  • Add 51-bit floating-point Montgomery multiplication for BN254 scalar field optimised for WASM
  • Rename block-multiplier to bn254-multiplier with reorganized module structure
  • Optimize carries and squaring operations in the b51 multiplier
  • Add Kani verification for integer-to-float conversion
  • Enable relaxed SIMD in WASI runners
  • Make benchmarks WASI-compatible

Reviewing: Not all file movements and renames are tracked properly by Github's diff view. The important folder is rne which contain the new Montgomery multiplication implementation. I've tried to stay true to the structure of the one in rtz.

@xrvdg xrvdg marked this pull request as draft January 23, 2026 06:29
@xrvdg xrvdg marked this pull request as ready for review January 26, 2026 08:28
@xrvdg xrvdg requested a review from Bisht13 January 28, 2026 11:56
@xrvdg xrvdg changed the title 51 bits RNE bn254 multiplier batched bn254 51 bits RNE multiplier Feb 3, 2026
@Bisht13 Bisht13 requested a review from ocdbytes February 4, 2026 08:56
Copy link
Copy Markdown
Collaborator

@ocdbytes ocdbytes left a comment

Choose a reason for hiding this comment

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

LGTM !
some nit picks and some personal doubts I had while reviewing.

Suggestion (Not necessary) : Also we can add edge case tests for 0 values, identity values etc. which may not come in proptest for simd_mul and simd_sqr.

Comment thread skyscraper/bn254-multiplier/src/rtz/constants.rs Outdated
};

/// Two parallel Montgomery squarings: `(v0², v1²)`.
/// input must fit in 2^255-1; no runtime checking
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Doubt : why are we not checking the limits of the inputs here ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The main reason is that these are internal functions to a kernel that runs a hot loop. The kernel needs to be designed in a way that the precondition holds because checking in a hot loop is costly. This note is there as a reminder to let the kernel have this invariant.

I did add a debug assert to u256_to_u255 to check if the invariant is actually being uphold when running in debug mode.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

cool works. Thanks for clarifying

Comment thread skyscraper/bn254-multiplier/src/rtz/portable_simd.rs
Comment thread skyscraper/bn254-multiplier/src/rne/portable_simd.rs Outdated
@ocdbytes ocdbytes self-requested a review February 4, 2026 16:43
@xrvdg
Copy link
Copy Markdown
Collaborator Author

xrvdg commented Feb 5, 2026

Suggestion (Not necessary) : Also we can add edge case tests for 0 values, identity values etc. which may not come in proptest for simd_mul and simd_sqr.

I try to not have overlap in tests. They are mathematically special but they are not edge cases. I would have used those if we didn't have a reference to test against.

Copy link
Copy Markdown
Collaborator

@ocdbytes ocdbytes left a comment

Choose a reason for hiding this comment

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

LGTM !!

Comment thread skyscraper/bn254-multiplier/src/rne/simd_utils.rs Outdated
Comment thread .github/workflows/benchmark.yml
Comment thread skyscraper/bn254-multiplier/src/rne/portable_simd.rs
}

#[test]
fn test_simd_sqr() {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nit: test_simd_sqr validates against simd_mul(a, a, b, b) but not independently against ark_ff_reference. Since test_simd_mul already validates mul against ark_ff, the chain sqr → mul → ark_ff provides transitive coverage. But the sqr-specific code path (cross-terms doubled + diagonal terms added separately) differs from mul's schoolbook, so a direct ark_ff_reference(a, a) check would add confidence for free:

let a2_ref = ark_ff_reference(a, a);
prop_assert_eq!(Fr::new(BigInt(a2s)), a2_ref);

Copy link
Copy Markdown
Collaborator Author

@xrvdg xrvdg Feb 6, 2026

Choose a reason for hiding this comment

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

simd_sqr can be bitwise compared against simd_mul without a transformation (happens within ark_ff_reference and Fr::new). This makes sqr-specific code path easier to debug. Property-based tests with transitivity gives us adequate coverage.

@Bisht13 Bisht13 merged commit e2c5ea3 into main Feb 6, 2026
4 of 5 checks passed
@Bisht13 Bisht13 deleted the xr/fmul branch February 6, 2026 11:15
dcbuild3r pushed a commit that referenced this pull request May 16, 2026
batched bn254 51 bits RNE multiplier
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.

3 participants