Skip to content

Commit 4f600db

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 362495b commit 4f600db

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
@@ -19,8 +19,7 @@ use crate::Error::{self, InvalidPublicKey, InvalidPublicKeySum, InvalidSecretKey
1919
#[cfg(feature = "global-context")]
2020
use crate::SECP256K1;
2121
use crate::{
22-
constants, ecdsa, from_hex, schnorr, AllPreallocated, Message, Scalar, Secp256k1, Signing,
23-
Verification,
22+
constants, ecdsa, from_hex, schnorr, Message, Scalar, Secp256k1, Signing, Verification,
2423
};
2524

2625
/// Secret key - a 256-bit key used to create ECDSA and Taproot signatures.
@@ -600,11 +599,12 @@ impl PublicKey {
600599
/// Negates the public key.
601600
#[inline]
602601
#[must_use = "you forgot to use the negated public key"]
603-
pub fn negate<C: Verification>(mut self, secp: &Secp256k1<C>) -> PublicKey {
604-
unsafe {
605-
let res = ffi::secp256k1_ec_pubkey_negate(secp.ctx.as_ptr(), &mut self.0);
606-
debug_assert_eq!(res, 1);
607-
}
602+
pub fn negate(mut self) -> PublicKey {
603+
let res = crate::with_raw_global_context(
604+
|ctx| unsafe { ffi::secp256k1_ec_pubkey_negate(ctx.as_ptr(), &mut self.0) },
605+
None,
606+
);
607+
debug_assert_eq!(res, 1);
608608
self
609609
}
610610

@@ -614,19 +614,17 @@ impl PublicKey {
614614
///
615615
/// Returns an error if the resulting key would be invalid.
616616
#[inline]
617-
pub fn add_exp_tweak<C: Verification>(
618-
mut self,
619-
secp: &Secp256k1<C>,
620-
tweak: &Scalar,
621-
) -> Result<PublicKey, Error> {
622-
unsafe {
623-
if ffi::secp256k1_ec_pubkey_tweak_add(secp.ctx.as_ptr(), &mut self.0, tweak.as_c_ptr())
624-
== 1
625-
{
626-
Ok(self)
627-
} else {
628-
Err(Error::InvalidTweak)
629-
}
617+
pub fn add_exp_tweak(mut self, tweak: &Scalar) -> Result<PublicKey, Error> {
618+
if crate::with_raw_global_context(
619+
|ctx| unsafe {
620+
ffi::secp256k1_ec_pubkey_tweak_add(ctx.as_ptr(), &mut self.0, tweak.as_c_ptr())
621+
},
622+
None,
623+
) == 1
624+
{
625+
Ok(self)
626+
} else {
627+
Err(Error::InvalidTweak)
630628
}
631629
}
632630

@@ -870,12 +868,9 @@ impl Keypair {
870868
/// or if the encoded number is an invalid scalar.
871869
#[deprecated(since = "0.31.0", note = "Use `from_seckey_byte_array` instead.")]
872870
#[inline]
873-
pub fn from_seckey_slice<C: Signing>(
874-
secp: &Secp256k1<C>,
875-
data: &[u8],
876-
) -> Result<Keypair, Error> {
871+
pub fn from_seckey_slice(data: &[u8]) -> Result<Keypair, Error> {
877872
match <[u8; constants::SECRET_KEY_SIZE]>::try_from(data) {
878-
Ok(data) => Self::from_seckey_byte_array(secp, data),
873+
Ok(data) => Self::from_seckey_byte_array(data),
879874
Err(_) => Err(Error::InvalidSecretKey),
880875
}
881876
}
@@ -886,13 +881,16 @@ impl Keypair {
886881
///
887882
/// [`Error::InvalidSecretKey`] if the encoded number is an invalid scalar.
888883
#[inline]
889-
pub fn from_seckey_byte_array<C: Signing>(
890-
secp: &Secp256k1<C>,
884+
pub fn from_seckey_byte_array(
891885
data: [u8; constants::SECRET_KEY_SIZE],
892886
) -> Result<Keypair, Error> {
893887
unsafe {
894888
let mut kp = ffi::Keypair::new();
895-
if ffi::secp256k1_keypair_create(secp.ctx.as_ptr(), &mut kp, data.as_c_ptr()) == 1 {
889+
if crate::with_raw_global_context(
890+
|ctx| ffi::secp256k1_keypair_create(ctx.as_ptr(), &mut kp, data.as_c_ptr()),
891+
Some(&data),
892+
) == 1
893+
{
896894
Ok(Keypair(kp))
897895
} else {
898896
Err(Error::InvalidSecretKey)
@@ -907,13 +905,8 @@ impl Keypair {
907905
/// [`Error::InvalidSecretKey`] if the string does not consist of exactly 64 hex characters,
908906
/// or if the encoded number is an invalid scalar.
909907
#[inline]
910-
pub fn from_seckey_str<C: Signing>(secp: &Secp256k1<C>, s: &str) -> Result<Keypair, Error> {
911-
let mut res = [0u8; constants::SECRET_KEY_SIZE];
912-
match from_hex(s, &mut res) {
913-
Ok(constants::SECRET_KEY_SIZE) => Keypair::from_seckey_byte_array(secp, res),
914-
_ => Err(Error::InvalidSecretKey),
915-
}
916-
}
908+
#[deprecated(note = "use FromStr or parse instead")]
909+
pub fn from_seckey_str(s: &str) -> Result<Self, Error> { s.parse() }
917910

918911
/// Creates a [`Keypair`] directly from a secret key string and the global [`SECP256K1`] context.
919912
///
@@ -922,10 +915,8 @@ impl Keypair {
922915
/// [`Error::InvalidSecretKey`] if the string does not consist of exactly 64 hex characters,
923916
/// or if the encoded number is an invalid scalar.
924917
#[inline]
925-
#[cfg(feature = "global-context")]
926-
pub fn from_seckey_str_global(s: &str) -> Result<Keypair, Error> {
927-
Keypair::from_seckey_str(SECP256K1, s)
928-
}
918+
#[deprecated(note = "use FromStr or parse instead")]
919+
pub fn from_seckey_str_global(s: &str) -> Result<Keypair, Error> { s.parse() }
929920

930921
/// Generates a new random key pair.
931922
/// # Examples
@@ -1097,10 +1088,11 @@ impl str::FromStr for Keypair {
10971088
type Err = Error;
10981089

10991090
fn from_str(s: &str) -> Result<Self, Self::Err> {
1100-
crate::with_global_context(
1101-
|secp: &Secp256k1<AllPreallocated>| Self::from_seckey_str(secp, s),
1102-
None,
1103-
)
1091+
let mut res = [0u8; constants::SECRET_KEY_SIZE];
1092+
match from_hex(s, &mut res) {
1093+
Ok(constants::SECRET_KEY_SIZE) => Keypair::from_seckey_byte_array(res),
1094+
_ => Err(Error::InvalidSecretKey),
1095+
}
11041096
}
11051097
}
11061098

@@ -1131,12 +1123,10 @@ impl<'de> serde::Deserialize<'de> for Keypair {
11311123
"a hex string representing 32 byte Keypair",
11321124
))
11331125
} else {
1134-
let visitor = super::serde_util::Tuple32Visitor::new("raw 32 bytes Keypair", |data| {
1135-
crate::with_global_context(
1136-
|secp: &Secp256k1<AllPreallocated>| Self::from_seckey_byte_array(secp, data),
1137-
None,
1138-
)
1139-
});
1126+
let visitor = super::serde_util::Tuple32Visitor::new(
1127+
"raw 32 bytes Keypair",
1128+
Keypair::from_seckey_byte_array,
1129+
);
11401130
d.deserialize_tuple(constants::SECRET_KEY_SIZE, visitor)
11411131
}
11421132
}
@@ -1767,10 +1757,9 @@ mod test {
17671757
}
17681758

17691759
#[test]
1770-
#[cfg(all(feature = "std", not(secp256k1_fuzz)))]
1760+
#[cfg(not(secp256k1_fuzz))]
17711761
fn erased_keypair_is_valid() {
1772-
let s = Secp256k1::new();
1773-
let kp = Keypair::from_seckey_byte_array(&s, [1u8; constants::SECRET_KEY_SIZE])
1762+
let kp = Keypair::from_seckey_byte_array([1u8; constants::SECRET_KEY_SIZE])
17741763
.expect("valid secret key");
17751764
let mut kp2 = kp;
17761765
kp2.non_secure_erase();
@@ -2045,24 +2034,21 @@ mod test {
20452034

20462035
let tweaked_sk = sk.add_tweak(&tweak).unwrap();
20472036
assert_ne!(sk, tweaked_sk); // Make sure we did something.
2048-
let tweaked_pk = pk.add_exp_tweak(&s, &tweak).unwrap();
2037+
let tweaked_pk = pk.add_exp_tweak(&tweak).unwrap();
20492038
assert_ne!(pk, tweaked_pk);
20502039

20512040
assert_eq!(PublicKey::from_secret_key(&s, &tweaked_sk), tweaked_pk);
20522041
}
20532042

20542043
#[test]
2055-
#[cfg(feature = "std")]
20562044
fn tweak_add_zero() {
2057-
let s = Secp256k1::new();
2058-
20592045
let (sk, pk) = crate::test_random_keypair();
20602046

20612047
let tweak = Scalar::ZERO;
20622048

20632049
let tweaked_sk = sk.add_tweak(&tweak).unwrap();
20642050
assert_eq!(sk, tweaked_sk); // Tweak by zero does nothing.
2065-
let tweaked_pk = pk.add_exp_tweak(&s, &tweak).unwrap();
2051+
let tweaked_pk = pk.add_exp_tweak(&tweak).unwrap();
20662052
assert_eq!(pk, tweaked_pk);
20672053
}
20682054

@@ -2107,9 +2093,9 @@ mod test {
21072093
let back_sk = neg.negate();
21082094
assert_eq!(sk, back_sk);
21092095

2110-
let neg = pk.negate(&s);
2096+
let neg = pk.negate();
21112097
assert_ne!(pk, neg);
2112-
let back_pk = neg.negate(&s);
2098+
let back_pk = neg.negate();
21132099
assert_eq!(pk, back_pk);
21142100

21152101
assert_eq!(PublicKey::from_secret_key(&s, &back_sk), pk);
@@ -2367,7 +2353,7 @@ mod test {
23672353
];
23682354
static SK_STR: &str = "01010101010101010001020304050607ffff0000ffff00006363636363636363";
23692355

2370-
let sk = Keypair::from_seckey_byte_array(SECP256K1, SK_BYTES).unwrap();
2356+
let sk = Keypair::from_seckey_byte_array(SK_BYTES).unwrap();
23712357
#[rustfmt::skip]
23722358
assert_tokens(&sk.compact(), &[
23732359
Token::Tuple{ len: 32 },
@@ -2548,7 +2534,7 @@ mod test {
25482534

25492535
static PK_STR: &str = "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166";
25502536

2551-
let kp = Keypair::from_seckey_byte_array(crate::SECP256K1, SK_BYTES).unwrap();
2537+
let kp = Keypair::from_seckey_byte_array(SK_BYTES).unwrap();
25522538
let (pk, _parity) = XOnlyPublicKey::from_keypair(&kp);
25532539

25542540
#[rustfmt::skip]
@@ -2576,11 +2562,10 @@ mod test {
25762562
}
25772563

25782564
#[test]
2579-
#[cfg(all(any(feature = "alloc", feature = "global-context"), feature = "serde"))]
2565+
#[cfg(feature = "serde")]
25802566
fn test_keypair_deserialize_serde() {
2581-
let ctx = crate::Secp256k1::new();
25822567
let sec_key_str = "4242424242424242424242424242424242424242424242424242424242424242";
2583-
let keypair = Keypair::from_seckey_str(&ctx, sec_key_str).unwrap();
2568+
let keypair = Keypair::from_str(sec_key_str).unwrap();
25842569

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

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)