Skip to content

refactor(stark): the grinding factor is not "security_bits" - #979

Merged
MauroToscano merged 1 commit into
mainfrom
fix/grinding-is-not-security
Sep 10, 2026
Merged

refactor(stark): the grinding factor is not "security_bits"#979
MauroToscano merged 1 commit into
mainfrom
fix/grinding-is-not-security

Conversation

@MauroToscano

Copy link
Copy Markdown
Contributor

Renames three local bindings that called the grinding factor security_bits. Follow-up to
#976, deliberately kept out of it so that PR stayed one idea.

+8 / −8 over 2 files, one signed commit. Base main.

What was wrong

prover.rs:2286    let security_bits = air.context().proof_options.grinding_factor;
verifier.rs:1582  let security_bits = air.context().proof_options.grinding_factor;
verifier.rs:1665  let security_bits = air.context().proof_options.grinding_factor;

Grinding is not the security level. It is one term in the FRI query round's error, and it
cannot move the commit-phase term (eps_C) at all — so a reader who takes these bindings
at their word concludes the proof carries 20 bits of security, or that raising the grinding
factor raises security generally. Neither follows.

#976 removed the same confusion where it did real damage: security_bits there was a query
budget that had never modelled eps_C, described in docs as the security the system
delivers. This PR is the cheap half of that fix — the naming, in the two files #976 did
not touch. It is not load-bearing on #976 and can merge in either order; it just reads
oddly to fix the doc claim and leave the variable.

The change

grinding_factor, which is what every function behind these call sites already names the
argument — grinding::is_valid_nonce, generate_nonce, generate_nonce_maybe_gpu, all of
which declare grinding_factor: u8. So the callers were passing security_bits into
grinding_factor; the rename removes a mismatch rather than introducing a convention.

✓ Nothing is shadowed: grinding_factor appeared in these two files only as the struct
field being read, never as a local.

✓ No message or doc needed correcting alongside the names. The one operator-facing string
in the area already says the right thing — error!("Grinding factor not satisfied") at
verifier.rs:1672 — and grinding.rs never uses the word "security" at all. A rename that
left a message lying would be half a fix; there was no such message.

Bit-inert

Eight identifier occurrences. No ProofOptions field moves — none is even written here,
only read — and no expression changes, so every proof this produces or accepts is
byte-identical. The change cannot be observed except by reading the source.

The differential that would prove it, if asked: run cargo test --release -p stark --lib and -p lambda-vm-prover --lib at main and at this head and require the result
lines, failure names included, to be identical. It is not proposed as necessary — an
8-line identifier rename with no expression change is verifiable by reading the diff, which
is 8 lines — but it is the same instrument #976 used and it is available.

Evidence

Laptop, at this head:

cargo test -p stark --lib     223 passed; 0 failed; 0 ignored
cargo fmt --all               no changes
make lint                     exit 0   (whole workspace, every feature pass)

223 was pre-registered before the run, derived as #976's 224 minus the one test that branch
adds and this one does not.

Three local bindings read `proof_options.grinding_factor` and named it
`security_bits`, then passed it to functions whose own parameter is
`grinding_factor`:

    prover.rs:2286    let security_bits = air.context().proof_options.grinding_factor;
    verifier.rs:1582  let security_bits = air.context().proof_options.grinding_factor;
    verifier.rs:1665  let security_bits = air.context().proof_options.grinding_factor;

Grinding is not the security level. It is one term in the query round's error,
and it cannot move the commit-phase term at all — so a reader who takes these
bindings at their word concludes the proof carries 20 bits of security, or that
raising the grinding factor raises security generally. Neither follows.

`grinding_factor` is what every function behind these call sites already calls
the argument (`grinding::is_valid_nonce`, `generate_nonce`,
`generate_nonce_maybe_gpu`), so the rename removes a mismatch rather than
introducing a new convention. Nothing is shadowed: the name appeared in these
two files only as the struct field being read.

Eight identifier occurrences, no behaviour, no field moved. The one operator-
facing message in the area already says the right thing — `error!("Grinding
factor not satisfied")` — so no text needed correcting alongside the names.
@MauroToscano
MauroToscano added this pull request to the merge queue Sep 10, 2026
Merged via the queue into main with commit 88a54cf Sep 10, 2026
15 checks passed
@MauroToscano
MauroToscano deleted the fix/grinding-is-not-security branch September 10, 2026 18:12
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.

2 participants