Fixing documentation for BIP 340-related functions

This commit is contained in:
Dr Maxim Orlovsky 2021-09-27 15:19:27 +02:00
parent 24a9c9c765
commit 931b560dc7
No known key found for this signature in database
GPG Key ID: FFC0250947E5C6F7
1 changed files with 38 additions and 20 deletions

View File

@ -7,7 +7,6 @@ use rand::thread_rng;
#[cfg(any(test, feature = "rand"))] #[cfg(any(test, feature = "rand"))]
use rand::{CryptoRng, Rng}; use rand::{CryptoRng, Rng};
use super::Error::{InvalidPublicKey, InvalidSecretKey, InvalidSignature};
use super::{from_hex, Error}; use super::{from_hex, Error};
use core::{fmt, ptr, str}; use core::{fmt, ptr, str};
use ffi::{self, CPtr}; use ffi::{self, CPtr};
@ -107,7 +106,7 @@ impl str::FromStr for PublicKey {
Ok(constants::SCHNORRSIG_PUBLIC_KEY_SIZE) => { Ok(constants::SCHNORRSIG_PUBLIC_KEY_SIZE) => {
PublicKey::from_slice(&res[0..constants::SCHNORRSIG_PUBLIC_KEY_SIZE]) PublicKey::from_slice(&res[0..constants::SCHNORRSIG_PUBLIC_KEY_SIZE])
} }
_ => Err(InvalidPublicKey), _ => Err(Error::InvalidPublicKey),
} }
} }
} }
@ -122,7 +121,7 @@ impl Signature {
ret[..].copy_from_slice(data); ret[..].copy_from_slice(data);
Ok(Signature(ret)) Ok(Signature(ret))
} }
_ => Err(InvalidSignature), _ => Err(Error::InvalidSignature),
} }
} }
} }
@ -142,9 +141,11 @@ impl KeyPair {
/// Creates a Schnorr KeyPair directly from generic Secp256k1 secret key /// Creates a Schnorr KeyPair directly from generic Secp256k1 secret key
/// ///
/// Panics if internal representation of the provided [`SecretKey`] does not /// # Panic
/// holds correct secret key value obtained from Secp256k1 library ///
/// previously /// Panics if internal representation of the provided [`SecretKey`] does not hold correct secret
/// key value obtained from Secp256k1 library previously, specifically when secret key value is
/// out-of-range (0 or in excess of the group order).
#[inline] #[inline]
pub fn from_secret_key<C: Signing>( pub fn from_secret_key<C: Signing>(
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
@ -160,14 +161,19 @@ impl KeyPair {
} }
} }
/// Creates a Schnorr KeyPair directly from a secret key slice /// Creates a Schnorr KeyPair directly from a secret key slice.
///
/// # Errors
///
/// [`Error::InvalidSecretKey`] if the provided data has an incorrect length, exceeds Secp256k1
/// field `p` value or the corresponding public key is not even.
#[inline] #[inline]
pub fn from_seckey_slice<C: Signing>( pub fn from_seckey_slice<C: Signing>(
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
data: &[u8], data: &[u8],
) -> Result<KeyPair, Error> { ) -> Result<KeyPair, Error> {
if data.is_empty() || data.len() != constants::SECRET_KEY_SIZE { if data.is_empty() || data.len() != constants::SECRET_KEY_SIZE {
return Err(InvalidSecretKey); return Err(Error::InvalidSecretKey);
} }
unsafe { unsafe {
@ -175,12 +181,16 @@ impl KeyPair {
if ffi::secp256k1_keypair_create(secp.ctx, &mut kp, data.as_c_ptr()) == 1 { if ffi::secp256k1_keypair_create(secp.ctx, &mut kp, data.as_c_ptr()) == 1 {
Ok(KeyPair(kp)) Ok(KeyPair(kp))
} else { } else {
Err(InvalidSecretKey) Err(Error::InvalidSecretKey)
} }
} }
} }
/// Creates a Schnorr KeyPair directly from a secret key string /// Creates a Schnorr KeyPair directly from a secret key string
///
/// # Errors
///
/// [`Error::InvalidSecretKey`] if corresponding public key for the provided secret key is not even.
#[inline] #[inline]
pub fn from_seckey_str<C: Signing>(secp: &Secp256k1<C>, s: &str) -> Result<KeyPair, Error> { pub fn from_seckey_str<C: Signing>(secp: &Secp256k1<C>, s: &str) -> Result<KeyPair, Error> {
let mut res = [0; constants::SECRET_KEY_SIZE]; let mut res = [0; constants::SECRET_KEY_SIZE];
@ -188,7 +198,7 @@ impl KeyPair {
Ok(constants::SECRET_KEY_SIZE) => { Ok(constants::SECRET_KEY_SIZE) => {
KeyPair::from_seckey_slice(secp, &res[0..constants::SECRET_KEY_SIZE]) KeyPair::from_seckey_slice(secp, &res[0..constants::SECRET_KEY_SIZE])
} }
_ => Err(InvalidPublicKey), _ => Err(Error::InvalidPublicKey),
} }
} }
@ -217,10 +227,15 @@ impl KeyPair {
*SecretKey::from_keypair(self).as_ref() *SecretKey::from_keypair(self).as_ref()
} }
/// Tweak a keypair by adding the given tweak to the secret key and updating the /// Tweak a keypair by adding the given tweak to the secret key and updating the public key
/// public key accordingly. /// accordingly.
/// Will return an error if the resulting key would be invalid or if ///
/// the tweak was not a 32-byte length slice. /// Will return an error if the resulting key would be invalid or if the tweak was not a 32-byte
/// length slice.
///
/// NB: Will not error if the tweaked public key has an odd value and can't be used for
/// BIP 340-342 purposes.
// TODO: Add checked implementation
#[inline] #[inline]
pub fn tweak_add_assign<C: Verification>( pub fn tweak_add_assign<C: Verification>(
&mut self, &mut self,
@ -260,7 +275,7 @@ impl PublicKey {
&mut self.0 &mut self.0
} }
/// 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) -> PublicKey {
let mut pk_parity = 0; let mut pk_parity = 0;
@ -278,10 +293,15 @@ impl PublicKey {
} }
/// Creates a Schnorr public key directly from a slice /// 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] #[inline]
pub fn from_slice(data: &[u8]) -> Result<PublicKey, Error> { pub fn from_slice(data: &[u8]) -> Result<PublicKey, 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(InvalidPublicKey); return Err(Error::InvalidPublicKey);
} }
unsafe { unsafe {
@ -294,15 +314,13 @@ impl PublicKey {
{ {
Ok(PublicKey(pk)) Ok(PublicKey(pk))
} else { } else {
Err(InvalidPublicKey) Err(Error::InvalidPublicKey)
} }
} }
} }
#[inline] #[inline]
/// Serialize the key as a byte-encoded pair of values. In compressed form /// Serialize the key as a byte-encoded x coordinate value (32 bytes).
/// the y-coordinate is represented by only a single bit, as x determines
/// it up to one bit.
pub fn serialize(&self) -> [u8; constants::SCHNORRSIG_PUBLIC_KEY_SIZE] { pub fn serialize(&self) -> [u8; constants::SCHNORRSIG_PUBLIC_KEY_SIZE] {
let mut ret = [0; constants::SCHNORRSIG_PUBLIC_KEY_SIZE]; let mut ret = [0; constants::SCHNORRSIG_PUBLIC_KEY_SIZE];