Add PublicKey struct encapsulating compressedness

- Move util::privkey to util::key
- Add PublicKey struct to util::key
- Implement de/serialization methods for util:🔑:PublicKey
This commit is contained in:
Carl Dong 2018-11-15 13:55:33 -08:00
parent 60c93c387f
commit 53a6efe33c
3 changed files with 48 additions and 9 deletions

View File

@ -76,6 +76,7 @@ pub use network::constants::Network;
pub use util::Error; pub use util::Error;
pub use util::address::Address; pub use util::address::Address;
pub use util::hash::BitcoinHash; pub use util::hash::BitcoinHash;
pub use util::privkey::PrivateKey; pub use util::key::PrivateKey;
pub use util::key::PublicKey;
pub use util::decimal::Decimal; pub use util::decimal::Decimal;
pub use util::decimal::UDecimal; pub use util::decimal::UDecimal;

View File

@ -11,19 +11,57 @@
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. // If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
// //
//! Private key //! Bitcoin Keys
//! //!
//! A private key represents the secret data associated with its proposed use //! Keys used in Bitcoin that can be roundtrip (de)serialized.
//! //!
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use std::io;
use std::str::FromStr; use std::str::FromStr;
use secp256k1::{self, Secp256k1}; use secp256k1::{self, Secp256k1};
use secp256k1::key::{PublicKey, SecretKey};
use consensus::encode; use consensus::encode;
use network::constants::Network; use network::constants::Network;
use util::base58; use util::base58;
/// A Bitcoin ECDSA public key
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct PublicKey {
/// Whether this public key represents a compressed address
pub compressed: bool,
/// The actual ECDSA key
pub key: secp256k1::PublicKey,
}
impl PublicKey {
/// Write the public key into a writer
pub fn write_into<W: io::Write>(&self, writer: &mut W) {
let write_res: io::Result<()> = if self.compressed {
writer.write_all(&self.key.serialize())
} else {
writer.write_all(&self.key.serialize_uncompressed())
};
debug_assert!(write_res.is_ok());
}
/// Deserialize a public key from a slice
pub fn from_slice(data: &[u8]) -> Result<PublicKey, encode::Error> {
let key: secp256k1::PublicKey = secp256k1::PublicKey::from_slice(data)
.map_err(|_| base58::Error::Other("Public key out of range".to_owned()))?;
let compressed: bool = match data.len() {
33 => true,
65 => false,
_ => { return Err(base58::Error::InvalidLength(data.len()).into()); },
};
Ok(PublicKey {
compressed: compressed,
key: key,
})
}
}
#[derive(Clone, PartialEq, Eq)] #[derive(Clone, PartialEq, Eq)]
/// A Bitcoin ECDSA private key /// A Bitcoin ECDSA private key
pub struct PrivateKey { pub struct PrivateKey {
@ -32,13 +70,13 @@ pub struct PrivateKey {
/// The network on which this key should be used /// The network on which this key should be used
pub network: Network, pub network: Network,
/// The actual ECDSA key /// The actual ECDSA key
pub key: SecretKey pub key: secp256k1::SecretKey,
} }
impl PrivateKey { impl PrivateKey {
/// Computes the public key as supposed to be used with this secret /// Computes the public key as supposed to be used with this secret
pub fn public_key<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> PublicKey { pub fn public_key<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> secp256k1::PublicKey {
PublicKey::from_secret_key(secp, &self.key) secp256k1::PublicKey::from_secret_key(secp, &self.key)
} }
/// Format the private key to WIF format. /// Format the private key to WIF format.
@ -82,7 +120,7 @@ impl PrivateKey {
x => { return Err(encode::Error::Base58(base58::Error::InvalidVersion(vec![x]))); } x => { return Err(encode::Error::Base58(base58::Error::InvalidVersion(vec![x]))); }
}; };
let key = SecretKey::from_slice(&data[1..33]) let key = secp256k1::SecretKey::from_slice(&data[1..33])
.map_err(|_| base58::Error::Other("Secret key out of range".to_owned()))?; .map_err(|_| base58::Error::Other("Secret key out of range".to_owned()))?;
Ok(PrivateKey { Ok(PrivateKey {

View File

@ -16,7 +16,7 @@
//! //!
//! Functions needed by all parts of the Bitcoin library //! Functions needed by all parts of the Bitcoin library
pub mod privkey; pub mod key;
pub mod address; pub mod address;
pub mod base58; pub mod base58;
pub mod bip32; pub mod bip32;