Use "tuples" instead of "bytes" in the Serde datamodel.

This is a breaking change to the serialization format.  It fixes it so that the
Serde encoding can match the conventional encoding of each type of object, and
so that Serde can be used with no overhead -- when using serde-bincode, the
Serde encoding now matches the manual encoding.
This commit is contained in:
Henry de Valence 2019-10-23 14:49:55 -07:00
parent 29ce0d4fe9
commit 0fc534d989
4 changed files with 79 additions and 65 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "curve25519-dalek" name = "curve25519-dalek"
version = "1.2.3" version = "2.0.0-alpha.0"
authors = ["Isis Lovecruft <isis@patternsinthevoid.net>", authors = ["Isis Lovecruft <isis@patternsinthevoid.net>",
"Henry de Valence <hdevalence@hdevalence.ca>"] "Henry de Valence <hdevalence@hdevalence.ca>"]
readme = "README.md" readme = "README.md"

View file

@ -217,7 +217,12 @@ impl Serialize for EdwardsPoint {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer where S: Serializer
{ {
serializer.serialize_bytes(self.compress().as_bytes()) use serde::ser::SerializeTuple;
let mut tup = serializer.serialize_tuple(32)?;
for byte in self.compress().as_bytes().iter() {
tup.serialize_element(byte)?;
}
tup.end()
} }
} }
@ -226,7 +231,12 @@ impl Serialize for CompressedEdwardsY {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer where S: Serializer
{ {
serializer.serialize_bytes(self.as_bytes()) use serde::ser::SerializeTuple;
let mut tup = serializer.serialize_tuple(32)?;
for byte in self.as_bytes().iter() {
tup.serialize_element(byte)?;
}
tup.end()
} }
} }
@ -244,22 +254,21 @@ impl<'de> Deserialize<'de> for EdwardsPoint {
formatter.write_str("a valid point in Edwards y + sign format") formatter.write_str("a valid point in Edwards y + sign format")
} }
fn visit_bytes<E>(self, v: &[u8]) -> Result<EdwardsPoint, E> fn visit_seq<A>(self, mut seq: A) -> Result<EdwardsPoint, A::Error>
where E: serde::de::Error where A: serde::de::SeqAccess<'de>
{ {
if v.len() == 32 { let mut bytes = [0u8; 32];
let mut arr32 = [0u8; 32]; for i in 0..32 {
arr32[0..32].copy_from_slice(v); bytes[i] = seq.next_element()?
CompressedEdwardsY(arr32) .ok_or(serde::de::Error::invalid_length(i, &"expected 32 bytes"))?;
.decompress()
.ok_or(serde::de::Error::custom("decompression failed"))
} else {
Err(serde::de::Error::invalid_length(v.len(), &self))
} }
CompressedEdwardsY(bytes)
.decompress()
.ok_or(serde::de::Error::custom("decompression failed"))
} }
} }
deserializer.deserialize_bytes(EdwardsPointVisitor) deserializer.deserialize_tuple(32, EdwardsPointVisitor)
} }
} }
@ -277,20 +286,19 @@ impl<'de> Deserialize<'de> for CompressedEdwardsY {
formatter.write_str("32 bytes of data") formatter.write_str("32 bytes of data")
} }
fn visit_bytes<E>(self, v: &[u8]) -> Result<CompressedEdwardsY, E> fn visit_seq<A>(self, mut seq: A) -> Result<CompressedEdwardsY, A::Error>
where E: serde::de::Error where A: serde::de::SeqAccess<'de>
{ {
if v.len() == 32 { let mut bytes = [0u8; 32];
let mut arr32 = [0u8; 32]; for i in 0..32 {
arr32[0..32].copy_from_slice(v); bytes[i] = seq.next_element()?
Ok(CompressedEdwardsY(arr32)) .ok_or(serde::de::Error::invalid_length(i, &"expected 32 bytes"))?;
} else {
Err(serde::de::Error::invalid_length(v.len(), &self))
} }
Ok(CompressedEdwardsY(bytes))
} }
} }
deserializer.deserialize_bytes(CompressedEdwardsYVisitor) deserializer.deserialize_tuple(32, CompressedEdwardsYVisitor)
} }
} }

View file

@ -334,7 +334,12 @@ impl Serialize for RistrettoPoint {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer where S: Serializer
{ {
serializer.serialize_bytes(self.compress().as_bytes()) use serde::ser::SerializeTuple;
let mut tup = serializer.serialize_tuple(32)?;
for byte in self.compress().as_bytes().iter() {
tup.serialize_element(byte)?;
}
tup.end()
} }
} }
@ -343,7 +348,12 @@ impl Serialize for CompressedRistretto {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer where S: Serializer
{ {
serializer.serialize_bytes(self.as_bytes()) use serde::ser::SerializeTuple;
let mut tup = serializer.serialize_tuple(32)?;
for byte in self.as_bytes().iter() {
tup.serialize_element(byte)?;
}
tup.end()
} }
} }
@ -361,22 +371,21 @@ impl<'de> Deserialize<'de> for RistrettoPoint {
formatter.write_str("a valid point in Ristretto format") formatter.write_str("a valid point in Ristretto format")
} }
fn visit_bytes<E>(self, v: &[u8]) -> Result<RistrettoPoint, E> fn visit_seq<A>(self, mut seq: A) -> Result<RistrettoPoint, A::Error>
where E: serde::de::Error where A: serde::de::SeqAccess<'de>
{ {
if v.len() == 32 { let mut bytes = [0u8; 32];
let mut arr32 = [0u8; 32]; for i in 0..32 {
arr32[0..32].copy_from_slice(v); bytes[i] = seq.next_element()?
CompressedRistretto(arr32) .ok_or(serde::de::Error::invalid_length(i, &"expected 32 bytes"))?;
.decompress()
.ok_or(serde::de::Error::custom("decompression failed"))
} else {
Err(serde::de::Error::invalid_length(v.len(), &self))
} }
CompressedRistretto(bytes)
.decompress()
.ok_or(serde::de::Error::custom("decompression failed"))
} }
} }
deserializer.deserialize_bytes(RistrettoPointVisitor) deserializer.deserialize_tuple(32, RistrettoPointVisitor)
} }
} }
@ -394,20 +403,19 @@ impl<'de> Deserialize<'de> for CompressedRistretto {
formatter.write_str("32 bytes of data") formatter.write_str("32 bytes of data")
} }
fn visit_bytes<E>(self, v: &[u8]) -> Result<CompressedRistretto, E> fn visit_seq<A>(self, mut seq: A) -> Result<CompressedRistretto, A::Error>
where E: serde::de::Error where A: serde::de::SeqAccess<'de>
{ {
if v.len() == 32 { let mut bytes = [0u8; 32];
let mut arr32 = [0u8; 32]; for i in 0..32 {
arr32[0..32].copy_from_slice(v); bytes[i] = seq.next_element()?
Ok(CompressedRistretto(arr32)) .ok_or(serde::de::Error::invalid_length(i, &"expected 32 bytes"))?;
} else {
Err(serde::de::Error::invalid_length(v.len(), &self))
} }
Ok(CompressedRistretto(bytes))
} }
} }
deserializer.deserialize_bytes(CompressedRistrettoVisitor) deserializer.deserialize_tuple(32, CompressedRistrettoVisitor)
} }
} }

View file

@ -385,7 +385,12 @@ impl Serialize for Scalar {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer where S: Serializer
{ {
serializer.serialize_bytes(self.reduce().as_bytes()) use serde::ser::SerializeTuple;
let mut tup = serializer.serialize_tuple(32)?;
for byte in self.as_bytes().iter() {
tup.serialize_element(byte)?;
}
tup.end()
} }
} }
@ -400,32 +405,25 @@ impl<'de> Deserialize<'de> for Scalar {
type Value = Scalar; type Value = Scalar;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
formatter.write_str("a canonically-encoded 32-byte scalar value") formatter.write_str("a valid point in Edwards y + sign format")
} }
fn visit_bytes<E>(self, v: &[u8]) -> Result<Scalar, E> fn visit_seq<A>(self, mut seq: A) -> Result<Scalar, A::Error>
where E: serde::de::Error where A: serde::de::SeqAccess<'de>
{ {
if v.len() == 32 { let mut bytes = [0u8; 32];
let mut bytes = [0u8;32]; for i in 0..32 {
bytes.copy_from_slice(v); bytes[i] = seq.next_element()?
.ok_or(serde::de::Error::invalid_length(i, &"expected 32 bytes"))?;
static ERRMSG: &'static str = "encoding was not canonical";
Scalar::from_canonical_bytes(bytes)
.ok_or(
serde::de::Error::invalid_value(
serde::de::Unexpected::Bytes(v),
&ERRMSG,
)
)
} else {
Err(serde::de::Error::invalid_length(v.len(), &self))
} }
Scalar::from_canonical_bytes(bytes)
.ok_or(serde::de::Error::custom(
&"scalar was not canonically encoded"
))
} }
} }
deserializer.deserialize_bytes(ScalarVisitor) deserializer.deserialize_tuple(32, ScalarVisitor)
} }
} }