use incrementalmerkletree::Hashable; use orchard::{ builder::Builder, bundle::{Authorized, Flags}, circuit::{ProvingKey, VerifyingKey}, keys::{FullViewingKey, SpendingKey}, tree::MerkleHashOrchard, value::NoteValue, Bundle, }; use rand::rngs::OsRng; fn verify_bundle(bundle: &Bundle, vk: &VerifyingKey) { assert!(matches!(bundle.verify_proof(&vk), Ok(()))); let sighash: [u8; 32] = bundle.commitment().into(); let bvk = bundle.binding_validating_key(); for action in bundle.actions() { assert_eq!(action.rk().verify(&sighash, action.authorization()), Ok(())); } assert_eq!( bvk.verify(&sighash, bundle.authorization().binding_signature()), Ok(()) ); } #[test] fn bundle_chain() { let mut rng = OsRng; let pk = ProvingKey::build(); let vk = VerifyingKey::build(); let sk = SpendingKey::from_bytes([0; 32]).unwrap(); let fvk = FullViewingKey::from(&sk); let recipient = fvk.address_at(0u32); // Create a shielding bundle. let shielding_bundle: Bundle<_, i64> = { // Use the empty tree. let anchor = MerkleHashOrchard::empty_root(32.into()).into(); let mut builder = Builder::new(Flags::from_parts(false, true), anchor); assert_eq!( builder.add_recipient(None, recipient, NoteValue::from_raw(5000), None), Ok(()) ); let unauthorized = builder.build(&mut rng).unwrap(); let sighash = unauthorized.commitment().into(); let proven = unauthorized.create_proof(&pk).unwrap(); proven.apply_signatures(&mut rng, sighash, &[]).unwrap() }; // Verify the shielding bundle. verify_bundle(&shielding_bundle, &vk); }