proof_system/sub_protocols/
mod.rs

1pub mod accumulator;
2#[macro_use]
3pub mod bbs_plus;
4pub mod bbdt16_kvac;
5pub mod bbs_23;
6pub mod bbs_23_ietf;
7pub mod bound_check_bpp;
8pub mod bound_check_legogroth16;
9pub mod bound_check_smc;
10pub mod bound_check_smc_with_kv;
11pub mod inequality;
12pub mod ps_signature;
13pub mod r1cs_legogorth16;
14pub mod saver;
15pub mod schnorr;
16pub mod verifiable_encryption_tz_21;
17
18use crate::{
19    error::ProofSystemError,
20    sub_protocols::{
21        accumulator::{
22            cdh::{
23                KBPositiveAccumulatorMembershipCDHSubProtocol,
24                KBUniversalAccumulatorMembershipCDHSubProtocol,
25                KBUniversalAccumulatorNonMembershipCDHSubProtocol,
26                VBAccumulatorMembershipCDHSubProtocol, VBAccumulatorNonMembershipCDHSubProtocol,
27            },
28            keyed_verification::{
29                KBUniversalAccumulatorMembershipKVSubProtocol,
30                KBUniversalAccumulatorNonMembershipKVSubProtocol,
31                VBAccumulatorMembershipKVSubProtocol,
32            },
33            KBPositiveAccumulatorMembershipSubProtocol,
34            KBUniversalAccumulatorMembershipSubProtocol,
35            KBUniversalAccumulatorNonMembershipSubProtocol,
36        },
37        bbdt16_kvac::PoKOfMACSubProtocol,
38        bound_check_bpp::BoundCheckBppProtocol,
39        bound_check_legogroth16::BoundCheckLegoGrothProtocol,
40        bound_check_smc::BoundCheckSmcProtocol,
41        bound_check_smc_with_kv::BoundCheckSmcWithKVProtocol,
42        inequality::InequalityProtocol,
43        r1cs_legogorth16::R1CSLegogroth16Protocol,
44        verifiable_encryption_tz_21::VeTZ21Protocol,
45    },
46};
47use accumulator::{
48    detached::{
49        DetachedAccumulatorMembershipSubProtocol, DetachedAccumulatorNonMembershipSubProtocol,
50    },
51    VBAccumulatorMembershipSubProtocol, VBAccumulatorNonMembershipSubProtocol,
52};
53use ark_ec::pairing::Pairing;
54use ark_ff::PrimeField;
55use ark_std::{format, io::Write};
56use core::borrow::Borrow;
57use itertools::{EitherOrBoth, Itertools};
58
59/// Various sub-protocols that are executed to create a `StatementProof` which are then combined to
60/// form a `Proof`
61#[derive(Clone, Debug, PartialEq)]
62pub enum SubProtocol<'a, E: Pairing> {
63    /// For BBS+ signature in group G1
64    PoKBBSSignatureG1(bbs_plus::PoKBBSSigG1SubProtocol<'a, E>),
65    VBAccumulatorMembership(VBAccumulatorMembershipSubProtocol<'a, E>),
66    VBAccumulatorNonMembership(VBAccumulatorNonMembershipSubProtocol<'a, E>),
67    PoKDiscreteLogs(schnorr::SchnorrProtocol<'a, E::G1Affine>),
68    /// For verifiable encryption using SAVER
69    Saver(saver::SaverProtocol<'a, E>),
70    /// For range proof using LegoGroth16
71    BoundCheckLegoGroth16(BoundCheckLegoGrothProtocol<'a, E>),
72    R1CSLegogroth16Protocol(R1CSLegogroth16Protocol<'a, E>),
73    PSSignaturePoK(ps_signature::PSSignaturePoK<'a, E>),
74    /// For BBS signature in group G1
75    PoKBBSSignature23G1(bbs_23::PoKBBSSigG1SubProtocol<'a, E>),
76    PoKBBSSignature23IETFG1(bbs_23_ietf::PoKBBSSigIETFG1SubProtocol<'a, E>),
77    /// For range proof using Bulletproofs++
78    BoundCheckBpp(BoundCheckBppProtocol<'a, E::G1Affine>),
79    /// For range proof using set-membership check
80    BoundCheckSmc(BoundCheckSmcProtocol<'a, E>),
81    /// For range proof using set-membership check with keyed verification
82    BoundCheckSmcWithKV(BoundCheckSmcWithKVProtocol<'a, E::G1Affine>),
83    /// To prove inequality of a signed message with a public value
84    Inequality(InequalityProtocol<'a, E::G1Affine>),
85    DetachedAccumulatorMembership(DetachedAccumulatorMembershipSubProtocol<'a, E>),
86    DetachedAccumulatorNonMembership(DetachedAccumulatorNonMembershipSubProtocol<'a, E>),
87    KBUniversalAccumulatorMembership(KBUniversalAccumulatorMembershipSubProtocol<'a, E>),
88    KBUniversalAccumulatorNonMembership(KBUniversalAccumulatorNonMembershipSubProtocol<'a, E>),
89    VBAccumulatorMembershipCDH(VBAccumulatorMembershipCDHSubProtocol<'a, E>),
90    VBAccumulatorNonMembershipCDH(VBAccumulatorNonMembershipCDHSubProtocol<'a, E>),
91    KBUniversalAccumulatorMembershipCDH(KBUniversalAccumulatorMembershipCDHSubProtocol<'a, E>),
92    KBUniversalAccumulatorNonMembershipCDH(
93        KBUniversalAccumulatorNonMembershipCDHSubProtocol<'a, E>,
94    ),
95    KBPositiveAccumulatorMembership(KBPositiveAccumulatorMembershipSubProtocol<'a, E>),
96    KBPositiveAccumulatorMembershipCDH(KBPositiveAccumulatorMembershipCDHSubProtocol<'a, E>),
97    PoKOfBBDT16MAC(PoKOfMACSubProtocol<'a, E::G1Affine>),
98    PoKDiscreteLogsG2(schnorr::SchnorrProtocol<'a, E::G2Affine>),
99    VBAccumulatorMembershipKV(VBAccumulatorMembershipKVSubProtocol<E::G1Affine>),
100    KBUniversalAccumulatorMembershipKV(KBUniversalAccumulatorMembershipKVSubProtocol<E::G1Affine>),
101    KBUniversalAccumulatorNonMembershipKV(
102        KBUniversalAccumulatorNonMembershipKVSubProtocol<E::G1Affine>,
103    ),
104    VeTZ21(VeTZ21Protocol<'a, E::G1Affine>),
105}
106
107macro_rules! delegate {
108    ($self: ident $($tt: tt)+) => {{
109        $crate::delegate_indexed! {
110            $self =>
111                PoKBBSSignatureG1,
112                VBAccumulatorMembership,
113                VBAccumulatorNonMembership,
114                PoKDiscreteLogs,
115                Saver,
116                BoundCheckLegoGroth16,
117                R1CSLegogroth16Protocol,
118                PSSignaturePoK,
119                PoKBBSSignature23G1,
120                PoKBBSSignature23IETFG1,
121                BoundCheckBpp,
122                BoundCheckSmc,
123                BoundCheckSmcWithKV,
124                Inequality,
125                DetachedAccumulatorMembership,
126                DetachedAccumulatorNonMembership,
127                KBUniversalAccumulatorMembership,
128                KBUniversalAccumulatorNonMembership,
129                VBAccumulatorMembershipCDH,
130                VBAccumulatorNonMembershipCDH,
131                KBUniversalAccumulatorMembershipCDH,
132                KBUniversalAccumulatorNonMembershipCDH,
133                KBPositiveAccumulatorMembership,
134                KBPositiveAccumulatorMembershipCDH,
135                PoKOfBBDT16MAC,
136                PoKDiscreteLogsG2,
137                VBAccumulatorMembershipKV,
138                KBUniversalAccumulatorMembershipKV,
139                KBUniversalAccumulatorNonMembershipKV,
140                VeTZ21
141            : $($tt)+
142        }
143    }};
144}
145
146impl<'a, E: Pairing> SubProtocol<'a, E> {
147    pub fn challenge_contribution<W: Write>(&self, writer: W) -> Result<(), ProofSystemError> {
148        delegate!(self.challenge_contribution(writer))
149    }
150}
151
152/// Merges indexed messages sorted by index with indexed blindings sorted by index.
153/// Messages which don't have corresponding blindings will be blinded randomly.
154/// In case blinding has an index that isn't present in the messages iterator,
155/// `invalid_blinding_idx` will be set to this index and iteration will be aborted.
156fn merge_indexed_messages_with_blindings<'a, M, B, R: 'a>(
157    indexed_msgs_sorted_by_index: impl IntoIterator<Item = (impl Borrow<usize>, M)> + 'a,
158    indexed_blindings_sorted_by_index: impl IntoIterator<Item = (impl Borrow<usize>, B)> + 'a,
159    mut map_randomly_blinded_msg: impl FnMut(M) -> R + 'a,
160    mut map_msg_with_blinding: impl FnMut(M, B) -> R + 'a,
161    invalid_blinding_idx: &'a mut Option<usize>,
162) -> impl Iterator<Item = (usize, R)> + 'a {
163    indexed_msgs_sorted_by_index
164        .into_iter()
165        .map(|(idx, msg)| (*idx.borrow(), msg))
166        .merge_join_by(
167            indexed_blindings_sorted_by_index
168                .into_iter()
169                .map(|(idx, msg)| (*idx.borrow(), msg)),
170            |(m_idx, _), (b_idx, _)| m_idx.cmp(b_idx),
171        )
172        .map(move |either| {
173            let item = match either {
174                EitherOrBoth::Left((idx, msg)) => (idx, map_randomly_blinded_msg(msg)),
175                EitherOrBoth::Both((idx, message), (_, blinding)) => {
176                    (idx, (map_msg_with_blinding)(message, blinding))
177                }
178                EitherOrBoth::Right((idx, _)) => {
179                    invalid_blinding_idx.replace(idx);
180
181                    return None;
182                }
183            };
184
185            Some(item)
186        })
187        .take_while(Option::is_some)
188        .flatten()
189}
190
191pub fn validate_bounds(min: u64, max: u64) -> Result<(), ProofSystemError> {
192    if max <= min {
193        return Err(ProofSystemError::BoundCheckMaxNotGreaterThanMin);
194    }
195    Ok(())
196}
197
198pub fn enforce_and_get_u64<F: PrimeField>(val: &F) -> Result<u64, ProofSystemError> {
199    let m = val.into_bigint();
200    let limbs: &[u64] = m.as_ref();
201    for i in 1..limbs.len() {
202        if limbs[i] != 0 {
203            return Err(ProofSystemError::UnsupportedValue(format!(
204                "Only supports 64 bit values Bulletproofs++ range proof but found {}",
205                val
206            )));
207        }
208    }
209    Ok(limbs[0])
210}