Fix missing use of `dk` in derivation of sapling internal FVK.

Also, factor out sapling internal fvk derivation so that it only
requires (fvk, dk) since we may not have the full extfvk.
This commit is contained in:
Kris Nuttycombe 2022-01-19 18:18:22 -07:00
parent f6f5096ae4
commit da3833f906
1 changed files with 42 additions and 20 deletions

View File

@ -235,6 +235,41 @@ pub fn sapling_default_address(
sapling_find_address(fvk, dk, DiversifierIndex::new()).unwrap()
}
/// Returns the internal full viewing key and diversifier key
/// for the provided external fvk and dk
pub fn sapling_derive_internal_fvk(
fvk: &FullViewingKey,
dk: &DiversifierKey,
) -> (FullViewingKey, DiversifierKey) {
let i = {
let mut h = Blake2bParams::new()
.hash_length(64)
.personal(crate::zip32::ZIP32_SAPLING_INT_PERSONALIZATION)
.to_state();
h.update(&fvk.to_bytes());
h.update(&dk.0);
h.finalize()
};
let i_nsk = jubjub::Fr::from_bytes_wide(prf_expand(i.as_bytes(), &[0x17]).as_array());
let r = prf_expand(i.as_bytes(), &[0x18]);
let r = r.as_bytes();
// PROOF_GENERATION_KEY_GENERATOR = \mathcal{H}^Sapling
let nk_internal = PROOF_GENERATION_KEY_GENERATOR * i_nsk + fvk.vk.nk;
let dk_internal = DiversifierKey(r[..32].try_into().unwrap());
let ovk_internal = OutgoingViewingKey(r[32..].try_into().unwrap());
(
FullViewingKey {
vk: ViewingKey {
ak: fvk.vk.ak,
nk: nk_internal,
},
ovk: ovk_internal,
},
dk_internal,
)
}
/// A Sapling extended spending key
#[derive(Clone)]
pub struct ExtendedSpendingKey {
@ -415,10 +450,13 @@ impl ExtendedSpendingKey {
pub fn derive_internal(&self) -> Self {
let i = {
let fvk = FullViewingKey::from_expanded_spending_key(&self.expsk);
Blake2bParams::new()
let mut h = Blake2bParams::new()
.hash_length(64)
.personal(crate::zip32::ZIP32_SAPLING_INT_PERSONALIZATION)
.hash(&fvk.to_bytes())
.to_state();
h.update(&fvk.to_bytes());
h.update(&self.dk.0);
h.finalize()
};
let i_nsk = jubjub::Fr::from_bytes_wide(prf_expand(i.as_bytes(), &[0x17]).as_array());
let r = prf_expand(i.as_bytes(), &[0x18]);
@ -546,30 +584,14 @@ impl ExtendedFullViewingKey {
}
pub fn derive_internal(&self) -> Self {
let i = Blake2bParams::new()
.hash_length(64)
.personal(crate::zip32::ZIP32_SAPLING_INT_PERSONALIZATION)
.hash(&self.fvk.to_bytes());
let i_nsk = jubjub::Fr::from_bytes_wide(prf_expand(i.as_bytes(), &[0x17]).as_array());
let r = prf_expand(i.as_bytes(), &[0x18]);
let r = r.as_bytes();
// PROOF_GENERATION_KEY_GENERATOR = \mathcal{H}^Sapling
let nk_internal = PROOF_GENERATION_KEY_GENERATOR * i_nsk + self.fvk.vk.nk;
let dk_internal = DiversifierKey(r[..32].try_into().unwrap());
let ovk_internal = OutgoingViewingKey(r[32..].try_into().unwrap());
let (fvk_internal, dk_internal) = sapling_derive_internal_fvk(&self.fvk, &self.dk);
ExtendedFullViewingKey {
depth: self.depth,
parent_fvk_tag: self.parent_fvk_tag,
child_index: self.child_index,
chain_code: self.chain_code,
fvk: FullViewingKey {
vk: ViewingKey {
ak: self.fvk.vk.ak,
nk: nk_internal,
},
ovk: ovk_internal,
},
fvk: fvk_internal,
dk: dk_internal,
}
}