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↗.