Incorrect assert in native get_pairs
Description
In the get_pairs function in circuits/src/batch_verify/universal/native.rs, there is the following assert:
assert!(
entry.inputs.0.len()
<= max_num_public_inputs + entry.has_commitment() as usize,
"Too many public inputs"
);Usually max_num_public_inputs is used for all public inputs, including the possible hash of the commitment (it is the L of the specification). For example, in circuits/src/batch_verify/universal/types.rs, the function UniversalBatchVerifierInput::assert_consistent has the following check:
assert!(
self.inputs.0.len() + num_commitments
<= config.max_num_public_inputs as usize,
"Public input length exceeds maximum allowed"
);Note that this check is for a UniversalBatchVerifierInput, which does not have the hash of the commitment appended yet. In get_pairs, the hash of the commitment has already been appended using update_batch when the check is done, so it should be as follows instead:
assert!(
entry.inputs.0.len()
<= max_num_public_inputs,
"Too many public inputs"
);Impact
The assert checks an inequality that is weaker than the inequality that should hold according to the specification.
Recommendations
We recommend to make the following change:
assert!(
entry.inputs.0.len()
- <= max_num_public_inputs + entry.has_commitment() as usize,
+ <= max_num_public_inputs,
"Too many public inputs"
);Remediation
This issue has been acknowledged by Nebra, and a fix was implemented in commit 3af8a51e↗.