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:
parent
f6f5096ae4
commit
da3833f906
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue