commonware_cryptography/bls12381/
mod.rs1pub mod dkg;
10pub mod primitives;
11mod scheme;
12pub use scheme::{Bls12381, PrivateKey, PublicKey, Signature};
13
14#[cfg(test)]
15mod tests {
16 use super::*;
17 use dkg::ops::generate_shares;
18 use primitives::group::Private;
19 use primitives::ops::{
20 partial_sign_message, partial_verify_message, threshold_signature_recover, verify_message,
21 };
22 use primitives::poly::public;
23 use primitives::Error;
24 use rand::{rngs::StdRng, SeedableRng};
25
26 #[test]
27 fn test_partial_aggregate_signature() {
28 let (n, t) = (5, 4);
29 let mut rng = StdRng::seed_from_u64(0);
30
31 let (group, shares) = generate_shares(&mut rng, None, n, t);
37
38 let namespace = Some(&b"test"[..]);
40 let msg = b"hello";
41 let partials = shares
42 .iter()
43 .map(|s| partial_sign_message(s, namespace, msg))
44 .collect::<Vec<_>>();
45
46 partials.iter().for_each(|partial| {
48 partial_verify_message(&group, namespace, msg, partial).unwrap();
49 });
50
51 let threshold_sig = threshold_signature_recover(t, partials).unwrap();
53 let threshold_pub = public(&group);
54 verify_message(&threshold_pub, namespace, msg, &threshold_sig).unwrap();
55 }
56
57 #[test]
58 fn test_partial_aggregate_signature_bad_namespace() {
59 let (n, t) = (5, 4);
60 let mut rng = StdRng::seed_from_u64(0);
61
62 let (group, shares) = generate_shares(&mut rng, None, n, t);
68
69 let namespace = Some(&b"test"[..]);
71 let msg = b"hello";
72 let partials = shares
73 .iter()
74 .map(|s| partial_sign_message(s, namespace, msg))
75 .collect::<Vec<_>>();
76
77 let namespace = Some(&b"bad"[..]);
79 partials.iter().for_each(|partial| {
80 assert!(matches!(
81 partial_verify_message(&group, namespace, msg, partial).unwrap_err(),
82 Error::InvalidSignature
83 ));
84 });
85
86 let threshold_sig = threshold_signature_recover(t, partials).unwrap();
88 let threshold_pub = public(&group);
89 assert!(matches!(
90 verify_message(&threshold_pub, namespace, msg, &threshold_sig).unwrap_err(),
91 Error::InvalidSignature
92 ));
93 }
94
95 #[test]
96 fn test_partial_aggregate_signature_insufficient() {
97 let (n, t) = (5, 4);
98 let mut rng = StdRng::seed_from_u64(0);
99
100 let (group, shares) = generate_shares(&mut rng, None, n, t);
103
104 let shares = shares.into_iter().take(t as usize - 1).collect::<Vec<_>>();
106
107 let namespace = Some(&b"test"[..]);
109 let msg = b"hello";
110 let partials = shares
111 .iter()
112 .map(|s| partial_sign_message(s, namespace, msg))
113 .collect::<Vec<_>>();
114
115 partials.iter().for_each(|partial| {
117 partial_verify_message(&group, namespace, msg, partial).unwrap();
118 });
119
120 assert!(matches!(
122 threshold_signature_recover(t, partials).unwrap_err(),
123 Error::NotEnoughPartialSignatures(4, 3)
124 ));
125 }
126
127 #[test]
128 fn test_partial_aggregate_signature_insufficient_duplicates() {
129 let (n, t) = (5, 4);
130 let mut rng = StdRng::seed_from_u64(0);
131
132 let (group, shares) = generate_shares(&mut rng, None, n, t);
135
136 let mut shares = shares.into_iter().take(t as usize - 1).collect::<Vec<_>>();
138 shares.push(shares[0]);
139
140 let namespace = Some(&b"test"[..]);
142 let msg = b"hello";
143 let partials = shares
144 .iter()
145 .map(|s| partial_sign_message(s, namespace, msg))
146 .collect::<Vec<_>>();
147
148 partials.iter().for_each(|partial| {
150 partial_verify_message(&group, namespace, msg, partial).unwrap();
151 });
152
153 assert!(matches!(
155 threshold_signature_recover(t, partials).unwrap_err(),
156 Error::DuplicateEval,
157 ));
158 }
159
160 #[test]
161 #[should_panic(expected = "InvalidSignature")]
162 fn test_partial_aggregate_signature_bad_share() {
163 let (n, t) = (5, 4);
164 let mut rng = StdRng::seed_from_u64(0);
165
166 let (group, mut shares) = generate_shares(&mut rng, None, n, t);
169
170 let share = shares.get_mut(3).unwrap();
172 share.private = Private::rand(&mut rand::thread_rng());
173
174 let namespace = Some(&b"test"[..]);
176 let msg = b"hello";
177 let partials = shares
178 .iter()
179 .map(|s| partial_sign_message(s, namespace, msg))
180 .collect::<Vec<_>>();
181
182 partials.iter().for_each(|partial| {
184 partial_verify_message(&group, namespace, msg, partial).unwrap();
185 });
186
187 let threshold_sig = threshold_signature_recover(t, partials).unwrap();
189 let threshold_pub = public(&group);
190 verify_message(&threshold_pub, namespace, msg, &threshold_sig).unwrap();
191 }
192}