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::address::Address;
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::UDecimal;

View File

@ -11,19 +11,57 @@
// 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::io;
use std::str::FromStr;
use secp256k1::{self, Secp256k1};
use secp256k1::key::{PublicKey, SecretKey};
use consensus::encode;
use network::constants::Network;
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)]
/// A Bitcoin ECDSA private key
pub struct PrivateKey {
@ -32,13 +70,13 @@ pub struct PrivateKey {
/// The network on which this key should be used
pub network: Network,
/// The actual ECDSA key
pub key: SecretKey
pub key: secp256k1::SecretKey,
}
impl PrivateKey {
/// Computes the public key as supposed to be used with this secret
pub fn public_key<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> PublicKey {
PublicKey::from_secret_key(secp, &self.key)
pub fn public_key<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> secp256k1::PublicKey {
secp256k1::PublicKey::from_secret_key(secp, &self.key)
}
/// Format the private key to WIF format.
@ -82,7 +120,7 @@ impl PrivateKey {
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()))?;
Ok(PrivateKey {

View File

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