Authors: The Scroll Security Council
Overview
On May 26, the Scroll Security Council performed an emergency upgrade to the Scroll mainnet to address a bug discovered in one of the dependencies of the OpenVM prover.
Scroll worked with the Plonky3 and Axiom teams, as well as the Scroll Security Council, to promptly review and fix the bug, and deploy the patch in this emergency upgrade.
Summary of the Vulnerability
The Plonky3 team found two bugs in the FRI verifier. Axiom reviewed the bug and found that the fix would result in the vkey change. That meant that the fix required upgrading the Scroll on-chain verifier contract.
Here is the overview of the missing randomness in mixed domain handling in FRI folding:
The folding needs to add beta^2
(since beta
is already used in the folding) to roll in new terms from reduced opening. So in function verify_query
, the betas_squared
of length log_max_height
will be passed in and used for random linear combination.
Below are the native verifier changes and recursion verifier changes.
Native verifier change (in Plonky3)
if let Some(v) = inputs_iter.next_if(|v| v.len() == folded.len()) {
- izip!(&mut folded, v).for_each(|(c, x)| *c += x);
+ // Each element of `inputs_iter` is a reduced opening polynomial, which is itself a
+ // random linear combination `f_{i, 0} + alpha f_{i, 1} + ...`, but when we add it
+ // to the current folded polynomial, we need to multiply by a new random factor since
+ // `f_{i, 0}` has no leading coefficient.
+ izip!(&mut folded, v).for_each(|(c, x)| *c += beta.square() * x);
}
Recursion verifier change (in OpenVM)
// Generate the beta squares
+ builder.iter_ptr_set(&betas_squared, beta_sq_ptr, sample * sample);
...
// Later in `verify_query`, use the randomness to folding polys
+ builder.assign(&folded_eval, folded_eval + beta_sq * reduced_opening);
num_queries
has also been updated accounting for poles. See the diff of stark-backend
listed below.
Release and code diffs:
plonky3
: Missing final polynomial degree check in FRI verifier · Advisory · Plonky3/Plonky3 · GitHub (patch)stark-backend
: Release v1.1.0 · openvm-org/stark-backend · GitHub (code diff)openvm
: Release v1.2.0 · openvm-org/openvm · GitHub (code diff)
Timeline
- 3 May: Received circuit vulnerability notice from the Plonky3 team.
- 3-20 May: Scroll dev team developed and tested the patched OpenVM circuits on a private shadowfork network.
- 23-24 May: The Scroll Security Council verified the fix independently and signed the emergency verifier update.
- 26 May: Scroll executed the on-chain verifier update in this transaction. Pending blocks were re-proven and finalized shortly after this.
Retrospective
This bug could not be meaningfully exploited on Scroll because the sequencer and provers are not permissionless. As we move toward decentralizing these components, we plan to implement additional safeguards, such as multi-proof system, to mitigate the risk of circuit and prover vulnerabilities.
Acknowledgement
We thank the Plonky3 and Axiom teams for the finding and disclosure of the bug and their prompt fix.