From 9704cc35bdc17f610aa518fe923fec7ae978a313 Mon Sep 17 00:00:00 2001 From: Yeastplume Date: Mon, 15 Jan 2018 20:45:26 +0000 Subject: [PATCH] Aggsig Serialization (#618) * changing ser of aggsig signature * serialise Signature as raw 64 bytes * remove compact sig * remove to_compact * remove unused import --- api/src/types.rs | 2 +- core/src/core/block.rs | 4 +--- core/src/core/build.rs | 9 ++------- core/src/core/mod.rs | 5 +++-- core/src/core/transaction.rs | 38 ++++++++++++++++++++++-------------- core/src/macros.rs | 10 ++++++---- core/src/ser.rs | 21 +++++++++++++++++++- util/Cargo.toml | 2 +- wallet/src/receiver.rs | 2 +- 9 files changed, 58 insertions(+), 35 deletions(-) diff --git a/api/src/types.rs b/api/src/types.rs index acd022f7e..a1941cf37 100644 --- a/api/src/types.rs +++ b/api/src/types.rs @@ -290,7 +290,7 @@ impl TxKernelPrintable { fee: k.fee, lock_height: k.lock_height, excess: util::to_hex(k.excess.0.to_vec()), - excess_sig: util::to_hex(k.excess_sig.to_vec()), + excess_sig: util::to_hex(k.excess_sig.to_raw_data().to_vec()), } } } diff --git a/core/src/core/block.rs b/core/src/core/block.rs index e5137139f..f24418248 100644 --- a/core/src/core/block.rs +++ b/core/src/core/block.rs @@ -588,12 +588,10 @@ impl Block { let msg = util::secp::Message::from_slice(&[0; secp::constants::MESSAGE_SIZE])?; let sig = keychain.aggsig_sign_from_key_id(&msg, &key_id).unwrap(); - let excess_sig = sig.serialize_der(&secp); - let proof = TxKernel { features: COINBASE_KERNEL, excess: excess, - excess_sig: excess_sig, + excess_sig: sig, fee: 0, lock_height: 0, }; diff --git a/core/src/core/build.rs b/core/src/core/build.rs index f691c1b60..94b97987b 100644 --- a/core/src/core/build.rs +++ b/core/src/core/build.rs @@ -25,7 +25,7 @@ //! build::transaction(vec![input_rand(75), output_rand(42), output_rand(32), //! with_fee(1)]) -use util::{secp, static_secp_instance, kernel_sig_msg}; +use util::{secp, kernel_sig_msg}; use core::{Input, Output, SwitchCommitHash, Transaction, DEFAULT_OUTPUT}; use util::LOGGER; @@ -137,12 +137,7 @@ pub fn transaction( ); let blind_sum = ctx.keychain.blind_sum(&sum)?; let msg = secp::Message::from_slice(&kernel_sig_msg(tx.fee, tx.lock_height))?; - let sig = Keychain::aggsig_sign_with_blinding(&keychain.secp(), &msg, &blind_sum)?; - - let secp = static_secp_instance(); - let secp = secp.lock().unwrap(); - tx.excess_sig = sig.serialize_der(&secp); - + tx.excess_sig = Keychain::aggsig_sign_with_blinding(&keychain.secp(), &msg, &blind_sum)?; Ok((tx, blind_sum)) } diff --git a/core/src/core/mod.rs b/core/src/core/mod.rs index e299bc0db..9cda932cd 100644 --- a/core/src/core/mod.rs +++ b/core/src/core/mod.rs @@ -261,8 +261,9 @@ mod test { let tx = tx2i1o(); let mut vec = Vec::new(); ser::serialize(&mut vec, &tx).expect("serialized failed"); - assert!(vec.len() > 5360); - assert!(vec.len() < 5380); + println!("{}", vec.len()); + assert!(vec.len() > 5340); + assert!(vec.len() < 5370); } #[test] diff --git a/core/src/core/transaction.rs b/core/src/core/transaction.rs index d680c6667..4a7afb400 100644 --- a/core/src/core/transaction.rs +++ b/core/src/core/transaction.rs @@ -110,7 +110,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: Vec, + pub excess_sig: Signature, } hashable_ord!(TxKernel); @@ -122,9 +122,9 @@ impl Writeable for TxKernel { [write_u8, self.features.bits()], [write_u64, self.fee], [write_u64, self.lock_height], - [write_fixed_bytes, &self.excess], - [write_bytes, &self.excess_sig] + [write_fixed_bytes, &self.excess] ); + self.excess_sig.write(writer)?; Ok(()) } } @@ -134,13 +134,12 @@ impl Readable for TxKernel { let features = KernelFeatures::from_bits(reader.read_u8()?).ok_or( ser::Error::CorruptedData, )?; - Ok(TxKernel { features: features, fee: reader.read_u64()?, lock_height: reader.read_u64()?, excess: Commitment::read(reader)?, - excess_sig: reader.read_vec()?, + excess_sig: Signature::read(reader)?, }) } } @@ -155,7 +154,7 @@ impl TxKernel { )); let secp = static_secp_instance(); let secp = secp.lock().unwrap(); - let sig = try!(Signature::from_der(&secp, &self.excess_sig)); + let sig = &self.excess_sig; let valid = Keychain::aggsig_verify_single_from_commit(&secp, &sig, &msg, &self.excess); if !valid{ return Err(secp::Error::IncorrectSignature); @@ -178,18 +177,22 @@ pub struct Transaction { pub lock_height: u64, /// The signature proving the excess is a valid public key, which signs /// the transaction fee. - pub excess_sig: Vec, + pub excess_sig: Signature, } /// Implementation of Writeable for a fully blinded transaction, defines how to /// write the transaction as binary. impl Writeable for Transaction { fn write(&self, writer: &mut W) -> Result<(), ser::Error> { + println!("Excess sig write: {:?}", self.excess_sig); ser_multiwrite!( writer, [write_u64, self.fee], - [write_u64, self.lock_height], - [write_bytes, &self.excess_sig], + [write_u64, self.lock_height] + ); + self.excess_sig.write(writer)?; + ser_multiwrite!( + writer, [write_u64, self.inputs.len() as u64], [write_u64, self.outputs.len() as u64] ); @@ -209,8 +212,13 @@ impl Writeable for Transaction { /// transaction from a binary stream. impl Readable for Transaction { fn read(reader: &mut Reader) -> Result { - let (fee, lock_height, excess_sig, input_len, output_len) = - ser_multiread!(reader, read_u64, read_u64, read_vec, read_u64, read_u64); + let (fee, lock_height) = + ser_multiread!(reader, read_u64, read_u64); + + let excess_sig = Signature::read(reader)?; + + let (input_len, output_len) = + ser_multiread!(reader, read_u64, read_u64); let inputs = read_and_verify_sorted(reader, input_len)?; let outputs = read_and_verify_sorted(reader, output_len)?; @@ -250,7 +258,7 @@ impl Transaction { Transaction { fee: 0, lock_height: 0, - excess_sig: vec![], + excess_sig: Signature::from_raw_data(&[0;64]).unwrap(), inputs: vec![], outputs: vec![], } @@ -267,7 +275,7 @@ impl Transaction { Transaction { fee: fee, lock_height: lock_height, - excess_sig: vec![], + excess_sig: Signature::from_raw_data(&[0;64]).unwrap(), inputs: inputs, outputs: outputs, } @@ -323,7 +331,7 @@ impl Transaction { let secp = static_secp_instance(); let secp = secp.lock().unwrap(); - let sig = Signature::from_der(&secp, &self.excess_sig)?; + let sig = self.excess_sig; // pretend the sum is a public key (which it is, being of the form r.G) and // verify the transaction sig with it let valid = Keychain::aggsig_verify_single_from_commit(&secp, &sig, &msg, &rsum); @@ -651,7 +659,7 @@ mod test { let commit = keychain.commit(5, &key_id).unwrap(); // just some bytes for testing ser/deser - let sig = vec![1, 0, 0, 0, 0, 0, 0, 1]; + let sig = secp::Signature::from_raw_data(&[0;64]).unwrap(); let kernel = TxKernel { features: DEFAULT_KERNEL, diff --git a/core/src/macros.rs b/core/src/macros.rs index 1c51c91af..c04254a24 100644 --- a/core/src/macros.rs +++ b/core/src/macros.rs @@ -75,16 +75,18 @@ macro_rules! try_to_o { } /// Eliminate some of the boilerplate of deserialization (package ser) by -/// passing just the list of reader function. +/// passing just the list of reader function (with optional single param) /// Example before: /// let foo = try!(reader.read_u64()); /// let bar = try!(reader.read_u32()); +/// let fixed_byte_var = try!(reader.read_fixed_bytes(64)); /// Example after: -/// let (foo, bar) = ser_multiread!(reader, read_u64, read_u32); +/// let (foo, bar, fixed_byte_var) = ser_multiread!(reader, read_u64, read_u32, +/// read_fixed_bytes(64)); #[macro_export] macro_rules! ser_multiread { - ($rdr:ident, $($read_call:ident),*) => { - ( $(try!($rdr.$read_call())),* ) + ($rdr:ident, $($read_call:ident $(($val:expr)),*),*) => { + ( $(try!($rdr.$read_call($($val),*))),* ) } } diff --git a/core/src/ser.rs b/core/src/ser.rs index d3b014c6a..e1ea54307 100644 --- a/core/src/ser.rs +++ b/core/src/ser.rs @@ -29,7 +29,8 @@ use core::hash::Hashed; use core::transaction::{SWITCH_COMMIT_HASH_SIZE, SwitchCommitHash}; use util::secp::pedersen::Commitment; use util::secp::pedersen::RangeProof; -use util::secp::constants::{MAX_PROOF_SIZE, PEDERSEN_COMMITMENT_SIZE}; +use util::secp::Signature; +use util::secp::constants::{MAX_PROOF_SIZE, PEDERSEN_COMMITMENT_SIZE, AGG_SIGNATURE_SIZE}; /// Possible errors deriving from serializing or deserializing. #[derive(Debug)] @@ -353,6 +354,24 @@ impl Readable for RangeProof { } } +impl Readable for Signature { + fn read(reader: &mut Reader) -> Result { + let a = try!(reader.read_fixed_bytes(AGG_SIGNATURE_SIZE)); + let mut c = [0; AGG_SIGNATURE_SIZE]; + for i in 0..AGG_SIGNATURE_SIZE { + c[i] = a[i]; + } + Ok(Signature::from_raw_data(&c).unwrap()) + } +} + +impl Writeable for Signature { + fn write(&self, writer: &mut W) -> Result<(), Error> { + writer.write_fixed_bytes(self) + } +} + + /// Utility wrapper for an underlying byte Writer. Defines higher level methods /// to write numbers, byte vectors, hashes, etc. struct BinWriter<'a> { diff --git a/util/Cargo.toml b/util/Cargo.toml index 8d6ef53da..c71ef7b7b 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -14,6 +14,6 @@ byteorder = "^0.5" rand = "0.3" serde = "~1.0.8" serde_derive = "~1.0.8" -secp256k1zkp = { git = "https://github.com/mimblewimble/rust-secp256k1-zkp", tag="grin_integration_6" } +secp256k1zkp = { git = "https://github.com/mimblewimble/rust-secp256k1-zkp", tag="grin_integration_7" } #secp256k1zkp = { path = "../../rust-secp256k1-zkp" } diff --git a/wallet/src/receiver.rs b/wallet/src/receiver.rs index 384fba352..1a7e6bece 100644 --- a/wallet/src/receiver.rs +++ b/wallet/src/receiver.rs @@ -370,7 +370,7 @@ fn build_final_transaction( keychain, )?; - final_tx.excess_sig = excess_sig.serialize_der(&keychain.secp()); + final_tx.excess_sig = excess_sig.clone(); // make sure the resulting transaction is valid (could have been lied to on // excess).