Implement derivation of the internal Sapling spending key.
This commit is contained in:
parent
3ddbe1fa06
commit
b46d85976d
|
@ -299,6 +299,12 @@ extern "C" {
|
|||
unsigned char *xsk_i
|
||||
);
|
||||
|
||||
/// Derive a internal ExtendedSpendingKey from an external key
|
||||
void librustzcash_zip32_xsk_derive_internal(
|
||||
const unsigned char *xsk_external,
|
||||
unsigned char *xsk_internal
|
||||
);
|
||||
|
||||
/// Derive a child ExtendedFullViewingKey from a parent.
|
||||
bool librustzcash_zip32_xfvk_derive(
|
||||
const unsigned char *xfvk_parent,
|
||||
|
|
|
@ -1059,6 +1059,23 @@ pub extern "C" fn librustzcash_zip32_xsk_derive(
|
|||
.expect("should be able to serialize an ExtendedSpendingKey");
|
||||
}
|
||||
|
||||
/// Derive the Sapling internal spending key from the external extended
|
||||
/// spending key
|
||||
#[no_mangle]
|
||||
pub extern "C" fn librustzcash_zip32_xsk_derive_internal(
|
||||
xsk_external: *const [c_uchar; 169],
|
||||
xsk_internal_ret: *mut [c_uchar; 169],
|
||||
) {
|
||||
let xsk_external = zip32::ExtendedSpendingKey::read(&unsafe { *xsk_external }[..])
|
||||
.expect("valid ExtendedSpendingKey");
|
||||
|
||||
let xsk_internal = xsk_external.derive_internal();
|
||||
|
||||
xsk_internal
|
||||
.write(&mut (unsafe { &mut *xsk_internal_ret })[..])
|
||||
.expect("should be able to serialize an ExtendedSpendingKey");
|
||||
}
|
||||
|
||||
/// Derive a child ExtendedFullViewingKey from a parent.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn librustzcash_zip32_xfvk_derive(
|
||||
|
@ -1081,7 +1098,7 @@ pub extern "C" fn librustzcash_zip32_xfvk_derive(
|
|||
true
|
||||
}
|
||||
|
||||
/// Derive the Sapling internal
|
||||
/// Derive the Sapling internal full viewing key from the corresponding external full viewing key
|
||||
#[no_mangle]
|
||||
pub extern "C" fn librustzcash_zip32_sapling_derive_internal_fvk(
|
||||
fvk: *const [c_uchar; 96],
|
||||
|
|
|
@ -4013,6 +4013,15 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp)
|
|||
// Generate the common ovk for recovering t->z outputs.
|
||||
HDSeed seed = pwalletMain->GetHDSeedForRPC();
|
||||
ovks.insert(ovkForShieldingFromTaddr(seed));
|
||||
|
||||
auto legacyAcctUFVK = pwalletMain->GetUnifiedFullViewingKeyByAccount(ZCASH_LEGACY_ACCOUNT);
|
||||
if (legacyAcctUFVK.has_value()) {
|
||||
auto legacyAcctOVKs = legacyAcctUFVK.value().GetTransparentOVKsForShielding();
|
||||
if (legacyAcctOVKs.has_value()) {
|
||||
ovks.insert(legacyAcctOVKs.value().first);
|
||||
ovks.insert(legacyAcctOVKs.value().second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sapling spends
|
||||
|
|
|
@ -504,6 +504,13 @@ std::optional<libzcash::ZcashdUnifiedSpendingKey>
|
|||
throw std::runtime_error("CWalletDB::GenerateUnifiedSpendingKeyForAccount(): Unable to add Sapling key component to the wallet.");
|
||||
}
|
||||
|
||||
// Add the Sapling change key to the wallet
|
||||
auto saplingChangeEsk = saplingEsk.DeriveInternalKey();
|
||||
if (addSpendingKey(saplingChangeEsk) == KeyNotAdded) {
|
||||
// If adding the Sapling change key to the wallet failed, abort the process.
|
||||
throw std::runtime_error("CWalletDB::GenerateUnifiedSpendingKeyForAccount(): Unable to add Sapling key component to the wallet.");
|
||||
}
|
||||
|
||||
auto zufvk = ZcashdUnifiedFullViewingKey::FromUnifiedFullViewingKey(Params(), ufvk);
|
||||
if (!CCryptoKeyStore::AddUnifiedFullViewingKey(zufvk)) {
|
||||
throw std::runtime_error("CWalletDB::GenerateUnifiedSpendingKeyForAccount(): Failed to add UFVK to the keystore.");
|
||||
|
|
|
@ -232,7 +232,19 @@ SaplingExtendedFullViewingKey SaplingExtendedSpendingKey::ToXFVK() const
|
|||
}
|
||||
|
||||
SaplingExtendedSpendingKey SaplingExtendedSpendingKey::DeriveInternalKey() const {
|
||||
throw std::runtime_error("Not yet implemented");
|
||||
CDataStream ss_p(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss_p << *this;
|
||||
CSerializeData external_key_bytes(ss_p.begin(), ss_p.end());
|
||||
|
||||
CSerializeData internal_key_bytes(ZIP32_XSK_SIZE);
|
||||
librustzcash_zip32_xsk_derive_internal(
|
||||
reinterpret_cast<unsigned char*>(external_key_bytes.data()),
|
||||
reinterpret_cast<unsigned char*>(internal_key_bytes.data()));
|
||||
|
||||
CDataStream ss_i(internal_key_bytes, SER_NETWORK, PROTOCOL_VERSION);
|
||||
SaplingExtendedSpendingKey xsk_internal;
|
||||
ss_i >> xsk_internal;
|
||||
return xsk_internal;
|
||||
}
|
||||
|
||||
HDKeyPath Zip32AccountKeyPath(
|
||||
|
|
Loading…
Reference in New Issue