diff --git a/core/src/libtx/secp_ser.rs b/core/src/libtx/secp_ser.rs index 7ba542cc8c..eeccedc985 100644 --- a/core/src/libtx/secp_ser.rs +++ b/core/src/libtx/secp_ser.rs @@ -96,6 +96,48 @@ pub mod option_sig_serde { } +/// Serializes an Option to and from hex +pub mod option_seckey_serde { + use crate::serde::{Deserialize, Deserializer, Serializer}; + use crate::util::{from_hex, secp, static_secp_instance, to_hex}; + use serde::de::Error; + + /// + pub fn serialize( + key: &Option, + serializer: S, + ) -> Result + where + S: Serializer, + { + match key { + Some(key) => serializer.serialize_str(&to_hex(key.0.to_vec())), + None => serializer.serialize_none(), + } + } + + /// + pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let static_secp = static_secp_instance(); + let static_secp = static_secp.lock(); + Option::::deserialize(deserializer).and_then(|res| match res { + Some(string) => from_hex(string.to_string()) + .map_err(|err| Error::custom(err.to_string())) + .and_then(|bytes: Vec| { + let mut b = [0u8; 32]; + b.copy_from_slice(&bytes[0..32]); + secp::key::SecretKey::from_slice(&static_secp, &b) + .map(|val| Some(val)) + .map_err(|err| Error::custom(err.to_string())) + }), + None => Ok(None), + }) + } +} + /// Serializes a secp::Signature to and from hex pub mod sig_serde { use crate::serde::{Deserialize, Deserializer, Serializer}; @@ -286,6 +328,8 @@ mod test { #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] struct SerTest { + #[serde(with = "option_seckey_serde")] + pub opt_skey: Option, #[serde(with = "pubkey_serde")] pub pub_key: PublicKey, #[serde(with = "option_sig_serde")] @@ -308,6 +352,7 @@ mod test { let msg = Message::from_slice(&msg).unwrap(); let sig = aggsig::sign_single(&secp, &msg, &sk, None, None).unwrap(); SerTest { + opt_skey: Some(sk.clone()), pub_key: PublicKey::from_secret_key(&secp, &sk).unwrap(), opt_sig: Some(sig.clone()), sig: sig.clone(), diff --git a/keychain/src/keychain.rs b/keychain/src/keychain.rs index 91bf5ed3cb..d6d52e49ea 100644 --- a/keychain/src/keychain.rs +++ b/keychain/src/keychain.rs @@ -69,6 +69,13 @@ impl Keychain for ExtKeychain { Ok(keychain) } + fn mask_master_key(&mut self, mask: &SecretKey) -> Result<(), Error> { + for i in 0..secp::constants::SECRET_KEY_SIZE { + self.master.secret_key.0[i] ^= mask.0[i]; + } + Ok(()) + } + /// For testing - probably not a good idea to use outside of tests. fn from_random_seed(is_floo: bool) -> Result { let seed: String = thread_rng().sample_iter(&Alphanumeric).take(16).collect(); diff --git a/keychain/src/types.rs b/keychain/src/types.rs index d29839da86..fe9e9602df 100644 --- a/keychain/src/types.rs +++ b/keychain/src/types.rs @@ -467,6 +467,9 @@ pub trait Keychain: Sync + Send + Clone { /// Generates a keychain from a randomly generated seed. Mostly used for tests. fn from_random_seed(is_floo: bool) -> Result; + /// XOR masks the keychain's master key against another key + fn mask_master_key(&mut self, mask: &SecretKey) -> Result<(), Error>; + /// Root identifier for that keychain fn root_key_id() -> Identifier;