1use crate::errors::{BBSError, BBSErrorKind};
2use crate::{
3 hash_to_g2, GeneratorG1, GeneratorG2, HashElem, RandomElem, ToVariableLengthBytes,
4 FR_COMPRESSED_SIZE, FR_UNCOMPRESSED_SIZE, G1_COMPRESSED_SIZE, G1_UNCOMPRESSED_SIZE,
5 G2_COMPRESSED_SIZE, G2_UNCOMPRESSED_SIZE,
6};
7use blake2::{digest::generic_array::GenericArray, Blake2b};
8use ff_zeroize::Field;
9use pairing_plus::{
10 bls12_381::{Fr, G1, G2},
11 hash_to_field::BaseFromRO,
12 serdes::SerDes,
13 CurveProjective,
14};
15use rand::prelude::*;
16#[cfg(feature = "rayon")]
17use rayon::prelude::*;
18use serde::{
19 de::{Error as DError, Visitor},
20 Deserialize, Deserializer, Serialize, Serializer,
21};
22use std::io::{Cursor, Read};
23use std::{
24 convert::TryFrom,
25 fmt::{Display, Formatter},
26};
27#[cfg(feature = "wasm")]
28use wasm_bindgen::JsValue;
29use zeroize::Zeroize;
30
31pub mod prelude {
33 pub use super::{
34 generate, DeterministicPublicKey, KeyGenOption, PublicKey, SecretKey,
35 DETERMINISTIC_PUBLIC_KEY_COMPRESSED_SIZE,
36 };
37}
38
39#[derive(Debug, Clone)]
41pub enum KeyGenOption {
42 UseSeed(Vec<u8>),
44 FromSecretKey(SecretKey),
46}
47
48#[derive(Clone, Debug, Eq, PartialEq)]
52pub struct SecretKey(pub(crate) Fr);
53
54impl SecretKey {
55 to_fixed_length_bytes_impl!(SecretKey, Fr, FR_COMPRESSED_SIZE, FR_COMPRESSED_SIZE);
56
57 pub fn validate(&self) -> Result<(), BBSError> {
59 if self.0.is_zero() {
62 return Err(BBSErrorKind::MalformedSecretKey.into());
63 }
64 Ok(())
65 }
66}
67
68default_zero_impl!(SecretKey, Fr);
69from_impl!(SecretKey, Fr, FR_COMPRESSED_SIZE);
70display_impl!(SecretKey);
71serdes_impl!(SecretKey);
72hash_elem_impl!(SecretKey, |data| { generate_secret_key(Some(data)) });
73random_elem_impl!(SecretKey, { generate_secret_key(None) });
74
75#[cfg(feature = "wasm")]
76wasm_slice_impl!(SecretKey);
77
78impl Zeroize for SecretKey {
79 fn zeroize(&mut self) {
80 self.0.zeroize();
81 }
82}
83
84impl Drop for SecretKey {
85 fn drop(&mut self) {
86 self.0.zeroize();
87 }
88}
89
90#[derive(Clone, Debug, PartialEq, Eq)]
94pub struct PublicKey {
95 pub h0: GeneratorG1,
97 pub h: Vec<GeneratorG1>,
99 pub w: GeneratorG2,
101}
102
103impl PublicKey {
104 pub fn message_count(&self) -> usize {
106 self.h.len()
107 }
108
109 pub(crate) fn to_bytes(&self, compressed: bool) -> Vec<u8> {
111 let mut out = Vec::new();
112 self.w.0.serialize(&mut out, compressed).unwrap();
113 self.h0.0.serialize(&mut out, compressed).unwrap();
114 out.extend_from_slice(&(self.h.len() as u32).to_be_bytes());
115 for p in &self.h {
116 p.0.serialize(&mut out, compressed).unwrap();
117 }
118 out
119 }
120
121 pub(crate) fn from_bytes(
123 data: &[u8],
124 g1_size: usize,
125 compressed: bool,
126 ) -> Result<Self, BBSError> {
127 if (data.len() - 4) % g1_size != 0 {
128 return Err(BBSErrorKind::MalformedPublicKey.into());
129 }
130 let mut c = Cursor::new(data);
131 let w = GeneratorG2(G2::deserialize(&mut c, compressed)?);
132 let h0 = GeneratorG1(G1::deserialize(&mut c, compressed)?);
133
134 let mut h_bytes = [0u8; 4];
135 c.read_exact(&mut h_bytes).unwrap();
136
137 let h_size = u32::from_be_bytes(h_bytes) as usize;
138 let mut h = Vec::with_capacity(h_size);
139 for _ in 0..h_size {
140 let p = GeneratorG1(G1::deserialize(&mut c, compressed)?);
141 h.push(p);
142 }
143 let pk = Self { w, h0, h };
144 pk.validate()?;
145 Ok(pk)
146 }
147
148 pub fn validate(&self) -> Result<(), BBSError> {
150 if self.h0.0.is_zero() || self.w.0.is_zero() || self.h.iter().any(|v| v.0.is_zero()) {
151 Err(BBSError::from_kind(BBSErrorKind::MalformedPublicKey))
152 } else {
153 Ok(())
154 }
155 }
156}
157
158impl ToVariableLengthBytes for PublicKey {
159 type Output = PublicKey;
160 type Error = BBSError;
161
162 fn to_bytes_compressed_form(&self) -> Vec<u8> {
163 self.to_bytes(true)
164 }
165
166 fn from_bytes_compressed_form<I: AsRef<[u8]>>(data: I) -> Result<Self::Output, Self::Error> {
167 Self::from_bytes(data.as_ref(), G1_COMPRESSED_SIZE, true)
168 }
169
170 fn to_bytes_uncompressed_form(&self) -> Vec<u8> {
171 self.to_bytes(false)
172 }
173
174 fn from_bytes_uncompressed_form<I: AsRef<[u8]>>(data: I) -> Result<Self::Output, Self::Error> {
175 Self::from_bytes(data.as_ref(), G1_UNCOMPRESSED_SIZE, false)
176 }
177}
178
179impl Default for PublicKey {
180 fn default() -> Self {
181 Self {
182 h0: GeneratorG1::default(),
183 h: Vec::new(),
184 w: GeneratorG2::default(),
185 }
186 }
187}
188
189try_from_impl!(PublicKey, BBSError);
190display_impl!(PublicKey);
191serdes_impl!(PublicKey);
192#[cfg(feature = "wasm")]
193wasm_slice_impl!(PublicKey);
194
195pub const DETERMINISTIC_PUBLIC_KEY_COMPRESSED_SIZE: usize = G2_COMPRESSED_SIZE;
197
198#[derive(Clone, Copy, Debug, PartialEq, Eq)]
201pub struct DeterministicPublicKey(pub(crate) G2);
202
203impl DeterministicPublicKey {
204 to_fixed_length_bytes_impl!(
205 DeterministicPublicKey,
206 G2,
207 G2_COMPRESSED_SIZE,
208 G2_UNCOMPRESSED_SIZE
209 );
210}
211
212default_zero_impl!(DeterministicPublicKey, G2);
213as_ref_impl!(DeterministicPublicKey, G2);
214from_impl!(
215 DeterministicPublicKey,
216 G2,
217 G2_COMPRESSED_SIZE,
218 G2_UNCOMPRESSED_SIZE
219);
220display_impl!(DeterministicPublicKey);
221serdes_impl!(DeterministicPublicKey);
222hash_elem_impl!(DeterministicPublicKey, |data| {
223 DeterministicPublicKey(hash_to_g2(data))
224});
225
226impl DeterministicPublicKey {
227 pub fn new(option: Option<KeyGenOption>) -> Result<(Self, SecretKey), BBSError> {
229 let secret = match option {
230 Some(ref o) => match o {
231 KeyGenOption::UseSeed(ref v) => generate_secret_key(Some(v)),
232 KeyGenOption::FromSecretKey(ref sk) => sk.clone(),
233 },
234 None => generate_secret_key(None),
235 };
236
237 secret.validate()?;
238 let mut w = G2::one();
239 w.mul_assign(secret.0);
240 Ok((Self(w), secret))
241 }
242
243 pub fn to_public_key(&self, message_count: usize) -> Result<PublicKey, BBSError> {
248 if message_count == 0 {
249 return Err(BBSErrorKind::KeyGenError.into());
250 }
251 let mc_bytes = (message_count as u32).to_be_bytes();
252 let mut data = Vec::with_capacity(10 + G2_UNCOMPRESSED_SIZE);
253 self.0.serialize(&mut data, false)?;
254 data.push(0u8);
256 let offset = data.len();
257 data.push(0u8);
259 data.push(0u8);
260 data.push(0u8);
261 data.push(0u8);
262 let end = data.len();
263 data.push(0u8);
265 data.extend_from_slice(&mc_bytes[..]);
267
268 let gen_count: Vec<usize> = (0..=message_count).collect();
269
270 #[cfg(feature = "rayon")]
271 let temp_iter = gen_count.par_iter();
272 #[cfg(not(feature = "rayon"))]
273 let temp_iter = gen_count.iter();
274
275 let h = temp_iter
276 .map(|i| {
277 let mut temp = data.clone();
278 let ii = *i as u32;
279 temp[offset..end].copy_from_slice(&(ii.to_be_bytes())[..]);
280 GeneratorG1::hash(temp)
281 })
282 .collect::<Vec<GeneratorG1>>();
283
284 Ok(PublicKey {
285 w: GeneratorG2(self.0),
286 h0: h[0],
287 h: h[1..].to_vec(),
288 })
289 }
290}
291
292#[cfg(feature = "wasm")]
293wasm_slice_impl!(DeterministicPublicKey);
294
295pub fn generate(message_count: usize) -> Result<(PublicKey, SecretKey), BBSError> {
297 if message_count == 0 {
298 return Err(BBSError::from_kind(BBSErrorKind::KeyGenError));
299 }
300 let secret = generate_secret_key(None);
301
302 let mut w = G2::one();
303 w.mul_assign(secret.0);
304 let gen_count: Vec<usize> = (0..=message_count).collect();
305
306 #[cfg(feature = "rayon")]
307 let temp_iter = gen_count.par_iter();
308 #[cfg(not(feature = "rayon"))]
309 let temp_iter = gen_count.iter();
310
311 let h = temp_iter
312 .map(|_| {
313 let mut rng = thread_rng();
314 let mut seed = [0u8; 32];
315 rng.fill_bytes(&mut seed);
316 GeneratorG1::hash(seed)
317 })
318 .collect::<Vec<GeneratorG1>>();
319 Ok((
320 PublicKey {
321 w: GeneratorG2(w),
322 h0: h[0],
323 h: h[1..].to_vec(),
324 },
325 secret,
326 ))
327}
328
329fn generate_secret_key(ikm: Option<&[u8]>) -> SecretKey {
332 let salt = b"BBS-SIG-KEYGEN-SALT-";
333 let info = [0u8, FR_UNCOMPRESSED_SIZE as u8]; let ikm = match ikm {
335 Some(v) => {
336 let mut t = vec![0u8; v.len() + 1];
337 t[..v.len()].copy_from_slice(v);
338 t
339 }
340 None => {
341 let mut bytes = vec![0u8; FR_COMPRESSED_SIZE + 1];
342 thread_rng().fill_bytes(bytes.as_mut_slice());
343 bytes[FR_COMPRESSED_SIZE] = 0;
344 bytes
345 }
346 };
347 let mut okm = [0u8; FR_UNCOMPRESSED_SIZE];
348 let h = hkdf::Hkdf::<Blake2b>::new(Some(&salt[..]), &ikm);
349 h.expand(&info[..], &mut okm).unwrap();
350 SecretKey(Fr::from_okm(GenericArray::from_slice(&okm[..])))
351}
352
353#[cfg(test)]
354mod tests {
355 use super::*;
356
357 #[test]
358 fn key_generate() {
359 let res = generate(0);
360 assert!(res.is_err());
361 let (public_key, _) = generate(1).unwrap();
363 let bytes = public_key.to_bytes_uncompressed_form();
364 assert_eq!(
365 bytes.len(),
366 G1_UNCOMPRESSED_SIZE * 2 + 4 + G2_UNCOMPRESSED_SIZE
367 );
368
369 let (public_key, _) = generate(5).unwrap();
370 assert_eq!(public_key.message_count(), 5);
371 assert!(public_key.validate().is_ok());
373 let bytes = public_key.to_bytes_uncompressed_form();
374 assert_eq!(
375 bytes.len(),
376 G1_UNCOMPRESSED_SIZE * 6 + 4 + G2_UNCOMPRESSED_SIZE
377 );
378 let public_key_2 = PublicKey::from_bytes_uncompressed_form(bytes.as_slice()).unwrap();
380 assert_eq!(public_key_2, public_key);
381
382 let bytes = public_key.to_bytes_compressed_form();
383 assert_eq!(bytes.len(), G1_COMPRESSED_SIZE * 6 + 4 + G2_COMPRESSED_SIZE);
384 let public_key_3 = PublicKey::from_bytes_compressed_form(bytes.as_slice());
385 assert!(public_key_3.is_ok());
386 assert_eq!(public_key_3.unwrap(), public_key);
387 }
388
389 #[test]
390 fn key_conversion() {
391 let (dpk, _) = DeterministicPublicKey::new(None).unwrap();
392 let res = dpk.to_public_key(5);
393
394 assert!(res.is_ok());
395
396 let pk = res.unwrap();
397 assert_eq!(pk.message_count(), 5);
398
399 for i in 0..pk.h.len() {
400 assert_ne!(pk.h0, pk.h[i], "h[0] == h[{}]", i + 1);
401
402 for j in (i + 1)..pk.h.len() {
403 assert_ne!(pk.h[i], pk.h[j], "h[{}] == h[{}]", i + 1, j + 1);
404 }
405 }
406
407 let res = dpk.to_public_key(0);
408
409 assert!(res.is_err());
410 }
411
412 #[test]
413 fn key_from_seed() {
414 let seed = vec![0u8; 32];
415 let (dpk, sk) = DeterministicPublicKey::new(Some(KeyGenOption::UseSeed(seed))).unwrap();
416
417 assert_eq!("a171467362a8fbbc444889efc39e53a5e683ec85fbed19aa1fd89edb5cdb9751871b4db568d8476892f0b6444ca854b50a1c354388c17055a6b8a9d8d5a647b25d41055ce73fb57e158394aea51a9c824b726f258f3e97a90723cc753a459eec", hex::encode(&dpk.to_bytes_compressed_form()[..]));
418 assert_eq!(
419 "0eb25c421350947e8c99faeaee643d64f9e01c568467e5de41050cc4190e8db8",
420 hex::encode(&sk.to_bytes_compressed_form()[..])
421 );
422
423 let seed = vec![1u8; 24];
424 let (dpk, sk) = DeterministicPublicKey::new(Some(KeyGenOption::UseSeed(seed))).unwrap();
425
426 assert_eq!("8dae8c4d40a8ec909e0d5c8541fc0edcfd46d302078edd246ea626853d5376d0a789481abd39ddba5e5145b950a580781802f6c7e70b24f492a1bd4d8edd596e0413fb88c9664bcca65e77460b8cf46680b4f689f28a2731f39891cdb96229c4", hex::encode(&dpk.to_bytes_compressed_form()[..]));
427 assert_eq!(
428 "3ac2bb3f5bfe0db27d5da9842ddb750326f7094d7aeeed78d474862f233f2948",
429 hex::encode(&sk.to_bytes_compressed_form()[..])
430 );
431 }
432
433 #[test]
434 fn key_compression() {
435 let (pk, sk) = generate(3).unwrap();
436
437 assert_eq!(292, pk.to_bytes_compressed_form().len());
438 assert_eq!(FR_COMPRESSED_SIZE, sk.to_bytes_compressed_form().len());
439
440 let (dpk, sk) = DeterministicPublicKey::new(Some(KeyGenOption::FromSecretKey(sk))).unwrap();
441 assert_eq!(96, dpk.to_bytes_compressed_form().len());
442
443 let res = PublicKey::from_bytes_compressed_form(pk.to_bytes_compressed_form());
444 assert!(res.is_ok());
445
446 assert!(res.unwrap().to_bytes_compressed_form() == pk.to_bytes_compressed_form());
447
448 let dpk1 = DeterministicPublicKey::from(dpk.to_bytes_compressed_form());
449 assert!(&dpk1.to_bytes_compressed_form()[..] == &dpk.to_bytes_compressed_form()[..]);
450
451 let sk1 = SecretKey::from(sk.to_bytes_compressed_form());
452 assert!(&sk1.to_bytes_compressed_form()[..] == &sk.to_bytes_compressed_form()[..]);
453 }
454}