This commit is contained in:
Hanh 2023-04-26 08:05:40 +10:00
parent c10a074fb6
commit 13d19cf143
3 changed files with 90 additions and 98 deletions

View File

@ -7,11 +7,9 @@ use group::GroupEncoding;
use hex_literal::hex; use hex_literal::hex;
use jubjub::{Fq, Fr}; use jubjub::{Fq, Fr};
use orchard::keys::Scope; use crate::ledger::builder::transparent_bundle::TransparentBuilder;
use crate::ledger::builder::transparent_bundle::{TransparentBuilder, TransparentInputUnAuthorized};
use crate::ledger::transport::*; use crate::ledger::transport::*;
use crate::taddr::derive_from_pubkey;
use crate::{CompactTxStreamerClient, Destination, RawTransaction, Source, TransactionPlan}; use crate::{CompactTxStreamerClient, Destination, RawTransaction, Source, TransactionPlan};
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use rand::{rngs::OsRng, RngCore, SeedableRng}; use rand::{rngs::OsRng, RngCore, SeedableRng};
@ -21,12 +19,12 @@ use secp256k1::PublicKey;
use sha2::Sha256; use sha2::Sha256;
use tonic::{transport::Channel, Request}; use tonic::{transport::Channel, Request};
use zcash_client_backend::encoding::{ use zcash_client_backend::encoding::{
decode_transparent_address, encode_extended_full_viewing_key, encode_transparent_address, encode_extended_full_viewing_key, encode_transparent_address,
}; };
use zcash_primitives::consensus::Network; use zcash_primitives::consensus::Network;
use zcash_primitives::consensus::Parameters; use zcash_primitives::consensus::Parameters;
use zcash_primitives::legacy::{Script, TransparentAddress}; use zcash_primitives::legacy::TransparentAddress;
use zcash_primitives::transaction::components::{transparent, OutPoint, TxIn, TxOut};
use zcash_primitives::zip32::ExtendedFullViewingKey; use zcash_primitives::zip32::ExtendedFullViewingKey;
use zcash_primitives::{ use zcash_primitives::{
@ -50,8 +48,8 @@ use zcash_primitives::{
}; };
use zcash_proofs::{prover::LocalTxProver, sapling::SaplingProvingContext}; use zcash_proofs::{prover::LocalTxProver, sapling::SaplingProvingContext};
mod transparent_bundle;
mod orchard_bundle; mod orchard_bundle;
mod transparent_bundle;
struct SpendDescriptionUnAuthorized { struct SpendDescriptionUnAuthorized {
cv: ValueCommitment, cv: ValueCommitment,
@ -88,10 +86,7 @@ pub async fn show_public_keys() -> Result<()> {
} }
pub fn create_hasher(perso: &[u8]) -> State { pub fn create_hasher(perso: &[u8]) -> State {
let h = Params::new() let h = Params::new().hash_length(32).personal(perso).to_state();
.hash_length(32)
.personal(perso)
.to_state();
h h
} }
@ -109,8 +104,7 @@ pub async fn build_broadcast_tx(
anyhow::bail!("This ledger wallet has a different address"); anyhow::bail!("This ledger wallet has a different address");
} }
let taddr = &tx_plan.taddr; let _taddr = &tx_plan.taddr;
// Compute header digest // Compute header digest
let mut h = create_hasher(b"ZTxIdHeadersHash"); let mut h = create_hasher(b"ZTxIdHeadersHash");
@ -137,7 +131,7 @@ pub async fn build_broadcast_tx(
let nf_key = proofgen_key.to_viewing_key().nk; let nf_key = proofgen_key.to_viewing_key().nk;
let o_fvk: [u8; 96] = ledger_get_o_fvk().await?.try_into().unwrap(); let o_fvk: [u8; 96] = ledger_get_o_fvk().await?.try_into().unwrap();
let o_fvk = let _o_fvk =
orchard::keys::FullViewingKey::from_bytes(&o_fvk).ok_or(anyhow!("Invalid Orchard FVK"))?; orchard::keys::FullViewingKey::from_bytes(&o_fvk).ok_or(anyhow!("Invalid Orchard FVK"))?;
assert_eq!( assert_eq!(
@ -180,7 +174,9 @@ pub async fn build_broadcast_tx(
for sp in tx_plan.spends.iter() { for sp in tx_plan.spends.iter() {
match sp.source { match sp.source {
Source::Transparent { txid, index } => { Source::Transparent { txid, index } => {
transparent_builder.add_input(txid, index, sp.amount).await?; transparent_builder
.add_input(txid, index, sp.amount)
.await?;
} }
Source::Sapling { Source::Sapling {
diversifier, diversifier,
@ -270,7 +266,9 @@ pub async fn build_broadcast_tx(
let mut shielded_outputs = vec![]; let mut shielded_outputs = vec![];
for output in tx_plan.outputs.iter() { for output in tx_plan.outputs.iter() {
if let Destination::Transparent(raw_address) = output.destination { if let Destination::Transparent(raw_address) = output.destination {
transparent_builder.add_output(raw_address, output.amount).await?; transparent_builder
.add_output(raw_address, output.amount)
.await?;
} }
} }
ledger_set_stage(3).await?; ledger_set_stage(3).await?;

View File

@ -1,13 +1,18 @@
use std::{fs::File, io::Read}; use std::{fs::File, io::Read};
use blake2b_simd::Params; use blake2b_simd::Params;
use byteorder::{LE, WriteBytesExt}; use byteorder::{WriteBytesExt, LE};
use group::{Group, GroupEncoding}; use group::{Group, GroupEncoding};
use orchard::{ use orchard::{
builder::{SpendInfo, InProgress, Unproven, Unauthorized as OrchardUnauthorized, SigningMetadata, SigningParts}, builder::{
bundle::{Authorized, Flags, Authorization}, InProgress, SigningMetadata, SigningParts, SpendInfo, Unauthorized as OrchardUnauthorized,
Unproven,
},
bundle::{Authorization, Authorized, Flags},
circuit::{Circuit, Instance, ProvingKey}, circuit::{Circuit, Instance, ProvingKey},
keys::{Diversifier, FullViewingKey, Scope, SpendValidatingKey, SpendingKey, SpendAuthorizingKey}, keys::{
Diversifier, FullViewingKey, Scope, SpendAuthorizingKey, SpendValidatingKey, SpendingKey,
},
note::{ExtractedNoteCommitment, Nullifier, RandomSeed, TransmittedNoteCiphertext}, note::{ExtractedNoteCommitment, Nullifier, RandomSeed, TransmittedNoteCiphertext},
note_encryption::OrchardNoteEncryption, note_encryption::OrchardNoteEncryption,
primitives::redpallas::{Signature, SpendAuth}, primitives::redpallas::{Signature, SpendAuth},
@ -19,16 +24,22 @@ use rand::{RngCore, SeedableRng};
use rand_chacha::ChaCha20Rng; use rand_chacha::ChaCha20Rng;
use ripemd::Digest; use ripemd::Digest;
use crate::{
connect_lightwalletd, decode_orchard_merkle_path, ledger::*, RawTransaction, TransactionPlan,
};
use anyhow::Result; use anyhow::Result;
use tonic::Request; use tonic::Request;
use crate::{decode_orchard_merkle_path, TransactionPlan, RawTransaction, connect_lightwalletd, ledger::*};
use zcash_primitives::{transaction::{components::Amount, TransactionData, TxVersion, Transaction, sighash_v5, sighash::SignableInput,
txid::TxIdDigester, Unauthorized, Authorized as TxAuthorized},
consensus::{BlockHeight, BranchId}};
use hex_literal::hex;
use group::ff::Field; use group::ff::Field;
use hex_literal::hex;
use nonempty::NonEmpty; use nonempty::NonEmpty;
use zcash_primitives::{
consensus::{BlockHeight, BranchId},
transaction::{
components::Amount, sighash::SignableInput, sighash_v5, txid::TxIdDigester,
Authorized as TxAuthorized, Transaction, TransactionData, TxVersion, Unauthorized,
},
};
use crate::{Destination, Source}; use crate::{Destination, Source};
@ -44,7 +55,7 @@ pub async fn build_orchard() -> Result<()> {
let mut prng = ChaCha20Rng::from_seed([0; 32]); let mut prng = ChaCha20Rng::from_seed([0; 32]);
let mut rseed_rng = ChaCha20Rng::from_seed([1; 32]); let mut rseed_rng = ChaCha20Rng::from_seed([1; 32]);
let mut alpha_rng = ChaCha20Rng::from_seed([2; 32]); let mut alpha_rng = ChaCha20Rng::from_seed([2; 32]);
let mut sig_rng = ChaCha20Rng::from_seed([3; 32]); let _sig_rng = ChaCha20Rng::from_seed([3; 32]);
let spending_key = hex::decode(dotenv::var("SPENDING_KEY").unwrap()).unwrap(); let spending_key = hex::decode(dotenv::var("SPENDING_KEY").unwrap()).unwrap();
let spk = SpendingKey::from_bytes(spending_key.try_into().unwrap()).unwrap(); let spk = SpendingKey::from_bytes(spending_key.try_into().unwrap()).unwrap();
@ -117,7 +128,7 @@ pub async fn build_orchard() -> Result<()> {
}) })
.collect(); .collect();
let zero_bsk = ValueCommitTrapdoor::zero().into_bsk(); let _zero_bsk = ValueCommitTrapdoor::zero().into_bsk();
let mut orchard_memos_hasher = Params::new() let mut orchard_memos_hasher = Params::new()
.hash_length(32) .hash_length(32)
@ -204,21 +215,28 @@ pub async fn build_orchard() -> Result<()> {
orchard_nc_hasher.update(&enc[564..]); orchard_nc_hasher.update(&enc[564..]);
orchard_nc_hasher.update(&out); orchard_nc_hasher.update(&out);
println!("d/pkd {}", hex::encode(&output.recipient.to_raw_address_bytes())); println!(
"d/pkd {}",
hex::encode(&output.recipient.to_raw_address_bytes())
);
println!("rho {}", hex::encode(&rho.to_bytes())); println!("rho {}", hex::encode(&rho.to_bytes()));
println!("amount {}", hex::encode(&output.amount.inner().to_le_bytes())); println!(
"amount {}",
hex::encode(&output.amount.inner().to_le_bytes())
);
println!("rseed {}", hex::encode(&rseed.as_bytes())); println!("rseed {}", hex::encode(&rseed.as_bytes()));
println!("cmx {}", hex::encode(&cmx.to_bytes())); println!("cmx {}", hex::encode(&cmx.to_bytes()));
let action: Action<SigningMetadata> = Action::from_parts( let action: Action<SigningMetadata> = Action::from_parts(
rho.clone(), rho.clone(),
rk.clone(), rk.clone(),
cmx.clone(), cmx.clone(),
encrypted_note, encrypted_note,
cv_net.clone(), cv_net.clone(),
SigningMetadata { SigningMetadata {
dummy_ask: None, dummy_ask: None,
parts: SigningParts { ak, alpha } }, parts: SigningParts { ak, alpha },
},
); );
actions.push(action); actions.push(action);
@ -238,13 +256,15 @@ pub async fn build_orchard() -> Result<()> {
let flags = Flags::from_parts(true, true); let flags = Flags::from_parts(true, true);
let bsk = sum_rcv.into_bsk(); let bsk = sum_rcv.into_bsk();
let bundle: Bundle<_, Amount> = Bundle::from_parts( let bundle: Bundle<_, Amount> = Bundle::from_parts(
actions, actions,
flags, flags,
amount, amount,
anchor, anchor,
InProgress::<Unproven, OrchardUnauthorized> { InProgress::<Unproven, OrchardUnauthorized> {
proof: Unproven { circuits: vec![] }, proof: Unproven { circuits: vec![] },
sigs: OrchardUnauthorized { bsk: bsk.clone() } }); sigs: OrchardUnauthorized { bsk: bsk.clone() },
},
);
let tx_data: TransactionData<Unauthorized> = TransactionData { let tx_data: TransactionData<Unauthorized> = TransactionData {
version: TxVersion::Zip225, version: TxVersion::Zip225,
@ -282,8 +302,7 @@ pub async fn build_orchard() -> Result<()> {
for (a, o) in bundle.actions().iter().zip(padded_outputs.iter()) { for (a, o) in bundle.actions().iter().zip(padded_outputs.iter()) {
let nf = a.nullifier().to_bytes(); let nf = a.nullifier().to_bytes();
let epk = a.encrypted_note().epk_bytes; let epk = a.encrypted_note().epk_bytes;
let address = let _address = ledger_add_o_action(
ledger_add_o_action(
&nf, &nf,
o.amount.inner(), o.amount.inner(),
&epk, &epk,
@ -291,7 +310,7 @@ pub async fn build_orchard() -> Result<()> {
&a.encrypted_note().enc_ciphertext[0..52], &a.encrypted_note().enc_ciphertext[0..52],
) )
.await .await
.unwrap(); .unwrap();
} }
ledger_set_stage(5).await.unwrap(); ledger_set_stage(5).await.unwrap();
ledger_set_net_orchard(-tx_plan.net_chg[1]).await.unwrap(); ledger_set_net_orchard(-tx_plan.net_chg[1]).await.unwrap();
@ -308,9 +327,13 @@ pub async fn build_orchard() -> Result<()> {
let sig_bytes: [u8; 64] = ledger_sign_orchard().await.unwrap().try_into().unwrap(); let sig_bytes: [u8; 64] = ledger_sign_orchard().await.unwrap().try_into().unwrap();
let signature: Signature<SpendAuth> = sig_bytes.into(); let signature: Signature<SpendAuth> = sig_bytes.into();
let auth_action = Action::from_parts( let auth_action = Action::from_parts(
a.nullifier().clone(), a.rk().clone(), a.cmx().clone(), a.nullifier().clone(),
a.encrypted_note().clone(), a.cv_net().clone(), a.rk().clone(),
signature); a.cmx().clone(),
a.encrypted_note().clone(),
a.cv_net().clone(),
signature,
);
auth_actions.push(auth_action); auth_actions.push(auth_action);
} }
let auth_actions = NonEmpty::from_slice(&auth_actions).unwrap(); let auth_actions = NonEmpty::from_slice(&auth_actions).unwrap();
@ -338,8 +361,8 @@ pub async fn build_orchard() -> Result<()> {
let mut tx_bytes = vec![]; let mut tx_bytes = vec![];
tx.write(&mut tx_bytes).unwrap(); tx.write(&mut tx_bytes).unwrap();
let orchard_memos_hash = orchard_memos_hasher.finalize(); let _orchard_memos_hash = orchard_memos_hasher.finalize();
let orchard_nc_hash = orchard_nc_hasher.finalize(); let _orchard_nc_hash = orchard_nc_hasher.finalize();
let mut client = connect_lightwalletd("https://lwdv3.zecwallet.co").await?; let mut client = connect_lightwalletd("https://lwdv3.zecwallet.co").await?;
let response = client let response = client

View File

@ -1,53 +1,23 @@
use blake2b_simd::Params;
use blake2b_simd::State; use blake2b_simd::State;
use byteorder::WriteBytesExt; use byteorder::WriteBytesExt;
use byteorder::LE; use byteorder::LE;
use ff::{Field, PrimeField};
use group::GroupEncoding;
use hex_literal::hex;
use jubjub::{Fq, Fr};
use orchard::keys::Scope; use hex_literal::hex;
use crate::ledger::transport::*; use crate::ledger::transport::*;
use crate::taddr::derive_from_pubkey; use crate::taddr::derive_from_pubkey;
use crate::{CompactTxStreamerClient, Destination, RawTransaction, Source, TransactionPlan};
use anyhow::{anyhow, Result}; use anyhow::Result;
use rand::{rngs::OsRng, RngCore, SeedableRng};
use rand_chacha::ChaChaRng; use ripemd::Digest;
use ripemd::{Digest, Ripemd160};
use secp256k1::PublicKey; use zcash_client_backend::encoding::decode_transparent_address;
use sha2::Sha256;
use tonic::{transport::Channel, Request};
use zcash_client_backend::encoding::{
decode_transparent_address, encode_extended_full_viewing_key, encode_transparent_address,
};
use zcash_primitives::consensus::Network; use zcash_primitives::consensus::Network;
use zcash_primitives::consensus::Parameters; use zcash_primitives::consensus::Parameters;
use zcash_primitives::legacy::{Script, TransparentAddress}; use zcash_primitives::legacy::{Script, TransparentAddress};
use zcash_primitives::transaction::components::{transparent, OutPoint, TxIn, TxOut}; use zcash_primitives::transaction::components::{transparent, OutPoint, TxIn, TxOut};
use zcash_primitives::zip32::ExtendedFullViewingKey;
use zcash_primitives::{ use zcash_primitives::transaction::components::Amount;
consensus::{BlockHeight, BranchId, MainNetwork},
constants::PROOF_GENERATION_KEY_GENERATOR,
merkle_tree::IncrementalWitness,
sapling::{
note_encryption::sapling_note_encryption,
prover::TxProver,
redjubjub::Signature,
value::{NoteValue, ValueCommitment, ValueSum},
Diversifier, Node, Note, Nullifier, PaymentAddress, Rseed,
},
transaction::{
components::{
sapling::{Authorized as SapAuthorized, Bundle},
Amount, OutputDescription, SpendDescription, GROTH_PROOF_SIZE,
},
Authorized, TransactionData, TxVersion,
},
};
use zcash_proofs::{prover::LocalTxProver, sapling::SaplingProvingContext};
use super::create_hasher; use super::create_hasher;
@ -76,13 +46,15 @@ impl TransparentBuilder {
&network.b58_pubkey_address_prefix(), &network.b58_pubkey_address_prefix(),
&network.b58_script_address_prefix(), &network.b58_script_address_prefix(),
&taddr_str, &taddr_str,
).unwrap().unwrap(); )
.unwrap()
.unwrap();
let pkh = match taddr { let pkh = match taddr {
TransparentAddress::PublicKey(pkh) => pkh, TransparentAddress::PublicKey(pkh) => pkh,
_ => unreachable!(), _ => unreachable!(),
}; };
let tin_pubscript = taddr.script(); let tin_pubscript = taddr.script();
TransparentBuilder { TransparentBuilder {
taddr: taddr_str, taddr: taddr_str,
pubkey: pubkey.to_vec(), pubkey: pubkey.to_vec(),
pkh: pkh.clone(), pkh: pkh.clone(),
@ -91,7 +63,7 @@ impl TransparentBuilder {
trscripts_hasher: create_hasher(b"ZTxTrScriptsHash"), trscripts_hasher: create_hasher(b"ZTxTrScriptsHash"),
sequences_hasher: create_hasher(b"ZTxIdSequencHash"), sequences_hasher: create_hasher(b"ZTxIdSequencHash"),
vin: vec![], vin: vec![],
vins: vec![], vins: vec![],
vout: vec![], vout: vec![],
} }
} }
@ -151,10 +123,10 @@ impl TransparentBuilder {
} }
pub async fn sign(&mut self) -> Result<()> { pub async fn sign(&mut self) -> Result<()> {
let mut vins: Vec<TxIn<transparent::Authorized>> = vec![]; let _vins: Vec<TxIn<transparent::Authorized>> = vec![];
for tin in self.vin.iter() { for tin in self.vin.iter() {
let mut txin_hasher = create_hasher(b"Zcash___TxInHash"); let mut txin_hasher = create_hasher(b"Zcash___TxInHash");
txin_hasher.update(tin.utxo.hash()); txin_hasher.update(tin.utxo.hash());
txin_hasher.update(&tin.utxo.n().to_le_bytes()); txin_hasher.update(&tin.utxo.n().to_le_bytes());
txin_hasher.update(&tin.coin.value.to_i64_le_bytes()); txin_hasher.update(&tin.coin.value.to_i64_le_bytes());
@ -163,15 +135,15 @@ impl TransparentBuilder {
txin_hasher.update(&0xFFFFFFFFu32.to_le_bytes()); txin_hasher.update(&0xFFFFFFFFu32.to_le_bytes());
let txin_hash = txin_hasher.finalize(); let txin_hash = txin_hasher.finalize();
log::info!("TXIN {}", hex::encode(txin_hash)); log::info!("TXIN {}", hex::encode(txin_hash));
let signature = ledger_sign_transparent(txin_hash.as_bytes()).await?; let signature = ledger_sign_transparent(txin_hash.as_bytes()).await?;
let signature = secp256k1::ecdsa::Signature::from_der(&signature)?; let signature = secp256k1::ecdsa::Signature::from_der(&signature)?;
let mut signature = signature.serialize_der().to_vec(); let mut signature = signature.serialize_der().to_vec();
signature.extend(&[0x01]); // add SIG_HASH_ALL signature.extend(&[0x01]); // add SIG_HASH_ALL
// witness is PUSH(signature) PUSH(pk) // witness is PUSH(signature) PUSH(pk)
let script_sig = Script::default() << &*signature << &*self.pubkey; let script_sig = Script::default() << &*signature << &*self.pubkey;
let txin = TxIn::<transparent::Authorized> { let txin = TxIn::<transparent::Authorized> {
prevout: tin.utxo.clone(), prevout: tin.utxo.clone(),
script_sig, script_sig,
@ -179,7 +151,7 @@ impl TransparentBuilder {
}; };
self.vins.push(txin); self.vins.push(txin);
} }
Ok(()) Ok(())
} }
@ -191,8 +163,7 @@ impl TransparentBuilder {
authorization: transparent::Authorized, authorization: transparent::Authorized,
}; };
Some(transparent_bundle) Some(transparent_bundle)
} } else {
else {
None None
} }
} }