Merge pull request #20 from apoelstra/2combine
expose 2-key version of PublicKey::combine
This commit is contained in:
commit
06137aefda
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
|
|
||||||
name = "secp256k1"
|
name = "secp256k1"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
authors = [ "Dawid Ciężarkiewicz <dpc@ucore.info>",
|
authors = [ "Dawid Ciężarkiewicz <dpc@ucore.info>",
|
||||||
"Andrew Poelstra <apoelstra@wpsoftware.net>" ]
|
"Andrew Poelstra <apoelstra@wpsoftware.net>" ]
|
||||||
license = "CC0-1.0"
|
license = "CC0-1.0"
|
||||||
|
|
44
src/key.rs
44
src/key.rs
|
@ -20,6 +20,8 @@
|
||||||
#[cfg(any(test, feature = "rustc-serialize"))] use serialize::{Decoder, Decodable, Encoder, Encodable};
|
#[cfg(any(test, feature = "rustc-serialize"))] use serialize::{Decoder, Decodable, Encoder, Encodable};
|
||||||
#[cfg(any(test, feature = "serde"))] use serde::{Serialize, Deserialize, Serializer, Deserializer};
|
#[cfg(any(test, feature = "serde"))] use serde::{Serialize, Deserialize, Serializer, Deserializer};
|
||||||
|
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
use super::{Secp256k1, ContextFlag};
|
use super::{Secp256k1, ContextFlag};
|
||||||
use super::Error::{self, IncapableContext, InvalidPublicKey, InvalidSecretKey};
|
use super::Error::{self, IncapableContext, InvalidPublicKey, InvalidSecretKey};
|
||||||
use constants;
|
use constants;
|
||||||
|
@ -252,6 +254,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<PublicKey, Error> {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "rustc-serialize"))]
|
#[cfg(any(test, feature = "rustc-serialize"))]
|
||||||
|
@ -377,8 +394,11 @@ mod test {
|
||||||
use super::{PublicKey, SecretKey};
|
use super::{PublicKey, SecretKey};
|
||||||
use super::super::constants;
|
use super::super::constants;
|
||||||
|
|
||||||
|
use serialize::hex::FromHex;
|
||||||
use rand::{Rng, thread_rng};
|
use rand::{Rng, thread_rng};
|
||||||
|
|
||||||
|
macro_rules! hex (($hex:expr) => (FromHex::from_hex($hex).unwrap()));
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn skey_from_slice() {
|
fn skey_from_slice() {
|
||||||
let s = Secp256k1::new();
|
let s = Secp256k1::new();
|
||||||
|
@ -734,6 +754,30 @@ mod test {
|
||||||
}).count();
|
}).count();
|
||||||
assert_eq!(count, COUNT);
|
assert_eq!(count, COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pubkey_combine() {
|
||||||
|
let s = Secp256k1::with_caps(ContextFlag::None);
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue