@@ -364,14 +364,22 @@ impl PublicKey {
364364 /// the result would be the point at infinity, i.e. we are adding this point
365365 /// to its own negation
366366 pub fn combine ( & self , other : & PublicKey ) -> Result < PublicKey , Error > {
367+ PublicKey :: combine_keys ( & [ self , other] )
368+ }
369+
370+ /// Adds the keys in the provided slice together, returning the sum. Returns
371+ /// an error if the result would be the point at infinity, i.e. we are adding
372+ /// a point to its own negation
373+ #[ cfg( all( feature = "std" ) ) ]
374+ pub fn combine_keys ( keys : & [ & PublicKey ] ) -> Result < PublicKey , Error > {
367375 unsafe {
368376 let mut ret = ffi:: PublicKey :: new ( ) ;
369- let ptrs = [ self . as_c_ptr ( ) , other . as_c_ptr ( ) ] ;
377+ let ptrs : Vec < * const secp256k1_sys :: PublicKey > = keys . iter ( ) . map ( |k| k . as_c_ptr ( ) ) . collect ( ) ;
370378 if ffi:: secp256k1_ec_pubkey_combine (
371379 ffi:: secp256k1_context_no_precomp,
372380 & mut ret,
373381 ptrs. as_c_ptr ( ) ,
374- 2
382+ keys . len ( ) as i32
375383 ) == 1
376384 {
377385 Ok ( PublicKey ( ret) )
@@ -794,6 +802,29 @@ mod test {
794802 assert_eq ! ( sum1. unwrap( ) , exp_sum) ;
795803 }
796804
805+ #[ test]
806+ fn pubkey_combine_keys ( ) {
807+ let compressed1 = PublicKey :: from_slice (
808+ & hex ! ( "0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba" ) ,
809+ ) . unwrap ( ) ;
810+ let compressed2 = PublicKey :: from_slice (
811+ & hex ! ( "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443" ) ,
812+ ) . unwrap ( ) ;
813+ let compressed3 = PublicKey :: from_slice (
814+ & hex ! ( "03e74897d8644eb3e5b391ca2ab257aec2080f4d1a95cad57e454e47f021168eb0" )
815+ ) . unwrap ( ) ;
816+ let exp_sum = PublicKey :: from_slice (
817+ & hex ! ( "0252d73a47f66cf341e5651542f0348f452b7c793af62a6d8bff75ade703a451ad" ) ,
818+ ) . unwrap ( ) ;
819+
820+ let sum1 = PublicKey :: combine_keys ( & [ & compressed1, & compressed2, & compressed3] ) ;
821+ assert ! ( sum1. is_ok( ) ) ;
822+ let sum2 = PublicKey :: combine_keys ( & [ & compressed1, & compressed2, & compressed3] ) ;
823+ assert ! ( sum2. is_ok( ) ) ;
824+ assert_eq ! ( sum1, sum2) ;
825+ assert_eq ! ( sum1. unwrap( ) , exp_sum) ;
826+ }
827+
797828 #[ test]
798829 fn pubkey_equal ( ) {
799830 let pk1 = PublicKey :: from_slice (
0 commit comments