Skip to content

Commit 879205e

Browse files
committed
key: update a couple arbitrary API functions to no longer take a context
This updates a couple functions, and their associated unit tests (which no longer need any std/alloc/global-context feature gates). This runs clean in valgrind, providing some evidence that my new code is sound.
1 parent 74295fe commit 879205e

File tree

3 files changed

+58
-85
lines changed

3 files changed

+58
-85
lines changed

src/key.rs

Lines changed: 48 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -593,11 +593,12 @@ impl PublicKey {
593593
/// Negates the public key.
594594
#[inline]
595595
#[must_use = "you forgot to use the negated public key"]
596-
pub fn negate<C: Verification>(mut self, secp: &Secp256k1<C>) -> PublicKey {
597-
unsafe {
598-
let res = ffi::secp256k1_ec_pubkey_negate(secp.ctx.as_ptr(), &mut self.0);
599-
debug_assert_eq!(res, 1);
600-
}
596+
pub fn negate(mut self) -> PublicKey {
597+
let res = crate::with_raw_global_context(
598+
|ctx| unsafe { ffi::secp256k1_ec_pubkey_negate(ctx.as_ptr(), &mut self.0) },
599+
None,
600+
);
601+
debug_assert_eq!(res, 1);
601602
self
602603
}
603604

@@ -607,19 +608,17 @@ impl PublicKey {
607608
///
608609
/// Returns an error if the resulting key would be invalid.
609610
#[inline]
610-
pub fn add_exp_tweak<C: Verification>(
611-
mut self,
612-
secp: &Secp256k1<C>,
613-
tweak: &Scalar,
614-
) -> Result<PublicKey, Error> {
615-
unsafe {
616-
if ffi::secp256k1_ec_pubkey_tweak_add(secp.ctx.as_ptr(), &mut self.0, tweak.as_c_ptr())
617-
== 1
618-
{
619-
Ok(self)
620-
} else {
621-
Err(Error::InvalidTweak)
622-
}
611+
pub fn add_exp_tweak(mut self, tweak: &Scalar) -> Result<PublicKey, Error> {
612+
if crate::with_raw_global_context(
613+
|ctx| unsafe {
614+
ffi::secp256k1_ec_pubkey_tweak_add(ctx.as_ptr(), &mut self.0, tweak.as_c_ptr())
615+
},
616+
None,
617+
) == 1
618+
{
619+
Ok(self)
620+
} else {
621+
Err(Error::InvalidTweak)
623622
}
624623
}
625624

@@ -863,12 +862,9 @@ impl Keypair {
863862
/// or if the encoded number is an invalid scalar.
864863
#[deprecated(since = "TBD", note = "Use `from_seckey_byte_array` instead.")]
865864
#[inline]
866-
pub fn from_seckey_slice<C: Signing>(
867-
secp: &Secp256k1<C>,
868-
data: &[u8],
869-
) -> Result<Keypair, Error> {
865+
pub fn from_seckey_slice(data: &[u8]) -> Result<Keypair, Error> {
870866
match <[u8; constants::SECRET_KEY_SIZE]>::try_from(data) {
871-
Ok(data) => Self::from_seckey_byte_array(secp, data),
867+
Ok(data) => Self::from_seckey_byte_array(data),
872868
Err(_) => Err(Error::InvalidSecretKey),
873869
}
874870
}
@@ -879,13 +875,16 @@ impl Keypair {
879875
///
880876
/// [`Error::InvalidSecretKey`] if the encoded number is an invalid scalar.
881877
#[inline]
882-
pub fn from_seckey_byte_array<C: Signing>(
883-
secp: &Secp256k1<C>,
878+
pub fn from_seckey_byte_array(
884879
data: [u8; constants::SECRET_KEY_SIZE],
885880
) -> Result<Keypair, Error> {
886881
unsafe {
887882
let mut kp = ffi::Keypair::new();
888-
if ffi::secp256k1_keypair_create(secp.ctx.as_ptr(), &mut kp, data.as_c_ptr()) == 1 {
883+
if crate::with_raw_global_context(
884+
|ctx| ffi::secp256k1_keypair_create(ctx.as_ptr(), &mut kp, data.as_c_ptr()),
885+
Some(&data),
886+
) == 1
887+
{
889888
Ok(Keypair(kp))
890889
} else {
891890
Err(Error::InvalidSecretKey)
@@ -900,13 +899,8 @@ impl Keypair {
900899
/// [`Error::InvalidSecretKey`] if the string does not consist of exactly 64 hex characters,
901900
/// or if the encoded number is an invalid scalar.
902901
#[inline]
903-
pub fn from_seckey_str<C: Signing>(secp: &Secp256k1<C>, s: &str) -> Result<Keypair, Error> {
904-
let mut res = [0u8; constants::SECRET_KEY_SIZE];
905-
match from_hex(s, &mut res) {
906-
Ok(constants::SECRET_KEY_SIZE) => Keypair::from_seckey_byte_array(secp, res),
907-
_ => Err(Error::InvalidSecretKey),
908-
}
909-
}
902+
#[deprecated(note = "use FromStr or parse instead")]
903+
pub fn from_seckey_str(s: &str) -> Result<Self, Error> { s.parse() }
910904

911905
/// Creates a [`Keypair`] directly from a secret key string and the global [`SECP256K1`] context.
912906
///
@@ -915,10 +909,8 @@ impl Keypair {
915909
/// [`Error::InvalidSecretKey`] if the string does not consist of exactly 64 hex characters,
916910
/// or if the encoded number is an invalid scalar.
917911
#[inline]
918-
#[cfg(feature = "global-context")]
919-
pub fn from_seckey_str_global(s: &str) -> Result<Keypair, Error> {
920-
Keypair::from_seckey_str(SECP256K1, s)
921-
}
912+
#[deprecated(note = "use FromStr or parse instead")]
913+
pub fn from_seckey_str_global(s: &str) -> Result<Keypair, Error> { s.parse() }
922914

923915
/// Generates a new random key pair.
924916
/// # Examples
@@ -1076,20 +1068,15 @@ impl<'a> From<&'a Keypair> for PublicKey {
10761068
fn from(pair: &'a Keypair) -> Self { PublicKey::from_keypair(pair) }
10771069
}
10781070

1079-
#[cfg(any(feature = "global-context", feature = "alloc"))]
10801071
impl str::FromStr for Keypair {
10811072
type Err = Error;
10821073

1083-
#[allow(unused_variables, unreachable_code)] // When built with no default features.
10841074
fn from_str(s: &str) -> Result<Self, Self::Err> {
1085-
#[cfg(feature = "global-context")]
1086-
let ctx = SECP256K1;
1087-
1088-
#[cfg(all(not(feature = "global-context"), feature = "alloc"))]
1089-
let ctx = Secp256k1::signing_only();
1090-
1091-
#[allow(clippy::needless_borrow)]
1092-
Keypair::from_seckey_str(&ctx, s)
1075+
let mut res = [0u8; constants::SECRET_KEY_SIZE];
1076+
match from_hex(s, &mut res) {
1077+
Ok(constants::SECRET_KEY_SIZE) => Keypair::from_seckey_byte_array(res),
1078+
_ => Err(Error::InvalidSecretKey),
1079+
}
10931080
}
10941081
}
10951082

@@ -1113,25 +1100,17 @@ impl serde::Serialize for Keypair {
11131100
}
11141101

11151102
#[cfg(feature = "serde")]
1116-
#[allow(unused_variables)] // For `data` under some feature combinations (the unconditional panic below).
1117-
#[cfg(all(feature = "serde", any(feature = "global-context", feature = "alloc")))]
11181103
impl<'de> serde::Deserialize<'de> for Keypair {
11191104
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
11201105
if d.is_human_readable() {
11211106
d.deserialize_str(super::serde_util::FromStrVisitor::new(
11221107
"a hex string representing 32 byte Keypair",
11231108
))
11241109
} else {
1125-
let visitor = super::serde_util::Tuple32Visitor::new("raw 32 bytes Keypair", |data| {
1126-
#[cfg(feature = "global-context")]
1127-
let ctx = SECP256K1;
1128-
1129-
#[cfg(all(not(feature = "global-context"), feature = "alloc"))]
1130-
let ctx = Secp256k1::signing_only();
1131-
1132-
#[allow(clippy::needless_borrow)]
1133-
Keypair::from_seckey_byte_array(&ctx, data)
1134-
});
1110+
let visitor = super::serde_util::Tuple32Visitor::new(
1111+
"raw 32 bytes Keypair",
1112+
Keypair::from_seckey_byte_array,
1113+
);
11351114
d.deserialize_tuple(constants::SECRET_KEY_SIZE, visitor)
11361115
}
11371116
}
@@ -1713,10 +1692,9 @@ mod test {
17131692
}
17141693

17151694
#[test]
1716-
#[cfg(all(feature = "std", not(secp256k1_fuzz)))]
1695+
#[cfg(not(secp256k1_fuzz))]
17171696
fn erased_keypair_is_valid() {
1718-
let s = Secp256k1::new();
1719-
let kp = Keypair::from_seckey_byte_array(&s, [1u8; constants::SECRET_KEY_SIZE])
1697+
let kp = Keypair::from_seckey_byte_array([1u8; constants::SECRET_KEY_SIZE])
17201698
.expect("valid secret key");
17211699
let mut kp2 = kp;
17221700
kp2.non_secure_erase();
@@ -1993,7 +1971,7 @@ mod test {
19931971

19941972
let tweaked_sk = sk.add_tweak(&tweak).unwrap();
19951973
assert_ne!(sk, tweaked_sk); // Make sure we did something.
1996-
let tweaked_pk = pk.add_exp_tweak(&s, &tweak).unwrap();
1974+
let tweaked_pk = pk.add_exp_tweak(&tweak).unwrap();
19971975
assert_ne!(pk, tweaked_pk);
19981976

19991977
assert_eq!(PublicKey::from_secret_key(&s, &tweaked_sk), tweaked_pk);
@@ -2010,7 +1988,7 @@ mod test {
20101988

20111989
let tweaked_sk = sk.add_tweak(&tweak).unwrap();
20121990
assert_eq!(sk, tweaked_sk); // Tweak by zero does nothing.
2013-
let tweaked_pk = pk.add_exp_tweak(&s, &tweak).unwrap();
1991+
let tweaked_pk = pk.add_exp_tweak(&tweak).unwrap();
20141992
assert_eq!(pk, tweaked_pk);
20151993
}
20161994

@@ -2057,9 +2035,9 @@ mod test {
20572035
let back_sk = neg.negate();
20582036
assert_eq!(sk, back_sk);
20592037

2060-
let neg = pk.negate(&s);
2038+
let neg = pk.negate();
20612039
assert_ne!(pk, neg);
2062-
let back_pk = neg.negate(&s);
2040+
let back_pk = neg.negate();
20632041
assert_eq!(pk, back_pk);
20642042

20652043
assert_eq!(PublicKey::from_secret_key(&s, &back_sk), pk);
@@ -2319,7 +2297,7 @@ mod test {
23192297
];
23202298
static SK_STR: &str = "01010101010101010001020304050607ffff0000ffff00006363636363636363";
23212299

2322-
let sk = Keypair::from_seckey_byte_array(SECP256K1, SK_BYTES).unwrap();
2300+
let sk = Keypair::from_seckey_byte_array(SK_BYTES).unwrap();
23232301
#[rustfmt::skip]
23242302
assert_tokens(&sk.compact(), &[
23252303
Token::Tuple{ len: 32 },
@@ -2499,7 +2477,7 @@ mod test {
24992477

25002478
static PK_STR: &str = "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166";
25012479

2502-
let kp = Keypair::from_seckey_byte_array(crate::SECP256K1, SK_BYTES).unwrap();
2480+
let kp = Keypair::from_seckey_byte_array(SK_BYTES).unwrap();
25032481
let (pk, _parity) = XOnlyPublicKey::from_keypair(&kp);
25042482

25052483
#[rustfmt::skip]
@@ -2529,11 +2507,10 @@ mod test {
25292507
}
25302508

25312509
#[test]
2532-
#[cfg(all(any(feature = "alloc", feature = "global-context"), feature = "serde"))]
2510+
#[cfg(feature = "serde")]
25332511
fn test_keypair_deserialize_serde() {
2534-
let ctx = crate::Secp256k1::new();
25352512
let sec_key_str = "4242424242424242424242424242424242424242424242424242424242424242";
2536-
let keypair = Keypair::from_seckey_str(&ctx, sec_key_str).unwrap();
2513+
let keypair = Keypair::from_str(sec_key_str).unwrap();
25372514

25382515
serde_test::assert_tokens(&keypair.readable(), &[Token::String(sec_key_str)]);
25392516

src/schnorr.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,9 @@ mod tests {
273273
let secp = Secp256k1::new();
274274

275275
let msg = hex_32!("E48441762FB75010B2AA31A512B62B4148AA3FB08EB0765D76B252559064A614");
276-
let sk = Keypair::from_seckey_str(
277-
&secp,
278-
"688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF",
279-
)
280-
.unwrap();
276+
let sk =
277+
Keypair::from_str("688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF")
278+
.unwrap();
281279
let aux_rand: [u8; 32] =
282280
hex_32!("02CCE08E913F22A36C5648D6405A2C7C50106E7AA2F1649E381C7F09D16B80AB");
283281
let expected_sig = Signature::from_str("6470FD1303DDA4FDA717B9837153C24A6EAB377183FC438F939E0ED2B620E9EE5077C4A8B8DCA28963D772A94F5F0DDF598E1C47C137F91933274C7C3EDADCE8").unwrap();
@@ -372,7 +370,7 @@ mod tests {
372370
fn test_xonly_key_extraction() {
373371
let secp = Secp256k1::new();
374372
let sk_str = "688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF";
375-
let keypair = Keypair::from_seckey_str(&secp, sk_str).unwrap();
373+
let keypair = Keypair::from_str(sk_str).unwrap();
376374
let sk = SecretKey::from_keypair(&keypair);
377375
assert_eq!(SecretKey::from_str(sk_str).unwrap(), sk);
378376
let pk = crate::key::PublicKey::from_keypair(&keypair);
@@ -386,14 +384,13 @@ mod tests {
386384
fn test_pubkey_display_output() {
387385
#[cfg(not(secp256k1_fuzz))]
388386
let pk = {
389-
let secp = Secp256k1::new();
390387
static SK_BYTES: [u8; 32] = [
391388
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
392389
0x06, 0x07, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63,
393390
0x63, 0x63, 0x63, 0x63,
394391
];
395392

396-
let kp = Keypair::from_seckey_byte_array(&secp, SK_BYTES).expect("sk");
393+
let kp = Keypair::from_seckey_byte_array(SK_BYTES).expect("sk");
397394

398395
// In fuzzing mode secret->public key derivation is different, so
399396
// hard-code the expected result.
@@ -473,7 +470,7 @@ mod tests {
473470
let s = Secp256k1::new();
474471

475472
let msg = [1; 32];
476-
let keypair = Keypair::from_seckey_byte_array(&s, [2; 32]).unwrap();
473+
let keypair = Keypair::from_seckey_byte_array([2; 32]).unwrap();
477474
let aux = [3u8; 32];
478475
let sig = s.sign_schnorr_with_aux_rand(&msg, &keypair, &aux);
479476
static SIG_BYTES: [u8; constants::SCHNORR_SIGNATURE_SIZE] = [
@@ -706,7 +703,7 @@ mod tests {
706703
} in vectors
707704
{
708705
if let (Some(secret_key), Some(aux_rand)) = (secret_key, aux_rand) {
709-
let keypair = Keypair::from_seckey_byte_array(&secp, secret_key).unwrap();
706+
let keypair = Keypair::from_seckey_byte_array(secret_key).unwrap();
710707
assert_eq!(keypair.x_only_public_key().0.serialize(), public_key);
711708
let sig = secp.sign_schnorr_with_aux_rand(&message, &keypair, &aux_rand);
712709
assert_eq!(sig.to_byte_array(), signature);

tests/serde.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ extern crate bincode;
44
extern crate secp256k1;
55
extern crate serde_cbor;
66

7-
use secp256k1::{musig, PublicKey, SecretKey, XOnlyPublicKey};
87
#[cfg(feature = "global-context")]
9-
use secp256k1::{Keypair, Secp256k1};
8+
use secp256k1::Keypair;
9+
use secp256k1::{musig, PublicKey, SecretKey, XOnlyPublicKey};
1010

1111
// Arbitrary key data.
1212

@@ -97,8 +97,7 @@ fn bincode_public_key() {
9797
#[test]
9898
#[cfg(feature = "global-context")]
9999
fn bincode_keypair() {
100-
let secp = Secp256k1::new();
101-
let kp = Keypair::from_seckey_byte_array(&secp, SK_BYTES).expect("failed to create keypair");
100+
let kp = Keypair::from_seckey_byte_array(SK_BYTES).expect("failed to create keypair");
102101
let ser = bincode::serialize(&kp).unwrap();
103102

104103
assert_eq!(ser, SK_BYTES);

0 commit comments

Comments
 (0)