1use crate::errors::prelude::*;
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
58default_zero_impl!(SecretKey, Fr);
59from_impl!(SecretKey, Fr, FR_COMPRESSED_SIZE);
60display_impl!(SecretKey);
61serdes_impl!(SecretKey);
62hash_elem_impl!(SecretKey, |data| { generate_secret_key(Some(data)) });
63random_elem_impl!(SecretKey, { generate_secret_key(None) });
64
65#[cfg(feature = "wasm")]
66wasm_slice_impl!(SecretKey);
67
68impl Zeroize for SecretKey {
69 fn zeroize(&mut self) {
70 self.0.zeroize();
71 }
72}
73
74impl Drop for SecretKey {
75 fn drop(&mut self) {
76 self.0.zeroize();
77 }
78}
79
80#[derive(Clone, Debug, PartialEq, Eq)]
84pub struct PublicKey {
85 pub h0: GeneratorG1,
87 pub h: Vec<GeneratorG1>,
89 pub w: GeneratorG2,
91}
92
93impl PublicKey {
94 pub fn message_count(&self) -> usize {
96 self.h.len()
97 }
98
99 pub(crate) fn to_bytes(&self, compressed: bool) -> Vec<u8> {
101 let mut out = Vec::new();
102 self.w.0.serialize(&mut out, compressed).unwrap();
103 self.h0.0.serialize(&mut out, compressed).unwrap();
104 out.extend_from_slice(&(self.h.len() as u32).to_be_bytes());
105 for p in &self.h {
106 p.0.serialize(&mut out, compressed).unwrap();
107 }
108 out
109 }
110
111 pub(crate) fn from_bytes(
113 data: &[u8],
114 g1_size: usize,
115 compressed: bool,
116 ) -> Result<Self, BBSError> {
117 if (data.len() - 4) % g1_size != 0 {
118 return Err(BBSErrorKind::MalformedPublicKey.into());
119 }
120 let mut c = Cursor::new(data);
121 let w = GeneratorG2(G2::deserialize(&mut c, compressed)?);
122 let h0 = GeneratorG1(G1::deserialize(&mut c, compressed)?);
123
124 let mut h_bytes = [0u8; 4];
125 c.read_exact(&mut h_bytes).unwrap();
126
127 let h_size = u32::from_be_bytes(h_bytes) as usize;
128 let mut h = Vec::with_capacity(h_size);
129 for _ in 0..h_size {
130 let p = GeneratorG1(G1::deserialize(&mut c, compressed)?);
131 h.push(p);
132 }
133 let pk = Self { w, h0, h };
134 pk.validate()?;
135 Ok(pk)
136 }
137
138 pub fn validate(&self) -> Result<(), BBSError> {
140 if self.h0.0.is_zero() || self.w.0.is_zero() || self.h.iter().any(|v| v.0.is_zero()) {
141 Err(BBSError::from_kind(BBSErrorKind::MalformedPublicKey))
142 } else {
143 Ok(())
144 }
145 }
146}
147
148impl ToVariableLengthBytes for PublicKey {
149 type Output = PublicKey;
150 type Error = BBSError;
151
152 fn to_bytes_compressed_form(&self) -> Vec<u8> {
153 self.to_bytes(true)
154 }
155
156 fn from_bytes_compressed_form<I: AsRef<[u8]>>(data: I) -> Result<Self::Output, Self::Error> {
157 Self::from_bytes(data.as_ref(), G1_COMPRESSED_SIZE, true)
158 }
159
160 fn to_bytes_uncompressed_form(&self) -> Vec<u8> {
161 self.to_bytes(false)
162 }
163
164 fn from_bytes_uncompressed_form<I: AsRef<[u8]>>(data: I) -> Result<Self::Output, Self::Error> {
165 Self::from_bytes(data.as_ref(), G1_UNCOMPRESSED_SIZE, false)
166 }
167}
168
169impl Default for PublicKey {
170 fn default() -> Self {
171 Self {
172 h0: GeneratorG1::default(),
173 h: Vec::new(),
174 w: GeneratorG2::default(),
175 }
176 }
177}
178
179try_from_impl!(PublicKey, BBSError);
180display_impl!(PublicKey);
181serdes_impl!(PublicKey);
182#[cfg(feature = "wasm")]
183wasm_slice_impl!(PublicKey);
184
185pub const DETERMINISTIC_PUBLIC_KEY_COMPRESSED_SIZE: usize = G2_COMPRESSED_SIZE;
187
188#[derive(Clone, Copy, Debug, PartialEq, Eq)]
191pub struct DeterministicPublicKey(pub(crate) G2);
192
193impl DeterministicPublicKey {
194 to_fixed_length_bytes_impl!(
195 DeterministicPublicKey,
196 G2,
197 G2_COMPRESSED_SIZE,
198 G2_UNCOMPRESSED_SIZE
199 );
200}
201
202default_zero_impl!(DeterministicPublicKey, G2);
203as_ref_impl!(DeterministicPublicKey, G2);
204from_impl!(
205 DeterministicPublicKey,
206 G2,
207 G2_COMPRESSED_SIZE,
208 G2_UNCOMPRESSED_SIZE
209);
210display_impl!(DeterministicPublicKey);
211serdes_impl!(DeterministicPublicKey);
212hash_elem_impl!(DeterministicPublicKey, |data| {
213 DeterministicPublicKey(hash_to_g2(data))
214});
215
216impl DeterministicPublicKey {
217 pub fn new(option: Option<KeyGenOption>) -> (Self, SecretKey) {
219 let secret = match option {
220 Some(ref o) => match o {
221 KeyGenOption::UseSeed(ref v) => generate_secret_key(Some(v)),
222 KeyGenOption::FromSecretKey(ref sk) => sk.clone(),
223 },
224 None => generate_secret_key(None),
225 };
226 let mut w = G2::one();
227 w.mul_assign(secret.0.clone());
228 (Self(w), secret)
229 }
230
231 pub fn to_public_key(&self, message_count: usize) -> Result<PublicKey, BBSError> {
236 if message_count == 0 {
237 return Err(BBSErrorKind::KeyGenError.into());
238 }
239 let mc_bytes = (message_count as u32).to_be_bytes();
240 let mut data = Vec::with_capacity(9 + G2_UNCOMPRESSED_SIZE);
241 self.0.serialize(&mut data, false)?;
242 data.push(0u8);
244 let offset = data.len();
245 data.push(0u8);
247 data.push(0u8);
248 data.push(0u8);
249 data.push(0u8);
250 let end = data.len();
251 data.push(0u8);
253 data.extend_from_slice(&mc_bytes[..]);
255
256 let gen_count: Vec<usize> = (0..=message_count).collect();
257
258 #[cfg(feature = "rayon")]
259 let temp_iter = gen_count.par_iter();
260 #[cfg(not(feature = "rayon"))]
261 let temp_iter = gen_count.iter();
262
263 let h = temp_iter
264 .map(|i| {
265 let mut temp = data.clone();
266 let ii = *i as u32;
267 temp[offset..end].copy_from_slice(&(ii.to_be_bytes())[..]);
268 GeneratorG1::hash(temp)
269 })
270 .collect::<Vec<GeneratorG1>>();
271
272 Ok(PublicKey {
273 w: GeneratorG2(self.0),
274 h0: h[0],
275 h: h[1..].to_vec(),
276 })
277 }
278}
279
280#[cfg(feature = "wasm")]
281wasm_slice_impl!(DeterministicPublicKey);
282
283pub fn generate(message_count: usize) -> Result<(PublicKey, SecretKey), BBSError> {
285 if message_count == 0 {
286 return Err(BBSError::from_kind(BBSErrorKind::KeyGenError));
287 }
288 let secret = generate_secret_key(None);
289
290 let mut w = G2::one();
291 w.mul_assign(secret.0.clone());
292 let gen_count: Vec<usize> = (0..=message_count).collect();
293
294 #[cfg(feature = "rayon")]
295 let temp_iter = gen_count.par_iter();
296 #[cfg(not(feature = "rayon"))]
297 let temp_iter = gen_count.iter();
298
299 let h = temp_iter
300 .map(|_| {
301 let mut rng = thread_rng();
302 let mut seed = [0u8; 32];
303 rng.fill_bytes(&mut seed);
304 GeneratorG1::hash(seed)
305 })
306 .collect::<Vec<GeneratorG1>>();
307 Ok((
308 PublicKey {
309 w: GeneratorG2(w),
310 h0: h[0],
311 h: h[1..].to_vec(),
312 },
313 secret,
314 ))
315}
316
317fn generate_secret_key(ikm: Option<&[u8]>) -> SecretKey {
320 let salt = b"BBS-SIG-KEYGEN-SALT-";
321 let info = [0u8, FR_UNCOMPRESSED_SIZE as u8]; let ikm = match ikm {
323 Some(v) => {
324 let mut t = vec![0u8; v.len() + 1];
325 t[..v.len()].copy_from_slice(v);
326 t
327 }
328 None => {
329 let mut bytes = vec![0u8; FR_COMPRESSED_SIZE + 1];
330 thread_rng().fill_bytes(bytes.as_mut_slice());
331 bytes[FR_COMPRESSED_SIZE] = 0;
332 bytes
333 }
334 };
335 let mut okm = [0u8; FR_UNCOMPRESSED_SIZE];
336 let h = hkdf::Hkdf::<Blake2b>::new(Some(&salt[..]), &ikm);
337 h.expand(&info[..], &mut okm).unwrap();
338 SecretKey(Fr::from_okm(GenericArray::from_slice(&okm[..])))
339}
340
341#[cfg(test)]
342mod tests {
343 use super::*;
344
345 #[test]
346 fn key_generate() {
347 let res = generate(0);
348 assert!(res.is_err());
349 let (public_key, _) = generate(1).unwrap();
351 let bytes = public_key.to_bytes_uncompressed_form();
352 assert_eq!(
353 bytes.len(),
354 G1_UNCOMPRESSED_SIZE * 2 + 4 + G2_UNCOMPRESSED_SIZE
355 );
356
357 let (public_key, _) = generate(5).unwrap();
358 assert_eq!(public_key.message_count(), 5);
359 assert!(public_key.validate().is_ok());
361 let bytes = public_key.to_bytes_uncompressed_form();
362 assert_eq!(
363 bytes.len(),
364 G1_UNCOMPRESSED_SIZE * 6 + 4 + G2_UNCOMPRESSED_SIZE
365 );
366 let public_key_2 = PublicKey::from_bytes_uncompressed_form(bytes.as_slice()).unwrap();
368 assert_eq!(public_key_2, public_key);
369
370 let bytes = public_key.to_bytes_compressed_form();
371 assert_eq!(bytes.len(), G1_COMPRESSED_SIZE * 6 + 4 + G2_COMPRESSED_SIZE);
372 let public_key_3 = PublicKey::from_bytes_compressed_form(bytes.as_slice());
373 assert!(public_key_3.is_ok());
374 assert_eq!(public_key_3.unwrap(), public_key);
375 }
376
377 #[test]
378 fn key_conversion() {
379 let (dpk, _) = DeterministicPublicKey::new(None);
380 let res = dpk.to_public_key(5);
381
382 assert!(res.is_ok());
383
384 let pk = res.unwrap();
385 assert_eq!(pk.message_count(), 5);
386
387 for i in 0..pk.h.len() {
388 assert_ne!(pk.h0, pk.h[i], "h[0] == h[{}]", i + 1);
389
390 for j in (i + 1)..pk.h.len() {
391 assert_ne!(pk.h[i], pk.h[j], "h[{}] == h[{}]", i + 1, j + 1);
392 }
393 }
394
395 let res = dpk.to_public_key(0);
396
397 assert!(res.is_err());
398 }
399
400 #[test]
401 fn key_from_seed() {
402 let seed = vec![0u8; 32];
403 let (dpk, sk) = DeterministicPublicKey::new(Some(KeyGenOption::UseSeed(seed)));
404
405 assert_eq!("a171467362a8fbbc444889efc39e53a5e683ec85fbed19aa1fd89edb5cdb9751871b4db568d8476892f0b6444ca854b50a1c354388c17055a6b8a9d8d5a647b25d41055ce73fb57e158394aea51a9c824b726f258f3e97a90723cc753a459eec", hex::encode(&dpk.to_bytes_compressed_form()[..]));
406 assert_eq!(
407 "0eb25c421350947e8c99faeaee643d64f9e01c568467e5de41050cc4190e8db8",
408 hex::encode(&sk.to_bytes_compressed_form()[..])
409 );
410
411 let seed = vec![1u8; 24];
412 let (dpk, sk) = DeterministicPublicKey::new(Some(KeyGenOption::UseSeed(seed)));
413
414 assert_eq!("8dae8c4d40a8ec909e0d5c8541fc0edcfd46d302078edd246ea626853d5376d0a789481abd39ddba5e5145b950a580781802f6c7e70b24f492a1bd4d8edd596e0413fb88c9664bcca65e77460b8cf46680b4f689f28a2731f39891cdb96229c4", hex::encode(&dpk.to_bytes_compressed_form()[..]));
415 assert_eq!(
416 "3ac2bb3f5bfe0db27d5da9842ddb750326f7094d7aeeed78d474862f233f2948",
417 hex::encode(&sk.to_bytes_compressed_form()[..])
418 );
419 }
420
421 #[test]
422 fn key_compression() {
423 let (pk, sk) = generate(3).unwrap();
424
425 assert_eq!(292, pk.to_bytes_compressed_form().len());
426 assert_eq!(FR_COMPRESSED_SIZE, sk.to_bytes_compressed_form().len());
427
428 let (dpk, sk) = DeterministicPublicKey::new(Some(KeyGenOption::FromSecretKey(sk)));
429 assert_eq!(96, dpk.to_bytes_compressed_form().len());
430
431 let res = PublicKey::from_bytes_compressed_form(pk.to_bytes_compressed_form());
432 assert!(res.is_ok());
433
434 assert!(res.unwrap().to_bytes_compressed_form() == pk.to_bytes_compressed_form());
435
436 let dpk1 = DeterministicPublicKey::from(dpk.to_bytes_compressed_form());
437 assert!(&dpk1.to_bytes_compressed_form()[..] == &dpk.to_bytes_compressed_form()[..]);
438
439 let sk1 = SecretKey::from(sk.to_bytes_compressed_form());
440 assert!(&sk1.to_bytes_compressed_form()[..] == &sk.to_bytes_compressed_form()[..]);
441 }
442}