jf_vid/payload_prover.rs
1// Copyright (c) 2023 Espresso Systems (espressosys.com)
2// This file is part of the Jellyfish library.
3
4// You should have received a copy of the MIT License
5// along with the Jellyfish library. If not, see <https://mit-license.org/>.
6
7//! Trait for additional functionality in Verifiable Information Retrieval (VID)
8//! to make and verify a proof of correctness of an arbitrary sub-slice of data
9//! from a payload.
10
11use core::fmt::Debug;
12
13use super::{VidResult, VidScheme};
14use ark_std::ops::Range;
15use serde::{de::DeserializeOwned, Serialize};
16
17/// Payload proof functionality for [`VidScheme`].
18pub trait PayloadProver<PROOF>: VidScheme
19where
20 PROOF: Clone + Debug + Eq + PartialEq + Serialize + DeserializeOwned,
21{
22 /// Compute a proof for a subslice of payload data.
23 ///
24 /// # Arguments
25 ///
26 /// - `payload`: a (possibly large) binary payload.
27 /// - `range`: indicates the subslice `payload[range.start..range.end]` of
28 /// `playload` for which a proof will be made.
29 ///
30 /// # Why not just a single `&[u8]` argument for `payload`?
31 ///
32 /// You might think it's sufficient that [`PayloadProver::payload_proof`]
33 /// take only a single `&[u8]` argument that the user creates via
34 /// `payload[range.start..range.end]`. However, the generated proof might
35 /// depend on `range.start` or on `payload` bytes outside of `range`. This
36 /// data would be lost if [`PayloadProver::payload_proof`] accepted only a
37 /// single `&[u8]` argument.
38 fn payload_proof<B>(&self, payload: B, range: Range<usize>) -> VidResult<PROOF>
39 where
40 B: AsRef<[u8]>;
41
42 /// Verify a proof made by [`PayloadProver::payload_proof`].
43 ///
44 /// # Arguments
45 ///
46 /// - `stmt`: see [`Statement`].
47 /// - `proof`: made by a call to [`PayloadProver::payload_proof`].
48 fn payload_verify(&self, stmt: Statement<Self>, proof: &PROOF) -> VidResult<Result<(), ()>>;
49}
50
51/// A convenience struct to reduce the list of arguments to
52/// [`PayloadProver::payload_verify`]. It's the statement proved by
53/// [`PayloadProver::payload_proof`].
54///
55/// # Why the `?Sized` bound?
56///
57/// Rust hates you: <https://stackoverflow.com/a/54465962>
58// TODO: figure out how to derive basic things like Clone, Debug, etc.
59// Seems that `Derivative` can't handle reference members.
60// #[derive(Derivative)]
61// #[derivative(
62// Clone(bound = "V::Common: Clone, V::Commit:Clone"),
63// )]
64pub struct Statement<'a, V>
65where
66 V: VidScheme + ?Sized,
67{
68 /// The subslice `payload[range.start..range.end]` from a call to
69 /// [`PayloadProver::payload_proof`].
70 pub payload_subslice: &'a [u8],
71 /// The range used to make [`Self::payload_subslice`].
72 pub range: Range<usize>,
73 /// VID commitment against which the proof will be checked.
74 pub commit: &'a V::Commit,
75 /// VID data against which the proof will be checked.
76 pub common: &'a V::Common,
77}
78
79impl<'a, V> Clone for Statement<'a, V>
80where
81 V: VidScheme,
82{
83 fn clone(&self) -> Self {
84 Self {
85 payload_subslice: self.payload_subslice,
86 range: self.range.clone(),
87 commit: self.commit,
88 common: self.common,
89 }
90 }
91}