Move `XOnlyPublicKey` to `key` module
This commit is contained in:
parent
87d936a765
commit
d4fb819d80
247
src/key.rs
247
src/key.rs
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#[cfg(any(test, feature = "rand"))] use rand::Rng;
|
#[cfg(any(test, feature = "rand"))] use rand::Rng;
|
||||||
|
|
||||||
use core::{fmt, str};
|
use core::{fmt, ptr, str};
|
||||||
|
|
||||||
use super::{from_hex, Secp256k1};
|
use super::{from_hex, Secp256k1};
|
||||||
use super::Error::{self, InvalidPublicKey, InvalidPublicKeySum, InvalidSecretKey};
|
use super::Error::{self, InvalidPublicKey, InvalidPublicKeySum, InvalidSecretKey};
|
||||||
|
@ -674,6 +674,251 @@ impl<'a> From<&'a KeyPair> for PublicKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A x-only public key, used for verification of Schnorr signatures and serialized according to BIP-340.
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct XOnlyPublicKey(ffi::XOnlyPublicKey);
|
||||||
|
|
||||||
|
impl fmt::LowerHex for XOnlyPublicKey {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let ser = self.serialize();
|
||||||
|
for ch in &ser[..] {
|
||||||
|
write!(f, "{:02x}", *ch)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for XOnlyPublicKey {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
fmt::LowerHex::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl str::FromStr for XOnlyPublicKey {
|
||||||
|
type Err = Error;
|
||||||
|
fn from_str(s: &str) -> Result<XOnlyPublicKey, Error> {
|
||||||
|
let mut res = [0u8; constants::SCHNORRSIG_PUBLIC_KEY_SIZE];
|
||||||
|
match from_hex(s, &mut res) {
|
||||||
|
Ok(constants::SCHNORRSIG_PUBLIC_KEY_SIZE) => {
|
||||||
|
XOnlyPublicKey::from_slice(&res[0..constants::SCHNORRSIG_PUBLIC_KEY_SIZE])
|
||||||
|
}
|
||||||
|
_ => Err(Error::InvalidPublicKey),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl XOnlyPublicKey {
|
||||||
|
/// Obtains a raw const pointer suitable for use with FFI functions
|
||||||
|
#[inline]
|
||||||
|
pub fn as_ptr(&self) -> *const ffi::XOnlyPublicKey {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Obtains a raw mutable pointer suitable for use with FFI functions
|
||||||
|
#[inline]
|
||||||
|
pub fn as_mut_ptr(&mut self) -> *mut ffi::XOnlyPublicKey {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new Schnorr public key from a Schnorr key pair.
|
||||||
|
#[inline]
|
||||||
|
pub fn from_keypair<C: Signing>(secp: &Secp256k1<C>, keypair: &KeyPair) -> XOnlyPublicKey {
|
||||||
|
let mut pk_parity = 0;
|
||||||
|
unsafe {
|
||||||
|
let mut xonly_pk = ffi::XOnlyPublicKey::new();
|
||||||
|
let ret = ffi::secp256k1_keypair_xonly_pub(
|
||||||
|
secp.ctx,
|
||||||
|
&mut xonly_pk,
|
||||||
|
&mut pk_parity,
|
||||||
|
keypair.as_ptr(),
|
||||||
|
);
|
||||||
|
debug_assert_eq!(ret, 1);
|
||||||
|
XOnlyPublicKey(xonly_pk)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a Schnorr public key directly from a slice
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// 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
|
||||||
|
#[inline]
|
||||||
|
pub fn from_slice(data: &[u8]) -> Result<XOnlyPublicKey, Error> {
|
||||||
|
if data.is_empty() || data.len() != constants::SCHNORRSIG_PUBLIC_KEY_SIZE {
|
||||||
|
return Err(Error::InvalidPublicKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let mut pk = ffi::XOnlyPublicKey::new();
|
||||||
|
if ffi::secp256k1_xonly_pubkey_parse(
|
||||||
|
ffi::secp256k1_context_no_precomp,
|
||||||
|
&mut pk,
|
||||||
|
data.as_c_ptr(),
|
||||||
|
) == 1
|
||||||
|
{
|
||||||
|
Ok(XOnlyPublicKey(pk))
|
||||||
|
} else {
|
||||||
|
Err(Error::InvalidPublicKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Serialize the key as a byte-encoded x coordinate value (32 bytes).
|
||||||
|
pub fn serialize(&self) -> [u8; constants::SCHNORRSIG_PUBLIC_KEY_SIZE] {
|
||||||
|
let mut ret = [0u8; constants::SCHNORRSIG_PUBLIC_KEY_SIZE];
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let err = ffi::secp256k1_xonly_pubkey_serialize(
|
||||||
|
ffi::secp256k1_context_no_precomp,
|
||||||
|
ret.as_mut_c_ptr(),
|
||||||
|
self.as_c_ptr(),
|
||||||
|
);
|
||||||
|
debug_assert_eq!(err, 1);
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tweak an x-only PublicKey by adding the generator multiplied with the given tweak to it.
|
||||||
|
///
|
||||||
|
/// Returns a boolean representing the parity of the tweaked key, which can be provided to
|
||||||
|
/// `tweak_add_check` which can be used to verify a tweak more efficiently than regenerating
|
||||||
|
/// it and checking equality. Will return an error if the resulting key would be invalid or
|
||||||
|
/// if the tweak was not a 32-byte length slice.
|
||||||
|
pub fn tweak_add_assign<V: Verification>(
|
||||||
|
&mut self,
|
||||||
|
secp: &Secp256k1<V>,
|
||||||
|
tweak: &[u8],
|
||||||
|
) -> Result<bool, Error> {
|
||||||
|
if tweak.len() != 32 {
|
||||||
|
return Err(Error::InvalidTweak);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let mut pubkey = ffi::PublicKey::new();
|
||||||
|
let mut err = ffi::secp256k1_xonly_pubkey_tweak_add(
|
||||||
|
secp.ctx,
|
||||||
|
&mut pubkey,
|
||||||
|
self.as_c_ptr(),
|
||||||
|
tweak.as_c_ptr(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if err != 1 {
|
||||||
|
return Err(Error::InvalidTweak);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut parity: ::secp256k1_sys::types::c_int = 0;
|
||||||
|
err = ffi::secp256k1_xonly_pubkey_from_pubkey(
|
||||||
|
secp.ctx,
|
||||||
|
&mut self.0,
|
||||||
|
&mut parity,
|
||||||
|
&pubkey,
|
||||||
|
);
|
||||||
|
|
||||||
|
if err == 0 {
|
||||||
|
Err(Error::InvalidPublicKey)
|
||||||
|
} else {
|
||||||
|
Ok(parity != 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Verify that a tweak produced by `tweak_add_assign` was computed correctly
|
||||||
|
///
|
||||||
|
/// Should be called on the original untweaked key. Takes the tweaked key and
|
||||||
|
/// output parity from `tweak_add_assign` as input.
|
||||||
|
///
|
||||||
|
/// Currently this is not much more efficient than just recomputing the tweak
|
||||||
|
/// and checking equality. However, in future this API will support batch
|
||||||
|
/// verification, which is significantly faster, so it is wise to design
|
||||||
|
/// protocols with this in mind.
|
||||||
|
pub fn tweak_add_check<V: Verification>(
|
||||||
|
&self,
|
||||||
|
secp: &Secp256k1<V>,
|
||||||
|
tweaked_key: &Self,
|
||||||
|
tweaked_parity: bool,
|
||||||
|
tweak: [u8; 32],
|
||||||
|
) -> bool {
|
||||||
|
let tweaked_ser = tweaked_key.serialize();
|
||||||
|
unsafe {
|
||||||
|
let err = ffi::secp256k1_xonly_pubkey_tweak_add_check(
|
||||||
|
secp.ctx,
|
||||||
|
tweaked_ser.as_c_ptr(),
|
||||||
|
if tweaked_parity { 1 } else { 0 },
|
||||||
|
&self.0,
|
||||||
|
tweak.as_c_ptr(),
|
||||||
|
);
|
||||||
|
|
||||||
|
err == 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CPtr for XOnlyPublicKey {
|
||||||
|
type Target = ffi::XOnlyPublicKey;
|
||||||
|
fn as_c_ptr(&self) -> *const Self::Target {
|
||||||
|
self.as_ptr()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
|
||||||
|
self.as_mut_ptr()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new Schnorr public key from a FFI x-only public key
|
||||||
|
impl From<ffi::XOnlyPublicKey> for XOnlyPublicKey {
|
||||||
|
#[inline]
|
||||||
|
fn from(pk: ffi::XOnlyPublicKey) -> XOnlyPublicKey {
|
||||||
|
XOnlyPublicKey(pk)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<::key::PublicKey> for XOnlyPublicKey {
|
||||||
|
fn from(src: ::key::PublicKey) -> XOnlyPublicKey {
|
||||||
|
unsafe {
|
||||||
|
let mut pk = ffi::XOnlyPublicKey::new();
|
||||||
|
assert_eq!(
|
||||||
|
1,
|
||||||
|
ffi::secp256k1_xonly_pubkey_from_pubkey(
|
||||||
|
ffi::secp256k1_context_no_precomp,
|
||||||
|
&mut pk,
|
||||||
|
ptr::null_mut(),
|
||||||
|
src.as_c_ptr(),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
XOnlyPublicKey(pk)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
impl ::serde::Serialize for XOnlyPublicKey {
|
||||||
|
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
|
||||||
|
if s.is_human_readable() {
|
||||||
|
s.collect_str(self)
|
||||||
|
} else {
|
||||||
|
s.serialize_bytes(&self.serialize())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
impl<'de> ::serde::Deserialize<'de> for XOnlyPublicKey {
|
||||||
|
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
|
||||||
|
if d.is_human_readable() {
|
||||||
|
d.deserialize_str(super::serde_util::FromStrVisitor::new(
|
||||||
|
"a hex string representing 32 byte schnorr public key"
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
d.deserialize_bytes(super::serde_util::BytesVisitor::new(
|
||||||
|
"raw 32 bytes schnorr public key",
|
||||||
|
XOnlyPublicKey::from_slice
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use Secp256k1;
|
use Secp256k1;
|
||||||
|
|
|
@ -156,6 +156,7 @@ pub use key::SecretKey;
|
||||||
pub use key::PublicKey;
|
pub use key::PublicKey;
|
||||||
pub use key::ONE_KEY;
|
pub use key::ONE_KEY;
|
||||||
pub use key::KeyPair;
|
pub use key::KeyPair;
|
||||||
|
pub use key::XOnlyPublicKey;
|
||||||
pub use context::*;
|
pub use context::*;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::{mem, fmt, ptr, str};
|
use core::{mem, fmt, ptr, str};
|
||||||
|
|
|
@ -11,8 +11,7 @@ use super::{from_hex, Error};
|
||||||
use core::{fmt, ptr, str};
|
use core::{fmt, ptr, str};
|
||||||
use ffi::{self, CPtr};
|
use ffi::{self, CPtr};
|
||||||
use {constants, Secp256k1};
|
use {constants, Secp256k1};
|
||||||
use {Message, Signing, Verification};
|
use {Message, Signing, KeyPair, XOnlyPublicKey};
|
||||||
use KeyPair;
|
|
||||||
|
|
||||||
/// Represents a Schnorr signature.
|
/// Represents a Schnorr signature.
|
||||||
pub struct Signature([u8; constants::SCHNORRSIG_SIGNATURE_SIZE]);
|
pub struct Signature([u8; constants::SCHNORRSIG_SIGNATURE_SIZE]);
|
||||||
|
@ -74,39 +73,6 @@ impl str::FromStr for Signature {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A x-only public key, used for verification of Schnorr signatures
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
|
|
||||||
pub struct XOnlyPublicKey(ffi::XOnlyPublicKey);
|
|
||||||
|
|
||||||
impl fmt::LowerHex for XOnlyPublicKey {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
let ser = self.serialize();
|
|
||||||
for ch in &ser[..] {
|
|
||||||
write!(f, "{:02x}", *ch)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for XOnlyPublicKey {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
fmt::LowerHex::fmt(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl str::FromStr for XOnlyPublicKey {
|
|
||||||
type Err = Error;
|
|
||||||
fn from_str(s: &str) -> Result<XOnlyPublicKey, Error> {
|
|
||||||
let mut res = [0u8; constants::SCHNORRSIG_PUBLIC_KEY_SIZE];
|
|
||||||
match from_hex(s, &mut res) {
|
|
||||||
Ok(constants::SCHNORRSIG_PUBLIC_KEY_SIZE) => {
|
|
||||||
XOnlyPublicKey::from_slice(&res[0..constants::SCHNORRSIG_PUBLIC_KEY_SIZE])
|
|
||||||
}
|
|
||||||
_ => Err(Error::InvalidPublicKey),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Signature {
|
impl Signature {
|
||||||
/// Creates a Signature directly from a slice
|
/// Creates a Signature directly from a slice
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -122,218 +88,6 @@ impl Signature {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XOnlyPublicKey {
|
|
||||||
/// Obtains a raw const pointer suitable for use with FFI functions
|
|
||||||
#[inline]
|
|
||||||
pub fn as_ptr(&self) -> *const ffi::XOnlyPublicKey {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Obtains a raw mutable pointer suitable for use with FFI functions
|
|
||||||
#[inline]
|
|
||||||
pub fn as_mut_ptr(&mut self) -> *mut ffi::XOnlyPublicKey {
|
|
||||||
&mut self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new Schnorr public key from a Schnorr key pair.
|
|
||||||
#[inline]
|
|
||||||
pub fn from_keypair<C: Signing>(secp: &Secp256k1<C>, keypair: &KeyPair) -> XOnlyPublicKey {
|
|
||||||
let mut pk_parity = 0;
|
|
||||||
unsafe {
|
|
||||||
let mut xonly_pk = ffi::XOnlyPublicKey::new();
|
|
||||||
let ret = ffi::secp256k1_keypair_xonly_pub(
|
|
||||||
secp.ctx,
|
|
||||||
&mut xonly_pk,
|
|
||||||
&mut pk_parity,
|
|
||||||
keypair.as_ptr(),
|
|
||||||
);
|
|
||||||
debug_assert_eq!(ret, 1);
|
|
||||||
XOnlyPublicKey(xonly_pk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a Schnorr public key directly from a slice
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// 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
|
|
||||||
#[inline]
|
|
||||||
pub fn from_slice(data: &[u8]) -> Result<XOnlyPublicKey, Error> {
|
|
||||||
if data.is_empty() || data.len() != constants::SCHNORRSIG_PUBLIC_KEY_SIZE {
|
|
||||||
return Err(Error::InvalidPublicKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let mut pk = ffi::XOnlyPublicKey::new();
|
|
||||||
if ffi::secp256k1_xonly_pubkey_parse(
|
|
||||||
ffi::secp256k1_context_no_precomp,
|
|
||||||
&mut pk,
|
|
||||||
data.as_c_ptr(),
|
|
||||||
) == 1
|
|
||||||
{
|
|
||||||
Ok(XOnlyPublicKey(pk))
|
|
||||||
} else {
|
|
||||||
Err(Error::InvalidPublicKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Serialize the key as a byte-encoded x coordinate value (32 bytes).
|
|
||||||
pub fn serialize(&self) -> [u8; constants::SCHNORRSIG_PUBLIC_KEY_SIZE] {
|
|
||||||
let mut ret = [0u8; constants::SCHNORRSIG_PUBLIC_KEY_SIZE];
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let err = ffi::secp256k1_xonly_pubkey_serialize(
|
|
||||||
ffi::secp256k1_context_no_precomp,
|
|
||||||
ret.as_mut_c_ptr(),
|
|
||||||
self.as_c_ptr(),
|
|
||||||
);
|
|
||||||
debug_assert_eq!(err, 1);
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Tweak an x-only PublicKey by adding the generator multiplied with the given tweak to it.
|
|
||||||
///
|
|
||||||
/// Returns a boolean representing the parity of the tweaked key, which can be provided to
|
|
||||||
/// `tweak_add_check` which can be used to verify a tweak more efficiently than regenerating
|
|
||||||
/// it and checking equality. Will return an error if the resulting key would be invalid or
|
|
||||||
/// if the tweak was not a 32-byte length slice.
|
|
||||||
pub fn tweak_add_assign<V: Verification>(
|
|
||||||
&mut self,
|
|
||||||
secp: &Secp256k1<V>,
|
|
||||||
tweak: &[u8],
|
|
||||||
) -> Result<bool, Error> {
|
|
||||||
if tweak.len() != 32 {
|
|
||||||
return Err(Error::InvalidTweak);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let mut pubkey = ffi::PublicKey::new();
|
|
||||||
let mut err = ffi::secp256k1_xonly_pubkey_tweak_add(
|
|
||||||
secp.ctx,
|
|
||||||
&mut pubkey,
|
|
||||||
self.as_c_ptr(),
|
|
||||||
tweak.as_c_ptr(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if err != 1 {
|
|
||||||
return Err(Error::InvalidTweak);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut parity: ::secp256k1_sys::types::c_int = 0;
|
|
||||||
err = ffi::secp256k1_xonly_pubkey_from_pubkey(
|
|
||||||
secp.ctx,
|
|
||||||
&mut self.0,
|
|
||||||
&mut parity,
|
|
||||||
&pubkey,
|
|
||||||
);
|
|
||||||
|
|
||||||
if err == 0 {
|
|
||||||
Err(Error::InvalidPublicKey)
|
|
||||||
} else {
|
|
||||||
Ok(parity != 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Verify that a tweak produced by `tweak_add_assign` was computed correctly
|
|
||||||
///
|
|
||||||
/// Should be called on the original untweaked key. Takes the tweaked key and
|
|
||||||
/// output parity from `tweak_add_assign` as input.
|
|
||||||
///
|
|
||||||
/// Currently this is not much more efficient than just recomputing the tweak
|
|
||||||
/// and checking equality. However, in future this API will support batch
|
|
||||||
/// verification, which is significantly faster, so it is wise to design
|
|
||||||
/// protocols with this in mind.
|
|
||||||
pub fn tweak_add_check<V: Verification>(
|
|
||||||
&self,
|
|
||||||
secp: &Secp256k1<V>,
|
|
||||||
tweaked_key: &Self,
|
|
||||||
tweaked_parity: bool,
|
|
||||||
tweak: [u8; 32],
|
|
||||||
) -> bool {
|
|
||||||
let tweaked_ser = tweaked_key.serialize();
|
|
||||||
unsafe {
|
|
||||||
let err = ffi::secp256k1_xonly_pubkey_tweak_add_check(
|
|
||||||
secp.ctx,
|
|
||||||
tweaked_ser.as_c_ptr(),
|
|
||||||
if tweaked_parity { 1 } else { 0 },
|
|
||||||
&self.0,
|
|
||||||
tweak.as_c_ptr(),
|
|
||||||
);
|
|
||||||
|
|
||||||
err == 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CPtr for XOnlyPublicKey {
|
|
||||||
type Target = ffi::XOnlyPublicKey;
|
|
||||||
fn as_c_ptr(&self) -> *const Self::Target {
|
|
||||||
self.as_ptr()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
|
|
||||||
self.as_mut_ptr()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new Schnorr public key from a FFI x-only public key
|
|
||||||
impl From<ffi::XOnlyPublicKey> for XOnlyPublicKey {
|
|
||||||
#[inline]
|
|
||||||
fn from(pk: ffi::XOnlyPublicKey) -> XOnlyPublicKey {
|
|
||||||
XOnlyPublicKey(pk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<::key::PublicKey> for XOnlyPublicKey {
|
|
||||||
fn from(src: ::key::PublicKey) -> XOnlyPublicKey {
|
|
||||||
unsafe {
|
|
||||||
let mut pk = ffi::XOnlyPublicKey::new();
|
|
||||||
assert_eq!(
|
|
||||||
1,
|
|
||||||
ffi::secp256k1_xonly_pubkey_from_pubkey(
|
|
||||||
ffi::secp256k1_context_no_precomp,
|
|
||||||
&mut pk,
|
|
||||||
ptr::null_mut(),
|
|
||||||
src.as_c_ptr(),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
XOnlyPublicKey(pk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
impl ::serde::Serialize for XOnlyPublicKey {
|
|
||||||
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
|
|
||||||
if s.is_human_readable() {
|
|
||||||
s.collect_str(self)
|
|
||||||
} else {
|
|
||||||
s.serialize_bytes(&self.serialize())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
impl<'de> ::serde::Deserialize<'de> for XOnlyPublicKey {
|
|
||||||
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
|
|
||||||
if d.is_human_readable() {
|
|
||||||
d.deserialize_str(super::serde_util::FromStrVisitor::new(
|
|
||||||
"a hex string representing 32 byte schnorr public key"
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
d.deserialize_bytes(super::serde_util::BytesVisitor::new(
|
|
||||||
"raw 32 bytes schnorr public key",
|
|
||||||
XOnlyPublicKey::from_slice
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: Signing> Secp256k1<C> {
|
impl<C: Signing> Secp256k1<C> {
|
||||||
fn schnorrsig_sign_helper(
|
fn schnorrsig_sign_helper(
|
||||||
&self,
|
&self,
|
||||||
|
|
Loading…
Reference in New Issue