Skip to content

fix: GLV subscalar range checks#1778

Merged
ivokub merged 31 commits into
masterfrom
fix/glv-subscalars
Jun 12, 2026
Merged

fix: GLV subscalar range checks#1778
ivokub merged 31 commits into
masterfrom
fix/glv-subscalars

Conversation

@ivokub

@ivokub ivokub commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Description

Fixes #1767

Also implements in generic hint calling in field emulation to define the range check amounts. I think this is also independently relevant elsewhere where we expect smaller outputs from the hint.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

How has this been tested?

Existing tests for scalarmul pass

Added tests for the reduced rangecheck edge cases in field emulation.

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
  • Any dependent changes have been merged and published in downstream modules

Note

Medium Risk
Changes in-circuit soundness assumptions for GLV/fake-GLV hints—incorrect bit bounds could admit malicious decompositions—though bounds match documented lattice limits and are covered by new tests.

Overview
Adds WithHintOutputRangeCheckBits to emulated generic hints so hint outputs can be range-checked and packed at a custom bit width (via packLimbsWithWidth / refactored enforceWidth), instead of always using full modulus-width checks.

GLV / fake-GLV scalar multiplication (emulated sw_emulated, native G2 on BLS12-381/BN254/BW6-761, Grumpkin) now passes LLL/Hermite-sized bounds on decomposed sub-scalars (u1,u2,v1,v2, s1,s2, etc.) when calling NewHintGeneric, aligning constraints with proven decomposition sizes and reducing scalar-mul cost (reflected in latest_stats.csv).

Removes unused decomposeScalarG1 / decomposeScalarG2 hint registrations where decomposition moved to shared emulated paths; Grumpkin’s callDecomposeScalar drops the simple flag and uses the generic hint API with 127-bit output checks.

New field_hint_test coverage exercises custom range-check indexing, multi-limb widths, and validation errors.

Reviewed by Cursor Bugbot for commit 852a650. Bugbot is set up for automated code reviews on this repo. Configure here.

@ivokub ivokub requested review from Copilot and yelhousni June 9, 2026 00:04
@ivokub ivokub self-assigned this Jun 9, 2026
@ivokub ivokub added the type: bug Something isn't working label Jun 9, 2026
@ivokub ivokub requested a review from YaoJGalteland June 9, 2026 00:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses soundness in GLV/FakeGLV scalar multiplication by ensuring sub-scalar (hint output) widths are range-checked to the mathematically expected bit bounds, and it extends emulated generic hint plumbing to support caller-specified per-output bit range checks.

Changes:

  • Add WithHintOutputRangeCheckBits to generic emulated hint calls and use it to enforce tighter (caller-defined) bit bounds on hint outputs.
  • Refactor limb packing / width enforcement to support packing elements at a specified bit width (packLimbsWithWidth, enforceWidth(nbBits)).
  • Update multiple curve scalar-mul paths (native + emulated) to pass tight sub-scalar bounds into hints; add tests for the new range-check behavior and update benchmark stats.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
std/math/emulated/field.go Refactors limb packing to support explicit bit-width packing and range checks.
std/math/emulated/field_assert.go Refactors width enforcement to take an explicit bit width (nbBits).
std/math/emulated/field_hint.go Adds generic-hint options, including per-output range-check bit configuration and output unpacking changes.
std/math/emulated/field_hint_test.go Adds tests covering custom hint-output range checks and option validation.
std/algebra/native/twistededwards/hints.go Removes duplicate / unused hint registration for scalar decomposition.
std/algebra/native/sw_grumpkin/hints.go Switches Grumpkin GLV decomposition to generic hint + tight output bit checks.
std/algebra/native/sw_grumpkin/wrapper.go Updates call sites for the Grumpkin scalar decomposition helper signature.
std/algebra/native/sw_grumpkin/g1.go Updates GLV scalar-mul call sites to the new decomposition helper signature.
std/algebra/native/sw_bls12377/hints.go Removes duplicate decompose-scalar hints from hint registration.
std/algebra/emulated/sw_emulated/point.go Applies tight hint-output bounds for emulated GLV/FakeGLV decompositions (soundness-related).
std/algebra/emulated/sw_bw6761/hints.go Removes duplicate emulated G1 decomposition hint.
std/algebra/emulated/sw_bw6761/g2.go Applies tight hint-output bounds for 4-way decomposition outputs.
std/algebra/emulated/sw_bn254/g2.go Applies tight hint-output bounds for 4-way decomposition outputs.
std/algebra/emulated/sw_bls12381/hints.go Removes duplicate emulated G1 decomposition hint.
std/algebra/emulated/sw_bls12381/g2.go Applies tight hint-output bounds for 4-way decomposition outputs.
internal/stats/latest_stats.csv Updates latest constraint-count stats after the optimization/tightening.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread std/math/emulated/field.go Outdated
Comment thread std/math/emulated/field_assert.go Outdated
Comment thread std/math/emulated/field_hint_test.go Outdated
Comment thread std/math/emulated/field_hint.go
@ivokub ivokub changed the title Fix/glv subscalars fix: GLV subscalar range checks Jun 9, 2026
@ivokub ivokub requested a review from Copilot June 9, 2026 11:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.

Comment thread std/math/emulated/field_hint.go
Comment thread std/math/emulated/field_hint.go
Comment thread std/math/emulated/field_hint.go
Comment thread std/math/emulated/field_hint_test.go Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Comment thread std/math/emulated/field_hint.go
Comment thread std/math/emulated/field.go

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4728f06. Configure here.

Comment thread std/algebra/native/sw_grumpkin/hints.go
yelhousni
yelhousni previously approved these changes Jun 11, 2026

@yelhousni yelhousni left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM. The bound tightening is mathematically sound — (BitLen+3)/4 + 2 covers γ₄·r^(1/4) and (BitLen+1)/2 covers γ₂·√r with comfortable slack. The WithHintOutputRangeCheckBits API is a clean generalization and the enforceWidth refactor preserves existing semantics. Test coverage (multi-limb, zero-bits, bad indices) is good.

Comment thread std/math/emulated/field_hint.go Outdated
Comment thread std/algebra/emulated/sw_emulated/point.go Outdated
@ivokub ivokub merged commit a3ad59a into master Jun 12, 2026
9 of 10 checks passed
@ivokub ivokub deleted the fix/glv-subscalars branch June 12, 2026 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: bound the subscalar widths in GLV methods

3 participants