Skip to content

Commit

Permalink
Add function to build multisig output
Browse files Browse the repository at this point in the history
Build a multisig output with a blank rangeproof, to build the rangeproof
over a number of rounds

Output commit is a sum of a partial commit to the output value and a
commit to zero
  • Loading branch information
GeneFerneau committed Jun 17, 2021
1 parent 5b12dcd commit d6edffd
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
2 changes: 2 additions & 0 deletions core/src/core/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1980,6 +1980,8 @@ enum_from_primitive! {
Plain = 0,
/// A coinbase output.
Coinbase = 1,
/// Multisignature output with shared ownership
Multisig = 2,
}
}

Expand Down
41 changes: 41 additions & 0 deletions core/src/libtx/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use crate::core::{Input, KernelFeatures, Output, OutputFeatures, Transaction, Tx
use crate::libtx::proof::{self, ProofBuild};
use crate::libtx::{aggsig, Error};
use keychain::{BlindSum, BlindingFactor, Identifier, Keychain, SwitchCommitmentType};
use util::secp::pedersen::{Commitment, RangeProof};

/// Context information available to transaction combinators.
pub struct Context<'a, K, B>
Expand Down Expand Up @@ -143,6 +144,46 @@ where
)
}

/// Adds an output with the provided value and key identifier from the
/// keychain.
///
/// Adds a blank Rangeproof, to build the multiparty bulletproof over
/// a number of rounds
pub fn multisig_output<K, B>(
value: u64,
key_id: Identifier,
part_commit: Commitment,
) -> Box<Append<K, B>>
where
K: Keychain,
B: ProofBuild,
{
Box::new(
move |build, acc| -> Result<(Transaction, BlindSum), Error> {
let (tx, sum) = acc?;

// TODO: proper support for different switch commitment schemes
let switch = SwitchCommitmentType::Regular;

// add commit to zero to the initiator's partial commit to the value
let commit_key = build.keychain.derive_key(value, &key_id, switch)?;
let secp = build.keychain.secp();
let commit = secp.commit(0, commit_key)?;
let commit_sum = secp.commit_sum(vec![commit, part_commit.clone()], vec![])?;

debug!("Building output: {}, {:?}", value, commit_sum);

// add zero Rangeproof to build the multiparty rangeproof over a number of steps
let proof = RangeProof::zero();

Ok((
tx.with_output(Output::new(OutputFeatures::Multisig, commit_sum, proof)),
sum.add_key_id(key_id.to_value_path(value)),
))
},
)
}

/// Adds a known excess value on the transaction being built. Usually used in
/// combination with the initial_tx function when a new transaction is built
/// by adding to a pre-existing one.
Expand Down

0 comments on commit d6edffd

Please sign in to comment.