From 4289843852e2d59b4addf5627492be3277f3870f Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Mon, 3 Dec 2018 12:54:11 +0000 Subject: [PATCH] Compute TxId for Transaction --- Cargo.lock | 70 +++++++++++++++++++++++ zcash_primitives/Cargo.toml | 1 + zcash_primitives/src/lib.rs | 1 + zcash_primitives/src/transaction/mod.rs | 25 ++++++-- zcash_primitives/src/transaction/tests.rs | 33 ++--------- 5 files changed, 98 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index baffb57..da35e28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,6 +72,17 @@ dependencies = [ "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "block-buffer" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-padding 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "block-cipher-trait" version = "0.5.3" @@ -80,11 +91,24 @@ dependencies = [ "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "block-padding" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "byte-tools" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "byte-tools" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "byteorder" version = "1.2.2" @@ -108,6 +132,19 @@ dependencies = [ "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "digest" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ff" version = "0.4.0" @@ -182,6 +219,14 @@ dependencies = [ "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "generic-array" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "group" version = "0.1.0" @@ -280,6 +325,11 @@ name = "opaque-debug" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "opaque-debug" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pairing" version = "0.14.2" @@ -376,6 +426,17 @@ dependencies = [ "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sha2" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "stream-cipher" version = "0.1.1" @@ -445,6 +506,7 @@ dependencies = [ "pairing 0.14.2", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "sapling-crypto 0.0.1", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -486,18 +548,24 @@ dependencies = [ "checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f" "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" "checksum blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)" = "" +"checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d" "checksum block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "370424437b9459f3dfd68428ed9376ddfe03d8b70ede29cc533b3557df186ab4" +"checksum block-padding 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc4358306e344bf9775d0197fd00d2603e5afb0771bb353538630f022068ea3" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" +"checksum byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "980479e6fde23246dfb54d47580d66b4e99202e7579c5eaa9fe10ecb5ebd2182" "checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" "checksum digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603" +"checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" +"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum fpe 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce3371c82bfbd984f624cab093f55e7336f5a6e589f8518e1258f54f011b89ad" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" +"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592" "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4da5f0e01bd8a71a224a4eedecaacfcabda388dbb7a80faf04d3514287572d95" @@ -510,6 +578,7 @@ dependencies = [ "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d620c9c26834b34f039489ac0dfdb12c7ac15ccaf818350a64c9b5334a452ad7" +"checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409" "checksum proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba8d4f9257b85eb6cdf13f055cea3190520aab1409ca2ab43493ea4820c25f0" "checksum proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5cb6f960ad471404618e9817c0e5d10b1ae74cfdf01fab89ea0641fe7fb2892" "checksum proc-macro2 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b331c6ad3411474cd55540398dc7ad89fc41488e64ec71fdecc9c9b86de96fb0" @@ -519,6 +588,7 @@ dependencies = [ "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" "checksum stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "30dc6118470d69ce0fdcf7e6f95e95853f7f4f72f80d835d4519577c323814ab" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" diff --git a/zcash_primitives/Cargo.toml b/zcash_primitives/Cargo.toml index ab0d87b..aac2e3b 100644 --- a/zcash_primitives/Cargo.toml +++ b/zcash_primitives/Cargo.toml @@ -13,6 +13,7 @@ lazy_static = "1" pairing = { path = "../pairing" } rand = "0.4" sapling-crypto = { path = "../sapling-crypto" } +sha2 = "0.8" [dependencies.blake2-rfc] git = "https://github.com/gtank/blake2-rfc" diff --git a/zcash_primitives/src/lib.rs b/zcash_primitives/src/lib.rs index ba76dc7..727d446 100644 --- a/zcash_primitives/src/lib.rs +++ b/zcash_primitives/src/lib.rs @@ -8,6 +8,7 @@ extern crate hex; extern crate pairing; extern crate rand; extern crate sapling_crypto; +extern crate sha2; use sapling_crypto::jubjub::JubjubBls12; diff --git a/zcash_primitives/src/transaction/mod.rs b/zcash_primitives/src/transaction/mod.rs index 6aea0cf..4f5d2a6 100644 --- a/zcash_primitives/src/transaction/mod.rs +++ b/zcash_primitives/src/transaction/mod.rs @@ -1,6 +1,7 @@ use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use hex; use sapling_crypto::redjubjub::Signature; +use sha2::{Digest, Sha256}; use std::fmt; use std::io::{self, Read, Write}; use std::ops::Deref; @@ -35,7 +36,7 @@ impl fmt::Display for TxId { /// A Zcash transaction. #[derive(Debug)] -pub struct Transaction(TransactionData); +pub struct Transaction(TransactionData, TxId); impl Deref for Transaction { type Target = TransactionData; @@ -125,12 +126,26 @@ impl TransactionData { header } - pub fn freeze(self) -> Transaction { - Transaction(self) + pub fn freeze(self) -> io::Result { + Transaction::from_data(self) } } impl Transaction { + fn from_data(data: TransactionData) -> io::Result { + let mut tx = Transaction(data, TxId([0; 32])); + let mut raw = vec![]; + tx.write(&mut raw)?; + (tx.1) + .0 + .copy_from_slice(&Sha256::digest(&Sha256::digest(&raw))); + Ok(tx) + } + + pub fn txid(&self) -> TxId { + self.1 + } + pub fn read(mut reader: R) -> io::Result { let header = reader.read_u32::()?; let overwintered = (header >> 31) == 1; @@ -195,7 +210,7 @@ impl Transaction { false => None, }; - Ok(Transaction(TransactionData { + Transaction::from_data(TransactionData { overwintered, version, version_group_id, @@ -210,7 +225,7 @@ impl Transaction { joinsplit_pubkey, joinsplit_sig, binding_sig, - })) + }) } pub fn write(&self, mut writer: W) -> io::Result<()> { diff --git a/zcash_primitives/src/transaction/tests.rs b/zcash_primitives/src/transaction/tests.rs index db3a4df..80513af 100644 --- a/zcash_primitives/src/transaction/tests.rs +++ b/zcash_primitives/src/transaction/tests.rs @@ -159,51 +159,33 @@ fn tx_read_write() { #[test] fn tx_write_rejects_unexpected_joinsplit_pubkey() { // Succeeds without a JoinSplit pubkey - { - let tx = TransactionData::new().freeze(); - let mut encoded = Vec::new(); - assert!(tx.write(&mut encoded).is_ok()); - } + assert!(TransactionData::new().freeze().is_ok()); // Fails with an unexpected JoinSplit pubkey { let mut tx = TransactionData::new(); tx.joinsplit_pubkey = Some([0; 32]); - let tx = tx.freeze(); - - let mut encoded = Vec::new(); - assert!(tx.write(&mut encoded).is_err()); + assert!(tx.freeze().is_err()); } } #[test] fn tx_write_rejects_unexpected_joinsplit_sig() { // Succeeds without a JoinSplit signature - { - let tx = TransactionData::new().freeze(); - let mut encoded = Vec::new(); - assert!(tx.write(&mut encoded).is_ok()); - } + assert!(TransactionData::new().freeze().is_ok()); // Fails with an unexpected JoinSplit signature { let mut tx = TransactionData::new(); tx.joinsplit_sig = Some([0; 64]); - let tx = tx.freeze(); - - let mut encoded = Vec::new(); - assert!(tx.write(&mut encoded).is_err()); + assert!(tx.freeze().is_err()); } } #[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()); - } + assert!(TransactionData::new().freeze().is_ok()); // Fails with an unexpected binding signature { @@ -218,10 +200,7 @@ fn tx_write_rejects_unexpected_binding_sig() { 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()); + assert!(tx.freeze().is_err()); } }