pczt sign: Move derivation path matching into protocol-specific crates

This commit is contained in:
Jack Grigg 2024-12-17 17:41:20 +00:00
parent fa2bb0c4aa
commit e7fdca7b8f
3 changed files with 75 additions and 99 deletions

49
Cargo.lock generated
View File

@ -1747,8 +1747,7 @@ dependencies = [
[[package]]
name = "equihash"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab579d7cf78477773b03e80bc2f89702ef02d7112c711d54ca93dcdce68533d5"
source = "git+https://github.com/zcash/librustzcash.git?rev=2bce3ceea756713b737367326069aa204464d3ee#2bce3ceea756713b737367326069aa204464d3ee"
dependencies = [
"blake2b_simd",
"byteorder",
@ -1799,8 +1798,7 @@ dependencies = [
[[package]]
name = "f4jumble"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d42773cb15447644d170be20231a3268600e0c4cea8987d013b93ac973d3cf7"
source = "git+https://github.com/zcash/librustzcash.git?rev=2bce3ceea756713b737367326069aa204464d3ee#2bce3ceea756713b737367326069aa204464d3ee"
dependencies = [
"blake2b_simd",
]
@ -3400,9 +3398,9 @@ dependencies = [
[[package]]
name = "nonempty"
version = "0.7.0"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7"
checksum = "549e471b99ccaf2f89101bec68f4d244457d5a95a9c3d0672e9564124397741d"
[[package]]
name = "noop_proc_macro"
@ -3611,8 +3609,7 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "orchard"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02f7152474406422f572de163e0bc63b2126cdbfe17bc849efbbde36fcfe647e"
source = "git+https://github.com/zcash/orchard.git?rev=4fa6d3b549f8803016a309281404eab095d04de8#4fa6d3b549f8803016a309281404eab095d04de8"
dependencies = [
"aes",
"bitvec",
@ -3780,8 +3777,7 @@ dependencies = [
[[package]]
name = "pczt"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "545f95dc3d5295b9ed0360aa3b63e610bd4a73f2f382c616b2fda66c3288e989"
source = "git+https://github.com/zcash/librustzcash.git?rev=2bce3ceea756713b737367326069aa204464d3ee#2bce3ceea756713b737367326069aa204464d3ee"
dependencies = [
"blake2b_simd",
"bls12_381",
@ -4857,8 +4853,7 @@ dependencies = [
[[package]]
name = "sapling-crypto"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85c2acdbbab83d554fc2dceea5f7d6d3da71e57adb18a6c80b8901bd0eee54b0"
source = "git+https://github.com/zcash/sapling-crypto.git?rev=3c2235747553da642fb142d1eeb9b1afa8391987#3c2235747553da642fb142d1eeb9b1afa8391987"
dependencies = [
"aes",
"bellman",
@ -7420,8 +7415,7 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
[[package]]
name = "zcash_address"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b955fe87f2d9052e3729bdbeb0e94975355f4fe39f7d26aea9457bec6a0bb55"
source = "git+https://github.com/zcash/librustzcash.git?rev=2bce3ceea756713b737367326069aa204464d3ee#2bce3ceea756713b737367326069aa204464d3ee"
dependencies = [
"bech32 0.11.0",
"bs58",
@ -7434,8 +7428,7 @@ dependencies = [
[[package]]
name = "zcash_client_backend"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a187ad05cdfe13707c07e6aedca8026b34921d081decfd0b43aac1efd438a7"
source = "git+https://github.com/zcash/librustzcash.git?rev=2bce3ceea756713b737367326069aa204464d3ee#2bce3ceea756713b737367326069aa204464d3ee"
dependencies = [
"arti-client",
"base64 0.22.1",
@ -7497,8 +7490,7 @@ dependencies = [
[[package]]
name = "zcash_client_sqlite"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b8046e94c3d746cc00e0ceb4ec4263c4fb93271a8681b425365ad600148ab15"
source = "git+https://github.com/zcash/librustzcash.git?rev=2bce3ceea756713b737367326069aa204464d3ee#2bce3ceea756713b737367326069aa204464d3ee"
dependencies = [
"bip32",
"bs58",
@ -7536,8 +7528,7 @@ dependencies = [
[[package]]
name = "zcash_encoding"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3654116ae23ab67dd1f849b01f8821a8a156f884807ff665eac109bf28306c4d"
source = "git+https://github.com/zcash/librustzcash.git?rev=2bce3ceea756713b737367326069aa204464d3ee#2bce3ceea756713b737367326069aa204464d3ee"
dependencies = [
"core2",
"nonempty",
@ -7546,8 +7537,7 @@ dependencies = [
[[package]]
name = "zcash_keys"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ad3cf576c6e6094cd03f446fcb83ad241ec315a088593cd50940f135cb03ce1"
source = "git+https://github.com/zcash/librustzcash.git?rev=2bce3ceea756713b737367326069aa204464d3ee#2bce3ceea756713b737367326069aa204464d3ee"
dependencies = [
"bech32 0.11.0",
"bip32",
@ -7589,8 +7579,7 @@ dependencies = [
[[package]]
name = "zcash_primitives"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b45f3ca3a9df34fcdbf036c2c814417bb417bde742812abc09d744bb3d7ed72"
source = "git+https://github.com/zcash/librustzcash.git?rev=2bce3ceea756713b737367326069aa204464d3ee#2bce3ceea756713b737367326069aa204464d3ee"
dependencies = [
"aes",
"bip32",
@ -7630,8 +7619,7 @@ dependencies = [
[[package]]
name = "zcash_proofs"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5826910c516675eca1f34b3557e159f4e35a4a1711b39fa4f01fb0adb9a9c24"
source = "git+https://github.com/zcash/librustzcash.git?rev=2bce3ceea756713b737367326069aa204464d3ee#2bce3ceea756713b737367326069aa204464d3ee"
dependencies = [
"bellman",
"blake2b_simd",
@ -7653,8 +7641,7 @@ dependencies = [
[[package]]
name = "zcash_protocol"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82cb36b15b5a1be70b30c32ce40372dead6561df8a467e297f96b892873a63a2"
source = "git+https://github.com/zcash/librustzcash.git?rev=2bce3ceea756713b737367326069aa204464d3ee#2bce3ceea756713b737367326069aa204464d3ee"
dependencies = [
"core2",
"document-features",
@ -7677,8 +7664,7 @@ dependencies = [
[[package]]
name = "zcash_transparent"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed0512e8e02af804e852fbbc4bd5db35a9037bc253d2ce396506293a6e7dd745"
source = "git+https://github.com/zcash/librustzcash.git?rev=2bce3ceea756713b737367326069aa204464d3ee#2bce3ceea756713b737367326069aa204464d3ee"
dependencies = [
"bip32",
"blake2b_simd",
@ -7809,8 +7795,7 @@ dependencies = [
[[package]]
name = "zip321"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3e613defb0940acef1f54774b51c7f48f2fa705613dd800870dc69f35cd2ea"
source = "git+https://github.com/zcash/librustzcash.git?rev=2bce3ceea756713b737367326069aa204464d3ee#2bce3ceea756713b737367326069aa204464d3ee"
dependencies = [
"base64 0.22.1",
"nom",

View File

@ -78,3 +78,17 @@ tui = [
"dep:tokio-util",
"dep:tui-logger",
]
[patch.crates-io]
orchard = { git = "https://github.com/zcash/orchard.git", rev = "4fa6d3b549f8803016a309281404eab095d04de8" }
pczt = { git = "https://github.com/zcash/librustzcash.git", rev = "2bce3ceea756713b737367326069aa204464d3ee" }
sapling = { package = "sapling-crypto", git = "https://github.com/zcash/sapling-crypto.git", rev = "3c2235747553da642fb142d1eeb9b1afa8391987" }
transparent = { package = "zcash_transparent", git = "https://github.com/zcash/librustzcash.git", rev = "2bce3ceea756713b737367326069aa204464d3ee" }
zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "2bce3ceea756713b737367326069aa204464d3ee" }
zcash_client_backend = { git = "https://github.com/zcash/librustzcash.git", rev = "2bce3ceea756713b737367326069aa204464d3ee" }
zcash_client_sqlite = { git = "https://github.com/zcash/librustzcash.git", rev = "2bce3ceea756713b737367326069aa204464d3ee" }
zcash_keys = { git = "https://github.com/zcash/librustzcash.git", rev = "2bce3ceea756713b737367326069aa204464d3ee" }
zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "2bce3ceea756713b737367326069aa204464d3ee" }
zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "2bce3ceea756713b737367326069aa204464d3ee" }
zcash_protocol = { git = "https://github.com/zcash/librustzcash.git", rev = "2bce3ceea756713b737367326069aa204464d3ee" }
zip321 = { git = "https://github.com/zcash/librustzcash.git", rev = "2bce3ceea756713b737367326069aa204464d3ee" }

View File

@ -1,9 +1,9 @@
use std::collections::BTreeMap;
use std::{collections::BTreeMap, convert::Infallible};
use anyhow::anyhow;
use gumdrop::Options;
use pczt::{
roles::{signer::Signer, updater::Updater},
roles::{signer::Signer, verifier::Verifier},
Pczt,
};
use secrecy::ExposeSecret;
@ -46,8 +46,7 @@ impl Command {
let seed_fp =
SeedFingerprint::from_seed(seed).ok_or_else(|| anyhow!("Invalid seed length"))?;
// Find all the spends matching our seed. For now as a hack, we use the Updater
// role to access the bundle data we need.
// Find all the spends matching our seed.
enum KeyRef {
Orchard {
index: usize,
@ -62,80 +61,58 @@ impl Command {
},
}
let mut keys = BTreeMap::<zip32::AccountId, Vec<KeyRef>>::new();
let pczt = Updater::new(pczt)
.update_orchard_with(|updater| {
for (index, action) in updater.bundle().actions().iter().enumerate() {
if let Some(derivation) = action.spend().zip32_derivation() {
if derivation.seed_fingerprint() == &seed_fp.to_bytes()
&& derivation.derivation_path().len() == 3
&& derivation.derivation_path()[0] == zip32::ChildIndex::hardened(32)
&& derivation.derivation_path()[1]
== zip32::ChildIndex::hardened(params.network_type().coin_type())
{
let account_index = zip32::AccountId::try_from(
derivation.derivation_path()[2].index() - (1 << 31),
let pczt = Verifier::new(pczt)
.with_orchard::<Infallible, _>(|bundle| {
for (index, action) in bundle.actions().iter().enumerate() {
if let Some(account_index) = action
.spend()
.zip32_derivation()
.as_ref()
.and_then(|derivation| {
derivation.extract_account_index(
&seed_fp,
zip32::ChildIndex::hardened(params.network_type().coin_type()),
)
.expect("valid");
keys.entry(account_index)
.or_default()
.push(KeyRef::Orchard { index });
}
})
{
keys.entry(account_index)
.or_default()
.push(KeyRef::Orchard { index });
}
}
Ok(())
})
.expect("no errors")
.update_sapling_with(|updater| {
for (index, spend) in updater.bundle().spends().iter().enumerate() {
if let Some(derivation) = spend.zip32_derivation() {
if derivation.seed_fingerprint() == &seed_fp.to_bytes()
&& derivation.derivation_path().len() == 3
&& derivation.derivation_path()[0] == zip32::ChildIndex::hardened(32)
&& derivation.derivation_path()[1]
== zip32::ChildIndex::hardened(params.network_type().coin_type())
{
let account_index = zip32::AccountId::try_from(
derivation.derivation_path()[2].index() - (1 << 31),
.map_err(|e| anyhow!("Invalid PCZT: {:?}", e))?
.with_sapling::<Infallible, _>(|bundle| {
for (index, spend) in bundle.spends().iter().enumerate() {
if let Some(account_index) =
spend.zip32_derivation().as_ref().and_then(|derivation| {
derivation.extract_account_index(
&seed_fp,
zip32::ChildIndex::hardened(params.network_type().coin_type()),
)
.expect("valid");
keys.entry(account_index)
.or_default()
.push(KeyRef::Sapling { index });
}
})
{
keys.entry(account_index)
.or_default()
.push(KeyRef::Sapling { index });
}
}
Ok(())
})
.expect("no errors")
.update_transparent_with(|updater| {
for (index, input) in updater.bundle().inputs().iter().enumerate() {
.map_err(|e| anyhow!("Invalid PCZT: {:?}", e))?
.with_transparent::<Infallible, _>(|bundle| {
for (index, input) in bundle.inputs().iter().enumerate() {
for derivation in input.bip32_derivation().values() {
if derivation.seed_fingerprint() == &seed_fp.to_bytes()
&& derivation.derivation_path().len() == 5
&& derivation.derivation_path()[0]
== bip32::ChildNumber::new(44, true).expect("valid")
&& derivation.derivation_path()[1]
== bip32::ChildNumber::new(params.network_type().coin_type(), true)
.expect("valid")
&& derivation.derivation_path()[2].is_hardened()
&& !derivation.derivation_path()[3].is_hardened()
&& !derivation.derivation_path()[4].is_hardened()
if let Some((account_index, scope, address_index)) = derivation
.extract_bip_44_fields(
&seed_fp,
bip32::ChildNumber(
params.network_type().coin_type()
| bip32::ChildNumber::HARDENED_FLAG,
),
)
{
let account_index =
zip32::AccountId::try_from(derivation.derivation_path()[2].index())
.expect("valid");
let scope = TransparentKeyScope::custom(
derivation.derivation_path()[3].index(),
)
.expect("valid");
let address_index = NonHardenedChildIndex::from_index(
derivation.derivation_path()[4].index(),
)
.expect("valid");
keys.entry(account_index)
.or_default()
.push(KeyRef::Transparent {
@ -148,7 +125,7 @@ impl Command {
}
Ok(())
})
.expect("no errors")
.map_err(|e| anyhow!("Invalid PCZT: {:?}", e))?
.finish();
let mut signer =