@ -3,6 +3,7 @@
use ff ::{ PrimeField , PrimeFieldRepr } ;
use ff ::{ PrimeField , PrimeFieldRepr } ;
use pairing ::bls12_381 ::{ Bls12 , Fr , FrRepr } ;
use pairing ::bls12_381 ::{ Bls12 , Fr , FrRepr } ;
use std ::collections ::HashSet ;
use std ::collections ::HashSet ;
use subtle ::{ ConditionallySelectable , ConstantTimeEq , CtOption } ;
use zcash_primitives ::{
use zcash_primitives ::{
jubjub ::{ edwards , fs ::Fs } ,
jubjub ::{ edwards , fs ::Fs } ,
merkle_tree ::{ CommitmentTree , IncrementalWitness } ,
merkle_tree ::{ CommitmentTree , IncrementalWitness } ,
@ -116,27 +117,28 @@ pub fn scan_block(
let num_outputs = tx . outputs . len ( ) ;
let num_outputs = tx . outputs . len ( ) ;
// Check for spent notes
// Check for spent notes
let shielded_spends : Vec < _ > =
// The only step that is not constant-time is the filter() at the end.
tx . spends
let shielded_spends : Vec < _ > = tx
. spends
. into_iter ( )
. into_iter ( )
. enumerate ( )
. enumerate ( )
. filter_map ( | ( index , spend ) | {
. map ( | ( index , spend ) | {
if let Some ( account ) = nullifiers . iter ( ) . find_map ( | & ( nf , acc ) | {
// Find the first tracked nullifier that matches this spend, and produce
if nf = = & spend . nf [ .. ] {
// a WalletShieldedSpend if there is a match, in constant time.
Some ( acc )
nullifiers
} else {
. iter ( )
None
. map ( | & ( nf , account ) | CtOption ::new ( account as u64 , nf . ct_eq ( & spend . nf [ .. ] ) ) )
}
. fold ( CtOption ::new ( 0 , 0. into ( ) ) , | first , next | {
} ) {
CtOption ::conditional_select ( & next , & first , first . is_some ( ) )
Some ( WalletShieldedSpend {
} )
. map ( | account | WalletShieldedSpend {
index ,
index ,
nf : spend . nf ,
nf : spend . nf ,
account ,
account : account as usize ,
} )
} )
} else {
None
}
} )
} )
. filter ( | spend | spend . is_some ( ) . into ( ) )
. map ( | spend | spend . unwrap ( ) )
. collect ( ) ;
. collect ( ) ;
// Collect the set of accounts that were spent from in this transaction
// Collect the set of accounts that were spent from in this transaction