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}