Skip to content

Commit aba2663

Browse files
committed
Merge #449: Re-implement public key ordering using underlying FFI functions
13af519 Make key comparison non-fuzzable (Dr Maxim Orlovsky) 7396604 Implement PublicKey ordering using FFI (Dr Maxim Orlovsky) 0faf404 Benchmark for key ordering (Dr Maxim Orlovsky) 999d165 FFI for pubkey comparison ops (Dr Maxim Orlovsky) Pull request description: Re-base #309 for @dr-orlovsky on request by @Kixunil. To do the rebase I just had to change instances of cfg_attr to use `v0_5_0` instead of `v0_4_1` e.g., ``` #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_5_0_xonly_pubkey_cmp")] ``` And drop the changes to `src/schnorrsig.rs`, all these changes are covered by the changes in `key.rs` I believe. ACKs for top commit: Kixunil: ACK 13af519 apoelstra: ACK 13af519 Tree-SHA512: 3054fcbc1707679f54466cdc91162c286394ad691e4f5c8ee18635a22b0854a4e60f1186ef3ca1532aacd8a637d0a153601ec203947e9e58dfcebf1bcb619955
2 parents 4dacf55 + 13af519 commit aba2663

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

secp256k1-sys/src/lib.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,12 @@ extern "C" {
434434
pk: *mut PublicKey) -> c_int;
435435

436436

437+
#[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_5_0_ec_pubkey_cmp")]
438+
pub fn secp256k1_ec_pubkey_cmp(cx: *const Context,
439+
pubkey1: *const PublicKey,
440+
pubkey2: *const PublicKey)
441+
-> c_int;
442+
437443
#[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_5_0_ec_pubkey_tweak_add")]
438444
pub fn secp256k1_ec_pubkey_tweak_add(cx: *const Context,
439445
pk: *mut PublicKey,
@@ -540,6 +546,13 @@ extern "C" {
540546
pubkey: *const PublicKey,
541547
) -> c_int;
542548

549+
#[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_5_0_xonly_pubkey_cmp")]
550+
pub fn secp256k1_xonly_pubkey_cmp(
551+
cx: *const Context,
552+
pubkey1: *const XOnlyPublicKey,
553+
pubkey2: *const XOnlyPublicKey
554+
) -> c_int;
555+
543556
#[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_5_0_xonly_pubkey_tweak_add")]
544557
pub fn secp256k1_xonly_pubkey_tweak_add(
545558
cx: *const Context,

src/key.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ pub const ONE_KEY: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0,
101101
/// [`bincode`]: https://docs.rs/bincode
102102
/// [`cbor`]: https://docs.rs/cbor
103103
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
104+
#[cfg_attr(feature = "fuzzing", derive(PartialOrd, Ord))]
104105
#[repr(transparent)]
105106
pub struct PublicKey(ffi::PublicKey);
106107

@@ -763,15 +764,20 @@ impl<'de> serde::Deserialize<'de> for PublicKey {
763764
}
764765
}
765766

767+
#[cfg(not(fuzzing))]
766768
impl PartialOrd for PublicKey {
767769
fn partial_cmp(&self, other: &PublicKey) -> Option<core::cmp::Ordering> {
768-
self.serialize().partial_cmp(&other.serialize())
770+
Some(self.cmp(other))
769771
}
770772
}
771773

774+
#[cfg(not(fuzzing))]
772775
impl Ord for PublicKey {
773776
fn cmp(&self, other: &PublicKey) -> core::cmp::Ordering {
774-
self.serialize().cmp(&other.serialize())
777+
let ret = unsafe {
778+
ffi::secp256k1_ec_pubkey_cmp(ffi::secp256k1_context_no_precomp, self.as_c_ptr(), other.as_c_ptr())
779+
};
780+
ret.cmp(&0i32)
775781
}
776782
}
777783

@@ -2069,6 +2075,7 @@ mod test {
20692075
assert_eq!(Ok(sksum), sum1);
20702076
}
20712077

2078+
#[cfg(not(fuzzing))]
20722079
#[test]
20732080
fn pubkey_equal() {
20742081
let pk1 = PublicKey::from_slice(
@@ -2079,7 +2086,7 @@ mod test {
20792086
&hex!("02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"),
20802087
).unwrap();
20812088

2082-
assert!(pk1 == pk2);
2089+
assert_eq!(pk1, pk2);
20832090
assert!(pk1 <= pk2);
20842091
assert!(pk2 <= pk1);
20852092
assert!(!(pk2 < pk1));
@@ -2430,3 +2437,24 @@ mod test {
24302437
assert_tokens(&pk.readable(), &[Token::String(PK_STR)]);
24312438
}
24322439
}
2440+
2441+
#[cfg(all(test, feature = "unstable"))]
2442+
mod benches {
2443+
use test::Bencher;
2444+
use std::collections::BTreeSet;
2445+
use crate::PublicKey;
2446+
use crate::constants::GENERATOR_X;
2447+
2448+
#[bench]
2449+
fn bench_pk_ordering(b: &mut Bencher) {
2450+
let mut map = BTreeSet::new();
2451+
let mut g_slice = [02u8; 33];
2452+
g_slice[1..].copy_from_slice(&GENERATOR_X);
2453+
let g = PublicKey::from_slice(&g_slice).unwrap();
2454+
let mut pk = g;
2455+
b.iter(|| {
2456+
map.insert(pk);
2457+
pk = pk.combine(&pk).unwrap();
2458+
})
2459+
}
2460+
}

0 commit comments

Comments
 (0)