Skip to content

Commit

Permalink
Add accordant address generation
Browse files Browse the repository at this point in the history
Add a new method on trait Accordant to generate the accordant address
used to lock funds based on keys generated during the commit/reveal
phase.
  • Loading branch information
h4sh3d committed Sep 27, 2021
1 parent 813fec0 commit d537434
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 10 deletions.
15 changes: 15 additions & 0 deletions src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use thiserror::Error;
use tiny_keccak::{Hasher, Keccak};

use crate::consensus::{self, CanonicalBytes, Decodable, Encodable};
use crate::role::Accordant;

/// List of cryptographic errors that can be encountered in cryptographic operations such as
/// signatures, proofs, key derivation, or commitments.
Expand All @@ -19,6 +20,9 @@ pub enum Error {
/// The key identifier is not supported and the key cannot be derived.
#[error("The key identifier is not supported and the key cannot be derived")]
UnsupportedKey,
/// The key or key identifier does not exists or is missing.
#[error("The key or key identifier does not exists or is missing")]
MissingKey,
/// The signature does not pass the validation tests.
#[error("The signature does not pass the validation")]
InvalidSignature,
Expand Down Expand Up @@ -239,6 +243,17 @@ impl Decodable for SharedKeyId {
}
}

pub struct AccordantKeys<A: Accordant> {
pub spend_key: A::PublicKey,
pub extra_accordant_keys: Vec<TaggedElement<u16, A::PublicKey>>,
pub shared_keys: Vec<TaggedElement<SharedKeyId, A::SharedSecretKey>>,
}

pub struct SwapAccordantKeys<A: Accordant> {
pub alice: AccordantKeys<A>,
pub bob: AccordantKeys<A>,
}

fixed_hash::construct_fixed_hash!(
/// Result of a keccak256 commitment.
#[cfg_attr(
Expand Down
51 changes: 48 additions & 3 deletions src/monero.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! Implementation of the Monero blockchain as an accordant blockchain in a swap. This
//! implementation should work in pair with any other arbitrating implementation, like Bitcoin.
use crate::blockchain::{self, Asset};
use crate::blockchain::{self, Asset, Network};
use crate::consensus::{self, CanonicalBytes};
use crate::crypto::{Keys, SharedKeyId, SharedSecretKeys};
use crate::crypto::{self, AccordantKeys, Keys, SharedKeyId, SharedSecretKeys, SwapAccordantKeys};
use crate::role::Accordant;

use monero::util::key::{PrivateKey, PublicKey};
Expand All @@ -22,7 +22,52 @@ pub const SHARED_VIEW_KEY_ID: u16 = 0x01;
#[derive(Clone, Debug, Copy, PartialEq, Eq)]
pub struct Monero;

impl Accordant for Monero {}
impl Accordant for Monero {
fn derive_lock_address(
network: Network,
keys: SwapAccordantKeys<Self>,
) -> Result<Address, crypto::Error> {
let SwapAccordantKeys {
alice:
AccordantKeys {
spend_key: a_spend_key,
shared_keys: a_shared_keys,
..
},
bob:
AccordantKeys {
spend_key: b_spend_key,
shared_keys: b_shared_keys,
..
},
} = keys;

let a_tagged_view_secretkey = a_shared_keys
.iter()
.find(|tagged_key| *tagged_key.tag() == SharedKeyId::new(SHARED_VIEW_KEY_ID))
.ok_or(crypto::Error::MissingKey)?;
let b_tagged_view_secretkey = b_shared_keys
.iter()
.find(|tagged_key| *tagged_key.tag() == SharedKeyId::new(SHARED_VIEW_KEY_ID))
.ok_or(crypto::Error::MissingKey)?;

let public_spend = a_spend_key + b_spend_key;
let secret_view = a_tagged_view_secretkey.elem() + b_tagged_view_secretkey.elem();
let public_view = PublicKey::from_private_key(&secret_view);

Ok(Address::standard(network.into(), public_spend, public_view))
}
}

impl From<Network> for monero::Network {
fn from(network: Network) -> Self {
match network {
Network::Mainnet => monero::Network::Mainnet,
Network::Testnet => monero::Network::Stagenet,
Network::Local => monero::Network::Testnet,
}
}
}

impl std::str::FromStr for Monero {
type Err = crate::consensus::Error;
Expand Down
3 changes: 0 additions & 3 deletions src/protocol_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,6 @@ where
type Strategy = AsStrict;
}

// TODO: Add more common data to reveal, e.g. help to ensure that both node uses the same value for
// fee

/// Reveals the parameters commited by the [`CommitAliceParameters`] protocol message.
#[derive(Clone, Debug, Display)]
#[display(Debug)]
Expand Down
16 changes: 12 additions & 4 deletions src/role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ use std::fmt::Debug;
use std::io;
use std::str::FromStr;

use crate::blockchain::{Address, Asset, Fee, FeePriority, Onchain, Timelock, Transactions};
use crate::blockchain::{
Address, Asset, Fee, FeePriority, Network, Onchain, Timelock, Transactions,
};
use crate::bundle::{
AliceParameters, BobParameters, CoreArbitratingTransactions, CosignedArbitratingCancel,
FullySignedBuy, FullySignedPunish, FullySignedRefund, SignedAdaptorBuy, SignedAdaptorRefund,
SignedArbitratingLock,
};
use crate::consensus::{self, Decodable, Encodable};
use crate::crypto::{
AccordantKeyId, ArbitratingKeyId, KeyGenerator, Keys, SharedSecretKeys, Sign, Signatures,
TaggedElement, TaggedExtraKeys, TaggedSharedKeys,
self, AccordantKeyId, ArbitratingKeyId, KeyGenerator, Keys, SharedSecretKeys, Sign, Signatures,
SwapAccordantKeys, TaggedElement, TaggedExtraKeys, TaggedSharedKeys,
};
use crate::negotiation::PublicOffer;
use crate::script::{DataLock, DataPunishableLock, DoubleKeys, ScriptPath};
Expand Down Expand Up @@ -1330,4 +1332,10 @@ pub trait Arbitrating:

/// An accordant is the blockchain which does not need transaction inside the protocol nor
/// timelocks, it is the blockchain with the less requirements for an atomic swap.
pub trait Accordant: Asset + Address + Keys + SharedSecretKeys + Clone + Eq {}
pub trait Accordant: Asset + Address + Keys + SharedSecretKeys + Clone + Eq {
/// Derive the lock address for the accordant blockchain.
fn derive_lock_address(
network: Network,
keys: SwapAccordantKeys<Self>,
) -> Result<Self::Address, crypto::Error>;
}

0 comments on commit d537434

Please sign in to comment.