Improve file-based tx send to not use private file (#1421)

Instead of generating a private file on send that needs to be
provided again in finalize, the private context information is
saved in the wallet db.

Also move internal Context to bona fide libwallet type
This commit is contained in:
Ignotus Peverell 2018-08-27 20:57:33 -04:00 committed by GitHub
parent a58558b38e
commit 4048a3011a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 190 additions and 159 deletions

View file

@ -13,7 +13,6 @@
// limitations under the License. // limitations under the License.
/// Grin client commands processing /// Grin client commands processing
use std::net::SocketAddr; use std::net::SocketAddr;
use clap::ArgMatches; use clap::ArgMatches;

View file

@ -247,12 +247,7 @@ pub fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) {
let tx_file = send_args let tx_file = send_args
.value_of("input") .value_of("input")
.expect("Receiver's transaction file required"); .expect("Receiver's transaction file required");
let priv_file = send_args let slate = api.file_finalize_tx(tx_file).expect("Finalize failed");
.value_of("private")
.expect("Private transaction file required");
let slate = api
.file_finalize_tx(priv_file, tx_file)
.expect("Finalize failed");
let result = api.post_tx(&slate, fluff); let result = api.post_tx(&slate, fluff);
match result { match result {

View file

@ -208,7 +208,7 @@ fn main() {
.default_value("1") .default_value("1")
.takes_value(true)) .takes_value(true))
.arg(Arg::with_name("dest") .arg(Arg::with_name("dest")
.help("Send the transaction to the provided server") .help("Send the transaction to the provided server (start with http://) or save as file.")
.short("d") .short("d")
.long("dest") .long("dest")
.takes_value(true)) .takes_value(true))
@ -232,11 +232,6 @@ fn main() {
.short("i") .short("i")
.long("input") .long("input")
.takes_value(true)) .takes_value(true))
.arg(Arg::with_name("private")
.help("Private transaction file previously generated by send.")
.short("p")
.long("private")
.takes_value(true))
.arg(Arg::with_name("fluff") .arg(Arg::with_name("fluff")
.help("Fluff the transaction (ignore Dandelion relay protocol)") .help("Fluff the transaction (ignore Dandelion relay protocol)")
.short("f") .short("f")

View file

@ -80,8 +80,7 @@ pub struct TUIPeerView;
impl TUIStatusListener for TUIPeerView { impl TUIStatusListener for TUIPeerView {
fn create() -> Box<View> { fn create() -> Box<View> {
let table_view = let table_view = TableView::<PeerStats, PeerColumn>::new()
TableView::<PeerStats, PeerColumn>::new()
.column(PeerColumn::Address, "Address", |c| c.width_percent(20)) .column(PeerColumn::Address, "Address", |c| c.width_percent(20))
.column(PeerColumn::State, "State", |c| c.width_percent(20)) .column(PeerColumn::State, "State", |c| c.width_percent(20))
.column(PeerColumn::Direction, "Direction", |c| c.width_percent(20)) .column(PeerColumn::Direction, "Direction", |c| c.width_percent(20))

View file

@ -664,7 +664,8 @@ impl<T: TableViewItem<H>, H: Eq + Hash + Copy + Clone + 'static> TableView<T, H>
fn column_select(&mut self) { fn column_select(&mut self) {
let next = self.active_column(); let next = self.active_column();
let column = self.columns[next].column; let column = self.columns[next].column;
let current = self.columns let current = self
.columns
.iter() .iter()
.position(|c| c.order != Ordering::Equal) .position(|c| c.order != Ordering::Equal)
.unwrap_or(0); .unwrap_or(0);
@ -736,8 +737,8 @@ impl<T: TableViewItem<H> + 'static, H: Eq + Hash + Copy + Clone + 'static> View
let column_count = self.columns.len(); let column_count = self.columns.len();
// Split up all columns into sized / unsized groups // Split up all columns into sized / unsized groups
let (mut sized, mut usized): (Vec<&mut TableColumn<H>>, Vec<&mut TableColumn<H>>) = let (mut sized, mut usized): (Vec<&mut TableColumn<H>>, Vec<&mut TableColumn<H>>) = self
self.columns .columns
.iter_mut() .iter_mut()
.partition(|c| c.requested_width.is_some()); .partition(|c| c.requested_width.is_some());

View file

@ -35,7 +35,7 @@ use error::{Error, ErrorKind};
use libwallet; use libwallet;
use libwallet::types::{ use libwallet::types::{
OutputData, TxLogEntry, WalletBackend, WalletClient, WalletDetails, WalletOutputBatch, Context, OutputData, TxLogEntry, WalletBackend, WalletClient, WalletDetails, WalletOutputBatch,
}; };
use types::{WalletConfig, WalletSeed}; use types::{WalletConfig, WalletSeed};
@ -121,6 +121,18 @@ where
unimplemented!() unimplemented!()
} }
fn save_private_context(
&mut self,
_slate_id: &[u8],
_ctx: &Context,
) -> Result<(), libwallet::Error> {
unimplemented!()
}
fn delete_private_context(&mut self, _slate_id: &[u8]) -> Result<(), libwallet::Error> {
unimplemented!()
}
fn commit(&self) -> Result<(), libwallet::Error> { fn commit(&self) -> Result<(), libwallet::Error> {
let mut data_file = File::create(self.data_file_path.clone()) let mut data_file = File::create(self.data_file_path.clone())
.context(libwallet::ErrorKind::CallbackImpl("Could not create"))?; .context(libwallet::ErrorKind::CallbackImpl("Could not create"))?;
@ -239,6 +251,10 @@ where
Box::new(self.tx_log.iter().cloned()) Box::new(self.tx_log.iter().cloned())
} }
fn get_private_context(&mut self, _slate_id: &[u8]) -> Result<Context, libwallet::Error> {
unimplemented!()
}
fn get(&self, id: &Identifier) -> Result<OutputData, libwallet::Error> { fn get(&self, id: &Identifier) -> Result<OutputData, libwallet::Error> {
self.outputs self.outputs
.get(&id.to_hex()) .get(&id.to_hex())

View file

@ -28,7 +28,7 @@ use core::core::hash::Hashed;
use core::ser; use core::ser;
use keychain::Keychain; use keychain::Keychain;
use libtx::slate::Slate; use libtx::slate::Slate;
use libwallet::internal::{selection, sigcontext, tx, updater}; use libwallet::internal::{selection, tx, updater};
use libwallet::types::{ use libwallet::types::{
BlockFees, CbData, OutputData, TxLogEntry, TxWrapper, WalletBackend, WalletClient, WalletInfo, BlockFees, CbData, OutputData, TxLogEntry, TxWrapper, WalletBackend, WalletClient, WalletInfo,
}; };
@ -207,9 +207,12 @@ where
let mut pub_tx = File::create(dest)?; let mut pub_tx = File::create(dest)?;
pub_tx.write_all(json::to_string(&slate).unwrap().as_bytes())?; pub_tx.write_all(json::to_string(&slate).unwrap().as_bytes())?;
pub_tx.sync_all()?; pub_tx.sync_all()?;
let mut priv_tx = File::create(dest.to_owned() + ".private")?;
priv_tx.write_all(json::to_string(&context).unwrap().as_bytes())?; {
priv_tx.sync_all()?; let mut batch = w.batch()?;
batch.save_private_context(slate.id.as_bytes(), &context)?;
batch.commit()?;
}
// lock our inputs // lock our inputs
lock_fn(&mut **w)?; lock_fn(&mut **w)?;
@ -259,23 +262,24 @@ where
/// propagation. /// propagation.
pub fn file_finalize_tx( pub fn file_finalize_tx(
&mut self, &mut self,
private_tx_file: &str,
receiver_file: &str, receiver_file: &str,
) -> Result<Slate, Error> { ) -> Result<Slate, Error> {
let mut pub_tx_f = File::open(receiver_file)?; let mut pub_tx_f = File::open(receiver_file)?;
let mut content = String::new(); let mut content = String::new();
pub_tx_f.read_to_string(&mut content)?; pub_tx_f.read_to_string(&mut content)?;
let mut slate: Slate = json::from_str(&content).map_err(|_| ErrorKind::Format)?; let mut slate: Slate = json::from_str(&content).map_err(|_| ErrorKind::Format)?;
let mut priv_tx_f = File::open(private_tx_file)?;
let mut content = String::new();
priv_tx_f.read_to_string(&mut content)?;
let context: sigcontext::Context = json::from_str(&content).map_err(|_| ErrorKind::Format)?;
let mut w = self.wallet.lock().unwrap(); let mut w = self.wallet.lock().unwrap();
w.open_with_credentials()?; w.open_with_credentials()?;
let context = w.get_private_context(slate.id.as_bytes())?;
tx::complete_tx(&mut **w, &mut slate, &context)?; tx::complete_tx(&mut **w, &mut slate, &context)?;
{
let mut batch = w.batch()?;
batch.delete_private_context(slate.id.as_bytes())?;
batch.commit()?;
}
w.close()?; w.close()?;
Ok(slate) Ok(slate)

View file

@ -24,6 +24,5 @@
pub mod keys; pub mod keys;
pub mod restore; pub mod restore;
pub mod selection; pub mod selection;
pub mod sigcontext;
pub mod tx; pub mod tx;
pub mod updater; pub mod updater;

View file

@ -17,7 +17,7 @@
use keychain::{Identifier, Keychain}; use keychain::{Identifier, Keychain};
use libtx::{build, slate::Slate, tx_fee}; use libtx::{build, slate::Slate, tx_fee};
use libwallet::error::{Error, ErrorKind}; use libwallet::error::{Error, ErrorKind};
use libwallet::internal::{keys, sigcontext}; use libwallet::internal::keys;
use libwallet::types::*; use libwallet::types::*;
use util::LOGGER; use util::LOGGER;
@ -37,14 +37,7 @@ pub fn build_send_tx_slate<T: ?Sized, C, K>(
max_outputs: usize, max_outputs: usize,
change_outputs: usize, change_outputs: usize,
selection_strategy_is_use_all: bool, selection_strategy_is_use_all: bool,
) -> Result< ) -> Result<(Slate, Context, impl FnOnce(&mut T) -> Result<(), Error>), Error>
(
Slate,
sigcontext::Context,
impl FnOnce(&mut T) -> Result<(), Error>,
),
Error,
>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
C: WalletClient, C: WalletClient,
@ -74,7 +67,7 @@ where
let blinding = slate.add_transaction_elements(&keychain, elems)?; let blinding = slate.add_transaction_elements(&keychain, elems)?;
// Create our own private context // Create our own private context
let mut context = sigcontext::Context::new( let mut context = Context::new(
wallet.keychain().secp(), wallet.keychain().secp(),
blinding.secret_key(&keychain.secp()).unwrap(), blinding.secret_key(&keychain.secp()).unwrap(),
); );
@ -149,7 +142,7 @@ pub fn build_recipient_output_with_slate<T: ?Sized, C, K>(
) -> Result< ) -> Result<
( (
Identifier, Identifier,
sigcontext::Context, Context,
impl FnOnce(&mut T) -> Result<(), Error>, impl FnOnce(&mut T) -> Result<(), Error>,
), ),
Error, Error,
@ -173,7 +166,7 @@ where
slate.add_transaction_elements(&keychain, vec![build::output(amount, key_id.clone())])?; slate.add_transaction_elements(&keychain, vec![build::output(amount, key_id.clone())])?;
// Add blinding sum to our context // Add blinding sum to our context
let mut context = sigcontext::Context::new( let mut context = Context::new(
keychain.secp(), keychain.secp(),
blinding blinding
.secret_key(wallet.keychain().clone().secp()) .secret_key(wallet.keychain().clone().secp())

View file

@ -1,84 +0,0 @@
// Copyright 2018 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Signature context holder helper (may be removed or replaced eventually)
use keychain::Identifier;
use libtx::aggsig;
use util::secp::key::{PublicKey, SecretKey};
use util::secp::{self, Secp256k1};
#[derive(Serialize, Deserialize, Clone, Debug)]
/// Holds the context for a single aggsig transaction
pub struct Context {
/// Secret key (of which public is shared)
pub sec_key: SecretKey,
/// Secret nonce (of which public is shared)
/// (basically a SecretKey)
pub sec_nonce: SecretKey,
/// store my outputs between invocations
pub output_ids: Vec<Identifier>,
/// store my inputs
pub input_ids: Vec<Identifier>,
/// store the calculated fee
pub fee: u64,
}
impl Context {
/// Create a new context with defaults
pub fn new(secp: &secp::Secp256k1, sec_key: SecretKey) -> Context {
Context {
sec_key: sec_key,
sec_nonce: aggsig::create_secnonce(secp).unwrap(),
input_ids: vec![],
output_ids: vec![],
fee: 0,
}
}
}
impl Context {
/// Tracks an output contributing to my excess value (if it needs to
/// be kept between invocations
pub fn add_output(&mut self, output_id: &Identifier) {
self.output_ids.push(output_id.clone());
}
/// Returns all stored outputs
pub fn get_outputs(&self) -> Vec<Identifier> {
self.output_ids.clone()
}
/// Tracks IDs of my inputs into the transaction
/// be kept between invocations
pub fn add_input(&mut self, input_id: &Identifier) {
self.input_ids.push(input_id.clone());
}
/// Returns all stored input identifiers
pub fn get_inputs(&self) -> Vec<Identifier> {
self.input_ids.clone()
}
/// Returns private key, private nonce
pub fn get_private_keys(&self) -> (SecretKey, SecretKey) {
(self.sec_key.clone(), self.sec_nonce.clone())
}
/// Returns public key, public nonce
pub fn get_public_keys(&self, secp: &Secp256k1) -> (PublicKey, PublicKey) {
(
PublicKey::from_secret_key(secp, &self.sec_key).unwrap(),
PublicKey::from_secret_key(secp, &self.sec_nonce).unwrap(),
)
}
}

View file

@ -18,8 +18,8 @@ use core::core::Transaction;
use keychain::{Identifier, Keychain}; use keychain::{Identifier, Keychain};
use libtx::slate::Slate; use libtx::slate::Slate;
use libtx::{build, tx_fee}; use libtx::{build, tx_fee};
use libwallet::internal::{selection, sigcontext, updater}; use libwallet::internal::{selection, updater};
use libwallet::types::{TxLogEntryType, WalletBackend, WalletClient}; use libwallet::types::{Context, TxLogEntryType, WalletBackend, WalletClient};
use libwallet::{Error, ErrorKind}; use libwallet::{Error, ErrorKind};
use util::LOGGER; use util::LOGGER;
@ -61,14 +61,7 @@ pub fn create_send_tx<T: ?Sized, C, K>(
max_outputs: usize, max_outputs: usize,
num_change_outputs: usize, num_change_outputs: usize,
selection_strategy_is_use_all: bool, selection_strategy_is_use_all: bool,
) -> Result< ) -> Result<(Slate, Context, impl FnOnce(&mut T) -> Result<(), Error>), Error>
(
Slate,
sigcontext::Context,
impl FnOnce(&mut T) -> Result<(), Error>,
),
Error,
>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
C: WalletClient, C: WalletClient,
@ -117,7 +110,7 @@ where
pub fn complete_tx<T: ?Sized, C, K>( pub fn complete_tx<T: ?Sized, C, K>(
wallet: &mut T, wallet: &mut T,
slate: &mut Slate, slate: &mut Slate,
context: &sigcontext::Context, context: &Context,
) -> Result<(), Error> ) -> Result<(), Error>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,

View file

@ -30,10 +30,12 @@ use core::ser;
use keychain::{Identifier, Keychain}; use keychain::{Identifier, Keychain};
use libtx::aggsig;
use libtx::slate::Slate; use libtx::slate::Slate;
use libwallet::error::{Error, ErrorKind}; use libwallet::error::{Error, ErrorKind};
use util::secp::pedersen; use util::secp::key::{PublicKey, SecretKey};
use util::secp::{self, pedersen, Secp256k1};
/// Combined trait to allow dynamic wallet dispatch /// Combined trait to allow dynamic wallet dispatch
pub trait WalletInst<C, K>: WalletBackend<C, K> + Send + Sync + 'static pub trait WalletInst<C, K>: WalletBackend<C, K> + Send + Sync + 'static
@ -82,6 +84,9 @@ where
/// Get an (Optional) tx log entry by uuid /// Get an (Optional) tx log entry by uuid
fn get_tx_log_entry(&self, uuid: &Uuid) -> Result<Option<TxLogEntry>, Error>; fn get_tx_log_entry(&self, uuid: &Uuid) -> Result<Option<TxLogEntry>, Error>;
/// Retrieves the private context associated with a given slate id
fn get_private_context(&mut self, slate_id: &[u8]) -> Result<Context, Error>;
/// Iterate over all output data stored by the backend /// Iterate over all output data stored by the backend
fn tx_log_iter<'a>(&'a self) -> Box<Iterator<Item = TxLogEntry> + 'a>; fn tx_log_iter<'a>(&'a self) -> Box<Iterator<Item = TxLogEntry> + 'a>;
@ -137,6 +142,12 @@ where
/// Save an output as locked in the backend /// Save an output as locked in the backend
fn lock_output(&mut self, out: &mut OutputData) -> Result<(), Error>; fn lock_output(&mut self, out: &mut OutputData) -> Result<(), Error>;
/// Saves the private context associated with a slate id
fn save_private_context(&mut self, slate_id: &[u8], ctx: &Context) -> Result<(), Error>;
/// Delete the private context associated with the slate id
fn delete_private_context(&mut self, slate_id: &[u8]) -> Result<(), Error>;
/// Write the wallet data to backend file /// Write the wallet data to backend file
fn commit(&self) -> Result<(), Error>; fn commit(&self) -> Result<(), Error>;
} }
@ -315,6 +326,85 @@ impl fmt::Display for OutputStatus {
} }
} }
#[derive(Serialize, Deserialize, Clone, Debug)]
/// Holds the context for a single aggsig transaction
pub struct Context {
/// Secret key (of which public is shared)
pub sec_key: SecretKey,
/// Secret nonce (of which public is shared)
/// (basically a SecretKey)
pub sec_nonce: SecretKey,
/// store my outputs between invocations
pub output_ids: Vec<Identifier>,
/// store my inputs
pub input_ids: Vec<Identifier>,
/// store the calculated fee
pub fee: u64,
}
impl Context {
/// Create a new context with defaults
pub fn new(secp: &secp::Secp256k1, sec_key: SecretKey) -> Context {
Context {
sec_key: sec_key,
sec_nonce: aggsig::create_secnonce(secp).unwrap(),
input_ids: vec![],
output_ids: vec![],
fee: 0,
}
}
}
impl Context {
/// Tracks an output contributing to my excess value (if it needs to
/// be kept between invocations
pub fn add_output(&mut self, output_id: &Identifier) {
self.output_ids.push(output_id.clone());
}
/// Returns all stored outputs
pub fn get_outputs(&self) -> Vec<Identifier> {
self.output_ids.clone()
}
/// Tracks IDs of my inputs into the transaction
/// be kept between invocations
pub fn add_input(&mut self, input_id: &Identifier) {
self.input_ids.push(input_id.clone());
}
/// Returns all stored input identifiers
pub fn get_inputs(&self) -> Vec<Identifier> {
self.input_ids.clone()
}
/// Returns private key, private nonce
pub fn get_private_keys(&self) -> (SecretKey, SecretKey) {
(self.sec_key.clone(), self.sec_nonce.clone())
}
/// Returns public key, public nonce
pub fn get_public_keys(&self, secp: &Secp256k1) -> (PublicKey, PublicKey) {
(
PublicKey::from_secret_key(secp, &self.sec_key).unwrap(),
PublicKey::from_secret_key(secp, &self.sec_nonce).unwrap(),
)
}
}
impl ser::Writeable for Context {
fn write<W: ser::Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
writer.write_bytes(&serde_json::to_vec(self).map_err(|_| ser::Error::CorruptedData)?)
}
}
impl ser::Readable for Context {
fn read(reader: &mut ser::Reader) -> Result<Context, ser::Error> {
let data = reader.read_vec()?;
serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData)
}
}
/// Block Identifier /// Block Identifier
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)] #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
pub struct BlockIdentifier(pub Hash); pub struct BlockIdentifier(pub Hash);

View file

@ -33,6 +33,7 @@ const COMMITMENT_PREFIX: u8 = 'C' as u8;
const OUTPUT_PREFIX: u8 = 'o' as u8; const OUTPUT_PREFIX: u8 = 'o' as u8;
const DERIV_PREFIX: u8 = 'd' as u8; const DERIV_PREFIX: u8 = 'd' as u8;
const CONFIRMED_HEIGHT_PREFIX: u8 = 'c' as u8; const CONFIRMED_HEIGHT_PREFIX: u8 = 'c' as u8;
const PRIVATE_TX_CONTEXT_PREFIX: u8 = 'p' as u8;
const TX_LOG_ENTRY_PREFIX: u8 = 't' as u8; const TX_LOG_ENTRY_PREFIX: u8 = 't' as u8;
const TX_LOG_ID_PREFIX: u8 = 'i' as u8; const TX_LOG_ID_PREFIX: u8 = 'i' as u8;
@ -161,6 +162,14 @@ where
Box::new(self.db.iter(&[TX_LOG_ENTRY_PREFIX]).unwrap()) Box::new(self.db.iter(&[TX_LOG_ENTRY_PREFIX]).unwrap())
} }
fn get_private_context(&mut self, slate_id: &[u8]) -> Result<Context, Error> {
let ctx_key = to_key(PRIVATE_TX_CONTEXT_PREFIX, &mut slate_id.to_vec());
option_to_not_found(
self.db.get_ser(&ctx_key),
&format!("Slate id: {:x?}", slate_id.to_vec()),
).map_err(|e| e.into())
}
fn batch<'a>(&'a mut self) -> Result<Box<WalletOutputBatch<K> + 'a>, Error> { fn batch<'a>(&'a mut self) -> Result<Box<WalletOutputBatch<K> + 'a>, Error> {
Ok(Box::new(Batch { Ok(Box::new(Batch {
_store: self, _store: self,
@ -336,6 +345,22 @@ where
self.save(out.clone()) self.save(out.clone())
} }
fn save_private_context(&mut self, slate_id: &[u8], ctx: &Context) -> Result<(), Error> {
let ctx_key = to_key(PRIVATE_TX_CONTEXT_PREFIX, &mut slate_id.to_vec());
self.db.borrow().as_ref().unwrap().put_ser(&ctx_key, &ctx)?;
Ok(())
}
fn delete_private_context(&mut self, slate_id: &[u8]) -> Result<(), Error> {
let ctx_key = to_key(PRIVATE_TX_CONTEXT_PREFIX, &mut slate_id.to_vec());
self.db
.borrow()
.as_ref()
.unwrap()
.delete(&ctx_key)
.map_err(|e| e.into())
}
fn commit(&self) -> Result<(), Error> { fn commit(&self) -> Result<(), Error> {
let db = self.db.replace(None); let db = self.db.replace(None);
db.unwrap().commit()?; db.unwrap().commit()?;

View file

@ -24,7 +24,7 @@ use keychain::{BlindSum, BlindingFactor, ExtKeychain, Keychain};
use util::secp::key::{PublicKey, SecretKey}; use util::secp::key::{PublicKey, SecretKey};
use util::{kernel_sig_msg, secp}; use util::{kernel_sig_msg, secp};
use wallet::libtx::{aggsig, proof}; use wallet::libtx::{aggsig, proof};
use wallet::libwallet::internal::sigcontext; use wallet::libwallet::types::Context;
use rand::thread_rng; use rand::thread_rng;
@ -46,9 +46,11 @@ fn aggsig_sender_receiver_interaction() {
let keychain = ExtKeychain::from_random_seed().unwrap(); let keychain = ExtKeychain::from_random_seed().unwrap();
let blinding_factor = keychain let blinding_factor = keychain
.blind_sum(&BlindSum::new() .blind_sum(
&BlindSum::new()
.sub_blinding_factor(BlindingFactor::from_secret_key(skey1)) .sub_blinding_factor(BlindingFactor::from_secret_key(skey1))
.add_blinding_factor(BlindingFactor::from_secret_key(skey2))) .add_blinding_factor(BlindingFactor::from_secret_key(skey2)),
)
.unwrap(); .unwrap();
keychain keychain
@ -76,7 +78,7 @@ fn aggsig_sender_receiver_interaction() {
let blind = blinding_factor.secret_key(&keychain.secp()).unwrap(); let blind = blinding_factor.secret_key(&keychain.secp()).unwrap();
s_cx = sigcontext::Context::new(&keychain.secp(), blind); s_cx = Context::new(&keychain.secp(), blind);
s_cx.get_public_keys(&keychain.secp()) s_cx.get_public_keys(&keychain.secp())
}; };
@ -89,7 +91,7 @@ fn aggsig_sender_receiver_interaction() {
// let blind = blind_sum.secret_key(&keychain.secp())?; // let blind = blind_sum.secret_key(&keychain.secp())?;
let blind = keychain.derived_key(&key_id).unwrap(); let blind = keychain.derived_key(&key_id).unwrap();
rx_cx = sigcontext::Context::new(&keychain.secp(), blind); rx_cx = Context::new(&keychain.secp(), blind);
let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp()); let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp());
rx_cx.add_output(&key_id); rx_cx.add_output(&key_id);
@ -234,12 +236,14 @@ fn aggsig_sender_receiver_interaction_offset() {
let keychain = ExtKeychain::from_random_seed().unwrap(); let keychain = ExtKeychain::from_random_seed().unwrap();
let blinding_factor = keychain let blinding_factor = keychain
.blind_sum(&BlindSum::new() .blind_sum(
&BlindSum::new()
.sub_blinding_factor(BlindingFactor::from_secret_key(skey1)) .sub_blinding_factor(BlindingFactor::from_secret_key(skey1))
.add_blinding_factor(BlindingFactor::from_secret_key(skey2)) .add_blinding_factor(BlindingFactor::from_secret_key(skey2))
// subtract the kernel offset here like as would when // subtract the kernel offset here like as would when
// verifying a kernel signature // verifying a kernel signature
.sub_blinding_factor(BlindingFactor::from_secret_key(kernel_offset))) .sub_blinding_factor(BlindingFactor::from_secret_key(kernel_offset)),
)
.unwrap(); .unwrap();
keychain keychain
@ -261,16 +265,18 @@ fn aggsig_sender_receiver_interaction_offset() {
// dealing with an input here so we need to negate the blinding_factor // dealing with an input here so we need to negate the blinding_factor
// rather than use it as is // rather than use it as is
let blinding_factor = keychain let blinding_factor = keychain
.blind_sum(&BlindSum::new() .blind_sum(
&BlindSum::new()
.sub_blinding_factor(BlindingFactor::from_secret_key(skey)) .sub_blinding_factor(BlindingFactor::from_secret_key(skey))
// subtract the kernel offset to create an aggsig context // subtract the kernel offset to create an aggsig context
// with our "split" key // with our "split" key
.sub_blinding_factor(BlindingFactor::from_secret_key(kernel_offset))) .sub_blinding_factor(BlindingFactor::from_secret_key(kernel_offset)),
)
.unwrap(); .unwrap();
let blind = blinding_factor.secret_key(&keychain.secp()).unwrap(); let blind = blinding_factor.secret_key(&keychain.secp()).unwrap();
s_cx = sigcontext::Context::new(&keychain.secp(), blind); s_cx = Context::new(&keychain.secp(), blind);
s_cx.get_public_keys(&keychain.secp()) s_cx.get_public_keys(&keychain.secp())
}; };
@ -282,7 +288,7 @@ fn aggsig_sender_receiver_interaction_offset() {
let blind = keychain.derived_key(&key_id).unwrap(); let blind = keychain.derived_key(&key_id).unwrap();
rx_cx = sigcontext::Context::new(&keychain.secp(), blind); rx_cx = Context::new(&keychain.secp(), blind);
let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp()); let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp());
rx_cx.add_output(&key_id); rx_cx.add_output(&key_id);