2021-07-22 15:59:02 -07:00
use std ::convert ::TryInto ;
use subtle ::CtOption ;
2021-03-12 16:04:13 -08:00
use crate ::{
keys ::{ DiversifiedTransmissionKey , Diversifier } ,
2021-05-11 01:06:16 -07:00
spec ::{ diversify_hash , NonIdentityPallasPoint } ,
2021-03-12 16:04:13 -08:00
} ;
2021-01-20 10:54:00 -08:00
/// A shielded payment address.
2021-03-05 16:57:30 -08:00
///
/// # Examples
///
/// ```
/// use orchard::keys::{SpendingKey, FullViewingKey};
///
/// let sk = SpendingKey::from_bytes([7; 32]).unwrap();
/// let address = FullViewingKey::from(&sk).default_address();
/// ```
2021-06-10 11:19:08 -07:00
#[ derive(Clone, Copy, Debug, PartialEq, Eq) ]
2021-01-21 04:16:50 -08:00
pub struct Address {
d : Diversifier ,
2021-03-05 17:03:53 -08:00
pk_d : DiversifiedTransmissionKey ,
2021-03-05 15:25:45 -08:00
}
impl Address {
2021-03-05 17:03:53 -08:00
pub ( crate ) fn from_parts ( d : Diversifier , pk_d : DiversifiedTransmissionKey ) -> Self {
2021-03-12 16:04:13 -08:00
// We assume here that pk_d is correctly-derived from d. We ensure this for
// internal APIs. For parsing from raw byte encodings, we assume that users aren't
// modifying internals of encoded address formats. If they do, that can result in
// lost funds, but we can't defend against that from here.
2021-03-05 15:25:45 -08:00
Address { d , pk_d }
}
2021-03-12 16:04:13 -08:00
2021-06-02 15:22:22 -07:00
pub ( crate ) fn diversifer ( & self ) -> Diversifier {
self . d
}
2021-05-11 01:06:16 -07:00
pub ( crate ) fn g_d ( & self ) -> NonIdentityPallasPoint {
2021-03-12 16:04:13 -08:00
diversify_hash ( self . d . as_array ( ) )
}
pub ( crate ) fn pk_d ( & self ) -> & DiversifiedTransmissionKey {
& self . pk_d
}
2021-07-22 15:59:02 -07:00
2021-07-23 13:09:30 -07:00
/// Serializes this address to its "raw" encoding as specified in [Zcash Protocol Spec § 5.6.4.2: Orchard Raw Payment Addresses][orchardpaymentaddrencoding]
///
/// [orchardpaymentaddrencoding]: https://zips.z.cash/protocol/protocol.pdf#orchardpaymentaddrencoding
2021-07-22 15:59:02 -07:00
pub fn to_raw_address_bytes ( & self ) -> [ u8 ; 43 ] {
let mut result = [ 0 u8 ; 43 ] ;
result [ .. 11 ] . copy_from_slice ( self . d . as_array ( ) ) ;
result [ 11 .. ] . copy_from_slice ( & self . pk_d . to_bytes ( ) ) ;
result
}
2021-07-23 13:09:30 -07:00
/// Parse an address from its "raw" encoding as specified in [Zcash Protocol Spec § 5.6.4.2: Orchard Raw Payment Addresses][orchardpaymentaddrencoding]
///
/// [orchardpaymentaddrencoding]: https://zips.z.cash/protocol/protocol.pdf#orchardpaymentaddrencoding
2021-07-22 15:59:02 -07:00
pub fn from_raw_address_bytes ( bytes : & [ u8 ; 43 ] ) -> CtOption < Self > {
DiversifiedTransmissionKey ::from_bytes ( bytes [ 11 .. ] . try_into ( ) . unwrap ( ) ) . map ( | pk_d | {
let d = Diversifier ::from_bytes ( bytes [ .. 11 ] . try_into ( ) . unwrap ( ) ) ;
Self ::from_parts ( d , pk_d )
} )
}
2021-01-20 10:54:00 -08:00
}
2021-04-27 06:49:49 -07:00
/// Generators for property testing.
#[ cfg(any(test, feature = " test-dependencies " )) ]
2021-12-17 14:08:58 -08:00
#[ cfg_attr(docsrs, doc(cfg(feature = " test-dependencies " ))) ]
2021-04-27 06:49:49 -07:00
pub mod testing {
use proptest ::prelude ::* ;
use crate ::keys ::{ testing ::arb_spending_key , FullViewingKey } ;
use super ::Address ;
prop_compose! {
2021-04-27 12:56:36 -07:00
/// Generates an arbitrary payment address.
2021-04-27 06:49:49 -07:00
pub ( crate ) fn arb_address ( ) ( sk in arb_spending_key ( ) ) -> Address {
let fvk = FullViewingKey ::from ( & sk ) ;
fvk . default_address ( )
}
}
}