Skip to content

Commit 6b1d13b

Browse files
committed
feat: add Dory assist verifier
1 parent aa8e52f commit 6b1d13b

38 files changed

Lines changed: 12875 additions & 0 deletions
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[package]
2+
name = "jolt-dory-assist-verifier"
3+
version = "0.1.0"
4+
edition = "2021"
5+
license = "MIT"
6+
description = "Dory-assist verifier implementation for Jolt PCS assist"
7+
8+
[lints]
9+
workspace = true
10+
11+
[dependencies]
12+
jolt-crypto = { workspace = true, features = ["grumpkin"] }
13+
jolt-claims = { workspace = true }
14+
jolt-dory = { path = "../jolt-dory" }
15+
jolt-field = { workspace = true }
16+
jolt-hyrax = { workspace = true }
17+
jolt-openings = { workspace = true }
18+
jolt-poly = { workspace = true }
19+
jolt-sumcheck = { workspace = true }
20+
jolt-transcript = { workspace = true }
21+
jolt-verifier = { workspace = true }
22+
serde = { workspace = true, features = ["derive"] }
23+
thiserror = { workspace = true }
Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
//! Layout helpers for public Dory proof artifacts staged into `Fq`.
2+
3+
use std::ops::Range;
4+
5+
use jolt_dory::DoryProof;
6+
use jolt_field::Fq;
7+
8+
pub use jolt_claims::protocols::dory_assist::formulas::artifacts::{
9+
DORY_PROOF_DIGEST_INDEX, DORY_REDUCE_ROUNDS_START, DORY_SCALAR_PRODUCT_E1_START,
10+
DORY_SCALAR_PRODUCT_E2_START, DORY_SCALAR_PRODUCT_P1_START, DORY_SCALAR_PRODUCT_P2_START,
11+
DORY_SCALAR_PRODUCT_Q_START, DORY_SCALAR_PRODUCT_R1_INDEX, DORY_SCALAR_PRODUCT_R2_INDEX,
12+
DORY_SCALAR_PRODUCT_R3_INDEX, DORY_SCALAR_PRODUCT_R_START, DORY_VMV_C_START, DORY_VMV_D2_START,
13+
DORY_VMV_E1_START, DORY_ZK_E2_START, DORY_ZK_Y_COM_START, FIRST_REDUCE_ARTIFACT_COORDS,
14+
G1_ARTIFACT_COORDS, G2_ARTIFACT_COORDS, GT_ARTIFACT_COEFFS, REDUCE_ROUND_ARTIFACT_COORDS,
15+
SECOND_REDUCE_ARTIFACT_COORDS,
16+
};
17+
18+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
19+
pub struct DoryProofArtifactLayout {
20+
reduce_rounds: usize,
21+
}
22+
23+
impl DoryProofArtifactLayout {
24+
pub const fn new(reduce_rounds: usize) -> Self {
25+
Self { reduce_rounds }
26+
}
27+
28+
pub fn for_proof(proof: &DoryProof) -> Self {
29+
Self::new(proof.reduce_round_count())
30+
}
31+
32+
pub const fn reduce_rounds(self) -> usize {
33+
self.reduce_rounds
34+
}
35+
36+
pub const fn expected_len(self) -> usize {
37+
self.final_e2_start() + G2_ARTIFACT_COORDS
38+
}
39+
40+
pub fn vmv_c(self) -> Range<usize> {
41+
gt_range(DORY_VMV_C_START)
42+
}
43+
44+
pub fn vmv_d2(self) -> Range<usize> {
45+
gt_range(DORY_VMV_D2_START)
46+
}
47+
48+
pub fn vmv_e1(self) -> Range<usize> {
49+
g1_range(DORY_VMV_E1_START)
50+
}
51+
52+
pub fn zk_e2(self) -> Range<usize> {
53+
g2_range(DORY_ZK_E2_START)
54+
}
55+
56+
pub fn zk_y_com(self) -> Range<usize> {
57+
g1_range(DORY_ZK_Y_COM_START)
58+
}
59+
60+
pub fn scalar_product_p1(self) -> Range<usize> {
61+
gt_range(DORY_SCALAR_PRODUCT_P1_START)
62+
}
63+
64+
pub fn scalar_product_p2(self) -> Range<usize> {
65+
gt_range(DORY_SCALAR_PRODUCT_P2_START)
66+
}
67+
68+
pub fn scalar_product_q(self) -> Range<usize> {
69+
gt_range(DORY_SCALAR_PRODUCT_Q_START)
70+
}
71+
72+
pub fn scalar_product_r(self) -> Range<usize> {
73+
gt_range(DORY_SCALAR_PRODUCT_R_START)
74+
}
75+
76+
pub fn scalar_product_e1(self) -> Range<usize> {
77+
g1_range(DORY_SCALAR_PRODUCT_E1_START)
78+
}
79+
80+
pub fn scalar_product_e2(self) -> Range<usize> {
81+
g2_range(DORY_SCALAR_PRODUCT_E2_START)
82+
}
83+
84+
pub const fn scalar_product_r1(self) -> usize {
85+
let _ = self;
86+
DORY_SCALAR_PRODUCT_R1_INDEX
87+
}
88+
89+
pub const fn scalar_product_r2(self) -> usize {
90+
let _ = self;
91+
DORY_SCALAR_PRODUCT_R2_INDEX
92+
}
93+
94+
pub const fn scalar_product_r3(self) -> usize {
95+
let _ = self;
96+
DORY_SCALAR_PRODUCT_R3_INDEX
97+
}
98+
99+
pub const fn reduce_round_start(self, round: usize) -> usize {
100+
DORY_REDUCE_ROUNDS_START + round * REDUCE_ROUND_ARTIFACT_COORDS
101+
}
102+
103+
pub fn reduce_round(self, round: usize) -> DoryReduceRoundArtifactRanges {
104+
DoryReduceRoundArtifactRanges::new(self.reduce_round_start(round))
105+
}
106+
107+
pub const fn final_e1_start(self) -> usize {
108+
DORY_REDUCE_ROUNDS_START + self.reduce_rounds * REDUCE_ROUND_ARTIFACT_COORDS
109+
}
110+
111+
pub const fn final_e2_start(self) -> usize {
112+
self.final_e1_start() + G1_ARTIFACT_COORDS
113+
}
114+
115+
pub fn final_e1(self) -> Range<usize> {
116+
g1_range(self.final_e1_start())
117+
}
118+
119+
pub fn final_e2(self) -> Range<usize> {
120+
g2_range(self.final_e2_start())
121+
}
122+
123+
pub fn gt_at(self, artifacts: &[Fq], range: Range<usize>) -> Option<[Fq; GT_ARTIFACT_COEFFS]> {
124+
let _ = self;
125+
copy_artifact(artifacts, range)
126+
}
127+
128+
pub fn g1_at(self, artifacts: &[Fq], range: Range<usize>) -> Option<[Fq; G1_ARTIFACT_COORDS]> {
129+
let _ = self;
130+
copy_artifact(artifacts, range)
131+
}
132+
133+
pub fn g2_at(self, artifacts: &[Fq], range: Range<usize>) -> Option<[Fq; G2_ARTIFACT_COORDS]> {
134+
let _ = self;
135+
copy_artifact(artifacts, range)
136+
}
137+
}
138+
139+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
140+
pub struct DoryReduceRoundArtifactRanges {
141+
start: usize,
142+
}
143+
144+
impl DoryReduceRoundArtifactRanges {
145+
pub const fn new(start: usize) -> Self {
146+
Self { start }
147+
}
148+
149+
pub fn first_d1_left(self) -> Range<usize> {
150+
gt_range(self.start)
151+
}
152+
153+
pub fn first_d1_right(self) -> Range<usize> {
154+
gt_range(self.first_d1_left().end)
155+
}
156+
157+
pub fn first_d2_left(self) -> Range<usize> {
158+
gt_range(self.first_d1_right().end)
159+
}
160+
161+
pub fn first_d2_right(self) -> Range<usize> {
162+
gt_range(self.first_d2_left().end)
163+
}
164+
165+
pub fn first_e1_beta(self) -> Range<usize> {
166+
g1_range(self.first_d2_right().end)
167+
}
168+
169+
pub fn first_e2_beta(self) -> Range<usize> {
170+
g2_range(self.first_e1_beta().end)
171+
}
172+
173+
pub fn second_c_plus(self) -> Range<usize> {
174+
gt_range(self.first_e2_beta().end)
175+
}
176+
177+
pub fn second_c_minus(self) -> Range<usize> {
178+
gt_range(self.second_c_plus().end)
179+
}
180+
181+
pub fn second_e1_plus(self) -> Range<usize> {
182+
g1_range(self.second_c_minus().end)
183+
}
184+
185+
pub fn second_e1_minus(self) -> Range<usize> {
186+
g1_range(self.second_e1_plus().end)
187+
}
188+
189+
pub fn second_e2_plus(self) -> Range<usize> {
190+
g2_range(self.second_e1_minus().end)
191+
}
192+
193+
pub fn second_e2_minus(self) -> Range<usize> {
194+
g2_range(self.second_e2_plus().end)
195+
}
196+
197+
pub fn full(self) -> Range<usize> {
198+
self.start..self.second_e2_minus().end
199+
}
200+
}
201+
202+
pub fn gt_range(start: usize) -> Range<usize> {
203+
start..start + GT_ARTIFACT_COEFFS
204+
}
205+
206+
pub fn g1_range(start: usize) -> Range<usize> {
207+
start..start + G1_ARTIFACT_COORDS
208+
}
209+
210+
pub fn g2_range(start: usize) -> Range<usize> {
211+
start..start + G2_ARTIFACT_COORDS
212+
}
213+
214+
pub fn copy_artifact<const N: usize>(artifacts: &[Fq], range: Range<usize>) -> Option<[Fq; N]> {
215+
if range.len() != N {
216+
return None;
217+
}
218+
let slice = artifacts.get(range)?;
219+
let mut artifact = [Fq::default(); N];
220+
artifact.copy_from_slice(slice);
221+
Some(artifact)
222+
}
223+
224+
#[cfg(test)]
225+
mod tests {
226+
use super::*;
227+
228+
#[test]
229+
fn fixed_artifact_ranges_are_contiguous() {
230+
let layout = DoryProofArtifactLayout::new(0);
231+
232+
assert_eq!(layout.vmv_c(), 1..17);
233+
assert_eq!(layout.vmv_d2(), 17..33);
234+
assert_eq!(layout.vmv_e1(), 33..36);
235+
assert_eq!(layout.zk_e2(), 36..41);
236+
assert_eq!(layout.zk_y_com(), 41..44);
237+
assert_eq!(layout.scalar_product_p1(), 44..60);
238+
assert_eq!(layout.scalar_product_p2(), 60..76);
239+
assert_eq!(layout.scalar_product_q(), 76..92);
240+
assert_eq!(layout.scalar_product_r(), 92..108);
241+
assert_eq!(layout.scalar_product_e1(), 108..111);
242+
assert_eq!(layout.scalar_product_e2(), 111..116);
243+
assert_eq!(layout.scalar_product_r1(), 116);
244+
assert_eq!(layout.scalar_product_r2(), 117);
245+
assert_eq!(layout.scalar_product_r3(), 118);
246+
assert_eq!(DORY_REDUCE_ROUNDS_START, 119);
247+
}
248+
249+
#[test]
250+
fn reduce_round_ranges_are_contiguous() {
251+
let round = DoryReduceRoundArtifactRanges::new(DORY_REDUCE_ROUNDS_START);
252+
253+
assert_eq!(round.first_d1_left(), 119..135);
254+
assert_eq!(round.first_d1_right(), 135..151);
255+
assert_eq!(round.first_d2_left(), 151..167);
256+
assert_eq!(round.first_d2_right(), 167..183);
257+
assert_eq!(round.first_e1_beta(), 183..186);
258+
assert_eq!(round.first_e2_beta(), 186..191);
259+
assert_eq!(round.second_c_plus(), 191..207);
260+
assert_eq!(round.second_c_minus(), 207..223);
261+
assert_eq!(round.second_e1_plus(), 223..226);
262+
assert_eq!(round.second_e1_minus(), 226..229);
263+
assert_eq!(round.second_e2_plus(), 229..234);
264+
assert_eq!(round.second_e2_minus(), 234..239);
265+
assert_eq!(round.full().len(), REDUCE_ROUND_ARTIFACT_COORDS);
266+
}
267+
268+
#[test]
269+
fn expected_len_accounts_for_reduce_rounds_and_final_pair() {
270+
assert_eq!(
271+
DoryProofArtifactLayout::new(0).expected_len(),
272+
DORY_REDUCE_ROUNDS_START + G1_ARTIFACT_COORDS + G2_ARTIFACT_COORDS
273+
);
274+
assert_eq!(
275+
DoryProofArtifactLayout::new(2).expected_len(),
276+
DORY_REDUCE_ROUNDS_START
277+
+ 2 * REDUCE_ROUND_ARTIFACT_COORDS
278+
+ G1_ARTIFACT_COORDS
279+
+ G2_ARTIFACT_COORDS
280+
);
281+
}
282+
283+
#[test]
284+
fn copy_artifact_rejects_wrong_width() {
285+
let artifacts = vec![Fq::default(); GT_ARTIFACT_COEFFS];
286+
287+
assert!(
288+
copy_artifact::<{ GT_ARTIFACT_COEFFS }>(&artifacts, 0..GT_ARTIFACT_COEFFS).is_some()
289+
);
290+
assert!(
291+
copy_artifact::<{ G1_ARTIFACT_COORDS }>(&artifacts, 0..GT_ARTIFACT_COEFFS).is_none()
292+
);
293+
}
294+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//! Dory-assist verifier configuration.
2+
3+
use serde::{Deserialize, Serialize};
4+
5+
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
6+
pub struct DoryAssistConfig;

0 commit comments

Comments
 (0)