@@ -196,15 +196,19 @@ impl VerificationKeyPoP {
196
196
// If we are really looking for performance improvements, we can combine the
197
197
// two final exponentiations (for verifying k1 and k2) into a single one.
198
198
pub fn check ( & self ) -> Result < ( ) , MultiSignatureError > {
199
- let result = verify_pairing ( & self . vk , & self . pop ) ;
200
-
201
- if !( self . pop . k1 . verify ( false , POP , & [ ] , & [ ] , & self . vk . 0 , false )
202
- == BLST_ERROR :: BLST_SUCCESS
203
- && result)
204
- {
205
- return Err ( MultiSignatureError :: KeyInvalid ( Box :: new ( * self ) ) ) ;
199
+ match self . vk . 0 . validate ( ) {
200
+ Ok ( _) => {
201
+ let result = verify_pairing ( & self . vk , & self . pop ) ;
202
+ if !( self . pop . k1 . verify ( false , POP , & [ ] , & [ ] , & self . vk . 0 , false )
203
+ == BLST_ERROR :: BLST_SUCCESS
204
+ && result)
205
+ {
206
+ return Err ( MultiSignatureError :: KeyInvalid ( Box :: new ( * self ) ) ) ;
207
+ }
208
+ Ok ( ( ) )
209
+ }
210
+ Err ( e) => blst_err_to_mithril ( e, None ) ,
206
211
}
207
- Ok ( ( ) )
208
212
}
209
213
210
214
/// Convert to a 144 byte string.
@@ -287,10 +291,13 @@ impl From<&SigningKey> for ProofOfPossession {
287
291
impl Signature {
288
292
/// Verify a signature against a verification key.
289
293
pub fn verify ( & self , msg : & [ u8 ] , mvk : & VerificationKey ) -> Result < ( ) , MultiSignatureError > {
290
- blst_err_to_mithril (
291
- self . 0 . verify ( false , msg, & [ ] , & [ ] , & mvk. 0 , false ) ,
292
- Some ( * self ) ,
293
- )
294
+ match self . 0 . validate ( true ) {
295
+ Ok ( _) => blst_err_to_mithril (
296
+ self . 0 . verify ( false , msg, & [ ] , & [ ] , & mvk. 0 , false ) ,
297
+ Some ( * self ) ,
298
+ ) ,
299
+ Err ( e) => blst_err_to_mithril ( e, Some ( * self ) ) ,
300
+ }
294
301
}
295
302
296
303
/// Dense mapping function indexed by the index to be evaluated.
@@ -376,7 +383,6 @@ impl Signature {
376
383
}
377
384
378
385
let transmuted_vks: Vec < blst_p2 > = vks. iter ( ) . map ( vk_from_p2_affine) . collect ( ) ;
379
-
380
386
let transmuted_sigs: Vec < blst_p1 > = signatures. iter ( ) . map ( sig_to_p1) . collect ( ) ;
381
387
382
388
let grouped_vks = p2_affines:: from ( transmuted_vks. as_slice ( ) ) ;
@@ -628,6 +634,7 @@ mod unsafe_helpers {
628
634
#[ cfg( test) ]
629
635
mod tests {
630
636
use super :: * ;
637
+ use crate :: key_reg:: KeyReg ;
631
638
use proptest:: prelude:: * ;
632
639
use rand_chacha:: ChaCha20Rng ;
633
640
use rand_core:: { OsRng , SeedableRng } ;
@@ -647,9 +654,7 @@ mod tests {
647
654
}
648
655
649
656
#[ test]
650
- fn test_invalid_sig( msg in prop:: collection:: vec( any:: <u8 >( ) , 1 ..128 ) ,
651
- seed in any:: <[ u8 ; 32 ] >( ) ,
652
- ) {
657
+ fn test_invalid_sig( msg in prop:: collection:: vec( any:: <u8 >( ) , 1 ..128 ) , seed in any:: <[ u8 ; 32 ] >( ) ) {
653
658
let mut rng = ChaCha20Rng :: from_seed( seed) ;
654
659
let sk1 = SigningKey :: gen ( & mut rng) ;
655
660
let vk1 = VerificationKey :: from( & sk1) ;
@@ -658,6 +663,51 @@ mod tests {
658
663
assert!( fake_sig. verify( & msg, & vk1) . is_err( ) ) ;
659
664
}
660
665
666
+ #[ test]
667
+ fn test_infinity_sig( msg in prop:: collection:: vec( any:: <u8 >( ) , 1 ..128 ) , seed in any:: <[ u8 ; 32 ] >( ) ) {
668
+ let mut rng = ChaCha20Rng :: from_seed( seed) ;
669
+ let sk = SigningKey :: gen ( & mut rng) ;
670
+ let vk = VerificationKey :: from( & sk) ;
671
+
672
+ let p1 = blst_p1:: default ( ) ;
673
+ let sig_infinity = Signature ( p1_affine_to_sig( & p1) ) ;
674
+
675
+ assert!( sig_infinity. verify( & msg, & vk) . is_err( ) ) ;
676
+ }
677
+
678
+ #[ test]
679
+ fn test_infinity_vk( seed in any:: <[ u8 ; 32 ] >( ) ) {
680
+ let mut rng = ChaCha20Rng :: from_seed( seed) ;
681
+ let sk = SigningKey :: gen ( & mut rng) ;
682
+ let pop = ProofOfPossession :: from( & sk) ;
683
+
684
+ let p2 = blst_p2:: default ( ) ;
685
+ let vk_infinity = VerificationKey ( p2_affine_to_vk( & p2) ) ;
686
+ let vkpop_infinity = VerificationKeyPoP { vk: vk_infinity, pop } ;
687
+
688
+ assert!( vkpop_infinity. check( ) . is_err( ) ) ;
689
+ }
690
+
691
+ #[ test]
692
+ fn test_keyreg_with_infinity_vk( num_sigs in 2 ..16usize , seed in any:: <[ u8 ; 32 ] >( ) ) {
693
+ let mut rng = ChaCha20Rng :: from_seed( seed) ;
694
+ let mut kr = KeyReg :: init( ) ;
695
+
696
+ let sk = SigningKey :: gen ( & mut rng) ;
697
+ let pop = ProofOfPossession :: from( & sk) ;
698
+ let p2 = blst_p2:: default ( ) ;
699
+ let vk_infinity = VerificationKey ( p2_affine_to_vk( & p2) ) ;
700
+ let vkpop_infinity = VerificationKeyPoP { vk: vk_infinity, pop } ;
701
+
702
+ for _ in 0 ..num_sigs {
703
+ let sk = SigningKey :: gen ( & mut rng) ;
704
+ let vkpop = VerificationKeyPoP :: from( & sk) ;
705
+ let _ = kr. register( 1 , vkpop) ;
706
+ }
707
+
708
+ assert!( kr. register( 1 , vkpop_infinity) . is_err( ) ) ;
709
+ }
710
+
661
711
#[ test]
662
712
fn test_aggregate_sig( msg in prop:: collection:: vec( any:: <u8 >( ) , 1 ..128 ) ,
663
713
num_sigs in 2 ..16 ,
0 commit comments