2021-05-28 04:42:01 -07:00
|
|
|
use blake2b_simd::Params;
|
|
|
|
|
|
|
|
const PRF_EXPAND_PERSONALIZATION: &[u8; 16] = b"Zcash_ExpandSeed";
|
|
|
|
|
2021-05-28 05:11:54 -07:00
|
|
|
/// The set of domains in which $PRF^\mathsf{expand}$ is defined.
|
|
|
|
pub(crate) enum PrfExpand {
|
|
|
|
Esk,
|
|
|
|
Rcm,
|
|
|
|
OrchardAsk,
|
|
|
|
OrchardNk,
|
|
|
|
OrchardRivk,
|
|
|
|
Psi,
|
2021-07-15 00:18:01 -07:00
|
|
|
OrchardZip32Child,
|
2021-05-28 05:11:54 -07:00
|
|
|
OrchardDkOvk,
|
2022-01-06 07:10:14 -08:00
|
|
|
OrchardRivkInternal,
|
2021-05-28 04:42:01 -07:00
|
|
|
}
|
|
|
|
|
2021-05-28 05:11:54 -07:00
|
|
|
impl PrfExpand {
|
|
|
|
fn domain_separator(&self) -> u8 {
|
|
|
|
match self {
|
|
|
|
Self::Esk => 0x04,
|
|
|
|
Self::Rcm => 0x05,
|
|
|
|
Self::OrchardAsk => 0x06,
|
|
|
|
Self::OrchardNk => 0x07,
|
|
|
|
Self::OrchardRivk => 0x08,
|
|
|
|
Self::Psi => 0x09,
|
2021-07-15 00:18:01 -07:00
|
|
|
Self::OrchardZip32Child => 0x81,
|
2021-05-28 05:11:54 -07:00
|
|
|
Self::OrchardDkOvk => 0x82,
|
2022-01-06 07:10:14 -08:00
|
|
|
Self::OrchardRivkInternal => 0x83,
|
2021-05-28 05:11:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Expands the given secret key in this domain, with no additional data.
|
|
|
|
///
|
|
|
|
/// $PRF^\mathsf{expand}(sk, dst) := BLAKE2b-512("Zcash_ExpandSeed", sk || dst)$
|
|
|
|
///
|
|
|
|
/// Defined in [Zcash Protocol Spec § 5.4.2: Pseudo Random Functions][concreteprfs].
|
|
|
|
///
|
|
|
|
/// [concreteprfs]: https://zips.z.cash/protocol/nu5.pdf#concreteprfs
|
|
|
|
pub(crate) fn expand(self, sk: &[u8]) -> [u8; 64] {
|
|
|
|
self.with_ad_slices(sk, &[])
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Expands the given secret key in this domain, with the given additional data.
|
|
|
|
///
|
|
|
|
/// $PRF^\mathsf{expand}(sk, dst, t) := BLAKE2b-512("Zcash_ExpandSeed", sk || dst || t)$
|
|
|
|
///
|
|
|
|
/// Defined in [Zcash Protocol Spec § 5.4.2: Pseudo Random Functions][concreteprfs].
|
|
|
|
///
|
|
|
|
/// [concreteprfs]: https://zips.z.cash/protocol/nu5.pdf#concreteprfs
|
|
|
|
pub(crate) fn with_ad(self, sk: &[u8], t: &[u8]) -> [u8; 64] {
|
|
|
|
self.with_ad_slices(sk, &[t])
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Expands the given secret key in this domain, with additional data concatenated
|
|
|
|
/// from the given slices.
|
|
|
|
///
|
|
|
|
/// $PRF^\mathsf{expand}(sk, dst, a, b, ...) := BLAKE2b-512("Zcash_ExpandSeed", sk || dst || a || b || ...)$
|
|
|
|
///
|
|
|
|
/// Defined in [Zcash Protocol Spec § 5.4.2: Pseudo Random Functions][concreteprfs].
|
|
|
|
///
|
|
|
|
/// [concreteprfs]: https://zips.z.cash/protocol/nu5.pdf#concreteprfs
|
|
|
|
pub(crate) fn with_ad_slices(self, sk: &[u8], ts: &[&[u8]]) -> [u8; 64] {
|
|
|
|
let mut h = Params::new()
|
|
|
|
.hash_length(64)
|
|
|
|
.personal(PRF_EXPAND_PERSONALIZATION)
|
|
|
|
.to_state();
|
|
|
|
h.update(sk);
|
|
|
|
h.update(&[self.domain_separator()]);
|
|
|
|
for t in ts {
|
|
|
|
h.update(t);
|
|
|
|
}
|
|
|
|
*h.finalize().as_array()
|
2021-05-28 04:42:01 -07:00
|
|
|
}
|
|
|
|
}
|