bbs_plus/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]
2#![allow(non_snake_case)]
3
4//! Implements BBS and BBS+ signatures.
5//!
6//! BBS+ signature according to the paper: [Anonymous Attestation Using the Strong Diffie Hellman Assumption Revisited](https://eprint.iacr.org/2016/663).
7//! Provides
8//! - signature creation and verification with signature in group G1 and public key in group G2 and vice-versa.
9//! - proof of knowledge of signature and corresponding messages in group G1 as that is more efficient.
10//!
11//! BBS signature according to the paper: [Revisiting BBS Signatures](https://eprint.iacr.org/2023/275).
12//! Provides
13//! - signature creation and verification with signature in group G1 and public key in group G2.
14//! - proof of knowledge of signature and corresponding messages. The implemented protocols are a bit
15//! different from whats mentioned in the paper. The modifications are made in the Schnorr proof part
16//! to allow for use-cases like proving equality (in zero-knowledge) of messages among same/different signatures
17//! or proving predicates (in zero-knowledge) about messages. Check the documentation of corresponding modules
18//! for more details.
19//!
20//! Threshold BBS and BBS+ signatures based on the paper [Threshold BBS+ Signatures for Distributed Anonymous Credential Issuance](https://eprint.iacr.org/2023/602)
21//! The threshold signing protocol has 3 phases (not communication rounds)
22//!     1. This is the randomness generation phase
23//!     2. This is the phase where multiplications happen
24//!     3. Here the outputs of phases 1 and 2 and the messages to be signed are used to generate the signature. This phase
25//!     is non-interactive from signers' point of view as they don't just interact among themselves
26//!
27//! Note that only 3rd phase requires the messages to be known so the first 2 phases can be treated as pre-computation
28//! and can be done proactively and thus only phase 1 and 2 are online phases of the MPC protocol and phase 3 is the offline
29//! phase.
30//! Secondly since the communication time among signers is most likely to be the bottleneck
31//! in threshold signing, phase 1 and 2 support batching meaning that to generate `n` signatures only a single execution
32//! of phase 1 and 2 needs to done, although with larger inputs. Then `n` executions of phase 3 are done to generate
33//! the signature.
34//! Also, its assumed that parties have done the DKG as well as the base OT and stored their results before starting phase 1.
35//! Both BBS and BBS+ implementations share the same multiplication phase and the base OT phase but their phase 1 is slightly
36//! less expensive as BBS+ needs 2 random fields elements but BBS needs only 1.
37//!
38//! ## Modules
39//!
40//! 1. BBS and BBS+ signature parameters and key generation module - [`setup`]. The signature params for BBS are slightly
41//! different from BBS+ but public key is same.
42//! 2. BBS+ signature module - [`signature`]
43//! 3. BBS+ proof of knowledge of signature module - [`proof`]
44//! 4. BBS signature module - [`signature_23`]
45//! 5. BBS proof of knowledge of signature module - [`proof_23`]
46//! 6. BBS proof of knowledge of signature module, implementation as in appendix B - [`proof_23_cdl`]
47//! 7. BBS proof of knowledge of signature module, implementation as in appendix A - [`proof_23_ietf`]
48//! 8. Threshold BBS and BBS+ signatures - [`threshold`]
49//!
50//! The implementation tries to use the same variable names as the paper and thus violate Rust's naming conventions at places.
51//!
52//!
53//! [`setup`]: crate::setup
54//! [`signature`]: crate::signature
55//! [`proof`]: crate::proof
56//! [`signature_23`]: crate::signature_23
57//! [`proof_23`]: crate::proof_23
58//! [`proof_23_cdl`]: crate::proof_23_cdl
59//! [`proof_23_ietf`]: crate::proof_23_ietf
60//! [`threshold`]: crate::threshold
61
62pub mod error;
63pub mod proof;
64pub mod proof_23;
65pub mod proof_23_cdl;
66pub mod proof_23_ietf;
67pub mod setup;
68pub mod signature;
69pub mod signature_23;
70pub mod threshold;
71
72pub mod prelude {
73    pub use crate::{
74        error::BBSPlusError,
75        proof::{PoKOfSignatureG1Proof, PoKOfSignatureG1Protocol},
76        proof_23_cdl::{PoKOfSignature23G1Proof, PoKOfSignature23G1Protocol},
77        setup::*,
78        signature::{SignatureG1, SignatureG2},
79        signature_23::Signature23G1,
80    };
81}
82
83#[cfg(test)]
84#[macro_use]
85pub mod tests {
86    #[macro_export]
87    macro_rules! test_serialization {
88        ($obj_type:ty, $obj: ident) => {
89            // Test ark serialization
90            let mut serz = vec![];
91            CanonicalSerialize::serialize_compressed(&$obj, &mut serz).unwrap();
92            let deserz: $obj_type =
93                CanonicalDeserialize::deserialize_compressed(&serz[..]).unwrap();
94            assert_eq!(deserz, $obj);
95
96            let mut serz = vec![];
97            $obj.serialize_uncompressed(&mut serz).unwrap();
98            let deserz: $obj_type =
99                CanonicalDeserialize::deserialize_uncompressed(&serz[..]).unwrap();
100            assert_eq!(deserz, $obj);
101
102            // Test JSON serialization
103            let ser = serde_json::to_string(&$obj).unwrap();
104            let deser = serde_json::from_str::<$obj_type>(&ser).unwrap();
105            assert_eq!($obj, deser);
106
107            // Test Message Pack serialization
108            let ser = rmp_serde::to_vec_named(&$obj).unwrap();
109            let deser = rmp_serde::from_slice::<$obj_type>(&ser).unwrap();
110            assert_eq!($obj, deser);
111        };
112    }
113}