diff --git a/src/serde_impl.rs b/src/serde_impl.rs index 34fcc55..8fdad40 100644 --- a/src/serde_impl.rs +++ b/src/serde_impl.rs @@ -3,6 +3,7 @@ pub use self::field_vec::FieldWrap; use std::borrow::Cow; +use std::ops::Deref; use crate::G1; use serde::de::Error as DeserializeError; @@ -10,9 +11,63 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_derive::{Deserialize, Serialize}; use crate::poly::{coeff_pos, BivarCommitment}; +use crate::serde_impl::serialize_secret_internal::SerializeSecret; const ERR_DEG: &str = "commitment degree does not match coefficients"; +pub(crate) mod serialize_secret_internal { + use serde::Serializer; + + /// To avoid deriving [`Serialize`] automatically for structs containing secret keys this trait + /// should be implemented instead. It only enables explicit serialization through + /// [`::serde_impls::SerdeSecret`]. + pub trait SerializeSecret { + fn serialize_secret(&self, serializer: S) -> Result; + } +} + +/// `SerdeSecret` is a wrapper struct for serializing and deserializing secret keys. Due to security +/// concerns serialize shouldn't be implemented for secret keys to avoid accidental leakage. +/// +/// Whenever this struct is used the integrity of security boundaries should be checked carefully. +pub struct SerdeSecret(T); + +impl Deref for SerdeSecret { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.inner() + } +} + +impl SerdeSecret { + /// Returns the actual secret from the wrapper + pub fn into_inner(self) -> T { + self.0 + } + + /// Returns a reference to the actual secret contained in the wrapper + pub fn inner(&self) -> &T { + &self.0 + } +} + +impl<'de, T: Deserialize<'de>> Deserialize<'de> for SerdeSecret { + fn deserialize(deserializer: D) -> Result where + D: Deserializer<'de> + { + Ok(SerdeSecret(Deserialize::deserialize(deserializer)?)) + } +} + +impl<'de, T: SerializeSecret> Serialize for SerdeSecret { + fn serialize(&self, serializer: S) -> Result where + S: Serializer + { + self.0.serialize_secret(serializer) + } +} + /// A type with the same content as `BivarCommitment`, but that has not been validated yet. #[derive(Serialize, Deserialize)] struct WireBivarCommitment<'a> {