From 0d41c23c2146c9d392856e9ae9282a2a6aa42da1 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Wed, 22 Aug 2018 20:18:25 +0000 Subject: [PATCH] Revert "remove PublicKey::combine" This reverts commit 17450e91fd83f396198dd9c14a2bd2b5c2d058bc. --- CHANGELOG.md | 4 ++++ src/key.rs | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a47b34..6d0d716 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ +# 0.11.1 - 2018-08-22 + +* Put `PublicKey::combine` back because it is currently needed to implement Lightning BOLT 3 + # 0.11.0 - 2018-08-22 * Update `rand` to 0.4 and `gcc` 0.3 to `cc` 1.0. (`rand` 0.5 exists but has a lot of breaking changes and no longer compiles with 1.14.0.) diff --git a/src/key.rs b/src/key.rs index 5bab047..463353c 100644 --- a/src/key.rs +++ b/src/key.rs @@ -273,6 +273,21 @@ impl PublicKey { } } } + + /// Adds a second key to this one, returning the sum. Returns an error if + /// the result would be the point at infinity, i.e. we are adding this point + /// to its own negation + pub fn combine(&self, secp: &Secp256k1, other: &PublicKey) -> Result { + unsafe { + let mut ret = mem::uninitialized(); + let ptrs = [self.as_ptr(), other.as_ptr()]; + if ffi::secp256k1_ec_pubkey_combine(secp.ctx, &mut ret, ptrs.as_ptr(), 2) == 1 { + Ok(PublicKey(ret)) + } else { + Err(InvalidPublicKey) + } + } + } } /// Creates a new public key from a FFI public key @@ -551,6 +566,30 @@ mod test { assert_eq!(count, COUNT); } + #[test] + fn pubkey_combine() { + let s = Secp256k1::without_caps(); + let compressed1 = PublicKey::from_slice( + &s, + &hex!("0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba"), + ).unwrap(); + let compressed2 = PublicKey::from_slice( + &s, + &hex!("02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"), + ).unwrap(); + let exp_sum = PublicKey::from_slice( + &s, + &hex!("0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07"), + ).unwrap(); + + let sum1 = compressed1.combine(&s, &compressed2); + assert!(sum1.is_ok()); + let sum2 = compressed2.combine(&s, &compressed1); + assert!(sum2.is_ok()); + assert_eq!(sum1, sum2); + assert_eq!(sum1.unwrap(), exp_sum); + } + #[test] fn pubkey_equal() { let s = Secp256k1::new();