sigma_fun/
lib.rs

1//!
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![no_std]
4#![allow(non_snake_case)]
5#![cfg_attr(feature = "secp256k1", doc = include_str!("../README.md"))]
6#![deny(missing_docs, warnings)]
7
8use core::fmt::Debug;
9use digest::Update;
10pub use generic_array::{self, typenum};
11use generic_array::{ArrayLength, GenericArray};
12pub use rand_core;
13use rand_core::{CryptoRng, RngCore};
14
15#[cfg(test)]
16#[macro_use]
17extern crate std;
18
19#[cfg(feature = "alloc")]
20#[allow(unused_imports)]
21#[macro_use]
22extern crate alloc;
23
24#[cfg(feature = "secp256k1")]
25#[cfg_attr(docsrs, doc(cfg(feature = "secp256k1")))]
26pub mod secp256k1;
27
28#[cfg(feature = "ed25519")]
29#[cfg_attr(docsrs, doc(cfg(feature = "ed25519")))]
30pub mod ed25519;
31
32mod and;
33pub use and::And;
34mod eq;
35pub use eq::Eq;
36
37#[cfg(feature = "alloc")]
38mod eq_all;
39#[cfg(feature = "alloc")]
40#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
41pub use eq_all::EqAll;
42mod or;
43pub use or::*;
44
45#[cfg(feature = "alloc")]
46mod all;
47#[cfg(feature = "alloc")]
48#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
49pub use all::All;
50pub mod ext;
51mod transcript;
52pub use transcript::*;
53mod fiat_shamir;
54pub use fiat_shamir::*;
55mod writable;
56pub use writable::*;
57
58/// The `Sigma` trait is used to define a Sigma protocol.
59///
60/// You will need to implement this yourself if you are unable to build your sigma protocol by
61/// composing it from existing sigma protocols.
62///
63/// The role of the main functions of the trait are depicted below:
64///
65///```ignore
66/// Prover(witness, statement, rng)                                                 Verifier(statement)
67/// ======
68/// announce_secret = gen_announce_secret(rng)
69/// announcement = announce(statement, announce_secret)
70///                                                       announcement
71///                                                   +------------------->
72///                                                        challenge         *uniformly sample ChallengeLength bytes*
73///                                                   <-------------------+
74/// response = respond(witness, statement,
75///                    announce_secret, announcement,
76///                    challenge)
77///
78///                                                        response
79///                                                   +------------------->
80///                                                                                             check
81///                                                                         implied_announcement(statement, challenge, response)
82///                                                                                               ==
83///                                                                                          announcement
84/// ```
85///
86/// The values taken and returned by the functions are all defined as associated types. In addition
87/// there is `ChallengeLength` associated type which defines the length of the challenge. Usually
88/// the trait is implemented for a sigma protocol for all lengths less than some maximum like so:
89///
90/// ```ignore
91/// use sigma_fun::generic_array::{
92///     typenum::{self, type_operators::IsLessOrEqual, U32},
93///     ArrayLength, GenericArray,
94/// };
95/// use sigma_fun::Sigma;
96/// struct MySigma<L> {
97///     // store the typenum in our type
98///     challenge_len: core::marker::PhantomData<L>,
99/// }
100/// // implement Sigma for any length less than or eqaul to 32-bytes.
101/// impl<L: ArrayLength<u8>> Sigma for MySigma<L>
102/// where
103///    L: IsLessOrEqual<U32>,
104///    <L as IsLessOrEqual<U32>>::Output: typenum::marker_traits::NonZero
105///    {
106///    // ...
107///    }
108/// ```
109pub trait Sigma: Writable {
110    /// The witness for the relation.
111    type Witness: Debug;
112    /// The elements of the statement the prover is proving.
113    type Statement: Debug;
114    /// The type for the secret the prover creates when generating the proof.
115    type AnnounceSecret: Debug;
116    /// The type for the public announcement the prover sends in the first round of the protocol.
117    type Announcement: core::cmp::Eq + Debug;
118    /// The type for the response the prover sends in the last round of the protocol.
119    type Response: Debug;
120    /// The length as a [`typenum`]
121    ///
122    /// [`typenum`]: crate::typenum
123    type ChallengeLength: ArrayLength<u8>;
124
125    /// Generates the prover's announcement message.
126    fn announce(
127        &self,
128        statement: &Self::Statement,
129        announce_secret: &Self::AnnounceSecret,
130    ) -> Self::Announcement;
131    /// Generates the secret data to create the announcement
132    fn gen_announce_secret<Rng: CryptoRng + RngCore>(
133        &self,
134        witness: &Self::Witness,
135        rng: &mut Rng,
136    ) -> Self::AnnounceSecret;
137    /// Uniformly samples a response from the response space of the Sigma protocol.
138    fn sample_response<Rng: CryptoRng + RngCore>(&self, rng: &mut Rng) -> Self::Response;
139
140    /// Generates the prover's response for the verifier's challenge.
141    fn respond(
142        &self,
143        witness: &Self::Witness,
144        statement: &Self::Statement,
145        announce_secret: Self::AnnounceSecret,
146        announce: &Self::Announcement,
147        challenge: &GenericArray<u8, Self::ChallengeLength>,
148    ) -> Self::Response;
149    /// Computes what the announcement must be for the `response` to be valid.
150    fn implied_announcement(
151        &self,
152        statement: &Self::Statement,
153        challenge: &GenericArray<u8, Self::ChallengeLength>,
154        response: &Self::Response,
155    ) -> Option<Self::Announcement>;
156
157    /// Hashes the statement.
158    fn hash_statement<H: Update>(&self, hash: &mut H, statement: &Self::Statement);
159    /// Hashes the announcement.
160    fn hash_announcement<H: Update>(&self, hash: &mut H, announcement: &Self::Announcement);
161    /// Hashes the witness.
162    fn hash_witness<H: Update>(&self, hash: &mut H, witness: &Self::Witness);
163}
164
165#[macro_export]
166#[doc(hidden)]
167macro_rules! impl_display {
168    ($name:ident<$($tp:ident),+>) => {
169        impl<$($tp),+> core::fmt::Display for $name<$($tp),+>
170            where $name<$($tp),+>: $crate::Sigma
171        {
172            fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
173                use $crate::Writable;
174                self.write_to(f)
175            }
176        }
177    }
178}