Add combine_keys function to PublicKey
This commit is contained in:
parent
63f4de78ce
commit
7d32182537
40
src/key.rs
40
src/key.rs
|
@ -65,6 +65,7 @@ pub const ONE_KEY: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
/// A Secp256k1 public key, used for verification of signatures
|
/// A Secp256k1 public key, used for verification of signatures
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
|
#[repr(transparent)]
|
||||||
pub struct PublicKey(ffi::PublicKey);
|
pub struct PublicKey(ffi::PublicKey);
|
||||||
|
|
||||||
impl fmt::LowerHex for PublicKey {
|
impl fmt::LowerHex for PublicKey {
|
||||||
|
@ -364,14 +365,26 @@ impl PublicKey {
|
||||||
/// the result would be the point at infinity, i.e. we are adding this point
|
/// the result would be the point at infinity, i.e. we are adding this point
|
||||||
/// to its own negation
|
/// to its own negation
|
||||||
pub fn combine(&self, other: &PublicKey) -> Result<PublicKey, Error> {
|
pub fn combine(&self, other: &PublicKey) -> Result<PublicKey, Error> {
|
||||||
|
PublicKey::combine_keys(&[self, other])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds the keys in the provided slice together, returning the sum. Returns
|
||||||
|
/// an error if the result would be the point at infinity, i.e. we are adding
|
||||||
|
/// a point to its own negation
|
||||||
|
pub fn combine_keys(keys: &[&PublicKey]) -> Result<PublicKey, Error> {
|
||||||
|
use core::mem::transmute;
|
||||||
|
use core::i32::MAX;
|
||||||
|
|
||||||
|
debug_assert!(keys.len() < MAX as usize);
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut ret = ffi::PublicKey::new();
|
let mut ret = ffi::PublicKey::new();
|
||||||
let ptrs = [self.as_c_ptr(), other.as_c_ptr()];
|
let ptrs : &[*const ffi::PublicKey] =
|
||||||
|
transmute::<&[&PublicKey], &[*const ffi::PublicKey]>(keys);
|
||||||
if ffi::secp256k1_ec_pubkey_combine(
|
if ffi::secp256k1_ec_pubkey_combine(
|
||||||
ffi::secp256k1_context_no_precomp,
|
ffi::secp256k1_context_no_precomp,
|
||||||
&mut ret,
|
&mut ret,
|
||||||
ptrs.as_c_ptr(),
|
ptrs.as_c_ptr(),
|
||||||
2
|
keys.len() as i32
|
||||||
) == 1
|
) == 1
|
||||||
{
|
{
|
||||||
Ok(PublicKey(ret))
|
Ok(PublicKey(ret))
|
||||||
|
@ -794,6 +807,29 @@ mod test {
|
||||||
assert_eq!(sum1.unwrap(), exp_sum);
|
assert_eq!(sum1.unwrap(), exp_sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pubkey_combine_keys() {
|
||||||
|
let compressed1 = PublicKey::from_slice(
|
||||||
|
&hex!("0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba"),
|
||||||
|
).unwrap();
|
||||||
|
let compressed2 = PublicKey::from_slice(
|
||||||
|
&hex!("02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"),
|
||||||
|
).unwrap();
|
||||||
|
let compressed3 = PublicKey::from_slice(
|
||||||
|
&hex!("03e74897d8644eb3e5b391ca2ab257aec2080f4d1a95cad57e454e47f021168eb0")
|
||||||
|
).unwrap();
|
||||||
|
let exp_sum = PublicKey::from_slice(
|
||||||
|
&hex!("0252d73a47f66cf341e5651542f0348f452b7c793af62a6d8bff75ade703a451ad"),
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let sum1 = PublicKey::combine_keys(&[&compressed1, &compressed2, &compressed3]);
|
||||||
|
assert!(sum1.is_ok());
|
||||||
|
let sum2 = PublicKey::combine_keys(&[&compressed1, &compressed2, &compressed3]);
|
||||||
|
assert!(sum2.is_ok());
|
||||||
|
assert_eq!(sum1, sum2);
|
||||||
|
assert_eq!(sum1.unwrap(), exp_sum);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn pubkey_equal() {
|
fn pubkey_equal() {
|
||||||
let pk1 = PublicKey::from_slice(
|
let pk1 = PublicKey::from_slice(
|
||||||
|
|
Loading…
Reference in New Issue