hotshot_types/vid/
advz.rs1use std::{fmt::Debug, ops::Range};
10
11use ark_bn254::Bn254;
12use ark_serialize::CanonicalDeserialize;
13use jf_advz::{
14 VidDisperse, VidResult, VidScheme,
15 advz::{
16 self,
17 payload_prover::{LargeRangeProof, SmallRangeProof},
18 },
19 payload_prover::{PayloadProver, Statement},
20};
21use jf_pcs::{
22 PolynomialCommitmentScheme,
23 prelude::{UnivariateKzgPCS, UnivariateUniversalParams},
24};
25use lazy_static::lazy_static;
26use serde::{Deserialize, Serialize};
27use sha2::Sha256;
28
29#[must_use]
48#[memoize::memoize(SharedCache, Capacity: 10)]
49pub fn advz_scheme(num_storage_nodes: usize) -> ADVZScheme {
50 let recovery_threshold = 1 << num_storage_nodes.ilog2();
54
55 #[allow(clippy::panic)]
56 let num_storage_nodes = u32::try_from(num_storage_nodes).unwrap_or_else(|err| {
57 panic!("num_storage_nodes {num_storage_nodes} should fit into u32; error: {err}")
58 });
59
60 #[allow(clippy::panic)]
62 ADVZScheme(
63 Advz::new(num_storage_nodes, recovery_threshold, &*KZG_SRS).unwrap_or_else(|err| {
64 panic!(
65 "advz construction failure: (num_storage \
66 nodes,recovery_threshold)=({num_storage_nodes},{recovery_threshold}); error: \
67 {err}"
68 )
69 }),
70 )
71}
72
73pub type ADVZCommitment = <ADVZScheme as VidScheme>::Commit;
75pub type ADVZCommon = <ADVZScheme as VidScheme>::Common;
77pub type ADVZShare = <ADVZScheme as VidScheme>::Share;
79
80#[cfg(not(feature = "gpu-vid"))]
81type Advz = advz::Advz<E, H>;
83#[cfg(feature = "gpu-vid")]
84type Advz = advz::AdvzGPU<'static, E, H>;
86
87#[derive(Clone)]
90pub struct ADVZScheme(Advz);
91
92#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
96pub struct LargeRangeProofType(
97 LargeRangeProof<<UnivariateKzgPCS<E> as PolynomialCommitmentScheme>::Evaluation>,
109);
110
111#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
115pub struct SmallRangeProofType(
116 SmallRangeProof<<UnivariateKzgPCS<E> as PolynomialCommitmentScheme>::Proof>,
120);
121
122lazy_static! {
124 static ref KZG_SRS: UnivariateUniversalParams<E> = {
126 let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/kzg_srs.bin"));
130 UnivariateUniversalParams::deserialize_compressed(bytes.as_slice())
131 .expect("failed to deserialize generated SRS")
132 };
133}
134
135type E = Bn254;
137type H = Sha256;
139
140impl VidScheme for ADVZScheme {
146 type Commit = <Advz as VidScheme>::Commit;
147 type Share = <Advz as VidScheme>::Share;
148 type Common = <Advz as VidScheme>::Common;
149
150 fn commit_only<B>(&mut self, payload: B) -> VidResult<Self::Commit>
151 where
152 B: AsRef<[u8]>,
153 {
154 self.0.commit_only(payload)
155 }
156
157 fn disperse<B>(&mut self, payload: B) -> VidResult<VidDisperse<Self>>
158 where
159 B: AsRef<[u8]>,
160 {
161 self.0.disperse(payload).map(vid_disperse_conversion)
162 }
163
164 fn verify_share(
165 &self,
166 share: &Self::Share,
167 common: &Self::Common,
168 commit: &Self::Commit,
169 ) -> VidResult<Result<(), ()>> {
170 self.0.verify_share(share, common, commit)
171 }
172
173 fn recover_payload(&self, shares: &[Self::Share], common: &Self::Common) -> VidResult<Vec<u8>> {
174 self.0.recover_payload(shares, common)
175 }
176
177 fn is_consistent(commit: &Self::Commit, common: &Self::Common) -> VidResult<()> {
178 <Advz as VidScheme>::is_consistent(commit, common)
179 }
180
181 fn get_payload_byte_len(common: &Self::Common) -> u32 {
182 <Advz as VidScheme>::get_payload_byte_len(common)
183 }
184
185 fn get_num_storage_nodes(common: &Self::Common) -> u32 {
186 <Advz as VidScheme>::get_num_storage_nodes(common)
187 }
188
189 fn get_multiplicity(common: &Self::Common) -> u32 {
190 <Advz as VidScheme>::get_multiplicity(common)
191 }
192}
193
194impl PayloadProver<LargeRangeProofType> for ADVZScheme {
195 fn payload_proof<B>(&self, payload: B, range: Range<usize>) -> VidResult<LargeRangeProofType>
196 where
197 B: AsRef<[u8]>,
198 {
199 self.0
200 .payload_proof(payload, range)
201 .map(LargeRangeProofType)
202 }
203
204 fn payload_verify(
205 &self,
206 stmt: Statement<'_, Self>,
207 proof: &LargeRangeProofType,
208 ) -> VidResult<Result<(), ()>> {
209 self.0.payload_verify(stmt_conversion(stmt), &proof.0)
210 }
211}
212
213impl PayloadProver<SmallRangeProofType> for ADVZScheme {
214 fn payload_proof<B>(&self, payload: B, range: Range<usize>) -> VidResult<SmallRangeProofType>
215 where
216 B: AsRef<[u8]>,
217 {
218 self.0
219 .payload_proof(payload, range)
220 .map(SmallRangeProofType)
221 }
222
223 fn payload_verify(
224 &self,
225 stmt: Statement<'_, Self>,
226 proof: &SmallRangeProofType,
227 ) -> VidResult<Result<(), ()>> {
228 self.0.payload_verify(stmt_conversion(stmt), &proof.0)
229 }
230}
231
232fn vid_disperse_conversion(vid_disperse: VidDisperse<Advz>) -> VidDisperse<ADVZScheme> {
241 VidDisperse {
242 shares: vid_disperse.shares,
243 common: vid_disperse.common,
244 commit: vid_disperse.commit,
245 }
246}
247
248fn stmt_conversion(stmt: Statement<'_, ADVZScheme>) -> Statement<'_, Advz> {
250 Statement {
251 payload_subslice: stmt.payload_subslice,
252 range: stmt.range,
253 commit: stmt.commit,
254 common: stmt.common,
255 }
256}