Skip to content
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

GKR backend for LogUp-GKR #296

Merged
merged 47 commits into from
Aug 30, 2024

Conversation

Al-Kindi-0
Copy link
Contributor

Builds on #295 and implements the GKR backend for the LogUp-GKR argument.

Copy link
Contributor

@plafer plafer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a full review yet

air/src/air/mod.rs Outdated Show resolved Hide resolved
air/src/air/context.rs Outdated Show resolved Hide resolved
air/src/air/logup_gkr.rs Outdated Show resolved Hide resolved
air/src/air/logup_gkr.rs Outdated Show resolved Hide resolved
air/src/air/logup_gkr.rs Outdated Show resolved Hide resolved
pub lagrange_kernel_eval_point: LagrangeKernelRandElements<E>,
pub openings_combining_randomness: Vec<E>,
pub openings: Vec<E>,
pub oracles: Vec<LogUpGkrOracle<E::BaseField>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is necessary to store the oracles here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is needed for the s-column, which is done in another PR building on this one

air/src/air/logup_gkr.rs Outdated Show resolved Hide resolved
prover/src/logup_gkr/prover.rs Outdated Show resolved Hide resolved
@irakliyk irakliyk changed the base branch from next to logup-gkr August 21, 2024 06:18
@Al-Kindi-0 Al-Kindi-0 force-pushed the al-gkr-backend-for-logup-gkr branch from ead8aa6 to 7caf36f Compare August 21, 2024 11:16
/// As part of the final sum-check protocol, the openings {f_j(ρ)} are provided as part of a
/// [`FinalOpeningClaim`]. This latter claim will be proven by the STARK prover later on using the
/// auxiliary trace.
pub fn prove_gkr<E: FieldElement>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub fn prove_gkr<E: FieldElement>(
pub fn prove_logup_gkr<E: FieldElement>(

I wonder if we should stick with logup_gkr instead of gkr everywhere. While it's clear to us that "gkr" stands for "gkr over the LogUp circuit", I'm not sure it would be so clear to someone first reading the codebase

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point. On the other hand, some of the structs (e.g., GkrCircuitProof) as well many of the comments fit better with the current name.
No strong preference though

Comment on lines +126 to +128
evaluator.build_query(&main_frame, &[], &mut query);

evaluator.evaluate_query(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't we merge build_query() and evaluate_query() into a single evaluate_fractions(), which internally builds & evaluates the query? I would see it as simplifying the interface by having one less method, as well as removing the risk that get_oracles() and build_query() be inconsistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

build_query is useful for building the input layer and the OOD evaluation. For the first one we can merge the two but for the second one the evaluate_query logic is not needed.
One the other hand, evaluate_query is used without the build_query logic in the high degree sum-check.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I missed that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I can't comment on sum_check_prove_higher_degree() since it wasn't modified in this file, so commenting here instead).

Two equations in the docstring don't render properly (I believe due to a bug in Katex). The workaround is to write \\B instead of \mathbb{B}:

/// $$
/// p_{n-1}\left(v_2, \cdots, v_{\mu}, x_1, \cdots, x_{\nu}\right) =
/// \sum_{y\in\\B_{\nu}} G(y_{1}, ..., y_{\nu})
/// $$
///
/// and
///
/// $$
/// q_{n-1}\left(v_2, \cdots, v_{\mu}, x_1, \cdots, x_{\nu}\right) =
/// \sum_{y\in\\B_{\nu}} H\left(y_1, \cdots, y_{\nu} \right)
/// $$

and update /.cargo/katex-header.html with a new macro:

            macros: {
                "\\B": "\\mathbb{B}",
            },

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thank you!

let mut query = vec![E::BaseField::ZERO; evaluator.get_oracles().len()];
let mut numerators = vec![E::ZERO; num_fractions];
let mut denominators = vec![E::ZERO; num_fractions];
for i in 0..main_trace.main_segment().num_rows() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we'll run into an issue when our oracles are the current row and next row. In this case, at the last row, we don't want to call build_query() on the evaluation frame, since the frame contains current_row: <last row> and next_row: <first row>.

Ultimately we want numerators equal to 0 (and whatever non-zero denominators) to be inserted for that last row, and somehow also encode this information in the GkrOracles. Have you thought about how we could fix this already?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking was that, at the "application" level, the selectors will be designed so as to be zero for such edge cases. Thus I didn't give much thought to a choice we can make with respect to NextRow oracles, namely either we choose a circular shift, as we do now, or we use a plain shift where we will get zero at the last row as a result.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

namely either we choose a circular shift, as we do now, or we use a plain shift where we will get zero at the last row as a result.

Right, we currently do a circular shift. But we actually want a plain shift, and I don't see how this would be possible with the current API. For example, when x represents the last row, how does evaluate_query() know that ultimately it should output 0s for the numerators and 1s for the denominator (since all it gets is the evaluations of the oracles at x)?

I'm currently not seeing it, but if you're confident that it's possible, then we can move on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, the numerators could be an expression involving selectors which are zero once a HALT instruction has been initiated. For this row, and all subsequent rows assuming that a HALT can only be followed by a HALT, the numerators will be zero. The denominators are not important as far as I can see, of course as long as they are not zero, and this is guaranteed with high probability by the LogUp randomness.
I might be missing something extra but we can, as you suggested, fix it in a subsequent targeted PR.

@@ -69,3 +68,57 @@ impl Air for FibAir {
]
}
}

#[derive(Clone, Default)]
pub struct PlainLogUpGkrEval<B: FieldElement> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should export a DummyLogUpGkrEval<BaseField, PublicInputs> can be used when LogUp-GKR is disabled (instead of reimplementing it everytime)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea!
Implemented and exported

Copy link
Contributor

@plafer plafer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

I'm still not sure if the LogUpGkrEvaluator API is flexible enough to properly support the use of the NextRow GkrOracle, but if it isn't we can always fix it in a subsequent PR

Copy link
Collaborator

@irakliyk irakliyk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Looks good! Not a full review yet - but I left some comments/questions inline.

sumcheck/Cargo.toml Outdated Show resolved Hide resolved
air/src/air/aux.rs Show resolved Hide resolved
air/src/air/mod.rs Outdated Show resolved Hide resolved
air/src/air/mod.rs Outdated Show resolved Hide resolved
air/src/air/trace_info.rs Show resolved Hide resolved
air/src/air/context.rs Outdated Show resolved Hide resolved
air/src/air/coefficients.rs Show resolved Hide resolved
air/src/air/coefficients.rs Outdated Show resolved Hide resolved
winterfell/src/lib.rs Outdated Show resolved Hide resolved
verifier/src/lib.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@irakliyk irakliyk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thank you! Still not a full review (though I think I covered 80% of the code by now) - but I left some more comments inline.

air/src/air/mod.rs Outdated Show resolved Hide resolved
air/src/air/logup_gkr.rs Outdated Show resolved Hide resolved
air/src/air/aux.rs Show resolved Hide resolved
air/src/air/aux.rs Outdated Show resolved Hide resolved
air/src/air/trace_info.rs Show resolved Hide resolved
examples/Cargo.toml Outdated Show resolved Hide resolved
verifier/src/lib.rs Outdated Show resolved Hide resolved
verifier/src/lib.rs Outdated Show resolved Hide resolved
prover/src/lib.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@irakliyk irakliyk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thank you! I left some more comments inline. Most of them are pretty minor and we can address them either here or in the subsequent PRs.

air/src/air/mod.rs Outdated Show resolved Hide resolved
air/src/air/mod.rs Outdated Show resolved Hide resolved
air/src/air/logup_gkr.rs Outdated Show resolved Hide resolved
/// Returns the GKR proof, if any.
pub fn read_gkr_proof(&self) -> Result<GkrCircuitProof<E>, VerifierError> {
GkrCircuitProof::read_from_bytes(
self.gkr_proof.as_ref().expect("Expected a GKR proof but there was none"),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this should also be an error rather than expect(). With expect(), I think a maliciously crafted proof could crush the verifier, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the deserialization fails then this should return an error but probably you are thinking about something else

verifier/src/lib.rs Outdated Show resolved Hide resolved
prover/src/lib.rs Outdated Show resolved Hide resolved
@irakliyk irakliyk merged commit aef404d into facebook:logup-gkr Aug 30, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants