bitcoin/util/
key.rs

1// Rust Bitcoin Library
2// Written in 2014 by
3//     Andrew Poelstra <apoelstra@wpsoftware.net>
4// To the extent possible under law, the author(s) have dedicated all
5// copyright and related and neighboring rights to this software to
6// the public domain worldwide. This software is distributed without
7// any warranty.
8//
9// You should have received a copy of the CC0 Public Domain Dedication
10// along with this software.
11// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
12//
13
14//! Bitcoin Keys
15//!
16//! Keys used in Bitcoin that can be roundtrip (de)serialized.
17//!
18
19use std::fmt::{self, Write};
20use std::{io, ops, error};
21use std::str::FromStr;
22
23use secp256k1::{self, ContextFlag, Secp256k1};
24use network::constants::Network;
25use hashes::{Hash, hash160};
26use hash_types::{PubkeyHash, WPubkeyHash};
27use util::base58;
28use util::misc::hex_bytes;
29
30/// A key-related error.
31#[derive(Debug)]
32pub enum Error {
33    /// Base58 encoding error
34    Base58(base58::Error),
35    /// secp256k1-related error
36    Secp256k1(secp256k1::Error),
37}
38
39
40impl fmt::Display for Error {
41    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42        match *self {
43            Error::Base58(ref e) => write!(f, "base58 error: {}", e),
44            Error::Secp256k1(ref e) => write!(f, "secp256k1 error: {}", e),
45        }
46    }
47}
48
49impl error::Error for Error {
50    fn cause(&self) -> Option<&dyn error::Error> {
51        match *self {
52            Error::Base58(ref e) => Some(e),
53            Error::Secp256k1(ref e) => Some(e),
54        }
55    }
56}
57
58#[doc(hidden)]
59impl From<base58::Error> for Error {
60    fn from(e: base58::Error) -> Error {
61        Error::Base58(e)
62    }
63}
64
65#[doc(hidden)]
66impl From<secp256k1::Error> for Error {
67    fn from(e: secp256k1::Error) -> Error {
68        Error::Secp256k1(e)
69    }
70}
71
72/// A Bitcoin ECDSA public key
73#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
74pub struct PublicKey {
75    /// Whether this public key should be serialized as compressed
76    pub compressed: bool,
77    /// The actual ECDSA key
78    pub key: secp256k1::PublicKey,
79}
80
81impl PublicKey {
82    /// Returns bitcoin 160-bit hash of the public key
83    pub fn pubkey_hash(&self, secp: &Secp256k1) -> PubkeyHash {
84        if self.compressed {
85            PubkeyHash::hash(&self.key.serialize_vec(secp, true).to_vec())
86        } else {
87            PubkeyHash::hash(&self.key.serialize_vec(secp, false).to_vec())
88        }
89    }
90
91    /// Returns bitcoin 160-bit hash of the public key for witness program
92    pub fn wpubkey_hash(&self, secp: &Secp256k1) -> Option<WPubkeyHash> {
93        if self.compressed {
94            Some(WPubkeyHash::from_inner(
95                hash160::Hash::hash(&self.key.serialize_vec(secp, true).to_vec()).into_inner()
96            ))
97        } else {
98            // We can't create witness pubkey hashes for an uncompressed
99            // public keys
100            None
101        }
102    }
103
104    /// Write the public key into a writer
105    pub fn write_into<W: io::Write>(&self, secp: &Secp256k1, mut writer: W) -> Result<(), io::Error> {
106        if self.compressed {
107            writer.write_all(&self.key.serialize_vec(secp, true).to_vec())
108        } else {
109            writer.write_all(&self.key.serialize_vec(secp, false).to_vec())
110        }
111    }
112
113    /// Read the public key from a reader
114    ///
115    /// This internally reads the first byte before reading the rest, so
116    /// use of a `BufReader` is recommended.
117    pub fn read_from<R: io::Read>(secp: &Secp256k1, mut reader: R) -> Result<Self, io::Error> {
118        let mut bytes = [0; 65];
119
120        reader.read_exact(&mut bytes[0..1])?;
121        let bytes = if bytes[0] < 4 {
122            &mut bytes[..33]
123        } else {
124            &mut bytes[..65]
125        };
126
127        reader.read_exact(&mut bytes[1..])?;
128        Self::from_slice(secp, bytes).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
129    }
130
131    /// Serialize the public key to bytes
132    pub fn to_bytes(&self, secp: &Secp256k1) -> Vec<u8> {
133        let mut buf = Vec::new();
134        self.write_into(secp, &mut buf).expect("vecs don't error");
135        buf
136    }
137
138    /// Deserialize a public key from a slice
139    pub fn from_slice(secp: &Secp256k1, data: &[u8]) -> Result<PublicKey, Error> {
140        let compressed: bool = match data.len() {
141            33 => true,
142            65 => false,
143            len =>  { return Err(base58::Error::InvalidLength(len).into()); },
144        };
145
146        Ok(PublicKey {
147            compressed: compressed,
148            key: secp256k1::PublicKey::from_slice(secp, data)?,
149        })
150    }
151
152    /// Computes the public key as supposed to be used with this secret
153    pub fn from_private_key(secp: &Secp256k1, sk: &PrivateKey) -> PublicKey {
154        sk.public_key(secp)
155    }
156}
157
158impl fmt::Display for PublicKey {
159    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
160        let secp = Secp256k1::with_caps(ContextFlag::None);
161        if self.compressed {
162            for ch in &self.key.serialize_vec(&secp, true)[..] {
163                write!(f, "{:02x}", ch)?;
164            }
165        } else {
166            for ch in &self.key.serialize_vec(&secp, false)[..] {
167                write!(f, "{:02x}", ch)?;
168            }
169        }
170        Ok(())
171    }
172}
173
174impl FromStr for PublicKey {
175    type Err = Error;
176    fn from_str(s: &str) -> Result<PublicKey, Error> {
177        let data = hex_bytes(s)
178            .map_err(|e| base58::Error::Other(format!("Unable to parse the HEX {}, {}", s, e)) )?;
179        let secp = Secp256k1::with_caps(ContextFlag::None);
180        let key = secp256k1::PublicKey::from_slice(&secp, &data)?;
181        Ok(PublicKey {
182            key: key,
183            compressed: s.len() == 66
184        })
185    }
186}
187
188#[derive(Clone, PartialEq, Eq)]
189/// A Bitcoin ECDSA private key
190pub struct PrivateKey {
191    /// Whether this private key should be serialized as compressed
192    pub compressed: bool,
193    /// The network on which this key should be used
194    pub network: Network,
195    /// The actual ECDSA key
196    pub key: secp256k1::SecretKey,
197}
198
199impl PrivateKey {
200    /// Creates a public key from this private key
201    pub fn public_key(&self, secp: &Secp256k1) -> PublicKey {
202        PublicKey {
203            compressed: self.compressed,
204            key: secp256k1::PublicKey::from_secret_key(secp, &self.key).unwrap()
205        }
206    }
207
208    /// Serialize the private key to bytes
209    pub fn to_bytes(&self) -> Vec<u8> {
210        self.key[..].to_vec()
211    }
212
213    /// Format the private key to WIF format.
214    pub fn fmt_wif(&self, fmt: &mut dyn fmt::Write) -> fmt::Result {
215        let mut ret = [0; 34];
216        ret[0] = match self.network {
217            Network::Bitcoin => 128,
218            Network::Testnet | Network::Signet | Network::Regtest => 239,
219        };
220        ret[1..33].copy_from_slice(&self.key[..]);
221        let privkey = if self.compressed {
222            ret[33] = 1;
223            base58::check_encode_slice(&ret[..])
224        } else {
225            base58::check_encode_slice(&ret[..33])
226        };
227        fmt.write_str(&privkey)
228    }
229
230    /// Get WIF encoding of this private key.
231    pub fn to_wif(&self) -> String {
232        let mut buf = String::new();
233        buf.write_fmt(format_args!("{}", self)).unwrap();
234        buf.shrink_to_fit();
235        buf
236    }
237
238    /// Parse WIF encoded private key.
239    pub fn from_wif(secp: &Secp256k1, wif: &str) -> Result<PrivateKey, Error> {
240        let data = base58::from_check(wif)?;
241
242        let compressed = match data.len() {
243            33 => false,
244            34 => true,
245            _ => { return Err(Error::Base58(base58::Error::InvalidLength(data.len()))); }
246        };
247
248        let network = match data[0] {
249            128 => Network::Bitcoin,
250            239 => Network::Testnet,
251            x   => { return Err(Error::Base58(base58::Error::InvalidVersion(vec![x]))); }
252        };
253
254        Ok(PrivateKey {
255            compressed: compressed,
256            network: network,
257            key: secp256k1::SecretKey::from_slice(secp, &data[1..33])?,
258        })
259    }
260}
261
262impl fmt::Display for PrivateKey {
263    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
264        self.fmt_wif(f)
265    }
266}
267
268impl fmt::Debug for PrivateKey {
269    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
270        write!(f, "[private key data]")
271    }
272}
273
274impl FromStr for PrivateKey {
275    type Err = Error;
276    fn from_str(s: &str) -> Result<PrivateKey, Error> {
277        let secp = Secp256k1::with_caps(ContextFlag::None);
278        PrivateKey::from_wif(&secp, s)
279    }
280}
281
282impl ops::Index<ops::RangeFull> for PrivateKey {
283    type Output = [u8];
284    fn index(&self, _: ops::RangeFull) -> &[u8] {
285        &self.key[..]
286    }
287}
288
289#[cfg(feature = "serde")]
290impl ::serde::Serialize for PrivateKey {
291    fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
292        s.collect_str(self)
293    }
294}
295
296#[cfg(feature = "serde")]
297impl<'de> ::serde::Deserialize<'de> for PrivateKey {
298    fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<PrivateKey, D::Error> {
299        struct WifVisitor;
300
301        impl<'de> ::serde::de::Visitor<'de> for WifVisitor {
302            type Value = PrivateKey;
303
304            fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
305                formatter.write_str("an ASCII WIF string")
306            }
307
308            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
309            where
310                E: ::serde::de::Error,
311            {
312                if let Ok(s) = ::std::str::from_utf8(v) {
313                    PrivateKey::from_str(s).map_err(E::custom)
314                } else {
315                    Err(E::invalid_value(::serde::de::Unexpected::Bytes(v), &self))
316                }
317            }
318
319            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
320            where
321                E: ::serde::de::Error,
322            {
323                PrivateKey::from_str(v).map_err(E::custom)
324            }
325        }
326
327        d.deserialize_str(WifVisitor)
328    }
329}
330
331#[cfg(feature = "serde")]
332impl ::serde::Serialize for PublicKey {
333    fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
334        if s.is_human_readable() {
335            s.collect_str(self)
336        } else {
337            if self.compressed {
338                s.serialize_bytes(&self.key.serialize()[..])
339            } else {
340                s.serialize_bytes(&self.key.serialize_uncompressed()[..])
341            }
342        }
343    }
344}
345
346#[cfg(feature = "serde")]
347impl<'de> ::serde::Deserialize<'de> for PublicKey {
348    fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<PublicKey, D::Error> {
349        if d.is_human_readable() {
350            struct HexVisitor;
351
352            impl<'de> ::serde::de::Visitor<'de> for HexVisitor {
353                type Value = PublicKey;
354
355                fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
356                    formatter.write_str("an ASCII hex string")
357                }
358
359                fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
360                where
361                    E: ::serde::de::Error,
362                {
363                    if let Ok(hex) = ::std::str::from_utf8(v) {
364                        PublicKey::from_str(hex).map_err(E::custom)
365                    } else {
366                        Err(E::invalid_value(::serde::de::Unexpected::Bytes(v), &self))
367                    }
368                }
369
370                fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
371                where
372                    E: ::serde::de::Error,
373                {
374                    PublicKey::from_str(v).map_err(E::custom)
375                }
376            }
377            d.deserialize_str(HexVisitor)
378        } else {
379            struct BytesVisitor;
380
381            impl<'de> ::serde::de::Visitor<'de> for BytesVisitor {
382                type Value = PublicKey;
383
384                fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
385                    formatter.write_str("a bytestring")
386                }
387
388                fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
389                where
390                    E: ::serde::de::Error,
391                {
392                    PublicKey::from_slice(v).map_err(E::custom)
393                }
394            }
395
396            d.deserialize_bytes(BytesVisitor)
397        }
398    }
399}
400
401#[cfg(test)]
402mod tests {
403    use super::{PrivateKey, PublicKey};
404    use secp256k1::{ContextFlag, Secp256k1};
405    use std::io;
406    use std::str::FromStr;
407    use hashes::hex::ToHex;
408    use network::constants::Network::Testnet;
409    use network::constants::Network::Bitcoin;
410    use util::address::Address;
411
412    #[test]
413    fn test_key_derivation() {
414        let secp = Secp256k1::new();
415        // testnet compressed
416        let sk = PrivateKey::from_wif(&secp, "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy").unwrap();
417        assert_eq!(sk.network, Testnet);
418        assert_eq!(sk.compressed, true);
419        assert_eq!(&sk.to_wif(), "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy");
420
421        let pk = Address::new_btc().p2pkh(&secp, &sk.public_key(&secp), sk.network);
422        assert_eq!(&pk.to_string(), "mqwpxxvfv3QbM8PU8uBx2jaNt9btQqvQNx");
423
424        // test string conversion
425        assert_eq!(&sk.to_string(), "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy");
426        let sk_str =
427            PrivateKey::from_str("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy").unwrap();
428        assert_eq!(&sk.to_wif(), &sk_str.to_wif());
429
430        // mainnet uncompressed
431        let sk = PrivateKey::from_wif(&secp,"5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3").unwrap();
432        assert_eq!(sk.network, Bitcoin);
433        assert_eq!(sk.compressed, false);
434        assert_eq!(&sk.to_wif(), "5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3");
435
436        let secp = Secp256k1::new();
437        let mut pk = sk.public_key(&secp);
438        assert_eq!(pk.compressed, false);
439        assert_eq!(&pk.to_string(), "042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133");
440        assert_eq!(pk, PublicKey::from_str("042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133").unwrap());
441        let addr = Address::new_btc().p2pkh(&secp, &pk, sk.network);
442        assert_eq!(&addr.to_string(), "1GhQvF6dL8xa6wBxLnWmHcQsurx9RxiMc8");
443        pk.compressed = true;
444        assert_eq!(&pk.to_string(), "032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af");
445        assert_eq!(pk, PublicKey::from_str("032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af").unwrap());
446    }
447
448    #[test]
449    fn test_pubkey_hash() {
450        let secp = Secp256k1::with_caps(ContextFlag::None);
451        let pk = PublicKey::from_str("032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af").unwrap();
452        let upk = PublicKey::from_str("042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133").unwrap();
453        assert_eq!(pk.pubkey_hash(&secp).to_hex(), "9511aa27ef39bbfa4e4f3dd15f4d66ea57f475b4");
454        assert_eq!(upk.pubkey_hash(&secp).to_hex(), "ac2e7daf42d2c97418fd9f78af2de552bb9c6a7a");
455    }
456
457    #[test]
458    fn test_wpubkey_hash() {
459        let secp = Secp256k1::with_caps(ContextFlag::None);
460        let pk = PublicKey::from_str("032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af").unwrap();
461        let upk = PublicKey::from_str("042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133").unwrap();
462        assert_eq!(pk.wpubkey_hash(&secp).unwrap().to_hex(), "9511aa27ef39bbfa4e4f3dd15f4d66ea57f475b4");
463        assert_eq!(upk.wpubkey_hash(&secp), None);
464    }
465
466    #[cfg(feature = "serde")]
467    #[test]
468    fn test_key_serde() {
469        use serde_test::{Configure, Token, assert_tokens};
470
471        static KEY_WIF: &'static str = "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy";
472        static PK_STR: &'static str = "039b6347398505f5ec93826dc61c19f47c66c0283ee9be980e29ce325a0f4679ef";
473        static PK_STR_U: &'static str = "\
474            04\
475            9b6347398505f5ec93826dc61c19f47c66c0283ee9be980e29ce325a0f4679ef\
476            87288ed73ce47fc4f5c79d19ebfa57da7cff3aff6e819e4ee971d86b5e61875d\
477        ";
478        static PK_BYTES: [u8; 33] = [
479            0x03,
480            0x9b, 0x63, 0x47, 0x39, 0x85, 0x05, 0xf5, 0xec,
481            0x93, 0x82, 0x6d, 0xc6, 0x1c, 0x19, 0xf4, 0x7c,
482            0x66, 0xc0, 0x28, 0x3e, 0xe9, 0xbe, 0x98, 0x0e,
483            0x29, 0xce, 0x32, 0x5a, 0x0f, 0x46, 0x79, 0xef,
484        ];
485        static PK_BYTES_U: [u8; 65] = [
486            0x04,
487            0x9b, 0x63, 0x47, 0x39, 0x85, 0x05, 0xf5, 0xec,
488            0x93, 0x82, 0x6d, 0xc6, 0x1c, 0x19, 0xf4, 0x7c,
489            0x66, 0xc0, 0x28, 0x3e, 0xe9, 0xbe, 0x98, 0x0e,
490            0x29, 0xce, 0x32, 0x5a, 0x0f, 0x46, 0x79, 0xef,
491            0x87, 0x28, 0x8e, 0xd7, 0x3c, 0xe4, 0x7f, 0xc4,
492            0xf5, 0xc7, 0x9d, 0x19, 0xeb, 0xfa, 0x57, 0xda,
493            0x7c, 0xff, 0x3a, 0xff, 0x6e, 0x81, 0x9e, 0x4e,
494            0xe9, 0x71, 0xd8, 0x6b, 0x5e, 0x61, 0x87, 0x5d,
495        ];
496
497        let s = Secp256k1::new();
498        let sk = PrivateKey::from_str(&KEY_WIF).unwrap();
499        let pk = PublicKey::from_private_key(&s, &sk);
500        let pk_u = PublicKey {
501            key: pk.key,
502            compressed: false,
503        };
504
505        assert_tokens(&sk, &[Token::BorrowedStr(KEY_WIF)]);
506        assert_tokens(&pk.compact(), &[Token::BorrowedBytes(&PK_BYTES[..])]);
507        assert_tokens(&pk.readable(), &[Token::BorrowedStr(PK_STR)]);
508        assert_tokens(&pk_u.compact(), &[Token::BorrowedBytes(&PK_BYTES_U[..])]);
509        assert_tokens(&pk_u.readable(), &[Token::BorrowedStr(PK_STR_U)]);
510    }
511
512    fn random_key(secp: &Secp256k1, mut seed: u8) -> PublicKey {
513        loop {
514            let mut data = [0; 65];
515            for byte in &mut data[..] {
516                *byte = seed;
517                // totally a rng
518                seed = seed.wrapping_mul(41).wrapping_add(43);
519            }
520            if data[0] % 2 == 0 {
521                data[0] = 4;
522                if let Ok(key) = PublicKey::from_slice(&secp, &data[..]) {
523                    return key;
524                }
525            } else {
526                data[0] = 2 + (data[0] >> 7);
527                if let Ok(key) = PublicKey::from_slice(&secp, &data[..33]) {
528                    return key;
529                }
530            }
531        }
532    }
533
534    #[test]
535    fn pubkey_read_write() {
536        let secp = Secp256k1::with_caps(ContextFlag::None);
537
538        const N_KEYS: usize = 20;
539        let keys: Vec<_> = (0..N_KEYS).map(|i| random_key(&secp, i as u8)).collect();
540
541        let mut v = vec![];
542        for k in &keys {
543            k.write_into(&secp, &mut v).expect("writing into vec");
544        }
545
546        let mut dec_keys = vec![];
547        let mut cursor = io::Cursor::new(&v);
548        for _ in 0..N_KEYS {
549            dec_keys.push(PublicKey::read_from(&secp, &mut cursor).expect("reading from vec"));
550        }
551
552        assert_eq!(keys, dec_keys);
553
554        // sanity checks
555        assert!(PublicKey::read_from(&secp, &mut cursor).is_err());
556        assert!(PublicKey::read_from(&secp, io::Cursor::new(&[])).is_err());
557        assert!(PublicKey::read_from(&secp, io::Cursor::new(&[0; 33][..])).is_err());
558        assert!(PublicKey::read_from(&secp, io::Cursor::new(&[2; 32][..])).is_err());
559        assert!(PublicKey::read_from(&secp, io::Cursor::new(&[0; 65][..])).is_err());
560        assert!(PublicKey::read_from(&secp, io::Cursor::new(&[4; 64][..])).is_err());
561    }
562}