Rename `schnorr::PublicKey` to `schnorr::XOnlyPublicKey`

The public key is unrelated to the signature algorithm. It will
be moved out of the module in another commit. For ease of review,
the renamed is kept separate.
This commit is contained in:
Thomas Eizinger 2021-09-09 19:37:31 +10:00
parent 2e0e731664
commit 87d936a765
No known key found for this signature in database
GPG Key ID: 651AC83A6C6C8B96
1 changed files with 51 additions and 51 deletions

View File

@ -74,11 +74,11 @@ impl str::FromStr for Signature {
} }
} }
/// A Schnorr public key, used for verification of Schnorr signatures /// A x-only public key, used for verification of Schnorr signatures
#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
pub struct PublicKey(ffi::XOnlyPublicKey); pub struct XOnlyPublicKey(ffi::XOnlyPublicKey);
impl fmt::LowerHex for PublicKey { impl fmt::LowerHex for XOnlyPublicKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let ser = self.serialize(); let ser = self.serialize();
for ch in &ser[..] { for ch in &ser[..] {
@ -88,19 +88,19 @@ impl fmt::LowerHex for PublicKey {
} }
} }
impl fmt::Display for PublicKey { impl fmt::Display for XOnlyPublicKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::LowerHex::fmt(self, f) fmt::LowerHex::fmt(self, f)
} }
} }
impl str::FromStr for PublicKey { impl str::FromStr for XOnlyPublicKey {
type Err = Error; type Err = Error;
fn from_str(s: &str) -> Result<PublicKey, Error> { fn from_str(s: &str) -> Result<XOnlyPublicKey, Error> {
let mut res = [0u8; constants::SCHNORRSIG_PUBLIC_KEY_SIZE]; let mut res = [0u8; constants::SCHNORRSIG_PUBLIC_KEY_SIZE];
match from_hex(s, &mut res) { match from_hex(s, &mut res) {
Ok(constants::SCHNORRSIG_PUBLIC_KEY_SIZE) => { Ok(constants::SCHNORRSIG_PUBLIC_KEY_SIZE) => {
PublicKey::from_slice(&res[0..constants::SCHNORRSIG_PUBLIC_KEY_SIZE]) XOnlyPublicKey::from_slice(&res[0..constants::SCHNORRSIG_PUBLIC_KEY_SIZE])
} }
_ => Err(Error::InvalidPublicKey), _ => Err(Error::InvalidPublicKey),
} }
@ -122,7 +122,7 @@ impl Signature {
} }
} }
impl PublicKey { impl XOnlyPublicKey {
/// Obtains a raw const pointer suitable for use with FFI functions /// Obtains a raw const pointer suitable for use with FFI functions
#[inline] #[inline]
pub fn as_ptr(&self) -> *const ffi::XOnlyPublicKey { pub fn as_ptr(&self) -> *const ffi::XOnlyPublicKey {
@ -137,7 +137,7 @@ impl PublicKey {
/// Creates a new Schnorr public key from a Schnorr key pair. /// Creates a new Schnorr public key from a Schnorr key pair.
#[inline] #[inline]
pub fn from_keypair<C: Signing>(secp: &Secp256k1<C>, keypair: &KeyPair) -> PublicKey { pub fn from_keypair<C: Signing>(secp: &Secp256k1<C>, keypair: &KeyPair) -> XOnlyPublicKey {
let mut pk_parity = 0; let mut pk_parity = 0;
unsafe { unsafe {
let mut xonly_pk = ffi::XOnlyPublicKey::new(); let mut xonly_pk = ffi::XOnlyPublicKey::new();
@ -148,7 +148,7 @@ impl PublicKey {
keypair.as_ptr(), keypair.as_ptr(),
); );
debug_assert_eq!(ret, 1); debug_assert_eq!(ret, 1);
PublicKey(xonly_pk) XOnlyPublicKey(xonly_pk)
} }
} }
@ -159,7 +159,7 @@ impl PublicKey {
/// Returns [`Error::InvalidPublicKey`] if the length of the data slice is not 32 bytes or the /// Returns [`Error::InvalidPublicKey`] if the length of the data slice is not 32 bytes or the
/// slice does not represent a valid Secp256k1 point x coordinate /// slice does not represent a valid Secp256k1 point x coordinate
#[inline] #[inline]
pub fn from_slice(data: &[u8]) -> Result<PublicKey, Error> { pub fn from_slice(data: &[u8]) -> Result<XOnlyPublicKey, Error> {
if data.is_empty() || data.len() != constants::SCHNORRSIG_PUBLIC_KEY_SIZE { if data.is_empty() || data.len() != constants::SCHNORRSIG_PUBLIC_KEY_SIZE {
return Err(Error::InvalidPublicKey); return Err(Error::InvalidPublicKey);
} }
@ -172,7 +172,7 @@ impl PublicKey {
data.as_c_ptr(), data.as_c_ptr(),
) == 1 ) == 1
{ {
Ok(PublicKey(pk)) Ok(XOnlyPublicKey(pk))
} else { } else {
Err(Error::InvalidPublicKey) Err(Error::InvalidPublicKey)
} }
@ -270,7 +270,7 @@ impl PublicKey {
} }
} }
impl CPtr for PublicKey { impl CPtr for XOnlyPublicKey {
type Target = ffi::XOnlyPublicKey; type Target = ffi::XOnlyPublicKey;
fn as_c_ptr(&self) -> *const Self::Target { fn as_c_ptr(&self) -> *const Self::Target {
self.as_ptr() self.as_ptr()
@ -282,15 +282,15 @@ impl CPtr for PublicKey {
} }
/// Creates a new Schnorr public key from a FFI x-only public key /// Creates a new Schnorr public key from a FFI x-only public key
impl From<ffi::XOnlyPublicKey> for PublicKey { impl From<ffi::XOnlyPublicKey> for XOnlyPublicKey {
#[inline] #[inline]
fn from(pk: ffi::XOnlyPublicKey) -> PublicKey { fn from(pk: ffi::XOnlyPublicKey) -> XOnlyPublicKey {
PublicKey(pk) XOnlyPublicKey(pk)
} }
} }
impl From<::key::PublicKey> for PublicKey { impl From<::key::PublicKey> for XOnlyPublicKey {
fn from(src: ::key::PublicKey) -> PublicKey { fn from(src: ::key::PublicKey) -> XOnlyPublicKey {
unsafe { unsafe {
let mut pk = ffi::XOnlyPublicKey::new(); let mut pk = ffi::XOnlyPublicKey::new();
assert_eq!( assert_eq!(
@ -302,13 +302,13 @@ impl From<::key::PublicKey> for PublicKey {
src.as_c_ptr(), src.as_c_ptr(),
) )
); );
PublicKey(pk) XOnlyPublicKey(pk)
} }
} }
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
impl ::serde::Serialize for PublicKey { impl ::serde::Serialize for XOnlyPublicKey {
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> { fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
if s.is_human_readable() { if s.is_human_readable() {
s.collect_str(self) s.collect_str(self)
@ -319,7 +319,7 @@ impl ::serde::Serialize for PublicKey {
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
impl<'de> ::serde::Deserialize<'de> for PublicKey { impl<'de> ::serde::Deserialize<'de> for XOnlyPublicKey {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> { fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
if d.is_human_readable() { if d.is_human_readable() {
d.deserialize_str(super::serde_util::FromStrVisitor::new( d.deserialize_str(super::serde_util::FromStrVisitor::new(
@ -328,7 +328,7 @@ impl<'de> ::serde::Deserialize<'de> for PublicKey {
} else { } else {
d.deserialize_bytes(super::serde_util::BytesVisitor::new( d.deserialize_bytes(super::serde_util::BytesVisitor::new(
"raw 32 bytes schnorr public key", "raw 32 bytes schnorr public key",
PublicKey::from_slice XOnlyPublicKey::from_slice
)) ))
} }
} }
@ -411,7 +411,7 @@ impl<C: Signing> Secp256k1<C> {
&self, &self,
sig: &Signature, sig: &Signature,
msg: &Message, msg: &Message,
pubkey: &PublicKey, pubkey: &XOnlyPublicKey,
) -> Result<(), Error> { ) -> Result<(), Error> {
unsafe { unsafe {
let ret = ffi::secp256k1_schnorrsig_verify( let ret = ffi::secp256k1_schnorrsig_verify(
@ -439,9 +439,9 @@ impl<C: Signing> Secp256k1<C> {
pub fn generate_schnorrsig_keypair<R: Rng + ?Sized>( pub fn generate_schnorrsig_keypair<R: Rng + ?Sized>(
&self, &self,
rng: &mut R, rng: &mut R,
) -> (KeyPair, PublicKey) { ) -> (KeyPair, XOnlyPublicKey) {
let sk = KeyPair::new(self, rng); let sk = KeyPair::new(self, rng);
let pubkey = PublicKey::from_keypair(self, &sk); let pubkey = XOnlyPublicKey::from_keypair(self, &sk);
(sk, pubkey) (sk, pubkey)
} }
} }
@ -450,7 +450,7 @@ impl<C: Signing> Secp256k1<C> {
mod tests { mod tests {
use super::super::Error::InvalidPublicKey; use super::super::Error::InvalidPublicKey;
use super::super::{constants, from_hex, All, Message, Secp256k1}; use super::super::{constants, from_hex, All, Message, Secp256k1};
use super::{KeyPair, PublicKey, Signature}; use super::{KeyPair, XOnlyPublicKey, Signature};
use rand::{rngs::ThreadRng, thread_rng, Error, ErrorKind, RngCore}; use rand::{rngs::ThreadRng, thread_rng, Error, ErrorKind, RngCore};
use rand_core::impls; use rand_core::impls;
use std::iter; use std::iter;
@ -548,7 +548,7 @@ mod tests {
let msg = Message::from_slice(&hex_msg).unwrap(); let msg = Message::from_slice(&hex_msg).unwrap();
let sig = Signature::from_str("6470FD1303DDA4FDA717B9837153C24A6EAB377183FC438F939E0ED2B620E9EE5077C4A8B8DCA28963D772A94F5F0DDF598E1C47C137F91933274C7C3EDADCE8").unwrap(); let sig = Signature::from_str("6470FD1303DDA4FDA717B9837153C24A6EAB377183FC438F939E0ED2B620E9EE5077C4A8B8DCA28963D772A94F5F0DDF598E1C47C137F91933274C7C3EDADCE8").unwrap();
let pubkey = let pubkey =
PublicKey::from_str("B33CC9EDC096D0A83416964BD3C6247B8FECD256E4EFA7870D2C854BDEB33390") XOnlyPublicKey::from_str("B33CC9EDC096D0A83416964BD3C6247B8FECD256E4EFA7870D2C854BDEB33390")
.unwrap(); .unwrap();
assert!(secp.schnorrsig_verify(&sig, &msg, &pubkey).is_ok()); assert!(secp.schnorrsig_verify(&sig, &msg, &pubkey).is_ok());
@ -556,9 +556,9 @@ mod tests {
#[test] #[test]
fn test_pubkey_from_slice() { fn test_pubkey_from_slice() {
assert_eq!(PublicKey::from_slice(&[]), Err(InvalidPublicKey)); assert_eq!(XOnlyPublicKey::from_slice(&[]), Err(InvalidPublicKey));
assert_eq!(PublicKey::from_slice(&[1, 2, 3]), Err(InvalidPublicKey)); assert_eq!(XOnlyPublicKey::from_slice(&[1, 2, 3]), Err(InvalidPublicKey));
let pk = PublicKey::from_slice(&[ let pk = XOnlyPublicKey::from_slice(&[
0xB3, 0x3C, 0xC9, 0xED, 0xC0, 0x96, 0xD0, 0xA8, 0x34, 0x16, 0x96, 0x4B, 0xD3, 0xC6, 0xB3, 0x3C, 0xC9, 0xED, 0xC0, 0x96, 0xD0, 0xA8, 0x34, 0x16, 0x96, 0x4B, 0xD3, 0xC6,
0x24, 0x7B, 0x8F, 0xEC, 0xD2, 0x56, 0xE4, 0xEF, 0xA7, 0x87, 0x0D, 0x2C, 0x85, 0x4B, 0x24, 0x7B, 0x8F, 0xEC, 0xD2, 0x56, 0xE4, 0xEF, 0xA7, 0x87, 0x0D, 0x2C, 0x85, 0x4B,
0xDE, 0xB3, 0x33, 0x90, 0xDE, 0xB3, 0x33, 0x90,
@ -571,7 +571,7 @@ mod tests {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
let (_, pubkey) = secp.generate_schnorrsig_keypair(&mut thread_rng()); let (_, pubkey) = secp.generate_schnorrsig_keypair(&mut thread_rng());
let ser = pubkey.serialize(); let ser = pubkey.serialize();
let pubkey2 = PublicKey::from_slice(&ser).unwrap(); let pubkey2 = XOnlyPublicKey::from_slice(&ser).unwrap();
assert_eq!(pubkey, pubkey2); assert_eq!(pubkey, pubkey2);
} }
@ -584,35 +584,35 @@ mod tests {
assert_eq!(SecretKey::from_str(sk_str).unwrap(), sk); assert_eq!(SecretKey::from_str(sk_str).unwrap(), sk);
let pk = ::key::PublicKey::from_keypair(&keypair); let pk = ::key::PublicKey::from_keypair(&keypair);
assert_eq!(::key::PublicKey::from_secret_key(&secp, &sk), pk); assert_eq!(::key::PublicKey::from_secret_key(&secp, &sk), pk);
let xpk = PublicKey::from_keypair(&secp, &keypair); let xpk = XOnlyPublicKey::from_keypair(&secp, &keypair);
assert_eq!(PublicKey::from(pk), xpk); assert_eq!(XOnlyPublicKey::from(pk), xpk);
} }
#[test] #[test]
fn test_pubkey_from_bad_slice() { fn test_pubkey_from_bad_slice() {
// Bad sizes // Bad sizes
assert_eq!( assert_eq!(
PublicKey::from_slice(&[0; constants::SCHNORRSIG_PUBLIC_KEY_SIZE - 1]), XOnlyPublicKey::from_slice(&[0; constants::SCHNORRSIG_PUBLIC_KEY_SIZE - 1]),
Err(InvalidPublicKey) Err(InvalidPublicKey)
); );
assert_eq!( assert_eq!(
PublicKey::from_slice(&[0; constants::SCHNORRSIG_PUBLIC_KEY_SIZE + 1]), XOnlyPublicKey::from_slice(&[0; constants::SCHNORRSIG_PUBLIC_KEY_SIZE + 1]),
Err(InvalidPublicKey) Err(InvalidPublicKey)
); );
// Bad parse // Bad parse
assert_eq!( assert_eq!(
PublicKey::from_slice(&[0xff; constants::SCHNORRSIG_PUBLIC_KEY_SIZE]), XOnlyPublicKey::from_slice(&[0xff; constants::SCHNORRSIG_PUBLIC_KEY_SIZE]),
Err(InvalidPublicKey) Err(InvalidPublicKey)
); );
// In fuzzing mode restrictions on public key validity are much more // In fuzzing mode restrictions on public key validity are much more
// relaxed, thus the invalid check below is expected to fail. // relaxed, thus the invalid check below is expected to fail.
#[cfg(not(fuzzing))] #[cfg(not(fuzzing))]
assert_eq!( assert_eq!(
PublicKey::from_slice(&[0x55; constants::SCHNORRSIG_PUBLIC_KEY_SIZE]), XOnlyPublicKey::from_slice(&[0x55; constants::SCHNORRSIG_PUBLIC_KEY_SIZE]),
Err(InvalidPublicKey) Err(InvalidPublicKey)
); );
assert_eq!(PublicKey::from_slice(&[]), Err(InvalidPublicKey)); assert_eq!(XOnlyPublicKey::from_slice(&[]), Err(InvalidPublicKey));
} }
#[test] #[test]
@ -630,43 +630,43 @@ mod tests {
// In fuzzing mode secret->public key derivation is different, so // In fuzzing mode secret->public key derivation is different, so
// hard-code the epected result. // hard-code the epected result.
#[cfg(not(fuzzing))] #[cfg(not(fuzzing))]
let pk = PublicKey::from_keypair(&s, &sk); let pk = XOnlyPublicKey::from_keypair(&s, &sk);
#[cfg(fuzzing)] #[cfg(fuzzing)]
let pk = PublicKey::from_slice(&[0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f, 0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92, 0x06, 0x7d, 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54, 0x4a, 0xc8, 0x87, 0xfe, 0x91, 0xdd, 0xd1, 0x66]).expect("pk"); let pk = XOnlyPublicKey::from_slice(&[0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f, 0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92, 0x06, 0x7d, 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54, 0x4a, 0xc8, 0x87, 0xfe, 0x91, 0xdd, 0xd1, 0x66]).expect("pk");
assert_eq!( assert_eq!(
pk.to_string(), pk.to_string(),
"18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166" "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166"
); );
assert_eq!( assert_eq!(
PublicKey::from_str("18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166") XOnlyPublicKey::from_str("18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166")
.unwrap(), .unwrap(),
pk pk
); );
assert!(PublicKey::from_str( assert!(XOnlyPublicKey::from_str(
"00000000000000000000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000000000000000000"
) )
.is_err()); .is_err());
assert!(PublicKey::from_str( assert!(XOnlyPublicKey::from_str(
"18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16601" "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16601"
) )
.is_err()); .is_err());
assert!(PublicKey::from_str( assert!(XOnlyPublicKey::from_str(
"18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16" "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16"
) )
.is_err()); .is_err());
assert!(PublicKey::from_str( assert!(XOnlyPublicKey::from_str(
"18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1" "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1"
) )
.is_err()); .is_err());
assert!(PublicKey::from_str( assert!(XOnlyPublicKey::from_str(
"xx18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1" "xx18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1"
) )
.is_err()); .is_err());
let long_str: String = iter::repeat('a').take(1024 * 1024).collect(); let long_str: String = iter::repeat('a').take(1024 * 1024).collect();
assert!(PublicKey::from_str(&long_str).is_err()); assert!(XOnlyPublicKey::from_str(&long_str).is_err());
} }
#[test] #[test]
@ -734,7 +734,7 @@ mod tests {
static PK_STR: &'static str = "\ static PK_STR: &'static str = "\
18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166\ 18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166\
"; ";
let pk = PublicKey::from_slice(&PK_BYTES).unwrap(); let pk = XOnlyPublicKey::from_slice(&PK_BYTES).unwrap();
assert_tokens(&sig.compact(), &[Token::BorrowedBytes(&SIG_BYTES[..])]); assert_tokens(&sig.compact(), &[Token::BorrowedBytes(&SIG_BYTES[..])]);
assert_tokens(&sig.compact(), &[Token::Bytes(&SIG_BYTES[..])]); assert_tokens(&sig.compact(), &[Token::Bytes(&SIG_BYTES[..])]);
@ -763,7 +763,7 @@ mod tests {
let orig_pk = pk; let orig_pk = pk;
kp.tweak_add_assign(&s, &tweak).expect("Tweak error"); kp.tweak_add_assign(&s, &tweak).expect("Tweak error");
let parity = pk.tweak_add_assign(&s, &tweak).expect("Tweak error"); let parity = pk.tweak_add_assign(&s, &tweak).expect("Tweak error");
assert_eq!(PublicKey::from_keypair(&s, &kp), pk); assert_eq!(XOnlyPublicKey::from_keypair(&s, &kp), pk);
assert!(orig_pk.tweak_add_check(&s, &pk, parity, tweak)); assert!(orig_pk.tweak_add_check(&s, &pk, parity, tweak));
} }
} }
@ -779,8 +779,8 @@ mod tests {
) )
.unwrap(); .unwrap();
let pk1 = PublicKey::from(kpk1); let pk1 = XOnlyPublicKey::from(kpk1);
let pk2 = PublicKey::from(kpk2); let pk2 = XOnlyPublicKey::from(kpk2);
assert_eq!(pk1.serialize()[..], kpk1.serialize()[1..]); assert_eq!(pk1.serialize()[..], kpk1.serialize()[1..]);
assert_eq!(pk2.serialize()[..], kpk2.serialize()[1..]); assert_eq!(pk2.serialize()[..], kpk2.serialize()[1..]);