zcash_keys: Keep the Ufvk and Uivk encodings private.
This commit is contained in:
parent
9ddbf1e3e9
commit
9e1a4327c3
|
@ -74,7 +74,6 @@ use std::io::{self, Cursor};
|
|||
use std::num::NonZeroU32;
|
||||
use std::ops::RangeInclusive;
|
||||
use tracing::debug;
|
||||
use zcash_address::unified::{Encoding, Uivk};
|
||||
use zcash_keys::keys::{
|
||||
AddressGenerationError, HdSeedFingerprint, UnifiedAddressRequest, UnifiedIncomingViewingKey,
|
||||
};
|
||||
|
@ -120,7 +119,7 @@ use {
|
|||
crate::UtxoId,
|
||||
rusqlite::Row,
|
||||
std::collections::BTreeSet,
|
||||
zcash_address::unified::Ivk,
|
||||
zcash_address::unified::{Encoding, Ivk, Uivk},
|
||||
zcash_client_backend::wallet::{TransparentAddressMetadata, WalletTransparentOutput},
|
||||
zcash_primitives::{
|
||||
legacy::{
|
||||
|
@ -347,7 +346,7 @@ pub(crate) fn add_account<P: consensus::Parameters>(
|
|||
":hd_seed_fingerprint": hd_seed_fingerprint.as_ref().map(|fp| fp.as_bytes()),
|
||||
":hd_account_index": hd_account_index.map(u32::from),
|
||||
":ufvk": viewing_key.ufvk().map(|ufvk| ufvk.encode(params)),
|
||||
":uivk": viewing_key.uivk().to_uivk().encode(¶ms.network_type()),
|
||||
":uivk": viewing_key.uivk().encode(params),
|
||||
":orchard_fvk_item_cache": orchard_item,
|
||||
":sapling_fvk_item_cache": sapling_item,
|
||||
":p2pkh_fvk_item_cache": transparent_item,
|
||||
|
@ -1503,18 +1502,9 @@ pub(crate) fn get_account<P: Parameters>(
|
|||
))
|
||||
} else {
|
||||
let uivk_str: String = row.get("uivk")?;
|
||||
let (network, uivk) = Uivk::decode(&uivk_str).map_err(|e| {
|
||||
SqliteClientError::CorruptedData(format!("Failure to decode UIVK: {e}"))
|
||||
})?;
|
||||
if network != params.network_type() {
|
||||
return Err(SqliteClientError::CorruptedData(
|
||||
"UIVK network type does not match wallet network type".to_string(),
|
||||
));
|
||||
}
|
||||
ViewingKey::Incoming(Box::new(
|
||||
UnifiedIncomingViewingKey::from_uivk(&uivk).map_err(|e| {
|
||||
SqliteClientError::CorruptedData(format!("Failure to decode UIVK: {e}"))
|
||||
})?,
|
||||
UnifiedIncomingViewingKey::decode(params, &uivk_str[..])
|
||||
.map_err(SqliteClientError::BadAccountData)?,
|
||||
))
|
||||
};
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ use rusqlite::{named_params, Transaction};
|
|||
use schemer_rusqlite::RusqliteMigration;
|
||||
use secrecy::{ExposeSecret, SecretVec};
|
||||
use uuid::Uuid;
|
||||
use zcash_address::unified::Encoding;
|
||||
use zcash_client_backend::{data_api::AccountKind, keys::UnifiedSpendingKey};
|
||||
use zcash_keys::keys::{HdSeedFingerprint, UnifiedFullViewingKey};
|
||||
use zcash_primitives::consensus;
|
||||
|
@ -122,8 +121,7 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
|
|||
|
||||
let uivk = ufvk_parsed
|
||||
.to_unified_incoming_viewing_key()
|
||||
.to_uivk()
|
||||
.encode(&self.params.network_type());
|
||||
.encode(&self.params);
|
||||
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
let transparent_item = ufvk_parsed.transparent().map(|k| k.serialize());
|
||||
|
|
|
@ -12,8 +12,6 @@ and this library adheres to Rust's notion of
|
|||
- `impl Display for zcash_keys::keys::AddressGenerationError`
|
||||
- `impl std::error::Error for zcash_keys::keys::AddressGenerationError`
|
||||
- `zcash_keys::keys::DecodingError`
|
||||
- `zcash_keys::keys::UnifiedFullViewingKey::from_ufvk`
|
||||
- `zcash_keys::keys::UnifiedFullViewingKey::to_ufvk`
|
||||
- `zcash_keys::keys::UnifiedFullViewingKey::to_unified_incoming_viewing_key`
|
||||
- `zcash_keys::keys::UnifiedIncomingViewingKey`
|
||||
|
||||
|
|
|
@ -740,13 +740,13 @@ impl UnifiedFullViewingKey {
|
|||
));
|
||||
}
|
||||
|
||||
Self::from_ufvk(&ufvk).map_err(|e| e.to_string())
|
||||
Self::parse(&ufvk).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// Parses a `UnifiedFullViewingKey` from its [ZIP 316] string encoding.
|
||||
///
|
||||
/// [ZIP 316]: https://zips.z.cash/zip-0316
|
||||
pub fn from_ufvk(ufvk: &Ufvk) -> Result<Self, DecodingError> {
|
||||
pub fn parse(ufvk: &Ufvk) -> Result<Self, DecodingError> {
|
||||
#[cfg(feature = "orchard")]
|
||||
let mut orchard = None;
|
||||
#[cfg(feature = "sapling")]
|
||||
|
@ -823,7 +823,7 @@ impl UnifiedFullViewingKey {
|
|||
}
|
||||
|
||||
/// Returns the string encoding of this `UnifiedFullViewingKey` for the given network.
|
||||
pub fn to_ufvk(&self) -> Ufvk {
|
||||
fn to_ufvk(&self) -> Ufvk {
|
||||
let items = std::iter::empty().chain(self.unknown.iter().map(|(typecode, data)| {
|
||||
unified::Fvk::Unknown {
|
||||
typecode: *typecode,
|
||||
|
@ -973,8 +973,24 @@ impl UnifiedIncomingViewingKey {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parses a `UnifiedFullViewingKey` from its [ZIP 316] string encoding.
|
||||
///
|
||||
/// [ZIP 316]: https://zips.z.cash/zip-0316
|
||||
pub fn decode<P: consensus::Parameters>(params: &P, encoding: &str) -> Result<Self, String> {
|
||||
let (net, ufvk) = unified::Uivk::decode(encoding).map_err(|e| e.to_string())?;
|
||||
let expected_net = params.network_type();
|
||||
if net != expected_net {
|
||||
return Err(format!(
|
||||
"UIVK is for network {:?} but we expected {:?}",
|
||||
net, expected_net,
|
||||
));
|
||||
}
|
||||
|
||||
Self::parse(&ufvk).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// Constructs a unified incoming viewing key from a parsed unified encoding.
|
||||
pub fn from_uivk(uivk: &Uivk) -> Result<Self, DecodingError> {
|
||||
fn parse(uivk: &Uivk) -> Result<Self, DecodingError> {
|
||||
#[cfg(feature = "orchard")]
|
||||
let mut orchard = None;
|
||||
#[cfg(feature = "sapling")]
|
||||
|
@ -1041,8 +1057,13 @@ impl UnifiedIncomingViewingKey {
|
|||
})
|
||||
}
|
||||
|
||||
/// Returns the string encoding of this `UnifiedFullViewingKey` for the given network.
|
||||
pub fn encode<P: consensus::Parameters>(&self, params: &P) -> String {
|
||||
self.render().encode(¶ms.network_type())
|
||||
}
|
||||
|
||||
/// Converts this unified incoming viewing key to a unified encoding.
|
||||
pub fn to_uivk(&self) -> Uivk {
|
||||
fn render(&self) -> Uivk {
|
||||
let items = std::iter::empty().chain(self.unknown.iter().map(|(typecode, data)| {
|
||||
unified::Ivk::Unknown {
|
||||
typecode: *typecode,
|
||||
|
@ -1530,7 +1551,7 @@ mod tests {
|
|||
orchard,
|
||||
);
|
||||
|
||||
let encoded = uivk.to_uivk().encode(&NetworkType::Main);
|
||||
let encoded = uivk.render().encode(&NetworkType::Main);
|
||||
|
||||
// Test encoded form against known values; these test vectors contain Orchard receivers
|
||||
// that will be treated as unknown if the `orchard` feature is not enabled.
|
||||
|
@ -1548,9 +1569,8 @@ mod tests {
|
|||
assert_eq!(encoded, _encoded_no_t);
|
||||
}
|
||||
|
||||
let decoded =
|
||||
UnifiedIncomingViewingKey::from_uivk(&Uivk::decode(&encoded).unwrap().1).unwrap();
|
||||
let reencoded = decoded.to_uivk().encode(&NetworkType::Main);
|
||||
let decoded = UnifiedIncomingViewingKey::parse(&Uivk::decode(&encoded).unwrap().1).unwrap();
|
||||
let reencoded = decoded.render().encode(&NetworkType::Main);
|
||||
assert_eq!(encoded, reencoded);
|
||||
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
|
@ -1570,7 +1590,7 @@ mod tests {
|
|||
);
|
||||
|
||||
let decoded_with_t =
|
||||
UnifiedIncomingViewingKey::from_uivk(&Uivk::decode(encoded_with_t).unwrap().1).unwrap();
|
||||
UnifiedIncomingViewingKey::parse(&Uivk::decode(encoded_with_t).unwrap().1).unwrap();
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
assert_eq!(
|
||||
decoded_with_t.transparent.map(|t| t.serialize()),
|
||||
|
|
Loading…
Reference in New Issue