Skip to content

Commit 9d35c5c

Browse files
authored
Merge pull request #345 from worldfnd/adds-spark-squashed
Adds SPARK
2 parents 985a639 + a899a06 commit 9d35c5c

30 files changed

Lines changed: 3577 additions & 341 deletions

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@
1414
*.pkp
1515
*.pkv
1616
*.np
17+
*.sp
18+
*.spc
19+
*.spctx
20+
spark_proofs/
1721
params_for_recursive_verifier
1822
params
1923
artifacts/
2024
spartan_vm_debug/
2125
mavros_debug/
26+
mavros/
2227

2328
# Don't ignore benchmarking artifacts
2429
!tooling/provekit-bench/benches/*

Cargo.lock

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ members = [
2020
"tooling/provekit-wasm",
2121
"tooling/verifier-server",
2222
"ntt",
23+
"provekit/spark",
2324
"poseidon2",
2425
"playground/passport-input-gen",
2526
]
@@ -107,6 +108,7 @@ provekit-ffi = { path = "tooling/provekit-ffi" }
107108
provekit-gnark = { path = "tooling/provekit-gnark" }
108109
provekit-prover = { path = "provekit/prover", default-features = false }
109110
provekit-r1cs-compiler = { path = "provekit/r1cs-compiler" }
111+
provekit-spark = { path = "provekit/spark" }
110112
provekit-verifier = { path = "provekit/verifier" }
111113
provekit-verifier-server = { path = "tooling/verifier-server" }
112114
provekit-wasm = { path = "tooling/provekit-wasm" }

provekit/backend/bn254/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ mod prove;
1616
mod scheme;
1717
mod skyscraper;
1818
mod solver;
19+
pub mod spark;
1920
mod transcript_sponge;
2021
mod verify;
2122
pub mod witness;
@@ -35,6 +36,7 @@ pub use {
3536
},
3637
skyscraper::SkyscraperPoW,
3738
solver::solve_witness_vec,
39+
spark::{MatrixDimensions, SparkSetup, SparkWhirConfigs},
3840
transcript_sponge::TranscriptSponge,
3941
verify::Verify,
4042
};

provekit/backend/bn254/src/mavros_prove.rs

Lines changed: 106 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@ use {
1616
utils::sumcheck::calculate_evaluations_over_boolean_hypercube_for_eq, PublicInputs,
1717
WhirR1CSProof, WhirR1CSScheme,
1818
},
19-
provekit_prover::{prove_from_alphas, run_zk_sumcheck_prover, WhirR1CSCommitment},
19+
provekit_prover::{
20+
prove_from_alphas_ctx, run_zk_sumcheck_prover, ProveFromAlphasCtx, SparkQueryData,
21+
WhirR1CSCommitment,
22+
},
2023
tracing::instrument,
2124
whir::{algebra::embedding::Identity, transcript::ProverState},
2225
};
2326

2427
pub trait MavrosR1CSProver {
28+
#[allow(clippy::too_many_arguments)]
2529
fn prove_mavros(
2630
&self,
2731
merlin: ProverState<TranscriptSponge>,
@@ -32,58 +36,128 @@ pub trait MavrosR1CSProver {
3236
constraints_layout: ConstraintsLayout,
3337
binary: &[u64],
3438
) -> Result<WhirR1CSProof>;
39+
40+
/// Like [`Self::prove_mavros`], but also produces the SPARK query data as
41+
/// a side output (the transcript is identical either way).
42+
#[allow(clippy::too_many_arguments)]
43+
fn prove_mavros_with_spark(
44+
&self,
45+
merlin: ProverState<TranscriptSponge>,
46+
witgen: WitgenResult,
47+
commitments: Vec<WhirR1CSCommitment<Bn254Field>>,
48+
public_inputs: &PublicInputs<FieldElement>,
49+
witness_layout: WitnessLayout,
50+
constraints_layout: ConstraintsLayout,
51+
binary: &[u64],
52+
) -> Result<(WhirR1CSProof, SparkQueryData<Bn254Field>)>;
3553
}
3654

3755
impl MavrosR1CSProver for WhirR1CSScheme<Bn254Field> {
3856
#[instrument(skip_all)]
3957
fn prove_mavros(
4058
&self,
41-
mut merlin: ProverState<TranscriptSponge>,
59+
merlin: ProverState<TranscriptSponge>,
4260
witgen: WitgenResult,
4361
commitments: Vec<WhirR1CSCommitment<Bn254Field>>,
4462
public_inputs: &PublicInputs<FieldElement>,
4563
witness_layout: WitnessLayout,
4664
constraints_layout: ConstraintsLayout,
4765
binary: &[u64],
4866
) -> Result<WhirR1CSProof> {
49-
ensure!(!commitments.is_empty(), "Need at least one commitment");
50-
51-
let blinding = commitments[0]
52-
.blinding
53-
.as_ref()
54-
.ok_or_else(|| anyhow::anyhow!("c1 must carry blinding state"))?;
55-
56-
// `g` is committed separately in the extension field; open `blinding_eval`
57-
// against the blinding vector (g flattened at offset 0).
58-
let (alpha, blinding_eval) = run_zk_sumcheck_prover(
59-
&Identity::new(),
60-
[witgen.out_a, witgen.out_b, witgen.out_c],
61-
&mut merlin,
62-
self.m_0,
63-
&blinding.polynomial,
64-
&blinding.vector,
65-
);
66-
67-
let eq_alpha =
68-
calculate_evaluations_over_boolean_hypercube_for_eq(&alpha, 1 << alpha.len());
69-
let (ad_a, ad_b, ad_c, _) = run_ad(
70-
binary,
71-
&eq_alpha[..constraints_layout.size()],
67+
let (proof, _) = prove_mavros_inner(
68+
self,
69+
merlin,
70+
witgen,
71+
commitments,
72+
public_inputs,
7273
witness_layout,
7374
constraints_layout,
75+
binary,
76+
false,
7477
)?;
75-
let alphas = [ad_a, ad_b, ad_c];
76-
77-
let blinding_weights = expand_powers::<4, _>(&alpha);
78+
Ok(proof)
79+
}
7880

79-
prove_from_alphas(
81+
#[instrument(skip_all)]
82+
fn prove_mavros_with_spark(
83+
&self,
84+
merlin: ProverState<TranscriptSponge>,
85+
witgen: WitgenResult,
86+
commitments: Vec<WhirR1CSCommitment<Bn254Field>>,
87+
public_inputs: &PublicInputs<FieldElement>,
88+
witness_layout: WitnessLayout,
89+
constraints_layout: ConstraintsLayout,
90+
binary: &[u64],
91+
) -> Result<(WhirR1CSProof, SparkQueryData<Bn254Field>)> {
92+
let (proof, queries) = prove_mavros_inner(
8093
self,
8194
merlin,
95+
witgen,
96+
commitments,
97+
public_inputs,
98+
witness_layout,
99+
constraints_layout,
100+
binary,
101+
true,
102+
)?;
103+
let queries = queries
104+
.ok_or_else(|| anyhow::anyhow!("SPARK query data must be produced when requested"))?;
105+
Ok((proof, queries))
106+
}
107+
}
108+
109+
#[instrument(skip_all)]
110+
#[allow(clippy::too_many_arguments)]
111+
fn prove_mavros_inner(
112+
scheme: &WhirR1CSScheme<Bn254Field>,
113+
mut merlin: ProverState<TranscriptSponge>,
114+
witgen: WitgenResult,
115+
commitments: Vec<WhirR1CSCommitment<Bn254Field>>,
116+
public_inputs: &PublicInputs<FieldElement>,
117+
witness_layout: WitnessLayout,
118+
constraints_layout: ConstraintsLayout,
119+
binary: &[u64],
120+
produce_spark_query: bool,
121+
) -> Result<(WhirR1CSProof, Option<SparkQueryData<Bn254Field>>)> {
122+
ensure!(!commitments.is_empty(), "Need at least one commitment");
123+
124+
let blinding = commitments[0]
125+
.blinding
126+
.as_ref()
127+
.ok_or_else(|| anyhow::anyhow!("c1 must carry blinding state"))?;
128+
129+
// `g` is committed separately in the extension field; open `blinding_eval`
130+
// against the blinding vector (g flattened at offset 0).
131+
let (alpha, blinding_eval) = run_zk_sumcheck_prover(
132+
&Identity::new(),
133+
[witgen.out_a, witgen.out_b, witgen.out_c],
134+
&mut merlin,
135+
scheme.m_0,
136+
&blinding.polynomial,
137+
&blinding.vector,
138+
);
139+
140+
let eq_alpha = calculate_evaluations_over_boolean_hypercube_for_eq(&alpha, 1 << alpha.len());
141+
let (ad_a, ad_b, ad_c, _) = run_ad(
142+
binary,
143+
&eq_alpha[..constraints_layout.size()],
144+
witness_layout,
145+
constraints_layout,
146+
)?;
147+
let alphas = [ad_a, ad_b, ad_c];
148+
149+
let blinding_weights = expand_powers::<4, _>(&alpha);
150+
151+
prove_from_alphas_ctx(
152+
scheme,
153+
merlin,
154+
ProveFromAlphasCtx {
82155
alphas,
83156
blinding_eval,
84157
blinding_weights,
85158
commitments,
86-
public_inputs,
87-
)
88-
}
159+
spark_row: produce_spark_query.then_some(alpha),
160+
},
161+
public_inputs,
162+
)
89163
}

0 commit comments

Comments
 (0)