Skip to content

Commit c7522b5

Browse files
committed
Add combine_keys function to PublicKey
1 parent 4ae0e7e commit c7522b5

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

src/key.rs

+33-2
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)