From 72c2e54a7bfca23cc5c8f22173ccc53d98853a05 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Mon, 24 Jan 2022 16:16:55 -0700 Subject: [PATCH] Add explicit serialize and deserialize methods to ExternalPubKey The serialization defined by HDWallet for the fields of ExtendedPubKey is in the opposite field order from what is defined in ZIP 316. --- zcash_primitives/src/transparent.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/zcash_primitives/src/transparent.rs b/zcash_primitives/src/transparent.rs index 686b598c1..a2caa6ca8 100644 --- a/zcash_primitives/src/transparent.rs +++ b/zcash_primitives/src/transparent.rs @@ -1,5 +1,6 @@ use crate::{legacy::TransparentAddress, sapling::keys::prf_expand_vec}; -use hdwallet::{traits::Deserialize, ExtendedPrivKey, ExtendedPubKey}; +use hdwallet::{ExtendedPrivKey, ExtendedPubKey}; +use secp256k1::PublicKey; use sha2::{Digest, Sha256}; use std::convert::TryInto; @@ -35,8 +36,7 @@ impl std::convert::TryFrom<&[u8; 65]> for ExternalPubKey { type Error = hdwallet::error::Error; fn try_from(data: &[u8; 65]) -> Result { - let ext_pub_key = ExtendedPubKey::deserialize(data)?; - Ok(Self(ext_pub_key)) + ExternalPubKey::deserialize(data) } } @@ -83,6 +83,21 @@ impl ExternalPubKey { pub fn external_ovk(&self) -> ExternalOvk { self.ovk_for_shielding().1 } + + pub fn serialize(&self) -> Vec { + let mut buf = self.0.chain_code.clone(); + buf.extend(self.0.public_key.serialize().to_vec()); + buf + } + + pub fn deserialize(data: &[u8; 65]) -> Result { + let chain_code = data[..32].to_vec(); + let public_key = PublicKey::from_slice(&data[32..])?; + Ok(ExternalPubKey(ExtendedPubKey { + public_key, + chain_code, + })) + } } /// Internal ovk used for autoshielding.