mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-20 19:11:08 +03:00
Refactor kernel sig msg creation (#1954)
* refactor kernel msg creation * rustfmt * Error not secp::Error * fix tests for refactored errors
This commit is contained in:
parent
29b2c3384c
commit
183d9c9f3e
9 changed files with 206 additions and 189 deletions
|
@ -21,6 +21,8 @@ use std::sync::Arc;
|
|||
use std::{error, fmt};
|
||||
use util::RwLock;
|
||||
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
|
||||
use consensus::{self, VerifySortOrder};
|
||||
use core::hash::Hashed;
|
||||
use core::verifier_cache::VerifierCache;
|
||||
|
@ -28,9 +30,9 @@ use core::{committed, Committed};
|
|||
use keychain::{self, BlindingFactor};
|
||||
use ser::{self, read_multi, FixedLength, PMMRable, Readable, Reader, Writeable, Writer};
|
||||
use util;
|
||||
use util::secp;
|
||||
use util::secp::pedersen::{Commitment, RangeProof};
|
||||
use util::secp::{self, Message, Signature};
|
||||
use util::{kernel_sig_msg, static_secp_instance};
|
||||
use util::static_secp_instance;
|
||||
|
||||
bitflags! {
|
||||
/// Options for a kernel's structure or use
|
||||
|
@ -81,6 +83,8 @@ pub enum Error {
|
|||
/// Validation error relating to kernel features.
|
||||
/// It is invalid for a transaction to contain a coinbase kernel, for example.
|
||||
InvalidKernelFeatures,
|
||||
/// Signature verification error.
|
||||
IncorrectSignature,
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
|
@ -143,7 +147,7 @@ pub struct TxKernel {
|
|||
pub excess: Commitment,
|
||||
/// The signature proving the excess is a valid public key, which signs
|
||||
/// the transaction fee.
|
||||
pub excess_sig: Signature,
|
||||
pub excess_sig: secp::Signature,
|
||||
}
|
||||
|
||||
hashable_ord!(TxKernel);
|
||||
|
@ -179,7 +183,7 @@ impl Readable for TxKernel {
|
|||
fee: reader.read_u64()?,
|
||||
lock_height: reader.read_u64()?,
|
||||
excess: Commitment::read(reader)?,
|
||||
excess_sig: Signature::read(reader)?,
|
||||
excess_sig: secp::Signature::read(reader)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -190,11 +194,17 @@ impl TxKernel {
|
|||
self.excess
|
||||
}
|
||||
|
||||
/// The msg signed as part of the tx kernel.
|
||||
/// Consists of the fee and the lock_height.
|
||||
pub fn msg_to_sign(&self) -> Result<secp::Message, Error> {
|
||||
let msg = kernel_sig_msg(self.fee, self.lock_height)?;
|
||||
Ok(msg)
|
||||
}
|
||||
|
||||
/// Verify the transaction proof validity. Entails handling the commitment
|
||||
/// as a public key and checking the signature verifies with the fee as
|
||||
/// message.
|
||||
pub fn verify(&self) -> Result<(), secp::Error> {
|
||||
let msg = Message::from_slice(&kernel_sig_msg(self.fee, self.lock_height))?;
|
||||
pub fn verify(&self) -> Result<(), Error> {
|
||||
let secp = static_secp_instance();
|
||||
let secp = secp.lock();
|
||||
let sig = &self.excess_sig;
|
||||
|
@ -203,14 +213,14 @@ impl TxKernel {
|
|||
if !secp::aggsig::verify_single(
|
||||
&secp,
|
||||
&sig,
|
||||
&msg,
|
||||
&self.msg_to_sign()?,
|
||||
None,
|
||||
&pubkey,
|
||||
Some(&pubkey),
|
||||
None,
|
||||
false,
|
||||
) {
|
||||
return Err(secp::Error::IncorrectSignature);
|
||||
return Err(Error::IncorrectSignature);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -222,7 +232,7 @@ impl TxKernel {
|
|||
fee: 0,
|
||||
lock_height: 0,
|
||||
excess: Commitment::from_vec(vec![0; 33]),
|
||||
excess_sig: Signature::from_raw_data(&[0; 64]).unwrap(),
|
||||
excess_sig: secp::Signature::from_raw_data(&[0; 64]).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1194,6 +1204,15 @@ impl Readable for OutputIdentifier {
|
|||
}
|
||||
}
|
||||
|
||||
/// Construct msg from tx fee and lock_height.
|
||||
pub fn kernel_sig_msg(fee: u64, lock_height: u64) -> Result<secp::Message, Error> {
|
||||
let mut bytes = [0; 32];
|
||||
BigEndian::write_u64(&mut bytes[16..24], fee);
|
||||
BigEndian::write_u64(&mut bytes[24..], lock_height);
|
||||
let msg = secp::Message::from_slice(&bytes)?;
|
||||
Ok(msg)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
|
|
@ -75,7 +75,7 @@ fn tx_double_ser_deser() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "InvalidSecretKey")]
|
||||
#[should_panic(expected = "Keychain Error")]
|
||||
fn test_zero_commit_fails() {
|
||||
let keychain = ExtKeychain::from_random_seed().unwrap();
|
||||
let key_id1 = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
|
||||
|
|
|
@ -58,7 +58,6 @@ pub use types::{LogLevel, LoggingConfig};
|
|||
pub mod macros;
|
||||
|
||||
// other utils
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
#[allow(unused_imports)]
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
|
@ -113,14 +112,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Construct msg bytes from tx fee and lock_height
|
||||
pub fn kernel_sig_msg(fee: u64, lock_height: u64) -> [u8; 32] {
|
||||
let mut bytes = [0; 32];
|
||||
BigEndian::write_u64(&mut bytes[16..24], fee);
|
||||
BigEndian::write_u64(&mut bytes[24..], lock_height);
|
||||
bytes
|
||||
}
|
||||
|
||||
/// Encode an utf8 string to a base64 string
|
||||
pub fn to_base64(s: &str) -> String {
|
||||
base64::encode(s)
|
||||
|
|
|
@ -30,122 +30,138 @@
|
|||
|
||||
#[macro_export]
|
||||
macro_rules! impl_array_newtype {
|
||||
($thing:ident, $ty:ty, $len:expr) => {
|
||||
impl $thing {
|
||||
#[inline]
|
||||
/// Converts the object to a raw pointer
|
||||
pub fn as_ptr(&self) -> *const $ty {
|
||||
let &$thing(ref dat) = self;
|
||||
dat.as_ptr()
|
||||
}
|
||||
($thing:ident, $ty:ty, $len:expr) => {
|
||||
impl $thing {
|
||||
#[inline]
|
||||
/// Converts the object to a raw pointer
|
||||
pub fn as_ptr(&self) -> *const $ty {
|
||||
let &$thing(ref dat) = self;
|
||||
dat.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Converts the object to a mutable raw pointer
|
||||
pub fn as_mut_ptr(&mut self) -> *mut $ty {
|
||||
let &mut $thing(ref mut dat) = self;
|
||||
dat.as_mut_ptr()
|
||||
}
|
||||
#[inline]
|
||||
/// Converts the object to a mutable raw pointer
|
||||
pub fn as_mut_ptr(&mut self) -> *mut $ty {
|
||||
let &mut $thing(ref mut dat) = self;
|
||||
dat.as_mut_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Returns the length of the object as an array
|
||||
pub fn len(&self) -> usize { $len }
|
||||
#[inline]
|
||||
/// Returns the length of the object as an array
|
||||
pub fn len(&self) -> usize {
|
||||
$len
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Returns whether the object, as an array, is empty. Always false.
|
||||
pub fn is_empty(&self) -> bool { false }
|
||||
#[inline]
|
||||
/// Returns whether the object, as an array, is empty. Always false.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Returns the underlying bytes.
|
||||
pub fn as_bytes(&self) -> &[$ty; $len] { &self.0 }
|
||||
#[inline]
|
||||
/// Returns the underlying bytes.
|
||||
pub fn as_bytes(&self) -> &[$ty; $len] {
|
||||
&self.0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Returns the underlying bytes.
|
||||
pub fn to_bytes(&self) -> [$ty; $len] { self.0.clone() }
|
||||
#[inline]
|
||||
/// Returns the underlying bytes.
|
||||
pub fn to_bytes(&self) -> [$ty; $len] {
|
||||
self.0.clone()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Returns the underlying bytes.
|
||||
pub fn into_bytes(self) -> [$ty; $len] { self.0 }
|
||||
}
|
||||
#[inline]
|
||||
/// Returns the underlying bytes.
|
||||
pub fn into_bytes(self) -> [$ty; $len] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a [$ty]> for $thing {
|
||||
fn from(data: &'a [$ty]) -> $thing {
|
||||
assert_eq!(data.len(), $len);
|
||||
let mut ret = [0; $len];
|
||||
ret.copy_from_slice(&data[..]);
|
||||
$thing(ret)
|
||||
}
|
||||
}
|
||||
impl<'a> From<&'a [$ty]> for $thing {
|
||||
fn from(data: &'a [$ty]) -> $thing {
|
||||
assert_eq!(data.len(), $len);
|
||||
let mut ret = [0; $len];
|
||||
ret.copy_from_slice(&data[..]);
|
||||
$thing(ret)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Index<usize> for $thing {
|
||||
type Output = $ty;
|
||||
impl ::std::ops::Index<usize> for $thing {
|
||||
type Output = $ty;
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: usize) -> &$ty {
|
||||
let &$thing(ref dat) = self;
|
||||
&dat[index]
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn index(&self, index: usize) -> &$ty {
|
||||
let &$thing(ref dat) = self;
|
||||
&dat[index]
|
||||
}
|
||||
}
|
||||
|
||||
impl_index_newtype!($thing, $ty);
|
||||
impl_index_newtype!($thing, $ty);
|
||||
|
||||
impl PartialEq for $thing {
|
||||
#[inline]
|
||||
fn eq(&self, other: &$thing) -> bool {
|
||||
&self[..] == &other[..]
|
||||
}
|
||||
}
|
||||
impl PartialEq for $thing {
|
||||
#[inline]
|
||||
fn eq(&self, other: &$thing) -> bool {
|
||||
&self[..] == &other[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for $thing {}
|
||||
impl Eq for $thing {}
|
||||
|
||||
impl PartialOrd for $thing {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &$thing) -> Option<::std::cmp::Ordering> {
|
||||
Some(self.cmp(&other))
|
||||
}
|
||||
}
|
||||
impl PartialOrd for $thing {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &$thing) -> Option<::std::cmp::Ordering> {
|
||||
Some(self.cmp(&other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for $thing {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &$thing) -> ::std::cmp::Ordering {
|
||||
// manually implement comparison to get little-endian ordering
|
||||
// (we need this for our numeric types; non-numeric ones shouldn't
|
||||
// be ordered anyway except to put them in BTrees or whatever, and
|
||||
// they don't care how we order as long as we're consisistent).
|
||||
for i in 0..$len {
|
||||
if self[$len - 1 - i] < other[$len - 1 - i] { return ::std::cmp::Ordering::Less; }
|
||||
if self[$len - 1 - i] > other[$len - 1 - i] { return ::std::cmp::Ordering::Greater; }
|
||||
}
|
||||
::std::cmp::Ordering::Equal
|
||||
}
|
||||
}
|
||||
impl Ord for $thing {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &$thing) -> ::std::cmp::Ordering {
|
||||
// manually implement comparison to get little-endian ordering
|
||||
// (we need this for our numeric types; non-numeric ones shouldn't
|
||||
// be ordered anyway except to put them in BTrees or whatever, and
|
||||
// they don't care how we order as long as we're consisistent).
|
||||
for i in 0..$len {
|
||||
if self[$len - 1 - i] < other[$len - 1 - i] {
|
||||
return ::std::cmp::Ordering::Less;
|
||||
}
|
||||
if self[$len - 1 - i] > other[$len - 1 - i] {
|
||||
return ::std::cmp::Ordering::Greater;
|
||||
}
|
||||
}
|
||||
::std::cmp::Ordering::Equal
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "clippy", allow(expl_impl_clone_on_copy))] // we don't define the `struct`, we have to explicitly impl
|
||||
impl Clone for $thing {
|
||||
#[inline]
|
||||
fn clone(&self) -> $thing {
|
||||
$thing::from(&self[..])
|
||||
}
|
||||
}
|
||||
#[cfg_attr(feature = "clippy", allow(expl_impl_clone_on_copy))] // we don't define the `struct`, we have to explicitly impl
|
||||
impl Clone for $thing {
|
||||
#[inline]
|
||||
fn clone(&self) -> $thing {
|
||||
$thing::from(&self[..])
|
||||
}
|
||||
}
|
||||
|
||||
impl Copy for $thing {}
|
||||
impl Copy for $thing {}
|
||||
|
||||
impl ::std::hash::Hash for $thing {
|
||||
#[inline]
|
||||
fn hash<H>(&self, state: &mut H)
|
||||
where H: ::std::hash::Hasher
|
||||
{
|
||||
(&self[..]).hash(state);
|
||||
}
|
||||
impl ::std::hash::Hash for $thing {
|
||||
#[inline]
|
||||
fn hash<H>(&self, state: &mut H)
|
||||
where
|
||||
H: ::std::hash::Hasher,
|
||||
{
|
||||
(&self[..]).hash(state);
|
||||
}
|
||||
|
||||
fn hash_slice<H>(data: &[$thing], state: &mut H)
|
||||
where H: ::std::hash::Hasher
|
||||
{
|
||||
for d in data.iter() {
|
||||
(&d[..]).hash(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fn hash_slice<H>(data: &[$thing], state: &mut H)
|
||||
where
|
||||
H: ::std::hash::Hasher,
|
||||
{
|
||||
for d in data.iter() {
|
||||
(&d[..]).hash(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
// limitations under the License.
|
||||
//! Aggsig helper functions used in transaction creation.. should be only
|
||||
//! interface into the underlying secp library
|
||||
|
||||
use keychain::{BlindingFactor, Identifier, Keychain};
|
||||
use libtx::error::{Error, ErrorKind};
|
||||
use util::kernel_sig_msg;
|
||||
use util::secp::key::{PublicKey, SecretKey};
|
||||
use util::secp::pedersen::Commitment;
|
||||
use util::secp::{self, aggsig, Message, Secp256k1, Signature};
|
||||
|
@ -34,12 +34,8 @@ pub fn calculate_partial_sig(
|
|||
sec_nonce: &SecretKey,
|
||||
nonce_sum: &PublicKey,
|
||||
pubkey_sum: Option<&PublicKey>,
|
||||
fee: u64,
|
||||
lock_height: u64,
|
||||
msg: &secp::Message,
|
||||
) -> Result<Signature, Error> {
|
||||
// Add public nonces kR*G + kS*G
|
||||
let msg = secp::Message::from_slice(&kernel_sig_msg(fee, lock_height))?;
|
||||
|
||||
//Now calculate signature using message M=fee, nonce in e=nonce_sum
|
||||
let sig = aggsig::sign_single(
|
||||
secp,
|
||||
|
@ -61,10 +57,8 @@ pub fn verify_partial_sig(
|
|||
pub_nonce_sum: &PublicKey,
|
||||
pubkey: &PublicKey,
|
||||
pubkey_sum: Option<&PublicKey>,
|
||||
fee: u64,
|
||||
lock_height: u64,
|
||||
msg: &secp::Message,
|
||||
) -> Result<(), Error> {
|
||||
let msg = secp::Message::from_slice(&kernel_sig_msg(fee, lock_height))?;
|
||||
if !verify_single(
|
||||
secp,
|
||||
sig,
|
||||
|
@ -114,7 +108,7 @@ pub fn verify_single_from_commit(
|
|||
commit: &Commitment,
|
||||
) -> Result<(), Error> {
|
||||
let pubkey = commit.to_pubkey(secp)?;
|
||||
if !verify_single(secp, sig, &msg, None, &pubkey, Some(&pubkey), false) {
|
||||
if !verify_single(secp, sig, msg, None, &pubkey, Some(&pubkey), false) {
|
||||
Err(ErrorKind::Signature(
|
||||
"Signature validation error".to_string(),
|
||||
))?
|
||||
|
@ -128,11 +122,9 @@ pub fn verify_sig_build_msg(
|
|||
sig: &Signature,
|
||||
pubkey: &PublicKey,
|
||||
pubkey_sum: Option<&PublicKey>,
|
||||
fee: u64,
|
||||
lock_height: u64,
|
||||
msg: &secp::Message,
|
||||
) -> Result<(), Error> {
|
||||
let msg = secp::Message::from_slice(&kernel_sig_msg(fee, lock_height))?;
|
||||
if !verify_single(secp, sig, &msg, None, pubkey, pubkey_sum, true) {
|
||||
if !verify_single(secp, sig, msg, None, pubkey, pubkey_sum, true) {
|
||||
Err(ErrorKind::Signature(
|
||||
"Signature validation error".to_string(),
|
||||
))?
|
||||
|
|
|
@ -25,10 +25,9 @@
|
|||
//! build::transaction(vec![input_rand(75), output_rand(42), output_rand(32),
|
||||
//! with_fee(1)])
|
||||
|
||||
use util::{kernel_sig_msg, secp};
|
||||
|
||||
use core::core::{Input, Output, OutputFeatures, Transaction, TxKernel};
|
||||
use keychain::{self, BlindSum, BlindingFactor, Identifier, Keychain};
|
||||
use keychain::{BlindSum, BlindingFactor, Identifier, Keychain};
|
||||
use libtx::Error;
|
||||
use libtx::{aggsig, proof};
|
||||
|
||||
/// Context information available to transaction combinators.
|
||||
|
@ -187,7 +186,7 @@ where
|
|||
pub fn partial_transaction<K>(
|
||||
elems: Vec<Box<Append<K>>>,
|
||||
keychain: &K,
|
||||
) -> Result<(Transaction, BlindingFactor), keychain::Error>
|
||||
) -> Result<(Transaction, BlindingFactor), Error>
|
||||
where
|
||||
K: Keychain,
|
||||
{
|
||||
|
@ -207,10 +206,7 @@ where
|
|||
}
|
||||
|
||||
/// Builds a complete transaction.
|
||||
pub fn transaction<K>(
|
||||
elems: Vec<Box<Append<K>>>,
|
||||
keychain: &K,
|
||||
) -> Result<Transaction, keychain::Error>
|
||||
pub fn transaction<K>(elems: Vec<Box<Append<K>>>, keychain: &K) -> Result<Transaction, Error>
|
||||
where
|
||||
K: Keychain,
|
||||
{
|
||||
|
@ -227,7 +223,7 @@ where
|
|||
let k2 = split.blind_2;
|
||||
|
||||
// Construct the message to be signed.
|
||||
let msg = secp::Message::from_slice(&kernel_sig_msg(kern.fee, kern.lock_height))?;
|
||||
let msg = kern.msg_to_sign()?;
|
||||
|
||||
// Generate kernel excess and excess_sig using the split key k1.
|
||||
let skey = k1.secret_key(&keychain.secp())?;
|
||||
|
|
|
@ -17,11 +17,12 @@
|
|||
use keychain::{Identifier, Keychain};
|
||||
|
||||
use core::consensus::reward;
|
||||
use core::core::transaction::kernel_sig_msg;
|
||||
use core::core::KernelFeatures;
|
||||
use core::core::{Output, OutputFeatures, TxKernel};
|
||||
use libtx::error::Error;
|
||||
use libtx::{aggsig, proof};
|
||||
use util::{kernel_sig_msg, secp, static_secp_instance};
|
||||
use util::static_secp_instance;
|
||||
|
||||
/// output a reward output
|
||||
pub fn output<K>(
|
||||
|
@ -59,7 +60,7 @@ where
|
|||
// not the lock_height of the tx (there is no tx for a coinbase output).
|
||||
// This output will not be spendable earlier than lock_height (and we sign this
|
||||
// here).
|
||||
let msg = secp::Message::from_slice(&kernel_sig_msg(0, height))?;
|
||||
let msg = kernel_sig_msg(0, height)?;
|
||||
let sig = aggsig::sign_from_key_id(&secp, keychain, &msg, &key_id, Some(&pubkey))?;
|
||||
|
||||
let proof = TxKernel {
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
|
||||
use rand::thread_rng;
|
||||
use std::sync::Arc;
|
||||
use util::RwLock;
|
||||
use uuid::Uuid;
|
||||
|
||||
use core::core::committed::Committed;
|
||||
use core::core::transaction::kernel_sig_msg;
|
||||
use core::core::verifier_cache::LruVerifierCache;
|
||||
use core::core::{amount_to_hr_string, Transaction};
|
||||
use keychain::{BlindSum, BlindingFactor, Keychain};
|
||||
|
@ -30,6 +30,7 @@ use libtx::{aggsig, build, tx_fee};
|
|||
use util::secp;
|
||||
use util::secp::key::{PublicKey, SecretKey};
|
||||
use util::secp::Signature;
|
||||
use util::RwLock;
|
||||
|
||||
/// Public data for each participant in the slate
|
||||
|
||||
|
@ -144,6 +145,13 @@ impl Slate {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// This is the msg that we will sign as part of the tx kernel.
|
||||
// Currently includes the fee and the lock_height.
|
||||
fn msg_to_sign(&self) -> Result<secp::Message, Error> {
|
||||
let msg = kernel_sig_msg(self.fee, self.lock_height)?;
|
||||
Ok(msg)
|
||||
}
|
||||
|
||||
/// Completes caller's part of round 2, completing signatures
|
||||
pub fn fill_round_2<K>(
|
||||
&mut self,
|
||||
|
@ -164,8 +172,7 @@ impl Slate {
|
|||
sec_nonce,
|
||||
&self.pub_nonce_sum(keychain.secp())?,
|
||||
Some(&self.pub_blind_sum(keychain.secp())?),
|
||||
self.fee,
|
||||
self.lock_height,
|
||||
&self.msg_to_sign()?,
|
||||
)?;
|
||||
self.participant_data[participant_id].part_sig = Some(sig_part);
|
||||
Ok(())
|
||||
|
@ -307,8 +314,7 @@ impl Slate {
|
|||
&self.pub_nonce_sum(secp)?,
|
||||
&p.public_blind_excess,
|
||||
Some(&self.pub_blind_sum(secp)?),
|
||||
self.fee,
|
||||
self.lock_height,
|
||||
&self.msg_to_sign()?,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
@ -352,8 +358,7 @@ impl Slate {
|
|||
&final_sig,
|
||||
&final_pubkey,
|
||||
Some(&final_pubkey),
|
||||
self.fee,
|
||||
self.lock_height,
|
||||
&self.msg_to_sign()?,
|
||||
)?;
|
||||
|
||||
Ok(final_sig)
|
||||
|
|
|
@ -20,9 +20,10 @@ extern crate grin_wallet as wallet;
|
|||
extern crate rand;
|
||||
extern crate uuid;
|
||||
|
||||
use core::core::transaction::kernel_sig_msg;
|
||||
use keychain::{BlindSum, BlindingFactor, ExtKeychain, Keychain};
|
||||
use util::secp;
|
||||
use util::secp::key::{PublicKey, SecretKey};
|
||||
use util::{kernel_sig_msg, secp};
|
||||
use wallet::libtx::{aggsig, proof};
|
||||
use wallet::libwallet::types::Context;
|
||||
|
||||
|
@ -105,14 +106,14 @@ fn aggsig_sender_receiver_interaction() {
|
|||
],
|
||||
).unwrap();
|
||||
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
let sig_part = aggsig::calculate_partial_sig(
|
||||
&keychain.secp(),
|
||||
&rx_cx.sec_key,
|
||||
&rx_cx.sec_nonce,
|
||||
&pub_nonce_sum,
|
||||
Some(&pub_key_sum),
|
||||
0,
|
||||
0,
|
||||
&msg,
|
||||
).unwrap();
|
||||
(pub_excess, pub_nonce, sig_part)
|
||||
};
|
||||
|
@ -121,14 +122,14 @@ fn aggsig_sender_receiver_interaction() {
|
|||
// received in the response back from the receiver
|
||||
{
|
||||
let keychain = sender_keychain.clone();
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
let sig_verifies = aggsig::verify_partial_sig(
|
||||
&keychain.secp(),
|
||||
&rx_sig_part,
|
||||
&pub_nonce_sum,
|
||||
&receiver_pub_excess,
|
||||
Some(&pub_key_sum),
|
||||
0,
|
||||
0,
|
||||
&msg,
|
||||
);
|
||||
assert!(!sig_verifies.is_err());
|
||||
}
|
||||
|
@ -136,14 +137,14 @@ fn aggsig_sender_receiver_interaction() {
|
|||
// now sender signs with their key
|
||||
let sender_sig_part = {
|
||||
let keychain = sender_keychain.clone();
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
let sig_part = aggsig::calculate_partial_sig(
|
||||
&keychain.secp(),
|
||||
&s_cx.sec_key,
|
||||
&s_cx.sec_nonce,
|
||||
&pub_nonce_sum,
|
||||
Some(&pub_key_sum),
|
||||
0,
|
||||
0,
|
||||
&msg,
|
||||
).unwrap();
|
||||
sig_part
|
||||
};
|
||||
|
@ -152,14 +153,14 @@ fn aggsig_sender_receiver_interaction() {
|
|||
// received by the sender
|
||||
{
|
||||
let keychain = receiver_keychain.clone();
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
let sig_verifies = aggsig::verify_partial_sig(
|
||||
&keychain.secp(),
|
||||
&sender_sig_part,
|
||||
&pub_nonce_sum,
|
||||
&sender_pub_excess,
|
||||
Some(&pub_key_sum),
|
||||
0,
|
||||
0,
|
||||
&msg,
|
||||
);
|
||||
assert!(!sig_verifies.is_err());
|
||||
}
|
||||
|
@ -168,14 +169,14 @@ fn aggsig_sender_receiver_interaction() {
|
|||
let (final_sig, final_pubkey) = {
|
||||
let keychain = receiver_keychain.clone();
|
||||
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
let our_sig_part = aggsig::calculate_partial_sig(
|
||||
&keychain.secp(),
|
||||
&rx_cx.sec_key,
|
||||
&rx_cx.sec_nonce,
|
||||
&pub_nonce_sum,
|
||||
Some(&pub_key_sum),
|
||||
0,
|
||||
0,
|
||||
&msg,
|
||||
).unwrap();
|
||||
|
||||
// Receiver now generates final signature from the two parts
|
||||
|
@ -200,6 +201,7 @@ fn aggsig_sender_receiver_interaction() {
|
|||
// Receiver checks the final signature verifies
|
||||
{
|
||||
let keychain = receiver_keychain.clone();
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
|
||||
// Receiver check the final signature verifies
|
||||
let sig_verifies = aggsig::verify_sig_build_msg(
|
||||
|
@ -207,8 +209,7 @@ fn aggsig_sender_receiver_interaction() {
|
|||
&final_sig,
|
||||
&final_pubkey,
|
||||
Some(&final_pubkey),
|
||||
0,
|
||||
0,
|
||||
&msg,
|
||||
);
|
||||
assert!(!sig_verifies.is_err());
|
||||
}
|
||||
|
@ -216,9 +217,7 @@ fn aggsig_sender_receiver_interaction() {
|
|||
// Check we can verify the sig using the kernel excess
|
||||
{
|
||||
let keychain = ExtKeychain::from_random_seed().unwrap();
|
||||
|
||||
let msg = secp::Message::from_slice(&kernel_sig_msg(0, 0)).unwrap();
|
||||
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
let sig_verifies =
|
||||
aggsig::verify_single_from_commit(&keychain.secp(), &final_sig, &msg, &kernel_excess);
|
||||
|
||||
|
@ -247,11 +246,11 @@ fn aggsig_sender_receiver_interaction_offset() {
|
|||
let blinding_factor = keychain
|
||||
.blind_sum(
|
||||
&BlindSum::new()
|
||||
.sub_blinding_factor(BlindingFactor::from_secret_key(skey1))
|
||||
.add_blinding_factor(BlindingFactor::from_secret_key(skey2))
|
||||
// subtract the kernel offset here like as would when
|
||||
// verifying a kernel signature
|
||||
.sub_blinding_factor(BlindingFactor::from_secret_key(kernel_offset)),
|
||||
.sub_blinding_factor(BlindingFactor::from_secret_key(skey1))
|
||||
.add_blinding_factor(BlindingFactor::from_secret_key(skey2))
|
||||
// subtract the kernel offset here like as would when
|
||||
// verifying a kernel signature
|
||||
.sub_blinding_factor(BlindingFactor::from_secret_key(kernel_offset)),
|
||||
).unwrap();
|
||||
|
||||
keychain
|
||||
|
@ -273,10 +272,10 @@ fn aggsig_sender_receiver_interaction_offset() {
|
|||
let blinding_factor = keychain
|
||||
.blind_sum(
|
||||
&BlindSum::new()
|
||||
.sub_blinding_factor(BlindingFactor::from_secret_key(skey))
|
||||
// subtract the kernel offset to create an aggsig context
|
||||
// with our "split" key
|
||||
.sub_blinding_factor(BlindingFactor::from_secret_key(kernel_offset)),
|
||||
.sub_blinding_factor(BlindingFactor::from_secret_key(skey))
|
||||
// subtract the kernel offset to create an aggsig context
|
||||
// with our "split" key
|
||||
.sub_blinding_factor(BlindingFactor::from_secret_key(kernel_offset)),
|
||||
).unwrap();
|
||||
|
||||
let blind = blinding_factor.secret_key(&keychain.secp()).unwrap();
|
||||
|
@ -314,14 +313,14 @@ fn aggsig_sender_receiver_interaction_offset() {
|
|||
],
|
||||
).unwrap();
|
||||
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
let sig_part = aggsig::calculate_partial_sig(
|
||||
&keychain.secp(),
|
||||
&rx_cx.sec_key,
|
||||
&rx_cx.sec_nonce,
|
||||
&pub_nonce_sum,
|
||||
Some(&pub_key_sum),
|
||||
0,
|
||||
0,
|
||||
&msg,
|
||||
).unwrap();
|
||||
(pub_excess, pub_nonce, sig_part)
|
||||
};
|
||||
|
@ -330,14 +329,14 @@ fn aggsig_sender_receiver_interaction_offset() {
|
|||
// received in the response back from the receiver
|
||||
{
|
||||
let keychain = sender_keychain.clone();
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
let sig_verifies = aggsig::verify_partial_sig(
|
||||
&keychain.secp(),
|
||||
&sig_part,
|
||||
&pub_nonce_sum,
|
||||
&receiver_pub_excess,
|
||||
Some(&pub_key_sum),
|
||||
0,
|
||||
0,
|
||||
&msg,
|
||||
);
|
||||
assert!(!sig_verifies.is_err());
|
||||
}
|
||||
|
@ -345,14 +344,14 @@ fn aggsig_sender_receiver_interaction_offset() {
|
|||
// now sender signs with their key
|
||||
let sender_sig_part = {
|
||||
let keychain = sender_keychain.clone();
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
let sig_part = aggsig::calculate_partial_sig(
|
||||
&keychain.secp(),
|
||||
&s_cx.sec_key,
|
||||
&s_cx.sec_nonce,
|
||||
&pub_nonce_sum,
|
||||
Some(&pub_key_sum),
|
||||
0,
|
||||
0,
|
||||
&msg,
|
||||
).unwrap();
|
||||
sig_part
|
||||
};
|
||||
|
@ -361,14 +360,14 @@ fn aggsig_sender_receiver_interaction_offset() {
|
|||
// received by the sender
|
||||
{
|
||||
let keychain = receiver_keychain.clone();
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
let sig_verifies = aggsig::verify_partial_sig(
|
||||
&keychain.secp(),
|
||||
&sender_sig_part,
|
||||
&pub_nonce_sum,
|
||||
&sender_pub_excess,
|
||||
Some(&pub_key_sum),
|
||||
0,
|
||||
0,
|
||||
&msg,
|
||||
);
|
||||
assert!(!sig_verifies.is_err());
|
||||
}
|
||||
|
@ -376,14 +375,14 @@ fn aggsig_sender_receiver_interaction_offset() {
|
|||
// Receiver now builds final signature from sender and receiver parts
|
||||
let (final_sig, final_pubkey) = {
|
||||
let keychain = receiver_keychain.clone();
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
let our_sig_part = aggsig::calculate_partial_sig(
|
||||
&keychain.secp(),
|
||||
&rx_cx.sec_key,
|
||||
&rx_cx.sec_nonce,
|
||||
&pub_nonce_sum,
|
||||
Some(&pub_key_sum),
|
||||
0,
|
||||
0,
|
||||
&msg,
|
||||
).unwrap();
|
||||
|
||||
// Receiver now generates final signature from the two parts
|
||||
|
@ -408,6 +407,7 @@ fn aggsig_sender_receiver_interaction_offset() {
|
|||
// Receiver checks the final signature verifies
|
||||
{
|
||||
let keychain = receiver_keychain.clone();
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
|
||||
// Receiver check the final signature verifies
|
||||
let sig_verifies = aggsig::verify_sig_build_msg(
|
||||
|
@ -415,8 +415,7 @@ fn aggsig_sender_receiver_interaction_offset() {
|
|||
&final_sig,
|
||||
&final_pubkey,
|
||||
Some(&final_pubkey),
|
||||
0,
|
||||
0,
|
||||
&msg,
|
||||
);
|
||||
assert!(!sig_verifies.is_err());
|
||||
}
|
||||
|
@ -424,9 +423,7 @@ fn aggsig_sender_receiver_interaction_offset() {
|
|||
// Check we can verify the sig using the kernel excess
|
||||
{
|
||||
let keychain = ExtKeychain::from_random_seed().unwrap();
|
||||
|
||||
let msg = secp::Message::from_slice(&kernel_sig_msg(0, 0)).unwrap();
|
||||
|
||||
let msg = kernel_sig_msg(0, 0).unwrap();
|
||||
let sig_verifies =
|
||||
aggsig::verify_single_from_commit(&keychain.secp(), &final_sig, &msg, &kernel_excess);
|
||||
|
||||
|
|
Loading…
Reference in a new issue