Remove custom Serde implementation (#44)
* Serialize `BlindedElement` as `GenericArray` * Don't hold input * Remove allocations from `VerifiableClient::batch_finalize` * Remove all allocation from serialization * Remove required `alloc` support. * Fix accidental usage of 1.57 API * Let `VerifiableClient::batch_finalize` return a concrete type * Simplify de-serialization * Remove custom Serde implementation
This commit is contained in:
+58
-134
@@ -8,14 +8,17 @@
|
||||
//! Handles the serialization of each of the components used in the VOPRF
|
||||
//! protocol
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::marker::PhantomData;
|
||||
use core::ops::Add;
|
||||
|
||||
use digest::{BlockInput, Digest};
|
||||
use generic_array::typenum::Unsigned;
|
||||
use generic_array::sequence::Concat;
|
||||
use generic_array::typenum::Sum;
|
||||
use generic_array::{ArrayLength, GenericArray};
|
||||
|
||||
use crate::errors::InternalError;
|
||||
use crate::group::Group;
|
||||
use crate::util::deserialize;
|
||||
use crate::voprf::{
|
||||
BlindedElement, EvaluationElement, NonVerifiableClient, NonVerifiableServer, Proof,
|
||||
VerifiableClient, VerifiableServer,
|
||||
@@ -28,23 +31,18 @@ use crate::voprf::{
|
||||
|
||||
impl<G: Group, H: BlockInput + Digest> NonVerifiableClient<G, H> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
[G::scalar_as_bytes(self.blind).as_slice(), &self.data].concat()
|
||||
pub fn serialize(&self) -> GenericArray<u8, G::ScalarLen> {
|
||||
G::scalar_as_bytes(self.blind)
|
||||
}
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
|
||||
let scalar_len = G::ScalarLen::USIZE;
|
||||
if input.len() < scalar_len {
|
||||
return Err(InternalError::SizeError);
|
||||
}
|
||||
let mut input = input.iter().copied();
|
||||
|
||||
let blind = G::from_scalar_slice(&input[..scalar_len])?;
|
||||
let data = input[scalar_len..].to_vec();
|
||||
let blind = G::from_scalar_slice(&deserialize(&mut input)?)?;
|
||||
|
||||
Ok(Self {
|
||||
blind,
|
||||
data,
|
||||
hash: PhantomData,
|
||||
})
|
||||
}
|
||||
@@ -52,31 +50,24 @@ impl<G: Group, H: BlockInput + Digest> NonVerifiableClient<G, H> {
|
||||
|
||||
impl<G: Group, H: BlockInput + Digest> VerifiableClient<G, H> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
[
|
||||
G::scalar_as_bytes(self.blind).as_slice(),
|
||||
&self.blinded_element.to_arr(),
|
||||
&self.data,
|
||||
]
|
||||
.concat()
|
||||
pub fn serialize(&self) -> GenericArray<u8, Sum<G::ScalarLen, G::ElemLen>>
|
||||
where
|
||||
G::ScalarLen: Add<G::ElemLen>,
|
||||
Sum<G::ScalarLen, G::ElemLen>: ArrayLength<u8>,
|
||||
{
|
||||
G::scalar_as_bytes(self.blind).concat(self.blinded_element.to_arr())
|
||||
}
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
|
||||
let scalar_len = G::ScalarLen::USIZE;
|
||||
let elem_len = G::ElemLen::USIZE;
|
||||
if input.len() < scalar_len + elem_len {
|
||||
return Err(InternalError::SizeError);
|
||||
}
|
||||
let mut input = input.iter().copied();
|
||||
|
||||
let blind = G::from_scalar_slice(&input[..scalar_len])?;
|
||||
let blinded_element = G::from_element_slice(&input[scalar_len..scalar_len + elem_len])?;
|
||||
let data = input[scalar_len + elem_len..].to_vec();
|
||||
let blind = G::from_scalar_slice(&deserialize(&mut input)?)?;
|
||||
let blinded_element = G::from_element_slice(&deserialize(&mut input)?)?;
|
||||
|
||||
Ok(Self {
|
||||
blind,
|
||||
blinded_element,
|
||||
data,
|
||||
hash: PhantomData,
|
||||
})
|
||||
}
|
||||
@@ -84,18 +75,15 @@ impl<G: Group, H: BlockInput + Digest> VerifiableClient<G, H> {
|
||||
|
||||
impl<G: Group, H: BlockInput + Digest> NonVerifiableServer<G, H> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
G::scalar_as_bytes(self.sk).to_vec()
|
||||
pub fn serialize(&self) -> GenericArray<u8, G::ScalarLen> {
|
||||
G::scalar_as_bytes(self.sk)
|
||||
}
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
|
||||
let scalar_len = G::ScalarLen::USIZE;
|
||||
if input.len() != scalar_len {
|
||||
return Err(InternalError::SizeError);
|
||||
}
|
||||
let mut input = input.iter().copied();
|
||||
|
||||
let sk = G::from_scalar_slice(input)?;
|
||||
let sk = G::from_scalar_slice(&deserialize(&mut input)?)?;
|
||||
|
||||
Ok(Self {
|
||||
sk,
|
||||
@@ -106,20 +94,20 @@ impl<G: Group, H: BlockInput + Digest> NonVerifiableServer<G, H> {
|
||||
|
||||
impl<G: Group, H: BlockInput + Digest> VerifiableServer<G, H> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
[G::scalar_as_bytes(self.sk).as_slice(), &self.pk.to_arr()].concat()
|
||||
pub fn serialize(&self) -> GenericArray<u8, Sum<G::ScalarLen, G::ElemLen>>
|
||||
where
|
||||
G::ScalarLen: Add<G::ElemLen>,
|
||||
Sum<G::ScalarLen, G::ElemLen>: ArrayLength<u8>,
|
||||
{
|
||||
G::scalar_as_bytes(self.sk).concat(self.pk.to_arr())
|
||||
}
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
|
||||
let scalar_len = G::ScalarLen::USIZE;
|
||||
let elem_len = G::ElemLen::USIZE;
|
||||
if input.len() != scalar_len + elem_len {
|
||||
return Err(InternalError::SizeError);
|
||||
}
|
||||
let mut input = input.iter().copied();
|
||||
|
||||
let sk = G::from_scalar_slice(&input[..scalar_len])?;
|
||||
let pk = G::from_element_slice(&input[scalar_len..])?;
|
||||
let sk = G::from_scalar_slice(&deserialize(&mut input)?)?;
|
||||
let pk = G::from_element_slice(&deserialize(&mut input)?)?;
|
||||
|
||||
Ok(Self {
|
||||
sk,
|
||||
@@ -131,23 +119,24 @@ impl<G: Group, H: BlockInput + Digest> VerifiableServer<G, H> {
|
||||
|
||||
impl<G: Group, H: BlockInput + Digest> Proof<G, H> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
[
|
||||
G::scalar_as_bytes(self.c_scalar),
|
||||
G::scalar_as_bytes(self.s_scalar),
|
||||
]
|
||||
.concat()
|
||||
pub fn serialize(&self) -> GenericArray<u8, Sum<G::ScalarLen, G::ScalarLen>>
|
||||
where
|
||||
G::ScalarLen: Add<G::ScalarLen>,
|
||||
Sum<G::ScalarLen, G::ScalarLen>: ArrayLength<u8>,
|
||||
{
|
||||
G::scalar_as_bytes(self.c_scalar).concat(G::scalar_as_bytes(self.s_scalar))
|
||||
}
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
|
||||
let scalar_len = G::ScalarLen::USIZE;
|
||||
if input.len() != scalar_len + scalar_len {
|
||||
return Err(InternalError::SizeError);
|
||||
}
|
||||
let mut input = input.iter().copied();
|
||||
|
||||
let c_scalar = G::from_scalar_slice(&deserialize(&mut input)?)?;
|
||||
let s_scalar = G::from_scalar_slice(&deserialize(&mut input)?)?;
|
||||
|
||||
Ok(Proof {
|
||||
c_scalar: G::from_scalar_slice(&input[..scalar_len])?,
|
||||
s_scalar: G::from_scalar_slice(&input[scalar_len..])?,
|
||||
c_scalar,
|
||||
s_scalar,
|
||||
hash: PhantomData,
|
||||
})
|
||||
}
|
||||
@@ -155,18 +144,18 @@ impl<G: Group, H: BlockInput + Digest> Proof<G, H> {
|
||||
|
||||
impl<G: Group, H: BlockInput + Digest> BlindedElement<G, H> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
self.value.to_arr().to_vec()
|
||||
pub fn serialize(&self) -> GenericArray<u8, G::ElemLen> {
|
||||
self.value.to_arr()
|
||||
}
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
|
||||
let elem_len = G::ElemLen::USIZE;
|
||||
if input.len() != elem_len {
|
||||
return Err(InternalError::SizeError);
|
||||
}
|
||||
let mut input = input.iter().copied();
|
||||
|
||||
let value = G::from_element_slice(&deserialize(&mut input)?)?;
|
||||
|
||||
Ok(Self {
|
||||
value: G::from_element_slice(input)?,
|
||||
value,
|
||||
hash: PhantomData,
|
||||
})
|
||||
}
|
||||
@@ -174,84 +163,19 @@ impl<G: Group, H: BlockInput + Digest> BlindedElement<G, H> {
|
||||
|
||||
impl<G: Group, H: BlockInput + Digest> EvaluationElement<G, H> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
self.value.to_arr().to_vec()
|
||||
pub fn serialize(&self) -> GenericArray<u8, G::ElemLen> {
|
||||
self.value.to_arr()
|
||||
}
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
|
||||
let elem_len = G::ElemLen::USIZE;
|
||||
if input.len() != elem_len {
|
||||
return Err(InternalError::SizeError);
|
||||
}
|
||||
let mut input = input.iter().copied();
|
||||
|
||||
let value = G::from_element_slice(&deserialize(&mut input)?)?;
|
||||
|
||||
Ok(Self {
|
||||
value: G::from_element_slice(input)?,
|
||||
value,
|
||||
hash: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Serde implementation for High-Level API //
|
||||
// ======================================= //
|
||||
/////////////////////////////////////////////
|
||||
|
||||
/// Macro used for deriving `serde`'s `Serialize` and `Deserialize` traits.
|
||||
macro_rules! impl_serialize_and_deserialize_for {
|
||||
($item:ident) => {
|
||||
#[cfg(feature = "serde")]
|
||||
impl<G: Group, H: BlockInput + Digest> serde::Serialize for $item<G, H> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_bytes(&self.serialize())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de, G: Group, H: BlockInput + Digest> serde::Deserialize<'de> for $item<G, H> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
use serde::de::Error;
|
||||
|
||||
struct ByteVisitor<G: Group, H: BlockInput + Digest>(core::marker::PhantomData<(G, H)>);
|
||||
|
||||
impl<'de, G: Group, H: BlockInput + Digest> serde::de::Visitor<'de> for ByteVisitor<G, H> {
|
||||
type Value = $item<G, H>;
|
||||
|
||||
fn expecting(
|
||||
&self,
|
||||
formatter: &mut core::fmt::Formatter,
|
||||
) -> core::fmt::Result {
|
||||
formatter.write_str(core::concat!(
|
||||
"the byte representation of a ",
|
||||
core::stringify!($item)
|
||||
))
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
$item::<G, H>::deserialize(value).map_err(|_| {
|
||||
Error::invalid_value(
|
||||
serde::de::Unexpected::Bytes(value),
|
||||
&core::concat!(
|
||||
"invalid byte sequence for ",
|
||||
core::stringify!($item)
|
||||
),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
deserializer
|
||||
.deserialize_bytes(ByteVisitor::<G, H>(core::marker::PhantomData))
|
||||
.map_err(Error::custom)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user