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:
parent
60c93c387f
commit
53a6efe33c
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue