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}