Skip to content

Commit

Permalink
fix serde / no_std incompatibility
Browse files Browse the repository at this point in the history
as an alternative to dalek-cryptography#288 this updates serde `Serialize` and `Deserialize` implementations to use a
custom visitor, removing the need for `alloc` or `std` for embedded use, and making this
consistent with implementations in
[curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek/blob/a63e14f4ded078d6bf262ba0b3f47026bdd7f7c0/src/edwards.rs#L269).

@pinkforest seems like it'd be good to have some serde tests / this should go over dalek-cryptography#289?

Co-Authored-By: Vlad Semenov <[email protected]>
  • Loading branch information
ryankurte and semenov-vladyslav committed Mar 20, 2023
1 parent 7dc1bbd commit b40661e
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 26 deletions.
10 changes: 0 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ sha2 = { version = "0.10", default-features = false }
merlin = { version = "3", default-features = false, optional = true }
rand_core = { version = "0.6.4", default-features = false, optional = true }
serde = { version = "1.0", default-features = false, optional = true }
serde_bytes = { version = "0.11", optional = true }
zeroize = { version = "1.5", default-features = false, optional = true }

[dev-dependencies]
Expand Down Expand Up @@ -68,5 +67,5 @@ legacy_compatibility = []
pkcs8 = ["ed25519/pkcs8"]
pem = ["alloc", "ed25519/pem", "pkcs8"]
rand_core = ["dep:rand_core"]
serde = ["dep:serde", "serde_bytes", "ed25519/serde"]
serde = ["dep:serde", "ed25519/serde"]
zeroize = ["dep:zeroize", "curve25519-dalek/zeroize"]
27 changes: 20 additions & 7 deletions src/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,8 @@ use ed25519::pkcs8;
#[cfg(any(test, feature = "rand_core"))]
use rand_core::CryptoRngCore;

#[cfg(feature = "serde")]
use serde::de::Error as SerdeError;
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde")]
use serde_bytes::{ByteBuf as SerdeByteBuf, Bytes as SerdeBytes};

use sha2::Sha512;

Expand Down Expand Up @@ -634,7 +630,7 @@ impl Serialize for SigningKey {
where
S: Serializer,
{
SerdeBytes::new(&self.secret_key).serialize(serializer)
serializer.serialize_bytes(&self.secret_key)
}
}

Expand All @@ -644,11 +640,28 @@ impl<'d> Deserialize<'d> for SigningKey {
where
D: Deserializer<'d>,
{
let bytes = <SerdeByteBuf>::deserialize(deserializer)?;
Self::try_from(bytes.as_ref()).map_err(SerdeError::custom)
struct SigningKeyVisitor;

impl <'de> serde::de::Visitor<'de> for SigningKeyVisitor {
type Value = SigningKey;

fn expecting(&self, formatter: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
write!(
formatter,
concat!("An ed25519 signing (private) key")
)
}

fn visit_borrowed_bytes<E: serde::de::Error>(self, bytes: &'de [u8]) -> Result<Self::Value, E> {
SigningKey::try_from(bytes.as_ref()).map_err(E::custom)
}
}

deserializer.deserialize_bytes(SigningKeyVisitor)
}
}


/// An "expanded" secret key.
///
/// This is produced by using an hash function with 512-bits output to digest a
Expand Down
26 changes: 19 additions & 7 deletions src/verifying.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,8 @@ use sha2::Sha512;
#[cfg(feature = "pkcs8")]
use ed25519::pkcs8;

#[cfg(feature = "serde")]
use serde::de::Error as SerdeError;
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde")]
use serde_bytes::{ByteBuf as SerdeByteBuf, Bytes as SerdeBytes};

#[cfg(feature = "digest")]
use crate::context::Context;
Expand Down Expand Up @@ -542,7 +538,7 @@ impl Serialize for VerifyingKey {
where
S: Serializer,
{
SerdeBytes::new(self.as_bytes()).serialize(serializer)
serializer.serialize_bytes(&self.as_bytes()[..])
}
}

Expand All @@ -552,7 +548,23 @@ impl<'d> Deserialize<'d> for VerifyingKey {
where
D: Deserializer<'d>,
{
let bytes = <SerdeByteBuf>::deserialize(deserializer)?;
VerifyingKey::try_from(bytes.as_ref()).map_err(SerdeError::custom)
struct VerifyingKeyVisitor;

impl <'de> serde::de::Visitor<'de> for VerifyingKeyVisitor {
type Value = VerifyingKey;

fn expecting(&self, formatter: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
write!(
formatter,
concat!("An ed25519 verifying (public) key")
)
}

fn visit_borrowed_bytes<E: serde::de::Error>(self, bytes: &'de [u8]) -> Result<Self::Value, E> {
VerifyingKey::try_from(bytes.as_ref()).map_err(E::custom)
}
}

deserializer.deserialize_bytes(VerifyingKeyVisitor)
}
}

0 comments on commit b40661e

Please sign in to comment.