-
Notifications
You must be signed in to change notification settings - Fork 583
fix: ultra num public inputs derivation #19950
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| // ECCVM proof | ||
| start_idx = end_idx; | ||
| end_idx += static_cast<std::ptrdiff_t>(ECCVMFlavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS); | ||
| end_idx += static_cast<std::ptrdiff_t>(ECCVMFlavor::PROOF_LENGTH); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was somewhat misleading to call those w/o pub inputs in VMs
| // Populate mock witness accumulator commitments | ||
| populate_field_elements_for_mock_commitments(proof, Flavor::NUM_WITNESS_ENTITIES / 2); | ||
| // Populate mock accumulator commitments (non_shifted + shifted) | ||
| populate_field_elements_for_mock_commitments(proof, Flavor::NUM_ACCUMULATOR_COMMITMENTS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Realized that MLB Flavor is quite confusing due to copy-pasted structures. Simplified those as a byproducr
|
|
||
| TYPED_TEST_SUITE(MockVerifierInputsTest, FlavorTypes); | ||
| // Static assertions for proof length constants | ||
| static_assert(MERGE_PROOF_SIZE == 42, "Merge proof size changed"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be faster to modify now
| DEFINE_FLAVOR_MEMBERS(DataType, | ||
| batched_unshifted_accumulator, // column 0: batched unshifted poly for accumulator | ||
| batched_unshifted_instance, // column 1: batched unshifted poly for instance | ||
| eq_accumulator, // column 2: eq(u, r_acc) - selects accumulator eval point |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class was essentially unused, + eq's are not witnesses.
| @@ -0,0 +1,181 @@ | |||
| // === AUDIT STATUS === | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, my goal was to always derive num_public_inputs from the proof size. But the methods used to compute the "fixed" sizes were flavor-linked. Instead I wanted to have something context-dependent like HypernovaInstanceToAccum length that still re-uses lots from Honk proof building blocks. As a result, we have all honk/chonk proof length computations in one place + it's easy to deduce num_public inputs
| verifier_instance->vk_and_hash->hash.assert_equal(vk_hash); | ||
|
|
||
| // Assert that the provided num_public_inputs matches VK's value (in-circuit constraint) | ||
| vk->num_public_inputs.assert_equal(FF(num_public_inputs), "OinkVerifier: num_public_inputs mismatch with VK"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note that previously we would use .get_value(). though substituting the real witness value with something else would have created a different circuit, feels more robust when such discrepancy immediately leads to a failed constraint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, so the idea is that leads to a better error in the circuit failure case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was concerned about vk->num_public_inputs.get_value() in general, as then we would need to analyze whether a malicious actor can ignore this value + the binding of the vk field with the proof was very implicit, namely through the loop for receiving the public inputs that uses the underlying native value, changing which would be enough to change this circuit's VK and cause a verification failure against a correctly computed VK, but now it's obvious that this loop uses the same value that's in the vk
| */ | ||
| template <typename Flavor, class IO> | ||
| typename UltraVerifier_<Flavor, IO>::PaddingData UltraVerifier_<Flavor, IO>::process_padding() const | ||
| template <typename Flavor, class IO> size_t UltraVerifier_<Flavor, IO>::compute_log_n() const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had to split process_padding method, cause integer log_n is needed before oink, and padding indicator array can only be computed after oink -- vk member log_circuit_size gets hashed and untagged as a free witness
…i/pub-inputs-clean-up
ledwards2225
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - thanks for the improvements
Flakey Tests🤖 says: This CI run detected 4 tests that failed, but were tolerated due to a .test_patterns.yml entry. |
Don't use get_value() on vk member, derive from proof size, make sure it matches the value from the vk
Added new
bb::ProofLengthgadget responsible for all Chonk and Honk proof/public inputs lengths computations