Skip to main content

indy_crypto/bls/
mod.rs

1use errors::prelude::*;
2use pair::{GroupOrderElement, PointG2, PointG1, Pair};
3
4use sha2::{Sha256, Digest};
5use sha3::Keccak256;
6
7/// BLS generator point.
8/// BLS algorithm requires choosing of generator point that must be known to all parties.
9/// The most of BLS methods require generator to be provided.
10#[derive(Debug)]
11pub struct Generator {
12    point: PointG2,
13    bytes: Vec<u8>
14}
15
16impl Generator {
17    /// Creates and returns random generator point that satisfy BLS algorithm requirements.
18    ///
19    /// # Example
20    ///
21    /// ```
22    /// use indy_crypto::bls::Generator;
23    /// Generator::new().unwrap();
24    /// ```
25    pub fn new() -> IndyCryptoResult<Generator> {
26        let point = PointG2::new()?;
27        Ok(Generator {
28            point: point,
29            bytes: point.to_bytes()?
30        })
31    }
32
33    /// Returns BLS generator point bytes representation.
34    ///
35    /// # Example
36    ///
37    /// ```
38    /// use indy_crypto::bls::*;
39    /// let gen = Generator::new().unwrap();
40    /// let gen_bytes = gen.as_bytes();
41    /// assert!(gen_bytes.len() > 0);
42    /// ```
43    pub fn as_bytes(&self) -> &[u8] {
44        self.bytes.as_slice()
45    }
46
47    /// Creates and returns generator point from bytes representation.
48    ///
49    /// # Example
50    ///
51    /// ```
52    /// use indy_crypto::bls::Generator;
53    /// let gen = Generator::new().unwrap();
54    /// let gen_bytes = gen.as_bytes();
55    /// Generator::from_bytes(gen_bytes).unwrap();
56    /// ```
57    pub fn from_bytes(bytes: &[u8]) -> IndyCryptoResult<Generator> {
58        Ok(
59            Generator {
60                point: PointG2::from_bytes(bytes)?,
61                bytes: bytes.to_vec()
62            }
63        )
64    }
65}
66
67/// BLS sign key.
68#[derive(Debug)]
69pub struct SignKey {
70    group_order_element: GroupOrderElement,
71    bytes: Vec<u8>
72}
73
74impl SignKey {
75    /// Creates and returns random (or seeded from seed) BLS sign key algorithm requirements.
76    ///
77    /// # Example
78    ///
79    /// ```
80    /// use indy_crypto::bls::Generator;
81    /// Generator::new().unwrap();
82    /// ```
83    pub fn new(seed: Option<&[u8]>) -> IndyCryptoResult<SignKey> {
84        let group_order_element = match seed {
85            Some(seed) => GroupOrderElement::new_from_seed(seed)?,
86            _ => GroupOrderElement::new()?
87        };
88
89        Ok(SignKey {
90            group_order_element: group_order_element,
91            bytes: group_order_element.to_bytes()?
92        })
93    }
94
95    /// Returns BLS sign key bytes representation.
96    ///
97    /// # Example
98    ///
99    /// ```
100    /// //TODO: Provide an example!
101    /// ```
102    pub fn as_bytes(&self) -> &[u8] {
103        self.bytes.as_slice()
104    }
105
106    /// Creates and returns BLS sign key from bytes representation.
107    ///
108    /// # Example
109    ///
110    /// ```
111    /// //TODO: Provide an example!
112    /// ```
113    pub fn from_bytes(bytes: &[u8]) -> IndyCryptoResult<SignKey> {
114        Ok(
115            SignKey {
116                group_order_element: GroupOrderElement::from_bytes(bytes)?,
117                bytes: bytes.to_vec()
118            }
119        )
120    }
121}
122
123/// BLS verification key.
124#[derive(Debug, Clone)]
125pub struct VerKey {
126    point: PointG2,
127    bytes: Vec<u8>
128}
129
130impl VerKey {
131    /// Creates and returns BLS ver key that corresponds to sign key.
132    ///
133    /// # Example
134    ///
135    /// ```
136    /// use indy_crypto::bls::Generator;
137    /// Generator::new().unwrap();
138    /// ```
139    pub fn new(gen: &Generator, sign_key: &SignKey) -> IndyCryptoResult<VerKey> {
140        let point = gen.point.mul(&sign_key.group_order_element)?;
141
142        Ok(VerKey {
143            point: point,
144            bytes: point.to_bytes()?
145        })
146    }
147
148    /// Returns BLS verification key to bytes representation.
149    ///
150    /// # Example
151    ///
152    /// ```
153    /// //TODO: Provide an example!
154    /// ```
155    pub fn as_bytes(&self) -> &[u8] {
156        self.bytes.as_slice()
157    }
158
159    /// Creates and returns BLS verification key from bytes representation.
160    ///
161    /// # Example
162    ///
163    /// ```
164    /// //TODO: Provide an example!
165    /// ```
166    pub fn from_bytes(bytes: &[u8]) -> IndyCryptoResult<VerKey> {
167        let point = PointG2::from_bytes(bytes)?;
168        Ok(
169            VerKey {
170                point,
171                bytes: bytes.to_vec()
172            }
173        )
174    }
175}
176
177
178/// Proof of possession for BLS verification key.
179#[derive(Debug, Clone)]
180pub struct ProofOfPossession {
181    point: PointG1,
182    bytes: Vec<u8>
183}
184
185impl ProofOfPossession {
186    /// Creates and returns BLS proof of possession that corresponds to ver key.
187    ///
188    /// # Arguments
189    ///
190    /// * `ver_key` - Ver key
191    /// * `sign_key` - Sign key
192    ///
193    /// # Example
194    ///
195    /// ```
196    /// use indy_crypto::bls::{Generator, SignKey, VerKey, ProofOfPossession};
197    /// let gen = Generator::new().unwrap();
198    /// let sign_key = SignKey::new(None).unwrap();
199    /// let ver_key = VerKey::new(&gen, &sign_key).unwrap();
200    /// ProofOfPossession::new(&ver_key, &sign_key).unwrap();
201    /// ```
202    pub fn new(ver_key: &VerKey, sign_key: &SignKey) -> IndyCryptoResult<ProofOfPossession> {
203        let point = Bls::_gen_signature(&ver_key.bytes, sign_key, Keccak256::default())?;
204
205        Ok(ProofOfPossession {
206            point: point,
207            bytes: point.to_bytes()?
208        })
209    }
210
211    /// Returns BLS proof of possession to bytes representation.
212    ///
213    /// # Example
214    ///
215    /// ```
216    /// //TODO: Provide an example!
217    /// ```
218    pub fn as_bytes(&self) -> &[u8] {
219        self.bytes.as_slice()
220    }
221
222    /// Creates and returns BLS proof of possession from bytes representation.
223    ///
224    /// # Example
225    ///
226    /// ```
227    /// //TODO: Provide an example!
228    /// ```
229    pub fn from_bytes(bytes: &[u8]) -> IndyCryptoResult<ProofOfPossession> {
230        let point = PointG1::from_bytes(bytes)?;
231        Ok(ProofOfPossession {
232            point,
233            bytes: bytes.to_vec()
234        })
235    }
236}
237
238
239/// BLS signature.
240#[derive(Debug)]
241pub struct Signature {
242    point: PointG1,
243    bytes: Vec<u8>,
244}
245
246impl Signature {
247    /// Returns BLS signature to bytes representation.
248    ///
249    /// # Example
250    ///
251    /// ```
252    /// //TODO: Provide an example!
253    /// ```
254    pub fn as_bytes(&self) -> &[u8] {
255        self.bytes.as_slice()
256    }
257
258    /// Creates and returns BLS signature from bytes representation.
259    ///
260    /// # Example
261    ///
262    /// ```
263    /// //TODO: Provide an example!
264    /// ```
265    pub fn from_bytes(bytes: &[u8]) -> IndyCryptoResult<Signature> {
266        let point = PointG1::from_bytes(bytes)?;
267        Ok(
268            Signature {
269                point,
270                bytes: bytes.to_vec()
271            }
272        )
273    }
274}
275
276/// BLS multi signature.
277#[derive(Debug)]
278pub struct MultiSignature {
279    point: PointG1,
280    bytes: Vec<u8>,
281}
282
283impl MultiSignature {
284    /// Creates and returns multi signature for provided list of signatures.
285   ///
286   /// # Arguments
287   ///
288   /// * `signatures` - List of signatures
289   ///
290   /// # Example
291   ///
292   /// ```
293   /// use indy_crypto::bls::*;
294   /// let sign_key1 = SignKey::new(None).unwrap();
295   /// let sign_key2 = SignKey::new(None).unwrap();
296   ///
297   /// let message = vec![1, 2, 3, 4, 5];
298   ///
299   /// let signature1 = Bls::sign(&message, &sign_key1).unwrap();
300   /// let signature2 = Bls::sign(&message, &sign_key2).unwrap();
301   ///
302   /// let signatures = vec![
303   ///    &signature1,
304   ///    &signature2
305   /// ];
306   ///
307   /// MultiSignature::new(&signatures).unwrap();
308   /// ```
309    pub fn new(signatures: &[&Signature]) -> IndyCryptoResult<MultiSignature> {
310        let mut point = PointG1::new_inf()?;
311
312        for signature in signatures {
313            point = point.add(&signature.point)?;
314        }
315
316        Ok(MultiSignature {
317            point,
318            bytes: point.to_bytes()?
319        })
320    }
321
322    /// Returns BLS multi signature bytes representation.
323    ///
324    /// # Example
325    ///
326    /// ```
327    /// //TODO: Provide an example!
328    /// ```
329    pub fn as_bytes(&self) -> &[u8] {
330        self.bytes.as_slice()
331    }
332
333    /// Creates and returns BLS multi signature from bytes representation.
334    ///
335    /// # Example
336    ///
337    /// ```
338    /// //TODO: Provide an example!
339    /// ```
340    pub fn from_bytes(bytes: &[u8]) -> IndyCryptoResult<MultiSignature> {
341        let point = PointG1::from_bytes(bytes)?;
342        Ok(
343            MultiSignature {
344                point: point,
345                bytes: bytes.to_vec()
346            }
347        )
348    }
349}
350
351pub struct Bls {}
352
353impl Bls {
354    /// Signs the message and returns signature.
355    ///
356    /// # Arguments
357    ///
358    /// * `message` - Message to sign
359    /// * `sign_key` - Sign key
360    ///
361    /// # Example
362    ///
363    /// ```
364    /// use indy_crypto::bls::*;
365    /// let message = vec![1, 2, 3, 4, 5];
366    /// let sign_key = SignKey::new(None).unwrap();
367    /// Bls::sign(&message, &sign_key).unwrap();
368    /// ```
369    pub fn sign(message: &[u8], sign_key: &SignKey) -> IndyCryptoResult<Signature> {
370        let point = Bls::_gen_signature(message, sign_key, Sha256::default())?;
371
372        Ok(Signature {
373            point,
374            bytes: point.to_bytes()?
375        })
376    }
377
378    /// Verifies the message signature and returns true - if signature valid or false otherwise.
379    ///
380    /// # Arguments
381    ///
382    /// * `signature` - Signature to verify
383    /// * `message` - Message to verify
384    /// * `ver_key` - Verification key
385    /// * `gen` - Generator point
386    ///
387    /// # Example
388    ///
389    /// ```
390    /// use indy_crypto::bls::*;
391    /// let gen = Generator::new().unwrap();
392    /// let sign_key = SignKey::new(None).unwrap();
393    /// let ver_key = VerKey::new(&gen, &sign_key).unwrap();
394    /// let message = vec![1, 2, 3, 4, 5];
395    /// let signature = Bls::sign(&message, &sign_key).unwrap();
396    ///
397    /// let valid = Bls::verify(&signature, &message, &ver_key, &gen).unwrap();
398    /// assert!(valid);
399    /// ```
400    pub fn verify(signature: &Signature, message: &[u8], ver_key: &VerKey, gen: &Generator) -> IndyCryptoResult<bool> {
401        Bls::_verify_signature(&signature.point, message, &ver_key.point, gen, Sha256::default())
402    }
403
404    /// Verifies the proof of possession and returns true - if valid or false otherwise.
405    ///
406    /// # Arguments
407    ///
408    /// * `pop` - Proof of possession
409    /// * `ver_key` - Verification key
410    /// * `gen` - Generator point
411    ///
412    /// # Example
413    ///
414    /// ```
415    /// use indy_crypto::bls::*;
416    /// let gen = Generator::new().unwrap();
417    /// let sign_key = SignKey::new(None).unwrap();
418    /// let ver_key = VerKey::new(&gen, &sign_key).unwrap();
419    /// let pop = ProofOfPossession::new(&ver_key, &sign_key).unwrap();
420    ///
421    /// let valid = Bls::verify_proof_of_posession(&pop, &ver_key, &gen).unwrap();
422    /// assert!(valid);
423    /// ```
424    pub fn verify_proof_of_posession(pop: &ProofOfPossession, ver_key: &VerKey, gen: &Generator) -> IndyCryptoResult<bool> {
425        Bls::_verify_signature(&pop.point, &ver_key.bytes, &ver_key.point, gen, Keccak256::default())
426    }
427
428    /// Verifies the message multi signature and returns true - if signature valid or false otherwise.
429    ///
430    /// # Arguments
431    ///
432    /// * `multi_sig` - Multi signature to verify
433    /// * `message` - Message to verify
434    /// * `ver_keys` - List of verification keys
435    /// * `gen` - Generator point
436    ///
437    /// # Example
438    ///
439    /// ```
440    /// use indy_crypto::bls::*;
441    /// let gen = Generator::new().unwrap();
442    ///
443    /// let sign_key1 = SignKey::new(None).unwrap();
444    /// let ver_key1 = VerKey::new(&gen, &sign_key1).unwrap();
445    /// let sign_key2 = SignKey::new(None).unwrap();
446    /// let ver_key2 = VerKey::new(&gen, &sign_key2).unwrap();
447    ///
448    /// let message = vec![1, 2, 3, 4, 5];
449    ///
450    /// let signature1 = Bls::sign(&message, &sign_key1).unwrap();
451    /// let signature2 = Bls::sign(&message, &sign_key2).unwrap();
452    ///
453    /// let signatures = vec![
454    ///    &signature1,
455    ///    &signature2
456    /// ];
457    ///
458    /// let multi_sig = MultiSignature::new(&signatures).unwrap();
459    ///
460    /// let ver_keys = vec![
461    ///   &ver_key1, &ver_key2
462    /// ];
463    ///
464    /// let valid = Bls::verify_multi_sig(&multi_sig, &message, &ver_keys, &gen).unwrap();
465    /// assert!(valid)
466    /// ```
467    pub fn verify_multi_sig(multi_sig: &MultiSignature, message: &[u8], ver_keys: &[&VerKey], gen: &Generator) -> IndyCryptoResult<bool> {
468        // Since each signer (identified by a Verkey) has signed the same message, the public keys
469        // can be added together to form the aggregated verkey
470        let mut aggregated_verkey = PointG2::new_inf()?;
471        for ver_key in ver_keys {
472            aggregated_verkey = aggregated_verkey.add(&ver_key.point)?;
473        }
474
475        // TODO: Add a new method that takes a message and an aggregated verkey and expose using
476        // the C API. Verifiers can thus cache the aggregated verkey and avoid several EC point additions.
477        // The code below should be moved to such method.
478
479        Bls::_verify_signature(&multi_sig.point, message, &aggregated_verkey, gen, Sha256::default())
480    }
481
482    fn _gen_signature<T>(message: &[u8], sign_key: &SignKey, hasher: T) -> IndyCryptoResult<PointG1> where T: Digest {
483        Bls::_hash(message, hasher)?.mul(&sign_key.group_order_element)
484    }
485
486    pub fn _verify_signature<T>(signature: &PointG1, message: &[u8], ver_key: &PointG2, gen: &Generator, hasher: T) -> IndyCryptoResult<bool> where T: Digest {
487        let h = Bls::_hash(message, hasher)?;
488        Ok(Pair::pair(&signature, &gen.point)?.eq(&Pair::pair(&h, &ver_key)?))
489    }
490
491    fn _hash<T>(message: &[u8], mut hasher: T) -> IndyCryptoResult<PointG1> where T: Digest {
492        hasher.input(message);
493        Ok(PointG1::from_hash(hasher.result().as_slice())?)
494    }
495}
496
497#[cfg(test)]
498mod tests {
499    use super::*;
500
501    #[test]
502    fn generator_new_works() {
503        Generator::new().unwrap();
504    }
505
506    #[test]
507    fn sign_key_new_works() {
508        SignKey::new(None).unwrap();
509    }
510
511    #[test]
512    fn sign_key_new_works_for_seed() {
513        let seed = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 21, 2, 3, 4, 5, 6, 7, 8, 9, 10, 31, 32];
514        SignKey::new(Some(&seed)).unwrap();
515    }
516
517    #[test]
518    fn ver_key_new_works() {
519        let gen = Generator::new().unwrap();
520        let sign_key = SignKey::new(None).unwrap();
521        VerKey::new(&gen, &sign_key).unwrap();
522    }
523
524    #[test]
525    fn pop_new_works() {
526        let gen = Generator::new().unwrap();
527        let sign_key = SignKey::new(None).unwrap();
528        let ver_key = VerKey::new(&gen, &sign_key).unwrap();
529        ProofOfPossession::new(&ver_key, &sign_key).unwrap();
530    }
531
532    #[test]
533    fn bls_sign_works() {
534        let sign_key = SignKey::new(None).unwrap();
535        let message = vec![1, 2, 3, 4, 5];
536
537        Bls::sign(&message, &sign_key).unwrap();
538    }
539
540    #[test]
541    fn multi_signature_new_works() {
542        let message = vec![1, 2, 3, 4, 5];
543
544        let sign_key1 = SignKey::new(None).unwrap();
545        let sign_key2 = SignKey::new(None).unwrap();
546
547        let signature1 = Bls::sign(&message, &sign_key1).unwrap();
548        let signature2 = Bls::sign(&message, &sign_key2).unwrap();
549
550        let signatures = vec![
551            &signature1,
552            &signature2
553        ];
554
555        MultiSignature::new(&signatures).unwrap();
556    }
557
558    #[test]
559    fn verify_works() {
560        let message = vec![1, 2, 3, 4, 5];
561
562        let gen = Generator::new().unwrap();
563        let sign_key = SignKey::new(None).unwrap();
564        let ver_key = VerKey::new(&gen, &sign_key).unwrap();
565        let signature = Bls::sign(&message, &sign_key).unwrap();
566
567        let valid = Bls::verify(&signature, &message, &ver_key, &gen).unwrap();
568        assert!(valid)
569    }
570
571    #[test]
572    fn verify_pop_works() {
573        let gen = Generator::new().unwrap();
574        let sign_key = SignKey::new(None).unwrap();
575        let ver_key = VerKey::new(&gen, &sign_key).unwrap();
576        let pop = ProofOfPossession::new(&ver_key, &sign_key).unwrap();
577
578        let valid = Bls::verify_proof_of_posession(&pop, &ver_key, &gen).unwrap();
579        assert!(valid)
580    }
581
582    #[test]
583    fn verify_works_for_invalid_message() {
584        let message = vec![1, 2, 3, 4, 5];
585        let message_invalid = vec![1, 2, 3, 4, 5, 6];
586
587        let gen = Generator::new().unwrap();
588        let sign_key = SignKey::new(None).unwrap();
589        let ver_key = VerKey::new(&gen, &sign_key).unwrap();
590        let signature = Bls::sign(&message, &sign_key).unwrap();
591
592        let valid = Bls::verify(&signature, &message_invalid, &ver_key, &gen).unwrap();
593        assert!(!valid)
594    }
595
596    #[test]
597    fn verify_works_for_invalid_signature() {
598        let message = vec![1, 2, 3, 4, 5];
599
600        let gen = Generator::new().unwrap();
601        let sign_key = SignKey::new(None).unwrap();
602        let ver_key = VerKey::new(&gen, &SignKey::new(None).unwrap()).unwrap();
603
604        let signature_invalid = Bls::sign(&message, &sign_key).unwrap();
605
606        let valid = Bls::verify(&signature_invalid, &message, &ver_key, &gen).unwrap();
607        assert!(!valid)
608    }
609
610    #[test]
611    fn verify_multi_sig_works() {
612        let message = vec![1, 2, 3, 4, 5];
613
614        let gen = Generator::new().unwrap();
615        let sign_key1 = SignKey::new(None).unwrap();
616        let ver_key1 = VerKey::new(&gen, &sign_key1).unwrap();
617        let sign_key2 = SignKey::new(None).unwrap();
618        let ver_key2 = VerKey::new(&gen, &sign_key2).unwrap();
619
620        let ver_keys = vec![
621            &ver_key1,
622            &ver_key2
623        ];
624
625        let signature1 = Bls::sign(&message, &sign_key1).unwrap();
626        let signature2 = Bls::sign(&message, &sign_key2).unwrap();
627
628        let signatures = vec![
629            &signature1,
630            &signature2
631        ];
632
633        let multi_signature = MultiSignature::new(&signatures).unwrap();
634        let valid = Bls::verify_multi_sig(&multi_signature, &message, &ver_keys, &gen).unwrap();
635
636        assert!(valid)
637    }
638
639    #[test]
640    fn verify_multi_sig_works_for_invalid_message() {
641        let message = vec![1, 2, 3, 4, 5];
642        let message_invalid = vec![1, 2, 3, 4, 5, 6];
643
644        let gen = Generator::new().unwrap();
645        let sign_key1 = SignKey::new(None).unwrap();
646        let ver_key1 = VerKey::new(&gen, &sign_key1).unwrap();
647        let sign_key2 = SignKey::new(None).unwrap();
648        let ver_key2 = VerKey::new(&gen, &sign_key2).unwrap();
649
650        let ver_keys = vec![
651            &ver_key1,
652            &ver_key2
653        ];
654
655        let signature1 = Bls::sign(&message, &sign_key1).unwrap();
656        let signature2 = Bls::sign(&message, &sign_key2).unwrap();
657
658        let signatures = vec![
659            &signature1,
660            &signature2
661        ];
662
663        let multi_signature = MultiSignature::new(&signatures).unwrap();
664        let valid = Bls::verify_multi_sig(&multi_signature, &message_invalid, &ver_keys, &gen).unwrap();
665
666        assert!(!valid)
667    }
668
669    #[test]
670    fn verify_multi_sig_works_for_invalid_signature() {
671        let message = vec![1, 2, 3, 4, 5];
672
673        let gen = Generator::new().unwrap();
674
675        let sign_key1 = SignKey::new(None).unwrap();
676        let ver_key1 = VerKey::new(&gen, &sign_key1).unwrap();
677        let sign_key2 = SignKey::new(None).unwrap();
678        let ver_key2 = VerKey::new(&gen, &SignKey::new(None).unwrap()).unwrap();
679
680        let ver_keys = vec![
681            &ver_key1,
682            &ver_key2
683        ];
684
685        let signature1 = Bls::sign(&message, &sign_key1).unwrap();
686        let signature2 = Bls::sign(&message, &sign_key2).unwrap();
687
688        let signatures = vec![
689            &signature1,
690            &signature2
691        ];
692
693        let multi_signature_invalid = MultiSignature::new(&signatures).unwrap();
694        let valid = Bls::verify_multi_sig(&multi_signature_invalid, &message, &ver_keys, &gen).unwrap();
695
696        assert!(!valid)
697    }
698}