1#![cfg_attr(not(feature = "std"), no_std)]
9#![allow(warnings)]
11#![deny(missing_docs)]
12#[cfg(test)]
13extern crate std;
14
15#[cfg(any(test, feature = "schnorr"))]
16#[macro_use]
17extern crate derivative;
18
19#[cfg(any(not(feature = "std"), target_has_atomic = "ptr"))]
20#[doc(hidden)]
21extern crate alloc;
22
23use ark_std::rand::{CryptoRng, RngCore};
24
25#[cfg(any(test, feature = "bls"))]
26pub mod bls_over_bls12381;
27#[cfg(any(test, feature = "bls"))]
28pub mod bls_over_bn254;
29pub mod constants;
30#[cfg(feature = "gadgets")]
31pub mod gadgets;
32#[cfg(any(test, feature = "schnorr"))]
33pub mod schnorr;
34
35use ark_std::{
36 format,
37 string::{String, ToString},
38};
39use blst::BLST_ERROR;
40use core::fmt::Debug;
41use displaydoc::Display;
42use serde::{Deserialize, Serialize};
43use zeroize::Zeroize;
44
45#[derive(Debug, Display, Eq, PartialEq)]
47pub enum SignatureError {
48 ParameterError(String),
50 FailedSubgroupCheck,
52 FailedOnCurveCheck,
54 FailedValidityCheck,
57 VerificationError(String),
59}
60
61impl ark_std::error::Error for SignatureError {}
62
63impl From<BLST_ERROR> for SignatureError {
64 fn from(e: BLST_ERROR) -> Self {
65 match e {
66 BLST_ERROR::BLST_SUCCESS => {
67 Self::ParameterError("Expecting an error, but got a success.".to_string())
68 },
69 BLST_ERROR::BLST_VERIFY_FAIL => Self::VerificationError(format!("{e:?}")),
70 _ => Self::ParameterError(format!("{e:?}")),
71 }
72 }
73}
74
75pub trait SignatureScheme: Clone + Send + Sync + 'static {
80 const CS_ID: &'static str;
82
83 type SigningKey: Debug + Clone + Send + Sync + Zeroize + PartialEq + Eq;
85
86 type VerificationKey: Debug
88 + Clone
89 + Send
90 + Sync
91 + for<'a> Deserialize<'a>
92 + Serialize
93 + PartialEq
94 + Eq;
95
96 type PublicParameter: Debug + Clone + PartialEq + for<'a> Deserialize<'a> + Serialize;
98
99 type Signature: Debug
101 + Clone
102 + Send
103 + Sync
104 + for<'a> Deserialize<'a>
105 + Serialize
106 + PartialEq
107 + Eq;
108
109 type MessageUnit: Debug + Clone + Send + Sync;
111
112 fn param_gen<R: CryptoRng + RngCore>(
119 prng: Option<&mut R>,
120 ) -> Result<Self::PublicParameter, SignatureError>;
121
122 fn key_gen<R: CryptoRng + RngCore>(
124 pp: &Self::PublicParameter,
125 prng: &mut R,
126 ) -> Result<(Self::SigningKey, Self::VerificationKey), SignatureError>;
127
128 fn sign<R: CryptoRng + RngCore, M: AsRef<[Self::MessageUnit]>>(
130 pp: &Self::PublicParameter,
131 sk: &Self::SigningKey,
132 msg: M,
133 prng: &mut R,
134 ) -> Result<Self::Signature, SignatureError>;
135
136 fn verify<M: AsRef<[Self::MessageUnit]>>(
138 pp: &Self::PublicParameter,
139 vk: &Self::VerificationKey,
140 msg: M,
141 sig: &Self::Signature,
142 ) -> Result<(), SignatureError>;
143}
144
145pub trait AggregateableSignatureSchemes:
150 SignatureScheme + Serialize + for<'a> Deserialize<'a> + Debug
151{
152 fn aggregate(
156 pp: &Self::PublicParameter,
157 vks: &[Self::VerificationKey],
158 sigs: &[Self::Signature],
159 ) -> Result<Self::Signature, SignatureError>;
160
161 fn aggregate_verify<M: AsRef<[Self::MessageUnit]>>(
165 pp: &Self::PublicParameter,
166 vks: &[Self::VerificationKey],
167 msgs: &[M],
168 sig: &Self::Signature,
169 ) -> Result<(), SignatureError>;
170
171 fn multi_sig_verify(
175 pp: &Self::PublicParameter,
176 vks: &[Self::VerificationKey],
177 msg: &[Self::MessageUnit],
178 sig: &Self::Signature,
179 ) -> Result<(), SignatureError>;
180}
181
182#[cfg(test)]
183mod tests {
184 use super::*;
185 use ark_std::{rand::prelude::StdRng, vec, vec::Vec};
186 use jf_utils::test_rng;
187
188 pub(crate) fn sign_and_verify<S: SignatureScheme>(message: &[S::MessageUnit]) {
189 let rng = &mut test_rng();
190 let parameters = S::param_gen(Some(rng)).unwrap();
191 let (sk, pk) = S::key_gen(¶meters, rng).unwrap();
192 let sig = S::sign(¶meters, &sk, message, rng).unwrap();
193 assert!(S::verify(¶meters, &pk, message, &sig).is_ok());
194
195 let parameters = S::param_gen::<StdRng>(None).unwrap();
196 let (sk, pk) = S::key_gen(¶meters, rng).unwrap();
197 let sig = S::sign(¶meters, &sk, message, rng).unwrap();
198 assert!(S::verify(¶meters, &pk, message, &sig).is_ok());
199 }
200
201 pub(crate) fn agg_sign_and_verify<S: AggregateableSignatureSchemes>(
202 messages: &[&[S::MessageUnit]],
203 bad_message: &[S::MessageUnit],
204 ) {
205 let rng = &mut test_rng();
206 let parameters = S::param_gen(Some(rng)).unwrap();
207 let mut pks = vec![];
208 let mut sigs = vec![];
209 let mut partial_sigs = vec![];
210 let message_for_msig = messages[0];
211 for message in messages.iter() {
212 let (sk, pk) = S::key_gen(¶meters, rng).unwrap();
213 let sig = S::sign(¶meters, &sk, message, rng).unwrap();
214 let partial_sig = S::sign(¶meters, &sk, message_for_msig, rng).unwrap();
215 pks.push(pk);
216 sigs.push(sig);
217 partial_sigs.push(partial_sig);
218 }
219 let agg_sig = S::aggregate(¶meters, &pks, &sigs).unwrap();
221 let multi_sig = S::aggregate(¶meters, &pks, &partial_sigs).unwrap();
222 assert!(S::aggregate_verify(¶meters, &pks, messages, &agg_sig).is_ok());
223 assert!(S::multi_sig_verify(¶meters, &pks, message_for_msig, &multi_sig).is_ok());
224 assert!(S::aggregate_verify(¶meters, &pks, &messages[1..], &agg_sig).is_err());
226 assert!(S::aggregate_verify(¶meters, &[], messages, &agg_sig).is_err());
228 assert!(S::multi_sig_verify(¶meters, &[], message_for_msig, &multi_sig).is_err());
229 let mut bad_messages: Vec<&[S::MessageUnit]> = messages.to_vec();
231 bad_messages[0] = bad_message;
232 assert!(S::aggregate_verify(¶meters, &pks, &bad_messages, &agg_sig).is_err());
233 assert!(S::multi_sig_verify(¶meters, &pks, bad_message, &multi_sig).is_err());
234 }
235
236 pub(crate) fn failed_verification<S: SignatureScheme>(
237 message: &[S::MessageUnit],
238 bad_message: &[S::MessageUnit],
239 ) {
240 let rng = &mut test_rng();
241 let parameters = S::param_gen(Some(rng)).unwrap();
242 let (sk, pk) = S::key_gen(¶meters, rng).unwrap();
243 let sig = S::sign(¶meters, &sk, message, rng).unwrap();
244 assert!(S::verify(¶meters, &pk, bad_message, &sig).is_err());
245 }
246}