Skip to content

Commit e5fa26a

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 f1d5d14 commit e5fa26a

File tree

3 files changed

+59
-78
lines changed

3 files changed

+59
-78
lines changed

src/key.rs

Lines changed: 49 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ use crate::ThirtyTwoByteHash;
2020
#[cfg(feature = "global-context")]
2121
use crate::SECP256K1;
2222
use crate::{
23-
constants, ecdsa, from_hex, schnorr, AllPreallocated, Message, Scalar, Secp256k1, Signing,
24-
Verification,
23+
constants, ecdsa, from_hex, schnorr, Message, Scalar, Secp256k1, Signing, Verification,
2524
};
2625

2726
/// Secret key - a 256-bit key used to create ECDSA and Taproot signatures.
@@ -610,11 +609,12 @@ impl PublicKey {
610609
/// Negates the public key.
611610
#[inline]
612611
#[must_use = "you forgot to use the negated public key"]
613-
pub fn negate<C: Verification>(mut self, secp: &Secp256k1<C>) -> PublicKey {
614-
unsafe {
615-
let res = ffi::secp256k1_ec_pubkey_negate(secp.ctx.as_ptr(), &mut self.0);
616-
debug_assert_eq!(res, 1);
617-
}
612+
pub fn negate(mut self) -> PublicKey {
613+
let res = crate::with_raw_global_context(
614+
|ctx| unsafe { ffi::secp256k1_ec_pubkey_negate(ctx.as_ptr(), &mut self.0) },
615+
None,
616+
);
617+
debug_assert_eq!(res, 1);
618618
self
619619
}
620620

@@ -624,19 +624,17 @@ impl PublicKey {
624624
///
625625
/// Returns an error if the resulting key would be invalid.
626626
#[inline]
627-
pub fn add_exp_tweak<C: Verification>(
628-
mut self,
629-
secp: &Secp256k1<C>,
630-
tweak: &Scalar,
631-
) -> Result<PublicKey, Error> {
632-
unsafe {
633-
if ffi::secp256k1_ec_pubkey_tweak_add(secp.ctx.as_ptr(), &mut self.0, tweak.as_c_ptr())
634-
== 1
635-
{
636-
Ok(self)
637-
} else {
638-
Err(Error::InvalidTweak)
639-
}
627+
pub fn add_exp_tweak(mut self, tweak: &Scalar) -> Result<PublicKey, Error> {
628+
if crate::with_raw_global_context(
629+
|ctx| unsafe {
630+
ffi::secp256k1_ec_pubkey_tweak_add(ctx.as_ptr(), &mut self.0, tweak.as_c_ptr())
631+
},
632+
None,
633+
) == 1
634+
{
635+
Ok(self)
636+
} else {
637+
Err(Error::InvalidTweak)
640638
}
641639
}
642640

@@ -880,12 +878,9 @@ impl Keypair {
880878
/// or if the encoded number is an invalid scalar.
881879
#[deprecated(since = "0.31.0", note = "Use `from_seckey_byte_array` instead.")]
882880
#[inline]
883-
pub fn from_seckey_slice<C: Signing>(
884-
secp: &Secp256k1<C>,
885-
data: &[u8],
886-
) -> Result<Keypair, Error> {
881+
pub fn from_seckey_slice(data: &[u8]) -> Result<Keypair, Error> {
887882
match <[u8; constants::SECRET_KEY_SIZE]>::try_from(data) {
888-
Ok(data) => Self::from_seckey_byte_array(secp, data),
883+
Ok(data) => Self::from_seckey_byte_array(data),
889884
Err(_) => Err(Error::InvalidSecretKey),
890885
}
891886
}
@@ -896,13 +891,16 @@ impl Keypair {
896891
///
897892
/// [`Error::InvalidSecretKey`] if the encoded number is an invalid scalar.
898893
#[inline]
899-
pub fn from_seckey_byte_array<C: Signing>(
900-
secp: &Secp256k1<C>,
894+
pub fn from_seckey_byte_array(
901895
data: [u8; constants::SECRET_KEY_SIZE],
902896
) -> Result<Keypair, Error> {
903897
unsafe {
904898
let mut kp = ffi::Keypair::new();
905-
if ffi::secp256k1_keypair_create(secp.ctx.as_ptr(), &mut kp, data.as_c_ptr()) == 1 {
899+
if crate::with_raw_global_context(
900+
|ctx| ffi::secp256k1_keypair_create(ctx.as_ptr(), &mut kp, data.as_c_ptr()),
901+
Some(&data),
902+
) == 1
903+
{
906904
Ok(Keypair(kp))
907905
} else {
908906
Err(Error::InvalidSecretKey)
@@ -917,13 +915,8 @@ impl Keypair {
917915
/// [`Error::InvalidSecretKey`] if the string does not consist of exactly 64 hex characters,
918916
/// or if the encoded number is an invalid scalar.
919917
#[inline]
920-
pub fn from_seckey_str<C: Signing>(secp: &Secp256k1<C>, s: &str) -> Result<Keypair, Error> {
921-
let mut res = [0u8; constants::SECRET_KEY_SIZE];
922-
match from_hex(s, &mut res) {
923-
Ok(constants::SECRET_KEY_SIZE) => Keypair::from_seckey_byte_array(secp, res),
924-
_ => Err(Error::InvalidSecretKey),
925-
}
926-
}
918+
#[deprecated(note = "use FromStr or parse instead")]
919+
pub fn from_seckey_str(s: &str) -> Result<Self, Error> { s.parse() }
927920

928921
/// Creates a [`Keypair`] directly from a secret key string and the global [`SECP256K1`] context.
929922
///
@@ -932,10 +925,8 @@ impl Keypair {
932925
/// [`Error::InvalidSecretKey`] if the string does not consist of exactly 64 hex characters,
933926
/// or if the encoded number is an invalid scalar.
934927
#[inline]
935-
#[cfg(feature = "global-context")]
936-
pub fn from_seckey_str_global(s: &str) -> Result<Keypair, Error> {
937-
Keypair::from_seckey_str(SECP256K1, s)
938-
}
928+
#[deprecated(note = "use FromStr or parse instead")]
929+
pub fn from_seckey_str_global(s: &str) -> Result<Keypair, Error> { s.parse() }
939930

940931
/// Generates a new random key pair.
941932
/// # Examples
@@ -1107,10 +1098,11 @@ impl str::FromStr for Keypair {
11071098
type Err = Error;
11081099

11091100
fn from_str(s: &str) -> Result<Self, Self::Err> {
1110-
crate::with_global_context(
1111-
|secp: &Secp256k1<AllPreallocated>| Self::from_seckey_str(secp, s),
1112-
None,
1113-
)
1101+
let mut res = [0u8; constants::SECRET_KEY_SIZE];
1102+
match from_hex(s, &mut res) {
1103+
Ok(constants::SECRET_KEY_SIZE) => Keypair::from_seckey_byte_array(res),
1104+
_ => Err(Error::InvalidSecretKey),
1105+
}
11141106
}
11151107
}
11161108

@@ -1141,12 +1133,10 @@ impl<'de> serde::Deserialize<'de> for Keypair {
11411133
"a hex string representing 32 byte Keypair",
11421134
))
11431135
} else {
1144-
let visitor = super::serde_util::Tuple32Visitor::new("raw 32 bytes Keypair", |data| {
1145-
crate::with_global_context(
1146-
|secp: &Secp256k1<AllPreallocated>| Self::from_seckey_byte_array(secp, data),
1147-
None,
1148-
)
1149-
});
1136+
let visitor = super::serde_util::Tuple32Visitor::new(
1137+
"raw 32 bytes Keypair",
1138+
Keypair::from_seckey_byte_array,
1139+
);
11501140
d.deserialize_tuple(constants::SECRET_KEY_SIZE, visitor)
11511141
}
11521142
}
@@ -1726,10 +1716,9 @@ mod test {
17261716
}
17271717

17281718
#[test]
1729-
#[cfg(all(feature = "std", not(secp256k1_fuzz)))]
1719+
#[cfg(not(secp256k1_fuzz))]
17301720
fn erased_keypair_is_valid() {
1731-
let s = Secp256k1::new();
1732-
let kp = Keypair::from_seckey_byte_array(&s, [1u8; constants::SECRET_KEY_SIZE])
1721+
let kp = Keypair::from_seckey_byte_array([1u8; constants::SECRET_KEY_SIZE])
17331722
.expect("valid secret key");
17341723
let mut kp2 = kp;
17351724
kp2.non_secure_erase();
@@ -2007,24 +1996,21 @@ mod test {
20071996

20081997
let tweaked_sk = sk.add_tweak(&tweak).unwrap();
20091998
assert_ne!(sk, tweaked_sk); // Make sure we did something.
2010-
let tweaked_pk = pk.add_exp_tweak(&s, &tweak).unwrap();
1999+
let tweaked_pk = pk.add_exp_tweak(&tweak).unwrap();
20112000
assert_ne!(pk, tweaked_pk);
20122001

20132002
assert_eq!(PublicKey::from_secret_key(&s, &tweaked_sk), tweaked_pk);
20142003
}
20152004

20162005
#[test]
2017-
#[cfg(feature = "std")]
20182006
fn tweak_add_zero() {
2019-
let s = Secp256k1::new();
2020-
20212007
let (sk, pk) = crate::test_random_keypair();
20222008

20232009
let tweak = Scalar::ZERO;
20242010

20252011
let tweaked_sk = sk.add_tweak(&tweak).unwrap();
20262012
assert_eq!(sk, tweaked_sk); // Tweak by zero does nothing.
2027-
let tweaked_pk = pk.add_exp_tweak(&s, &tweak).unwrap();
2013+
let tweaked_pk = pk.add_exp_tweak(&tweak).unwrap();
20282014
assert_eq!(pk, tweaked_pk);
20292015
}
20302016

@@ -2069,9 +2055,9 @@ mod test {
20692055
let back_sk = neg.negate();
20702056
assert_eq!(sk, back_sk);
20712057

2072-
let neg = pk.negate(&s);
2058+
let neg = pk.negate();
20732059
assert_ne!(pk, neg);
2074-
let back_pk = neg.negate(&s);
2060+
let back_pk = neg.negate();
20752061
assert_eq!(pk, back_pk);
20762062

20772063
assert_eq!(PublicKey::from_secret_key(&s, &back_sk), pk);
@@ -2329,7 +2315,7 @@ mod test {
23292315
];
23302316
static SK_STR: &str = "01010101010101010001020304050607ffff0000ffff00006363636363636363";
23312317

2332-
let sk = Keypair::from_seckey_byte_array(SECP256K1, SK_BYTES).unwrap();
2318+
let sk = Keypair::from_seckey_byte_array(SK_BYTES).unwrap();
23332319
#[rustfmt::skip]
23342320
assert_tokens(&sk.compact(), &[
23352321
Token::Tuple{ len: 32 },
@@ -2510,7 +2496,7 @@ mod test {
25102496

25112497
static PK_STR: &str = "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166";
25122498

2513-
let kp = Keypair::from_seckey_byte_array(crate::SECP256K1, SK_BYTES).unwrap();
2499+
let kp = Keypair::from_seckey_byte_array(SK_BYTES).unwrap();
25142500
let (pk, _parity) = XOnlyPublicKey::from_keypair(&kp);
25152501

25162502
#[rustfmt::skip]
@@ -2538,11 +2524,10 @@ mod test {
25382524
}
25392525

25402526
#[test]
2541-
#[cfg(all(any(feature = "alloc", feature = "global-context"), feature = "serde"))]
2527+
#[cfg(feature = "serde")]
25422528
fn test_keypair_deserialize_serde() {
2543-
let ctx = crate::Secp256k1::new();
25442529
let sec_key_str = "4242424242424242424242424242424242424242424242424242424242424242";
2545-
let keypair = Keypair::from_seckey_str(&ctx, sec_key_str).unwrap();
2530+
let keypair = Keypair::from_str(sec_key_str).unwrap();
25462531

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

src/schnorr.rs

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

281281
let msg = hex_32!("E48441762FB75010B2AA31A512B62B4148AA3FB08EB0765D76B252559064A614");
282-
let sk = Keypair::from_seckey_str(
283-
&secp,
284-
"688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF",
285-
)
286-
.unwrap();
282+
let sk =
283+
Keypair::from_str("688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF")
284+
.unwrap();
287285
let aux_rand: [u8; 32] =
288286
hex_32!("02CCE08E913F22A36C5648D6405A2C7C50106E7AA2F1649E381C7F09D16B80AB");
289287
let expected_sig = Signature::from_str("6470FD1303DDA4FDA717B9837153C24A6EAB377183FC438F939E0ED2B620E9EE5077C4A8B8DCA28963D772A94F5F0DDF598E1C47C137F91933274C7C3EDADCE8").unwrap();
@@ -378,7 +376,7 @@ mod tests {
378376
fn test_xonly_key_extraction() {
379377
let secp = Secp256k1::new();
380378
let sk_str = "688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF";
381-
let keypair = Keypair::from_seckey_str(&secp, sk_str).unwrap();
379+
let keypair = Keypair::from_str(sk_str).unwrap();
382380
let sk = SecretKey::from_keypair(&keypair);
383381
assert_eq!(SecretKey::from_str(sk_str).unwrap(), sk);
384382
let pk = crate::key::PublicKey::from_keypair(&keypair);
@@ -392,14 +390,13 @@ mod tests {
392390
fn test_pubkey_display_output() {
393391
#[cfg(not(secp256k1_fuzz))]
394392
let pk = {
395-
let secp = Secp256k1::new();
396393
static SK_BYTES: [u8; 32] = [
397394
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
398395
0x06, 0x07, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63,
399396
0x63, 0x63, 0x63, 0x63,
400397
];
401398

402-
let kp = Keypair::from_seckey_byte_array(&secp, SK_BYTES).expect("sk");
399+
let kp = Keypair::from_seckey_byte_array(SK_BYTES).expect("sk");
403400

404401
// In fuzzing mode secret->public key derivation is different, so
405402
// hard-code the expected result.
@@ -479,7 +476,7 @@ mod tests {
479476
let s = Secp256k1::new();
480477

481478
let msg = [1; 32];
482-
let keypair = Keypair::from_seckey_byte_array(&s, [2; 32]).unwrap();
479+
let keypair = Keypair::from_seckey_byte_array([2; 32]).unwrap();
483480
let aux = [3u8; 32];
484481
let sig = s.sign_schnorr_with_aux_rand(&msg, &keypair, &aux);
485482
static SIG_BYTES: [u8; constants::SCHNORR_SIGNATURE_SIZE] = [
@@ -712,7 +709,7 @@ mod tests {
712709
} in vectors
713710
{
714711
if let (Some(secret_key), Some(aux_rand)) = (secret_key, aux_rand) {
715-
let keypair = Keypair::from_seckey_byte_array(&secp, secret_key).unwrap();
712+
let keypair = Keypair::from_seckey_byte_array(secret_key).unwrap();
716713
assert_eq!(keypair.x_only_public_key().0.serialize(), public_key);
717714
let sig = secp.sign_schnorr_with_aux_rand(&message, &keypair, &aux_rand);
718715
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)