diff --git a/Cargo.lock b/Cargo.lock index aad590e..8421fc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -708,6 +708,7 @@ dependencies = [ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "pairing 0.14.2", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "sapling-crypto 0.0.1", ] diff --git a/zcash_primitives/Cargo.toml b/zcash_primitives/Cargo.toml index 32431e8..bf6c03f 100644 --- a/zcash_primitives/Cargo.toml +++ b/zcash_primitives/Cargo.toml @@ -9,6 +9,7 @@ authors = [ byteorder = "1" lazy_static = "1" pairing = { path = "../pairing" } +rand = "0.4" sapling-crypto = { path = "../sapling-crypto" } [dependencies.blake2-rfc] diff --git a/zcash_primitives/src/lib.rs b/zcash_primitives/src/lib.rs index a2fee17..5f4dd05 100644 --- a/zcash_primitives/src/lib.rs +++ b/zcash_primitives/src/lib.rs @@ -4,6 +4,7 @@ extern crate lazy_static; extern crate blake2_rfc; extern crate byteorder; extern crate pairing; +extern crate rand; extern crate sapling_crypto; use sapling_crypto::jubjub::JubjubBls12; diff --git a/zcash_primitives/src/transaction/mod.rs b/zcash_primitives/src/transaction/mod.rs index 74d34fb..9f12cb3 100644 --- a/zcash_primitives/src/transaction/mod.rs +++ b/zcash_primitives/src/transaction/mod.rs @@ -211,6 +211,11 @@ impl Transaction { )) } } + } else if self.binding_sig.is_some() { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Binding signature should not be present", + )); } Ok(()) diff --git a/zcash_primitives/src/transaction/tests.rs b/zcash_primitives/src/transaction/tests.rs index 24b5513..89b12a8 100644 --- a/zcash_primitives/src/transaction/tests.rs +++ b/zcash_primitives/src/transaction/tests.rs @@ -1,8 +1,13 @@ +use pairing::bls12_381::Bls12; +use rand::{thread_rng, Rng}; +use sapling_crypto::{jubjub::FixedGenerators, redjubjub::PrivateKey}; + use super::{ components::{Amount, Script}, sighash::signature_hash, - Transaction, + Transaction, TransactionData, }; +use JUBJUB; #[test] fn tx_read_write() { @@ -151,6 +156,35 @@ fn tx_read_write() { assert_eq!(&data[..], &encoded[..]); } +#[test] +fn tx_write_rejects_unexpected_binding_sig() { + // Succeeds without a binding signature + { + let tx = TransactionData::new().freeze(); + let mut encoded = Vec::new(); + assert!(tx.write(&mut encoded).is_ok()); + } + + // Fails with an unexpected binding signature + { + let rng = &mut thread_rng(); + let sk = PrivateKey::(rng.gen()); + let sig = sk.sign( + b"Foo bar", + rng, + FixedGenerators::SpendingKeyGenerator, + &JUBJUB, + ); + + let mut tx = TransactionData::new(); + tx.binding_sig = Some(sig); + let tx = tx.freeze(); + + let mut encoded = Vec::new(); + assert!(tx.write(&mut encoded).is_err()); + } +} + #[test] fn zip_0143() { struct TestVector {