From 0eec80789a9f591317126fd6a47262a142685fb5 Mon Sep 17 00:00:00 2001 From: Yeastplume Date: Tue, 20 Nov 2018 13:02:51 +0000 Subject: [PATCH] start libtx docs (#1998) --- wallet/src/libtx/aggsig.rs | 140 +++++++++++++++++++++++++++++++++++-- wallet/src/libtx/mod.rs | 4 +- 2 files changed, 136 insertions(+), 8 deletions(-) diff --git a/wallet/src/libtx/aggsig.rs b/wallet/src/libtx/aggsig.rs index 07b6cd393..5efecefcc 100644 --- a/wallet/src/libtx/aggsig.rs +++ b/wallet/src/libtx/aggsig.rs @@ -11,8 +11,10 @@ // 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. -//! Aggsig helper functions used in transaction creation.. should be only -//! interface into the underlying secp library + +//! Aggregated Signature functions used in the creation of Grin transactions. +//! This module interfaces into the underlying +//! [Rust Aggsig library](https://github.com/mimblewimble/rust-secp256k1-zkp/blob/master/src/aggsig.rs) use keychain::{BlindingFactor, Identifier, Keychain}; use libtx::error::{Error, ErrorKind}; @@ -20,14 +22,78 @@ use util::secp::key::{PublicKey, SecretKey}; use util::secp::pedersen::Commitment; use util::secp::{self, aggsig, Message, Secp256k1, Signature}; -/// exports a secure nonce guaranteed to be usable -/// in aggsig creation +/// Creates a new secure nonce (as a SecretKey), guaranteed to be usable during +/// aggsig creation. +/// +/// # Arguments +/// +/// * `secp` - A Secp256k1 Context initialized for Signing +/// +/// # Example +/// +/// ``` +/// # extern crate grin_util as util; +/// # extern crate grin_wallet as wallet; +/// use wallet::libtx::aggsig; +/// use util::secp::{ContextFlag, Secp256k1}; +/// let secp = Secp256k1::with_caps(ContextFlag::SignOnly); +/// let secret_nonce = aggsig::create_secnonce(&secp).unwrap(); +/// ``` +/// # Remarks +/// +/// The resulting SecretKey is guaranteed to have Jacobi symbol 1. + pub fn create_secnonce(secp: &Secp256k1) -> Result { let nonce = aggsig::export_secnonce_single(secp)?; Ok(nonce) } -/// Calculate a partial sig +/// Calculates a partial signature given the signer's secure key, +/// the sum of all public nonces and (optionally) the sum of all public keys. +/// +/// # Arguments +/// +/// * `secp` - A Secp256k1 Context initialized for Signing +/// * `sec_key` - The signer's secret key +/// * `sec_nonce` - The signer's secret nonce (the public version of which +/// was added to the `nonce_sum` total) +/// * `nonce_sum` - The sum of the public nonces of all signers participating +/// in the full signature. This value is encoded in e. +/// * `pubkey_sum` - (Optional) The sum of the public keys of all signers participating +/// in the full signature. If included, this value is encoded in e. +/// * `msg` - The message to sign. +/// +/// # Example +/// +/// ``` +/// # extern crate grin_util as util; +/// # extern crate grin_wallet as wallet; +/// # extern crate rand; +/// use rand::thread_rng; +/// use wallet::libtx::aggsig; +/// use util::secp::key::{PublicKey, SecretKey}; +/// use util::secp::{ContextFlag, Secp256k1, Message}; +/// +/// let secp = Secp256k1::with_caps(ContextFlag::SignOnly); +/// let secret_nonce = aggsig::create_secnonce(&secp).unwrap(); +/// let secret_key = SecretKey::new(&secp, &mut thread_rng()); +/// let pub_nonce_sum = PublicKey::from_secret_key(&secp, &secret_nonce).unwrap(); +/// // ... Add all other participating nonces +/// let pub_key_sum = PublicKey::from_secret_key(&secp, &secret_key).unwrap(); +/// // ... Add all other participating keys +/// let mut msg_bytes = [0; 32]; +/// // ... Encode message +/// let message = Message::from_slice(&msg_bytes).unwrap(); +/// let sig_part = aggsig::calculate_partial_sig( +/// &secp, +/// &secret_key, +/// &secret_nonce, +/// &pub_nonce_sum, +/// Some(&pub_key_sum), +/// &message, +///).unwrap(); +/// ``` + pub fn calculate_partial_sig( secp: &Secp256k1, sec_key: &SecretKey, @@ -50,7 +116,69 @@ pub fn calculate_partial_sig( Ok(sig) } -/// Verifies a partial sig given all public nonces used in the round +/// Verifies a partial signature from a public key. All nonce and public +/// key sum values must be identical to those provided in the call to +/// [`calculate_partial_sig`](fn.calculate_partial_sig.html). Returns +/// `Result::Ok` if the signature is valid, or a Signature +/// [ErrorKind](../enum.ErrorKind.html) otherwise +/// +/// # Arguments +/// +/// * `secp` - A Secp256k1 Context initialized for Validation +/// * `sig` - The signature to validate, created via a call to +/// [`calculate_partial_sig`](fn.calculate_partial_sig.html) +/// * `pub_nonce_sum` - The sum of the public nonces of all signers participating +/// in the full signature. This value is encoded in e. +/// * `pubkey` - Corresponding Public Key of the private key used to sign the message. +/// was added to the `nonce_sum` total) +/// * `pubkey_sum` - (Optional) The sum of the public keys of all signers participating +/// in the full signature. If included, this value is encoded in e. +/// * `msg` - The message to verify. +/// +/// # Example +/// +/// ``` +/// # extern crate grin_util as util; +/// # extern crate grin_wallet as wallet; +/// # extern crate rand; +/// use rand::thread_rng; +/// use wallet::libtx::aggsig; +/// use util::secp::key::{PublicKey, SecretKey}; +/// use util::secp::{ContextFlag, Secp256k1, Message}; +/// +/// let secp = Secp256k1::with_caps(ContextFlag::Full); +/// let secret_nonce = aggsig::create_secnonce(&secp).unwrap(); +/// let secret_key = SecretKey::new(&secp, &mut thread_rng()); +/// let pub_nonce_sum = PublicKey::from_secret_key(&secp, &secret_nonce).unwrap(); +/// // ... Add all other participating nonces +/// let pub_key_sum = PublicKey::from_secret_key(&secp, &secret_key).unwrap(); +/// // ... Add all other participating keys +/// let mut msg_bytes = [0; 32]; +/// // ... Encode message +/// let message = Message::from_slice(&msg_bytes).unwrap(); +/// let sig_part = aggsig::calculate_partial_sig( +/// &secp, +/// &secret_key, +/// &secret_nonce, +/// &pub_nonce_sum, +/// Some(&pub_key_sum), +/// &message, +///).unwrap(); +/// +/// // Now verify the signature, ensuring the same values used to create +/// // the signature are provided: +/// let public_key = PublicKey::from_secret_key(&secp, &secret_key).unwrap(); +/// +/// let result = aggsig::verify_partial_sig( +/// &secp, +/// &sig_part, +/// &pub_nonce_sum, +/// &public_key, +/// Some(&pub_key_sum), +/// &message, +///); +/// ``` + pub fn verify_partial_sig( secp: &Secp256k1, sig: &Signature, diff --git a/wallet/src/libtx/mod.rs b/wallet/src/libtx/mod.rs index b1a36fb8e..9a17da5d9 100644 --- a/wallet/src/libtx/mod.rs +++ b/wallet/src/libtx/mod.rs @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Wallet lib... should be used by clients to build wallets and -//! encapsulate all functions needed to build transactions and operate a wallet +//! Library containing lower-level transaction building functions needed by +//! all wallets. #![deny(non_upper_case_globals)] #![deny(non_camel_case_types)]