Adding serialization and docs (#6)

This commit is contained in:
Kevin Lewi
2021-09-15 17:49:31 -07:00
committed by GitHub
parent 671d1180a2
commit fa2d8ec191
8 changed files with 1120 additions and 907 deletions
+175 -1
View File
@@ -3,8 +3,182 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
use crate::errors::InternalError;
//! Handles the serialization of each of the components used
//! in the VOPRF protocol
use crate::{
ciphersuite::CipherSuite,
errors::InternalError,
group::Group,
voprf::{
BlindedElement, EvaluationElement, NonVerifiableClient, NonVerifiableServer, Proof,
VerifiableClient, VerifiableServer,
},
};
use alloc::vec::Vec;
use generic_array::{typenum::Unsigned, GenericArray};
//////////////////////////////////////////////////////////
// Serialization and Deserialization for High-Level API //
// ==================================================== //
//////////////////////////////////////////////////////////
impl<CS: CipherSuite> NonVerifiableClient<CS> {
/// Serialization into bytes
pub fn serialize(&self) -> Vec<u8> {
[
CS::Group::scalar_as_bytes(self.blind).to_vec(),
self.data.clone(),
]
.concat()
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
let scalar_len = <CS::Group as Group>::ScalarLen::USIZE;
if input.len() < scalar_len {
return Err(InternalError::SizeError);
}
let blind = CS::Group::from_scalar_slice(GenericArray::from_slice(&input[..scalar_len]))?;
let data = input[scalar_len..].to_vec();
Ok(Self { blind, data })
}
}
impl<CS: CipherSuite> VerifiableClient<CS> {
/// Serialization into bytes
pub fn serialize(&self) -> Vec<u8> {
[
CS::Group::scalar_as_bytes(self.blind).to_vec(),
self.blinded_element.to_arr().to_vec(),
self.data.clone(),
]
.concat()
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
let scalar_len = <CS::Group as Group>::ScalarLen::USIZE;
let elem_len = <CS::Group as Group>::ElemLen::USIZE;
if input.len() < scalar_len + elem_len {
return Err(InternalError::SizeError);
}
let blind = CS::Group::from_scalar_slice(GenericArray::from_slice(&input[..scalar_len]))?;
let blinded_element = CS::Group::from_element_slice(GenericArray::from_slice(
&input[scalar_len..scalar_len + elem_len],
))?;
let data = input[scalar_len + elem_len..].to_vec();
Ok(Self {
blind,
blinded_element,
data,
})
}
}
impl<CS: CipherSuite> NonVerifiableServer<CS> {
/// Serialization into bytes
pub fn serialize(&self) -> Vec<u8> {
CS::Group::scalar_as_bytes(self.sk).to_vec()
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
let scalar_len = <CS::Group as Group>::ScalarLen::USIZE;
if input.len() != scalar_len {
return Err(InternalError::SizeError);
}
let sk = CS::Group::from_scalar_slice(GenericArray::from_slice(input))?;
Ok(Self { sk })
}
}
impl<CS: CipherSuite> VerifiableServer<CS> {
/// Serialization into bytes
pub fn serialize(&self) -> Vec<u8> {
[
CS::Group::scalar_as_bytes(self.sk).to_vec(),
self.pk.to_arr().to_vec(),
]
.concat()
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
let scalar_len = <CS::Group as Group>::ScalarLen::USIZE;
let elem_len = <CS::Group as Group>::ElemLen::USIZE;
if input.len() != scalar_len + elem_len {
return Err(InternalError::SizeError);
}
let sk = CS::Group::from_scalar_slice(GenericArray::from_slice(&input[..scalar_len]))?;
let pk = CS::Group::from_element_slice(GenericArray::from_slice(&input[scalar_len..]))?;
Ok(Self { sk, pk })
}
}
impl<CS: CipherSuite> Proof<CS> {
/// Serialization into bytes
pub fn serialize(&self) -> Vec<u8> {
[
CS::Group::scalar_as_bytes(self.c_scalar),
CS::Group::scalar_as_bytes(self.s_scalar),
]
.concat()
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
let scalar_len = <CS::Group as Group>::ScalarLen::USIZE;
if input.len() < scalar_len + scalar_len {
return Err(InternalError::SizeError);
}
Ok(Proof {
c_scalar: CS::Group::from_scalar_slice(GenericArray::from_slice(&input[..scalar_len]))?,
s_scalar: CS::Group::from_scalar_slice(GenericArray::from_slice(&input[scalar_len..]))?,
})
}
}
impl<CS: CipherSuite> BlindedElement<CS> {
/// Serialization into bytes
pub fn serialize(&self) -> Vec<u8> {
self.0.to_arr().to_vec()
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
Ok(Self(CS::Group::from_element_slice(
GenericArray::from_slice(input),
)?))
}
}
impl<CS: CipherSuite> EvaluationElement<CS> {
/// Serialization into bytes
pub fn serialize(&self) -> Vec<u8> {
self.0.to_arr().to_vec()
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
Ok(Self(CS::Group::from_element_slice(
GenericArray::from_slice(input),
)?))
}
}
//////////////////////
// Helper Functions //
// ================ //
//////////////////////
// Corresponds to the I2OSP() function from RFC8017
pub(crate) fn i2osp(input: usize, length: usize) -> Result<alloc::vec::Vec<u8>, InternalError> {