mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-02-21 23:29:50 -05:00
Sketch initial type-level state machine for signing Monero transactions
This commit is contained in:
parent
702e1767c7
commit
25c4a5a9b9
@ -3,7 +3,9 @@
|
|||||||
use monero::ViewPair;
|
use monero::ViewPair;
|
||||||
use monero_harness::Monero;
|
use monero_harness::Monero;
|
||||||
use monero_rpc::monerod::MonerodRpc;
|
use monero_rpc::monerod::MonerodRpc;
|
||||||
use monero_wallet::{ConfidentialTransactionBuilder, MonerodClientExt};
|
use monero_wallet::{
|
||||||
|
CalculateKeyOffsetBoundaries, ConfidentialTransactionBuilder, FetchDecoyInputs,
|
||||||
|
};
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use testcontainers::clients::Cli;
|
use testcontainers::clients::Cli;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
mod v2;
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use curve25519_dalek::constants::ED25519_BASEPOINT_POINT;
|
use curve25519_dalek::constants::ED25519_BASEPOINT_POINT;
|
||||||
use curve25519_dalek::edwards::{CompressedEdwardsY, EdwardsPoint};
|
use curve25519_dalek::edwards::{CompressedEdwardsY, EdwardsPoint};
|
||||||
@ -278,13 +280,17 @@ fn random_array<T: Default + Copy, const N: usize>(rng: impl FnMut() -> T) -> [T
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
pub trait MonerodClientExt {
|
pub trait CalculateKeyOffsetBoundaries {
|
||||||
async fn calculate_key_offset_boundaries(&self) -> Result<(VarInt, VarInt)>;
|
async fn calculate_key_offset_boundaries(&self) -> Result<(VarInt, VarInt)>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
pub trait FetchDecoyInputs {
|
||||||
async fn fetch_decoy_inputs(&self, indices: [u64; 10]) -> Result<[DecoyInput; 10]>;
|
async fn fetch_decoy_inputs(&self, indices: [u64; 10]) -> Result<[DecoyInput; 10]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl MonerodClientExt for monerod::Client {
|
impl CalculateKeyOffsetBoundaries for monerod::Client {
|
||||||
/// Chooses 10 random key offsets for use within a new confidential
|
/// Chooses 10 random key offsets for use within a new confidential
|
||||||
/// transactions.
|
/// transactions.
|
||||||
///
|
///
|
||||||
@ -315,7 +321,10 @@ impl MonerodClientExt for monerod::Client {
|
|||||||
|
|
||||||
Ok((VarInt(0), VarInt(last_index)))
|
Ok((VarInt(0), VarInt(last_index)))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl FetchDecoyInputs for monerod::Client {
|
||||||
async fn fetch_decoy_inputs(&self, indices: [u64; 10]) -> Result<[DecoyInput; 10]> {
|
async fn fetch_decoy_inputs(&self, indices: [u64; 10]) -> Result<[DecoyInput; 10]> {
|
||||||
let response = self
|
let response = self
|
||||||
.get_outs(
|
.get_outs(
|
||||||
@ -403,7 +412,7 @@ mod tests {
|
|||||||
// key: todo!(),
|
// key: todo!(),
|
||||||
// };
|
// };
|
||||||
//
|
//
|
||||||
// let (lower, upper) = wallet.calculate_key_offset_boundaries().await.unwrap();
|
// let (lower, upper) = wallet.CalculateKeyOffsetBoundaries().await.unwrap();
|
||||||
|
|
||||||
todo!("fix");
|
todo!("fix");
|
||||||
// let result = rpc_client
|
// let result = rpc_client
|
||||||
|
110
monero-wallet/src/v2.rs
Normal file
110
monero-wallet/src/v2.rs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
use crate::{CalculateKeyOffsetBoundaries, DecoyInput, FetchDecoyInputs};
|
||||||
|
use curve25519_dalek::edwards::EdwardsPoint;
|
||||||
|
use curve25519_dalek::scalar::Scalar;
|
||||||
|
use monero::util::ringct::Clsag;
|
||||||
|
use monero::{Address, KeyPair, OwnedTxOut, Transaction};
|
||||||
|
use rand::{CryptoRng, RngCore};
|
||||||
|
|
||||||
|
pub struct EmptyTransaction {}
|
||||||
|
|
||||||
|
impl EmptyTransaction {
|
||||||
|
pub fn spend_from(input: OwnedTxOut<'_>, global_output_index: u64) -> InputAdded {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct InputAdded {}
|
||||||
|
|
||||||
|
impl InputAdded {
|
||||||
|
pub fn with_static_decoy_inputs(self, decoys: [DecoyInput; 10]) -> DecoyOffsetsAdded {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_random_decoy_inputs(
|
||||||
|
self,
|
||||||
|
rng: &mut impl RngCore,
|
||||||
|
client: &(impl FetchDecoyInputs + CalculateKeyOffsetBoundaries),
|
||||||
|
) -> DecoyOffsetsAdded {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_decoys_from_indices(
|
||||||
|
self,
|
||||||
|
decoy_indices: [u64; 10],
|
||||||
|
client: &(impl FetchDecoyInputs),
|
||||||
|
) -> DecoyOffsetsAdded {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DecoyOffsetsAdded {}
|
||||||
|
|
||||||
|
impl DecoyOffsetsAdded {
|
||||||
|
pub fn add_output(
|
||||||
|
self,
|
||||||
|
to: Address,
|
||||||
|
amount: u64,
|
||||||
|
rng: &mut (impl RngCore + CryptoRng),
|
||||||
|
) -> OutputsAdded {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct OutputsAdded {}
|
||||||
|
|
||||||
|
impl OutputsAdded {
|
||||||
|
pub fn add_output(
|
||||||
|
self,
|
||||||
|
to: Address,
|
||||||
|
amount: u64,
|
||||||
|
rng: &mut (impl RngCore + CryptoRng),
|
||||||
|
) -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn blind_outputs(self, rng: &mut (impl RngCore + CryptoRng)) -> OutputsBlinded {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct OutputsBlinded {}
|
||||||
|
|
||||||
|
impl OutputsBlinded {
|
||||||
|
pub fn signature_parameters(&self) -> SignatureParameters {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Signs the transaction.
|
||||||
|
///
|
||||||
|
/// This function calls the CLSAG sign algorithm with a set of parameters that will work. This however, assumes the caller does not want to have control over these parameters.
|
||||||
|
pub fn sign(self, keys: KeyPair, rng: &mut (impl RngCore + CryptoRng)) -> Transaction {
|
||||||
|
// TODO: Do we want a sign_recommended API in monero::clsag?
|
||||||
|
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Use the given signature for the internal transaction.
|
||||||
|
///
|
||||||
|
/// This function is useful if the caller wants to have full control over certain parameters such as responses, L, R or I.
|
||||||
|
/// The provided signature will be validated to make sure it is correct.
|
||||||
|
pub fn with_signature(self, sig: Clsag) -> Result<Transaction, InvalidSignature> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct InvalidSignature;
|
||||||
|
|
||||||
|
// TODO: We can break the CLSAG fn signature down into two parts:
|
||||||
|
// 1. What we see below
|
||||||
|
// 2. What an adaptor sig wants to control (signing key, alpha, L, R & I)
|
||||||
|
pub struct SignatureParameters {
|
||||||
|
message: [u8; 32],
|
||||||
|
z: Scalar,
|
||||||
|
ring: [EdwardsPoint; 11],
|
||||||
|
commitment_ring: [EdwardsPoint; 11],
|
||||||
|
// TODO: Can the adaptor sig protocol control the signing key index?
|
||||||
|
// Do we even need to control it?
|
||||||
|
// We need to know the public key to know the index.
|
||||||
|
// signing_key_index: usize,
|
||||||
|
pseudo_output_commitment: EdwardsPoint,
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user