mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 11:31:08 +03:00
parent
34520a46d9
commit
1465599df1
3 changed files with 168 additions and 8 deletions
|
@ -130,7 +130,6 @@ pub fn calculate_partial_sig(
|
|||
/// * `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.
|
||||
|
@ -203,7 +202,59 @@ pub fn verify_partial_sig(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Just a simple sig, creates its own nonce, etc
|
||||
/// Creates a single-signer aggsig signature from a key id. Generally,
|
||||
/// this function is used to create transaction kernel signatures for
|
||||
/// coinbase outputs.
|
||||
/// Returns `Ok(Signature)` if the signature is valid, or a Signature
|
||||
/// [ErrorKind](../enum.ErrorKind.html) otherwise
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `secp` - A Secp256k1 Context initialized for Signing
|
||||
/// * `k` - The Keychain implementation being used
|
||||
/// * `msg` - The message to sign (fee|lockheight).
|
||||
/// * `key_id` - The keychain key id corresponding to the private key
|
||||
/// with which to sign the message
|
||||
/// * `blind_sum` - (Optional) The sum of all blinding factors in the transaction
|
||||
/// in the case of a coinbase transaction this will simply be the corresponding
|
||||
/// public key.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate grin_util as util;
|
||||
/// # extern crate grin_core as core;
|
||||
/// # extern crate grin_wallet as wallet;
|
||||
/// # extern crate grin_keychain as keychain;
|
||||
/// use core::consensus::reward;
|
||||
/// use wallet::libtx::{aggsig, proof};
|
||||
/// use util::secp::key::{PublicKey, SecretKey};
|
||||
/// use util::secp::{ContextFlag, Secp256k1};
|
||||
/// use core::core::transaction::kernel_sig_msg;
|
||||
/// use core::core::{Output, OutputFeatures};
|
||||
/// use keychain::{Keychain, ExtKeychain};
|
||||
///
|
||||
/// let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
||||
/// let keychain = ExtKeychain::from_random_seed().unwrap();
|
||||
/// let fees = 10_000;
|
||||
/// let value = reward(fees);
|
||||
/// let key_id = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
|
||||
/// let commit = keychain.commit(value, &key_id).unwrap();
|
||||
/// let rproof = proof::create(&keychain, value, &key_id, commit, None).unwrap();
|
||||
/// let output = Output {
|
||||
/// features: OutputFeatures::COINBASE_OUTPUT,
|
||||
/// commit: commit,
|
||||
/// proof: rproof,
|
||||
/// };
|
||||
/// let height = 20;
|
||||
/// let over_commit = secp.commit_value(reward(fees)).unwrap();
|
||||
/// let out_commit = output.commitment();
|
||||
/// let msg = kernel_sig_msg(0, height).unwrap();
|
||||
/// let excess = secp.commit_sum(vec![out_commit], vec![over_commit]).unwrap();
|
||||
/// let pubkey = excess.to_pubkey(&secp).unwrap();
|
||||
/// let sig = aggsig::sign_from_key_id(&secp, &keychain, &msg, &key_id, Some(&pubkey)).unwrap();
|
||||
/// ```
|
||||
|
||||
pub fn sign_from_key_id<K>(
|
||||
secp: &Secp256k1,
|
||||
k: &K,
|
||||
|
@ -228,7 +279,61 @@ where
|
|||
Ok(sig)
|
||||
}
|
||||
|
||||
/// Verifies a sig given a commitment
|
||||
/// Simple verification a single signature from a commitment. The public
|
||||
/// key used to verify the signature is derived from the commit.
|
||||
/// Returns `Ok(())` if the signature is valid, or a Signature
|
||||
/// [ErrorKind](../enum.ErrorKind.html) otherwise
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `secp` - A Secp256k1 Context initialized for Verification
|
||||
/// * `sig` - The Signature to verify
|
||||
/// * `msg` - The message to sign (fee|lockheight).
|
||||
/// * `commit` - The commitment to verify. The actual public key used
|
||||
/// during verification is derived from this commit.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate grin_util as util;
|
||||
/// # extern crate grin_core as core;
|
||||
/// # extern crate grin_wallet as wallet;
|
||||
/// # extern crate grin_keychain as keychain;
|
||||
/// use core::consensus::reward;
|
||||
/// use wallet::libtx::{aggsig, proof};
|
||||
/// use util::secp::key::{PublicKey, SecretKey};
|
||||
/// use util::secp::{ContextFlag, Secp256k1};
|
||||
/// use core::core::transaction::kernel_sig_msg;
|
||||
/// use core::core::{Output, OutputFeatures};
|
||||
/// use keychain::{Keychain, ExtKeychain};
|
||||
///
|
||||
/// // Create signature
|
||||
/// let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
||||
/// let keychain = ExtKeychain::from_random_seed().unwrap();
|
||||
/// let fees = 10_000;
|
||||
/// let value = reward(fees);
|
||||
/// let key_id = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
|
||||
/// let commit = keychain.commit(value, &key_id).unwrap();
|
||||
/// let rproof = proof::create(&keychain, value, &key_id, commit, None).unwrap();
|
||||
/// let output = Output {
|
||||
/// features: OutputFeatures::COINBASE_OUTPUT,
|
||||
/// commit: commit,
|
||||
/// proof: rproof,
|
||||
/// };
|
||||
/// let height = 20;
|
||||
/// let over_commit = secp.commit_value(reward(fees)).unwrap();
|
||||
/// let out_commit = output.commitment();
|
||||
/// let msg = kernel_sig_msg(0, height).unwrap();
|
||||
/// let excess = secp.commit_sum(vec![out_commit], vec![over_commit]).unwrap();
|
||||
/// let pubkey = excess.to_pubkey(&secp).unwrap();
|
||||
/// let sig = aggsig::sign_from_key_id(&secp, &keychain, &msg, &key_id, Some(&pubkey)).unwrap();
|
||||
///
|
||||
/// // Verify the signature from the excess commit
|
||||
/// let sig_verifies =
|
||||
/// aggsig::verify_single_from_commit(&keychain.secp(), &sig, &msg, &excess);
|
||||
/// assert!(!sig_verifies.is_err());
|
||||
/// ```
|
||||
|
||||
pub fn verify_single_from_commit(
|
||||
secp: &Secp256k1,
|
||||
sig: &Signature,
|
||||
|
@ -244,8 +349,63 @@ pub fn verify_single_from_commit(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Verify a sig, with built message
|
||||
pub fn verify_sig_build_msg(
|
||||
/// Verifies a completed (summed) signature, which must include the message
|
||||
/// and pubkey sum values that are used during signature creation time
|
||||
/// to create 'e'
|
||||
/// Returns `Ok(())` if the signature is valid, or a Signature
|
||||
/// [ErrorKind](../enum.ErrorKind.html) otherwise
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `secp` - A Secp256k1 Context initialized for Verification
|
||||
/// * `sig` - The Signature to verify
|
||||
/// * `pubkey` - Corresponding Public Key of the private key used to sign the message.
|
||||
/// * `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. Must be the same
|
||||
/// value as when the signature was created to verify correctly.
|
||||
/// * `msg` - The message to verify (fee|lockheight).
|
||||
///
|
||||
/// # 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();
|
||||
/// // ... Verify above, once all signatures have been added together
|
||||
/// let sig_verifies = aggsig::verify_completed_sig(
|
||||
/// &secp,
|
||||
/// &sig_part,
|
||||
/// &pub_key_sum,
|
||||
/// Some(&pub_key_sum),
|
||||
/// &message,
|
||||
/// );
|
||||
/// assert!(!sig_verifies.is_err());
|
||||
/// ```
|
||||
|
||||
pub fn verify_completed_sig(
|
||||
secp: &Secp256k1,
|
||||
sig: &Signature,
|
||||
pubkey: &PublicKey,
|
||||
|
|
|
@ -353,7 +353,7 @@ impl Slate {
|
|||
// Calculate the final public key (for our own sanity check)
|
||||
|
||||
// Check our final sig verifies
|
||||
aggsig::verify_sig_build_msg(
|
||||
aggsig::verify_completed_sig(
|
||||
&keychain.secp(),
|
||||
&final_sig,
|
||||
&final_pubkey,
|
||||
|
|
|
@ -205,7 +205,7 @@ fn aggsig_sender_receiver_interaction() {
|
|||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
|
||||
// Receiver check the final signature verifies
|
||||
let sig_verifies = aggsig::verify_sig_build_msg(
|
||||
let sig_verifies = aggsig::verify_completed_sig(
|
||||
&keychain.secp(),
|
||||
&final_sig,
|
||||
&final_pubkey,
|
||||
|
@ -411,7 +411,7 @@ fn aggsig_sender_receiver_interaction_offset() {
|
|||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
|
||||
// Receiver check the final signature verifies
|
||||
let sig_verifies = aggsig::verify_sig_build_msg(
|
||||
let sig_verifies = aggsig::verify_completed_sig(
|
||||
&keychain.secp(),
|
||||
&final_sig,
|
||||
&final_pubkey,
|
||||
|
|
Loading…
Reference in a new issue