bitcoin_wallet/
context.rs

1//
2// Copyright 2018-2019 Tamas Blummer
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16//!
17//! # Key derivation
18//!
19use bitcoin::{
20    network::constants::Network,
21    util::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey},
22    PrivateKey, PublicKey,
23};
24use secp256k1::{All, Message, Secp256k1, Signature};
25
26use account::Seed;
27use error::Error;
28
29pub struct SecpContext {
30    secp: Secp256k1<All>,
31}
32
33impl SecpContext {
34    pub fn new() -> SecpContext {
35        SecpContext {
36            secp: Secp256k1::new(),
37        }
38    }
39
40    /// create a master private key from seed
41    pub fn master_private_key(
42        &self,
43        network: Network,
44        seed: &Seed,
45    ) -> Result<ExtendedPrivKey, Error> {
46        Ok(ExtendedPrivKey::new_master(network, &seed.0)?)
47    }
48
49    /// get extended public key for a known private key
50    pub fn extended_public_from_private(
51        &self,
52        extended_private_key: &ExtendedPrivKey,
53    ) -> ExtendedPubKey {
54        ExtendedPubKey::from_private(&self.secp, extended_private_key)
55    }
56
57    pub fn private_child(
58        &self,
59        extended_private_key: &ExtendedPrivKey,
60        child: ChildNumber,
61    ) -> Result<ExtendedPrivKey, Error> {
62        Ok(extended_private_key.ckd_priv(&self.secp, child)?)
63    }
64
65    pub fn public_child(
66        &self,
67        extended_public_key: &ExtendedPubKey,
68        child: ChildNumber,
69    ) -> Result<ExtendedPubKey, Error> {
70        Ok(extended_public_key.ckd_pub(&self.secp, child)?)
71    }
72
73    pub fn public_from_private(&self, private: &PrivateKey) -> PublicKey {
74        PublicKey::from_private_key(&self.secp, private)
75    }
76
77    pub fn sign(&self, digest: &[u8], key: &PrivateKey) -> Result<Signature, Error> {
78        Ok(self.secp.sign(&Message::from_slice(digest)?, &key.key))
79    }
80
81    pub fn tweak_add(&self, key: &mut PrivateKey, tweak: &[u8]) -> Result<(), Error> {
82        key.key.add_assign(tweak)?;
83        Ok(())
84    }
85
86    pub fn tweak_exp_add(&self, key: &mut PublicKey, tweak: &[u8]) -> Result<(), Error> {
87        key.key.add_exp_assign(&self.secp, tweak)?;
88        Ok(())
89    }
90}