Merge network::Seed into crate::Seed

This allows us to unify the way we derive new secret key material
and simplify the usage of seed by only having a single one.
This commit is contained in:
Thomas Eizinger 2021-03-03 13:26:12 +11:00
parent 089ac0806e
commit a4c25080b6
No known key found for this signature in database
GPG Key ID: 651AC83A6C6C8B96
7 changed files with 41 additions and 46 deletions

View File

@ -89,7 +89,7 @@ async fn main() -> Result<()> {
let (bitcoin_wallet, monero_wallet) = init_wallets( let (bitcoin_wallet, monero_wallet) = init_wallets(
config.clone(), config.clone(),
&wallet_data_dir, &wallet_data_dir,
seed.extended_private_key(BITCOIN_NETWORK)?, seed.derive_extended_private_key(BITCOIN_NETWORK)?,
) )
.await?; .await?;

View File

@ -256,7 +256,7 @@ async fn init_bitcoin_wallet(
config.bitcoin.electrum_http_url, config.bitcoin.electrum_http_url,
bitcoin_network, bitcoin_network,
bitcoin_wallet_data_dir, bitcoin_wallet_data_dir,
seed.extended_private_key(bitcoin_network)?, seed.derive_extended_private_key(bitcoin_network)?,
) )
.await?; .await?;

View File

@ -2,10 +2,8 @@ pub mod peer_tracker;
pub mod request_response; pub mod request_response;
pub mod transport; pub mod transport;
use crate::seed::SEED_LENGTH;
use bitcoin::hashes::{sha256, Hash, HashEngine};
use futures::prelude::*; use futures::prelude::*;
use libp2p::{core::Executor, identity::ed25519}; use libp2p::core::Executor;
use std::pin::Pin; use std::pin::Pin;
use tokio::runtime::Handle; use tokio::runtime::Handle;
@ -19,35 +17,3 @@ impl Executor for TokioExecutor {
let _ = self.handle.spawn(future); let _ = self.handle.spawn(future);
} }
} }
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct Seed([u8; SEED_LENGTH]);
impl Seed {
/// prefix "NETWORK" to the provided seed and apply sha256
pub fn new(seed: crate::seed::Seed) -> Self {
let mut engine = sha256::HashEngine::default();
engine.input(&seed.bytes());
engine.input(b"NETWORK");
let hash = sha256::Hash::from_engine(engine);
Self(hash.into_inner())
}
fn bytes(&self) -> [u8; SEED_LENGTH] {
self.0
}
pub fn derive_libp2p_identity(&self) -> libp2p::identity::Keypair {
let mut engine = sha256::HashEngine::default();
engine.input(&self.bytes());
engine.input(b"LIBP2P_IDENTITY");
let hash = sha256::Hash::from_engine(engine);
let key =
ed25519::SecretKey::from_bytes(hash.into_inner()).expect("we always pass 32 bytes");
libp2p::identity::Keypair::Ed25519(key.into())
}
}

View File

@ -5,7 +5,6 @@ use crate::{
execution_params::ExecutionParams, execution_params::ExecutionParams,
monero, monero,
monero::{Amount, BalanceTooLow}, monero::{Amount, BalanceTooLow},
network,
network::{transport, TokioExecutor}, network::{transport, TokioExecutor},
protocol::{ protocol::{
alice, alice,
@ -113,7 +112,7 @@ where
rate_service: RS, rate_service: RS,
max_sell: Amount, max_sell: Amount,
) -> Result<(Self, mpsc::Receiver<RemoteHandle<Result<AliceState>>>)> { ) -> Result<(Self, mpsc::Receiver<RemoteHandle<Result<AliceState>>>)> {
let identity = network::Seed::new(seed).derive_libp2p_identity(); let identity = seed.derive_libp2p_identity();
let behaviour = Behaviour::default(); let behaviour = Behaviour::default();
let transport = transport::build(&identity)?; let transport = transport::build(&identity)?;
let peer_id = PeerId::from(identity.public()); let peer_id = PeerId::from(identity.public());

View File

@ -4,7 +4,7 @@ use crate::{
bitcoin, bitcoin,
database::Database, database::Database,
execution_params::ExecutionParams, execution_params::ExecutionParams,
monero, network, monero,
network::peer_tracker::{self, PeerTracker}, network::peer_tracker::{self, PeerTracker},
protocol::{alice, alice::TransferProof, bob}, protocol::{alice, alice::TransferProof, bob},
seed::Seed, seed::Seed,
@ -79,7 +79,7 @@ impl Builder {
alice_peer_id: PeerId, alice_peer_id: PeerId,
execution_params: ExecutionParams, execution_params: ExecutionParams,
) -> Self { ) -> Self {
let identity = network::Seed::new(seed).derive_libp2p_identity(); let identity = seed.derive_libp2p_identity();
Self { Self {
swap_id, swap_id,

View File

@ -2,6 +2,8 @@ use crate::fs::ensure_directory_exists;
use ::bitcoin::secp256k1::{self, constants::SECRET_KEY_SIZE, SecretKey}; use ::bitcoin::secp256k1::{self, constants::SECRET_KEY_SIZE, SecretKey};
use anyhow::Result; use anyhow::Result;
use bdk::bitcoin::util::bip32::ExtendedPrivKey; use bdk::bitcoin::util::bip32::ExtendedPrivKey;
use bitcoin::hashes::{sha256, Hash, HashEngine};
use libp2p::identity;
use pem::{encode, Pem}; use pem::{encode, Pem};
use rand::prelude::*; use rand::prelude::*;
use std::{ use std::{
@ -28,13 +30,21 @@ impl Seed {
Ok(Seed(bytes)) Ok(Seed(bytes))
} }
pub fn extended_private_key(&self, network: bitcoin::Network) -> Result<ExtendedPrivKey> { pub fn derive_extended_private_key(
let private_key = ExtendedPrivKey::new_master(network, &self.bytes())?; &self,
network: bitcoin::Network,
) -> Result<ExtendedPrivKey> {
let seed = self.derive(b"BITCOIN_EXTENDED_PRIVATE_KEY").bytes();
let private_key = ExtendedPrivKey::new_master(network, &seed)?;
Ok(private_key) Ok(private_key)
} }
pub fn bytes(&self) -> [u8; SEED_LENGTH] { pub fn derive_libp2p_identity(&self) -> identity::Keypair {
self.0 let bytes = self.derive(b"NETWORK").derive(b"LIBP2P_IDENTITY").bytes();
let key = identity::ed25519::SecretKey::from_bytes(bytes).expect("we always pass 32 bytes");
identity::Keypair::Ed25519(key.into())
} }
pub fn from_file_or_generate(data_dir: &Path) -> Result<Self, Error> { pub fn from_file_or_generate(data_dir: &Path) -> Result<Self, Error> {
@ -53,6 +63,26 @@ impl Seed {
Ok(random_seed) Ok(random_seed)
} }
/// Derive a new seed using the given scope.
///
/// This function is purposely kept private because it is only a helper
/// function for deriving specific secret material from the root seed
/// like the libp2p identity or the seed for the Bitcoin wallet.
fn derive(&self, scope: &[u8]) -> Self {
let mut engine = sha256::HashEngine::default();
engine.input(&self.bytes());
engine.input(scope);
let hash = sha256::Hash::from_engine(engine);
Self(hash.into_inner())
}
fn bytes(&self) -> [u8; SEED_LENGTH] {
self.0
}
fn from_file<D>(seed_file: D) -> Result<Self, Error> fn from_file<D>(seed_file: D) -> Result<Self, Error>
where where
D: AsRef<OsStr>, D: AsRef<OsStr>,

View File

@ -606,7 +606,7 @@ async fn init_test_wallets(
electrum_http_url, electrum_http_url,
bitcoin::Network::Regtest, bitcoin::Network::Regtest,
datadir, datadir,
seed.extended_private_key(bitcoin::Network::Regtest) seed.derive_extended_private_key(bitcoin::Network::Regtest)
.expect("Could not create extended private key from seed"), .expect("Could not create extended private key from seed"),
) )
.await .await