Skip to content

jolt-openings crate API cutover#1521

Open
quangvdao wants to merge 4 commits into
a16z:mainfrom
quangvdao:quang/jolt-openings-crate
Open

jolt-openings crate API cutover#1521
quangvdao wants to merge 4 commits into
a16z:mainfrom
quangvdao:quang/jolt-openings-crate

Conversation

@quangvdao
Copy link
Copy Markdown
Contributor

@quangvdao quangvdao commented May 12, 2026

Summary

This PR now scopes the cutover to the extracted PCS crates only. The earlier jolt-core integration experiment was useful for finding the right abstraction boundary, but the merge target leaves legacy jolt-core untouched so it can remain the end-to-end reference implementation.

The intended consumer for this API is the upcoming Bolt-generated prover/verifier split, such as #1514. Generated role crates should be able to use jolt-openings / jolt-dory directly without going through the old in-core PCS trait family.

What Changed

  • Defines the verifier/prover PCS trait split in crates/jolt-openings.
  • Adds backend-neutral commitment and opening source abstractions, including natural_chunk_len and separate linear-combination opening support.
  • Moves ordinary homomorphic batch helpers into jolt-openings.
  • Implements the extracted trait family for jolt-dory, preserving source-backed streaming behavior and ZK openings.
  • Keeps DoryScheme::BatchProof = Vec<DoryProof>, with one proof per opening-point group.
  • Keeps jolt-hyperkzg aligned with the same base trait family.
  • Rewrites the spec around the crate-level API and future generated-role integration path.
  • Removes the previous jolt-core, SDK, example, transpiler, CLI, book, and extractor diff surface from the PR.

Validation

  • cargo fmt -q --check
  • cargo check -p jolt-openings -q --features test-utils
  • cargo check -p jolt-dory -q
  • cargo check -p jolt-hyperkzg -q
  • cargo nextest run -p jolt-openings --cargo-quiet --features test-utils
  • cargo nextest run -p jolt-dory --cargo-quiet
  • cargo nextest run -p jolt-hyperkzg --cargo-quiet
  • cargo clippy -p jolt-openings -q --features test-utils --all-targets -- -D warnings
  • cargo clippy -p jolt-dory -q --all-targets -- -D warnings
  • cargo clippy -p jolt-hyperkzg -q --all-targets -- -D warnings

Posted by Cursor assistant (model: GPT-5.5) on behalf of the user (Quang Dao) with approval.

@github-actions github-actions Bot added the spec Tracking issue for a feature spec label May 12, 2026
@quangvdao quangvdao changed the title Spec: jolt-openings PCS API cutover jolt-openings PCS API cutover May 12, 2026
@moodlezoup moodlezoup added the claude-spec-review-request Triggers Claude spec analysis label May 12, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Claude spec review session started: https://claude.ai/code/session_016zYwqpvB8AFnhWrGjedjok

Copy link
Copy Markdown
Collaborator

Spec Analysis: jolt-openings PCS API Cutover

Dimension Score Gap
Goal 0.90 Clear — one-sentence goal stated in Intent; trait hierarchy and dependency direction fully spelled out in Design.
Constraints 0.85 Clear — 15 explicit invariants, 10 non-goals, dependency-tree checks.
Success Criteria 0.85 Clear — ~25 checkbox acceptance criteria with exact cargo invocations; testing strategy split across jolt-openings, jolt-dory, and jolt-core.
Context 0.90 Clear — names #1467 + branch layerzero/quang/pcs-prover-verifier-split as transplant source, references concrete files in current main (Stage 8, BlindFold, Dory layout).
Ambiguity ≈ 12.5%

Status: Approved — The spec is clear enough for one-shot implementation.

Verification against the current tree:

  • crates/jolt-openings/src/schemes.rs today defines CommitmentScheme, AdditivelyHomomorphic, ZkOpeningScheme, StreamingCommitment, but has no CommitmentSchemeVerifier and keeps open/verify on the base trait — matching the spec's premise.
  • crates/jolt-openings/src/reduction.rs exposes the reduce_prover / reduce_verifier API the spec proposes to remove or demote.
  • crates/jolt-dory/src/scheme.rs already implements the existing jolt-openings trait family, but jolt-core does not depend on jolt-openings/jolt-dory and still imports jolt-core/src/poly/commitment/commitment_scheme.rs (associated types: Commitment, Proof, BatchedProof, OpeningProofHint, plus ZkEvalCommitment and StreamingCommitmentScheme companions).
  • JoltProof.joint_opening_proof is PCS::Proof today (jolt-core/src/zkvm/proof_serialization.rs); the spec's swap to PCS::BatchProof is well-defined.
  • DoryOpeningState::build_streaming_rlc lives in jolt-core/src/poly/opening_proof.rs; Stage 8's BlindFold path (OpeningProofData, y_com, y_blinding) lives in jolt-core/src/subprotocols/blindfold/mod.rs and jolt-core/src/poly/commitment/dory/commitment_scheme.rs. The spec preserves each explicitly.

Summary of what will be built:

  • New verifier-first trait hierarchy in crates/jolt-openings/src/schemes.rs: CommitmentSchemeVerifierCommitmentScheme; AdditivelyHomomorphicVerifierAdditivelyHomomorphic; ZkOpeningSchemeVerifierZkOpeningScheme; StreamingCommitment unchanged.
  • open/verify removed from the base PCS trait, retained only on homomorphic extension traits.
  • Fused prove_batch / verify_batch on the base traits; homomorphic_prove_batch / homomorphic_verify_batch in homomorphic.rs provide the default group-by-point RLC implementation; reduce_prover / reduce_verifier removed or demoted.
  • crates/jolt-dory re-implements the split trait family, preserving current Dory hardening, ZK y_com/y_blinding behavior, transcript bridge, streaming commitment, and bounded proof deserialization.
  • jolt-core adds jolt-openings + jolt-dory deps, swaps PCS::CommitmentPCS::Output, joint_opening_proof: PCS::ProofPCS::BatchProof, and routes Stage 8 through prove_batch / verify_batch (one-group batch wrapping the current streaming RLC).

Key invariants to preserve (all named in the spec):

  • jolt-openings stays leaf-crate-only (no jolt-core, jolt-dory, dory, arkworks, common, tracer, jolt-sdk, Akita, Hachi).
  • Fiat–Shamir byte-identity between prover and verifier in the homomorphic batch helper (claim count, evaluations, per-point rho schedule).
  • Stage 8 keeps current dense increment scaling, RA ordering, advice Lagrange scaling, opening_ids, constraint_coeffs, and joint_claim semantics.
  • ZK mode still extracts and binds the Dory evaluation commitment for BlindFold.

Critical evaluation criteria:

  • cargo nextest run -p jolt-core muldiv passes with both --features host and --features host,zk.
  • cargo nextest run -p jolt-openings --features test-utils and cargo nextest run -p jolt-dory pass.
  • cargo clippy --all --features host -- -D warnings and the matching host,zk invocation pass with zero warnings.
  • cargo tree -d shows no duplicate Jolt leaf crates; cargo tree -p jolt-openings shows no edge into jolt-core/jolt-dory/dory/tracer/Akita.

Minor soft spots (not blocking):

  • Performance is stated qualitatively ("should not regress", "no obvious runtime blowups"). For a mechanical refactor that explicitly preserves the existing streaming-RLC hot path, this is acceptable — muldiv timing in CI is the implicit guardrail.
  • "Claims<F> … should remain unless a strictly mechanical replacement falls out" and "dory_layout should remain in this PR unless a small PCS config type already exists" are intentionally hedged. Both have a clear default (keep) and a bounded escape hatch — fine for a one-shot.

Next step: Run /implement-spec to implement this spec:


Generated by Claude Code

@moodlezoup moodlezoup added claude-spec-approved Claude spec analysis found no ambiguities and removed claude-spec-review-request Triggers Claude spec analysis labels May 12, 2026 — with Claude
Copy link
Copy Markdown
Collaborator

@moodlezoup moodlezoup left a comment

Choose a reason for hiding this comment

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

this looks good to me, just a couple of minor comments.
Also, while you're refactoring the PCS traits, perhaps you could also take a look at the relationship between the streaming and ZK traits? There's an awkward interaction there for Dory which I flagged here

Comment thread specs/jolt-openings-crate.md Outdated
2. `jolt-openings` depends only on reusable leaf crates plus generic dependencies: `jolt-field`, `jolt-poly`, `jolt-transcript`, `jolt-crypto`, `serde`, `thiserror`, and `tracing`.
3. The base verifier trait does not expose prover-only associated types such as `ProverSetup`, `Polynomial`, `OpeningHint`, or `SetupParams`.
4. The base PCS traits expose fused batched openings through `prove_batch` and `verify_batch`.
5. Single-claim `open` and `verify` are not on the base PCS trait.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why? seems like they would make more sense on the base triat

Comment thread specs/jolt-openings-crate.md Outdated
1. `Field = Fr`.
2. `VerifierSetup = DoryVerifierSetup`.
3. `Proof = DoryProof`.
4. `BatchProof = Vec<DoryProof>`.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

the relationship between BatchProof and the AdditivelyHomomorphic traits is a little unclear –– below it says that prove_batch and verify_batch delegate to their homomorphic counterparts, but then shouldn't BatchProof = DoryProof?

@quangvdao
Copy link
Copy Markdown
Contributor Author

@moodlezoup thanks for the comments! I updated the spec to reflect the resolution, and the spec now has a redesign of the CommitmentScheme trait that bakes in streaming via a generic "polynomial source" rather than having a separate trait. Below is GPT-5.5's response after discussion:

__

First, agreed on single-claim openings: open / verify now live on the base PCS traits. The homomorphic traits are only responsible for the extra linear-combination operations (combine, combine_hints) needed by batch/RLC helpers. That makes the base trait a complete single-opening PCS interface, which is the cleaner split.

Second, the Dory batch-proof shape is now spelled out more explicitly. For Dory, BatchProof = Vec<DoryProof>, where each DoryProof corresponds to one opening-point group after the homomorphic helper RLC-combines that group’s claims. In the first Stage 8 cutover, Jolt currently forms one joint group, so this is a one-element Vec<DoryProof>. That should explain why prove_batch / verify_batch can delegate to the homomorphic helpers while still keeping the batch proof as a vector.

On the streaming/ZK interaction: I think the right fix is to remove StreamingCommitment as a public commitment-scheme abstraction rather than trying to make finish branch on ZK-ness. The new direction is source-oriented:

  • CommitmentSource describes where polynomial data comes from.
  • CommitmentSourceBatch describes a batch of such sources.
  • commit_batch and commit_batch_zk are the PCS-level entry points.
  • Dory overrides those methods to preserve the existing CycleMajor streaming behavior exactly: same padded trace scan, same row order, same one-hot row handling, same row-commitment hint structure, and no materialization of all witness polynomials.

So the ZK distinction moves to the PCS method boundary (commit_batch vs commit_batch_zk) rather than being hidden inside a streaming commitment object.

One subtlety: Stage 8 has a different “streaming” path from witness commitment streaming. Stage 8 currently builds a joint RLC polynomial directly from the trace/hints before opening, and we should preserve that optimized construction for this PR. The new API still applies there: Stage 8 should feed the resulting joint polynomial/claim through prove_batch / verify_batch. In other words, the public API changes, but we do not need to deeply redesign the Stage 8 opening accumulator or BlindFold constraint wiring as part of this cutover.

Net-net: I think this addresses the awkward Dory ZK/streaming interaction you flagged by making streaming a property of sources and batch commitment, not a separate commitment scheme trait.

@moodlezoup
Copy link
Copy Markdown
Collaborator

On the streaming/ZK interaction: I think the right fix is to remove StreamingCommitment as a public commitment-scheme abstraction rather than trying to make finish branch on ZK-ness. The new direction is source-oriented:

  • CommitmentSource describes where polynomial data comes from.
  • CommitmentSourceBatch describes a batch of such sources.
  • commit_batch and commit_batch_zk are the PCS-level entry points.
  • Dory overrides those methods to preserve the existing CycleMajor streaming behavior exactly: same padded trace scan, same row order, same one-hot row handling, same row-commitment hint structure, and no materialization of all witness polynomials.

I guess I'm not convinced that streaming can be fully quarantined to the source implementation. It seems to me like streaming tends to have implications on the commitment algorithm itself, e.g. how we parallelize

@quangvdao
Copy link
Copy Markdown
Contributor Author

@moodlezoup yeah, I agree with this. I overstated it by saying streaming lives in the source implementation.

The distinction I want is closer to the compute/backend split in the Bolt work on refactor/crates: protocol-level code should be oblivious to the streaming/parallelization strategy, but the backend absolutely still owns that strategy.

So the intended split is:

  • CommitmentSource / BatchCommitmentSource describe the data and traversal shape: what sources exist, how to evaluate them, and how to expose row-shaped access without materializing all witness polynomials.
  • PCS::commit_batch / commit_batch_zk are the backend execution boundary.
  • Dory overrides those methods precisely because streaming affects the commitment algorithm: row MSMs, one-hot grouping, row/source/aggregation parallelism, hint construction, and transparent-vs-ZK finishing.

So no, streaming is not fully quarantined inside the source. The source gives the PCS enough structure to avoid materialization; the PCS/backend decides how to consume that structure.

This also seems compatible with the Bolt direction. Bolt has compute-level obligations like compute.oracle_dense_trace, compute.oracle_one_hot_chunk, compute.oracle_family_append, and compute.pcs_commit_batch. Those describe oracle data/families and batch commitment obligations, while the eventual backend/provider decides whether to materialize, stream, use sparse one-hot paths, or target a different execution backend.

I updated the spec to call this out explicitly. The goal is that this PR gives Bolt a Rust PCS boundary it can lower into, without baking Dory’s current row-major streaming schedule into jolt-openings.

Posted by Cursor assistant (model: GPT-5) on behalf of the user (Quang Dao) with approval.

@github-actions github-actions Bot added the implementation PR contains implementation of a spec label May 12, 2026
@quangvdao quangvdao changed the title jolt-openings PCS API cutover jolt-openings PCS type-family cutover May 14, 2026
@moodlezoup moodlezoup added the claude-review-request Request a review from Claude Code label May 14, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Claude code review session started: https://claude.ai/code/session_01QPkTEyadrKJEohTo3cymWD

Copy link
Copy Markdown
Collaborator

@moodlezoup moodlezoup left a comment

Choose a reason for hiding this comment

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

Reviewed the jolt-openings cutover. The Stage 8 prover/verifier symmetry holds, transcript binding order is preserved, and the ZK/standard mode split looks consistent end-to-end. Most flags below are footguns introduced by the new trait surface (silent defaults and duplicated helpers) that will bite a future PCS backend or a future SourceRow variant rather than the current Dory-only path.


Generated by Claude Code

Comment thread crates/jolt-openings/src/schemes.rs Outdated
Comment on lines 214 to 219
@@ -78,23 +219,8 @@ where
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Silent default that returns OpeningHint::default() will silently produce wrong opening proofs for any backend that implements AdditivelyHomomorphic but forgets to override combine_hints. homomorphic_prove_batch (homomorphic.rs:80) consumes the result without checks, and the verifier just sees a bad proof. Verifier-side combine has no default (good); making this required matches.

Suggested change
fn combine_hints(
hints: Vec<Self::OpeningHint>,
scalars: &[Self::Field],
) -> Self::OpeningHint;

Generated by Claude Code

Comment on lines 1040 to 1077
@@ -277,166 +1060,600 @@ impl AdditivelyHomomorphic for DoryScheme {
.map(|row| {
let mut acc = Bn254G1::default();
for (hint, &scalar) in hints.iter().zip(scalars.iter()) {
acc += hint.row_commitments[row].scalar_mul(&scalar);
if let Some(row_commitment) = hint.row_commitments.get(row) {
acc += row_commitment.scalar_mul(&scalar);
}
}
acc
})
.collect();

DoryHint::new(combined, combined_blind)
let chunk_len = hints
.iter()
.map(|hint| hint.chunk_len)
.max()
.unwrap_or_default();
DoryHint::new(combined, combined_blind, chunk_len)
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Body is textually identical to combine_hint_refs at line 657 (modulo Vec<&DoryHint> vs Vec<DoryHint>). Any future change to hint combination has to be made twice. Express one via the other — either have the trait impl call the helper with .iter().collect(), or take impl IntoIterator<Item: Borrow<DoryHint>> in the helper.


Generated by Claude Code

Comment thread crates/jolt-hyperkzg/src/scheme.rs Outdated
Comment on lines +385 to +452
fn source_to_evaluations<F, S>(source: &S) -> Vec<F>
where
F: Field,
S: CommitmentSource<F> + ?Sized,
{
let mut evaluations = Vec::with_capacity(1 << source.num_vars());
let chunk_len = source
.natural_chunk_len()
.unwrap_or_else(|| 1usize << source.num_vars());
source.for_each_row(chunk_len, |_, row| match row {
SourceRow::FieldElements(values) => evaluations.extend_from_slice(values),
SourceRow::StridedFieldElements {
values,
column_stride,
} => {
for value in values {
evaluations.push(*value);
evaluations.extend(repeat_n(F::zero(), column_stride.saturating_sub(1)));
}
}
SourceRow::I128(values) => {
evaluations.extend(values.iter().map(|&value| F::from_i128(value)));
}
SourceRow::StridedI128 {
values,
column_stride,
} => {
for value in values {
evaluations.push(F::from_i128(*value));
evaluations.extend(repeat_n(F::zero(), column_stride.saturating_sub(1)));
}
}
SourceRow::U64(values) => {
evaluations.extend(values.iter().map(|&value| F::from_u64(value)));
}
SourceRow::StridedU64 {
values,
column_stride,
} => {
for value in values {
evaluations.push(F::from_u64(*value));
evaluations.extend(repeat_n(F::zero(), column_stride.saturating_sub(1)));
}
}
SourceRow::OneHot(row) => {
let domain_size = 1usize << row.log_domain_size;
match row.entries {
OneHotEntries::OnePerColumn(indices) => {
for hot_index in indices {
let mut dense = vec![F::zero(); domain_size];
dense[hot_index.get()] = F::from_u64(1);
evaluations.extend(dense);
}
}
OneHotEntries::MaybeZero(indices) => {
for hot_index in indices {
let mut dense = vec![F::zero(); domain_size];
if let Some(hot_index) = hot_index {
dense[hot_index.get()] = F::from_u64(1);
}
evaluations.extend(dense);
}
}
}
}
});
evaluations
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This re-implements the same SourceRow enum dispatch as materialize_source_evaluations in jolt-openings/src/sources.rs:438, but with a different one-hot layout (column-major inline here vs hot-index-major accumulated in jolt-openings). Adding a new SourceRow variant requires updating two places, and the divergent one-hot handling means a multi-row one-hot source produces a different polynomial through HyperKZG vs the canonical helper. Easiest fix is making materialize_source_evaluations pub and deleting this copy; if the column-major shape was intentional for HyperKZG, leave a comment explaining why.


Generated by Claude Code

Comment thread jolt-core/src/zkvm/prover.rs Outdated
Comment on lines +260 to +283
if rebuild {
let mut advice_polys = self
.advice_polys
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner());
let advice_polys = advice_polys.take().unwrap_or_default();
let (poly_ids, coeffs): (Vec<_>, Vec<_>) = terms
.iter()
.map(|term| (term.source_id, term.coefficient))
.unzip();
let source = MultilinearPolynomial::RLC(RLCPolynomial::new_streaming(
self.one_hot_params.clone(),
Arc::clone(&self.streaming_data),
self.trace_source.clone(),
poly_ids,
&coeffs,
advice_polys,
));
*cache = Some(Stage8CachedRlc {
terms: terms.to_vec(),
chunk_len,
source,
});
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

advice_polys.take() permanently moves the advice map out of the Mutex<Option<...>> on the first rebuild. If fold_linear_rows is ever invoked a second time with a different terms or chunk_len (cache miss), the second rebuild gets None and unwrap_or_default() silently substitutes an empty HashMap — advice contributions vanish from the RLC with no error.

Current Dory path is safe because prove_source_backed_batch_with_mode calls vector_matrix_product with a single fixed (terms, chunk_len). But Stage8OpeningSource::fold_rows at line 326 builds a single-element terms per source, so anything that routes through the default prove_batch_opening and hits this from multiple sources will silently drop advice starting on the second call. Worth either making the advice map cloneable so rebuilds remain consistent, or debug_assert!(cache.is_none()) here so a second rebuild fails loudly.


Generated by Claude Code

Comment thread jolt-core/src/zkvm/prover.rs Outdated
Comment on lines +315 to +324
fn evaluate(&self, _point: &[F]) -> F {
panic!("Stage8OpeningSource is only used through source-backed batch opening")
}

fn for_each_row<V>(&self, _chunk_len: usize, _visit: V)
where
V: for<'row> FnMut(usize, SourceRow<'row, F>),
{
panic!("Stage8OpeningSource is only used through source-backed batch opening")
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Panicking evaluate/for_each_row means any PCS that uses the default prove_batch_opening against Stage8OpeningSourceBatch (which routes per-id through source(id)) will crash at runtime instead of failing at compile time. Dory overrides prove_batch_opening, so this is latent today, but it's a non-obvious coupling between this source impl and the chosen backend. Worth a doc comment noting the requirement that the backend implement source-backed batch opening directly.


Generated by Claude Code

@quangvdao quangvdao changed the title jolt-openings PCS type-family cutover jolt-openings crate API cutover May 14, 2026
@quangvdao quangvdao force-pushed the quang/jolt-openings-crate branch from 7f569b3 to 37ddc5c Compare May 14, 2026 16:45
Scope the extracted PCS cutover to jolt-openings, jolt-dory, and related crate-level backends. Keep legacy jolt-core unchanged as the reference implementation while documenting the generated-role integration path.
@quangvdao quangvdao force-pushed the quang/jolt-openings-crate branch from bc7a13c to 8ee3947 Compare May 14, 2026 16:54
}
}

impl CanonicalSerialize for Bn254GT {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

can we just #[derive(CanonicalSerialize, CanonicalDeserialize)] on Bn254GT instead of manually implementing these?

/// proof algorithm. Most schemes set both fields equal; Dory uses `proof` for
/// its private row-major opening order while Jolt keeps `public` in protocol
/// order.
#[derive(Clone, Debug, PartialEq, Eq)]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't really like this; I feel like the PCS implementation should just expect one coordinate order, and it should be responsible for any reordering it might need

Comment on lines +121 to +126
/// Expression describing how a PCS output is derived from raw claim terms.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum BatchOutputExpression<F: Field, ClaimId> {
/// Linear relation `output = Σ coefficient_i * claim_i`.
Linear(Vec<(ClaimId, F)>),
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

can we fold this into BatchOutputRelation instead of introducing a new type?

materialize_source_evaluations(source)
}

type ProverPointGroup<F, PCS, S> = Vec<(Vec<F>, Vec<ProverClaimWithHint<F, PCS, S>>)>;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

i feel like a map makes more sense here?

groups
}

type OpeningPointGroup<F, PCS> = Vec<(Vec<F>, Vec<OpeningClaim<F, PCS>>)>;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

same here

Comment thread crates/jolt-openings/src/schemes.rs Outdated
/// cannot: their verifier setup contains trapdoor-derived elements generated
/// during setup, so verifier-only code should receive the verifier setup as an
/// input rather than pretending it can derive it from public generators.
pub trait PublicVerifierSetup: CommitmentSchemeVerifier {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why have a separate trait here?

Comment thread crates/jolt-openings/src/schemes.rs Outdated

fn verifier_setup(prover_setup: &Self::ProverSetup) -> Self::VerifierSetup;
/// Projects prover setup down to verifier setup.
fn project_verifier_setup(prover_setup: &Self::ProverSetup) -> Self::VerifierSetup;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
fn project_verifier_setup(prover_setup: &Self::ProverSetup) -> Self::VerifierSetup;
fn prover_to_verifier_setup(prover_setup: &Self::ProverSetup) -> Self::VerifierSetup;

Comment thread crates/jolt-openings/src/sources.rs Outdated
Comment on lines +123 to +134
/// A dense row of unsigned 64-bit integers embedded canonically into the field.
///
/// This preserves the common compact-polynomial benchmark and commitment
/// path without paying the cost of first converting every row entry into a
/// full-width field element.
U64(&'a [u64]),

/// A strided unsigned-integer row embedded canonically into the field.
StridedU64 {
values: &'a [u64],
column_stride: usize,
},
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think I slightly prefer to collapse this into a single variant, since U64 is just the special case of StridedU64 with a stride of 1. Same for FieldElements and I128. wdyt?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude-review-request Request a review from Claude Code claude-spec-approved Claude spec analysis found no ambiguities implementation PR contains implementation of a spec spec Tracking issue for a feature spec

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants