Files
voprf-vx/src/serialization.rs
T

375 lines
12 KiB
Rust
Raw Normal View History

2021-09-09 01:56:54 -07:00
// Copyright (c) Facebook, Inc. and its affiliates.
//
2021-09-27 18:53:06 -07:00
// This source code is licensed under both the MIT license found in the
// LICENSE-MIT file in the root directory of this source tree and the Apache
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
// of this source tree.
2021-09-09 01:56:54 -07:00
2021-12-23 01:17:03 +01:00
//! Handles the serialization of each of the components used in the VOPRF
//! protocol
2021-09-15 17:49:31 -07:00
2021-12-23 21:03:38 +01:00
use core::ops::Add;
2021-12-23 01:17:03 +01:00
2021-12-23 21:58:00 +01:00
use digest::core_api::BlockSizeUser;
2022-01-21 22:52:09 +01:00
use digest::OutputSizeUser;
2021-12-23 21:03:38 +01:00
use generic_array::sequence::Concat;
2022-01-28 01:38:17 +01:00
use generic_array::typenum::{IsLess, IsLessOrEqual, Sum, Unsigned, U256};
2021-12-23 21:03:38 +01:00
use generic_array::{ArrayLength, GenericArray};
2021-09-15 17:49:31 -07:00
2021-12-25 22:54:27 +01:00
use crate::{
2022-02-13 04:00:11 -08:00
BlindedElement, CipherSuite, Error, EvaluationElement, Group, OprfClient, OprfServer,
PoprfClient, PoprfServer, Proof, Result, VoprfClient, VoprfServer,
2021-12-23 01:17:03 +01:00
};
2021-09-15 17:49:31 -07:00
//////////////////////////////////////////////////////////
// Serialization and Deserialization for High-Level API //
// ==================================================== //
//////////////////////////////////////////////////////////
2022-02-13 04:00:11 -08:00
/// Length of [`OprfClient`] in bytes for serialization.
pub type OprfClientLen<CS> = <<CS as CipherSuite>::Group as Group>::ScalarLen;
2022-01-21 22:52:09 +01:00
2022-02-13 04:00:11 -08:00
impl<CS: CipherSuite> OprfClient<CS>
2022-01-21 22:52:09 +01:00
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
2021-09-15 17:49:31 -07:00
/// Serialization into bytes
2022-02-13 04:00:11 -08:00
pub fn serialize(&self) -> GenericArray<u8, OprfClientLen<CS>> {
2022-01-21 22:52:09 +01:00
CS::Group::serialize_scalar(self.blind)
2021-09-15 17:49:31 -07:00
}
/// Deserialization from bytes
2022-01-25 05:55:02 +01:00
///
/// # Errors
/// [`Error::Deserialization`] if failed to deserialize `input`.
2021-12-25 22:54:27 +01:00
pub fn deserialize(input: &[u8]) -> Result<Self> {
2021-12-23 21:03:38 +01:00
let mut input = input.iter().copied();
2021-09-15 17:49:31 -07:00
2022-01-28 01:38:17 +01:00
let blind = deserialize_scalar::<CS::Group, _>(&mut input)?;
2021-09-15 17:49:31 -07:00
2022-01-21 22:52:09 +01:00
Ok(Self { blind })
2021-09-15 17:49:31 -07:00
}
}
2022-02-13 04:00:11 -08:00
/// Length of [`VoprfClient`] in bytes for serialization.
pub type VoprfClientLen<CS> = Sum<
2022-01-21 22:52:09 +01:00
<<CS as CipherSuite>::Group as Group>::ScalarLen,
<<CS as CipherSuite>::Group as Group>::ElemLen,
>;
2022-02-13 04:00:11 -08:00
impl<CS: CipherSuite> VoprfClient<CS>
2022-01-21 22:52:09 +01:00
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
2021-09-15 17:49:31 -07:00
/// Serialization into bytes
2022-02-13 04:00:11 -08:00
pub fn serialize(&self) -> GenericArray<u8, VoprfClientLen<CS>>
2021-12-23 21:03:38 +01:00
where
2022-01-21 22:52:09 +01:00
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
2022-02-13 04:00:11 -08:00
VoprfClientLen<CS>: ArrayLength<u8>,
2021-12-23 21:03:38 +01:00
{
2022-01-21 22:52:09 +01:00
<CS::Group as Group>::serialize_scalar(self.blind)
.concat(<CS::Group as Group>::serialize_elem(self.blinded_element))
2021-09-15 17:49:31 -07:00
}
/// Deserialization from bytes
2022-01-25 05:55:02 +01:00
///
/// # Errors
/// [`Error::Deserialization`] if failed to deserialize `input`.
2021-12-25 22:54:27 +01:00
pub fn deserialize(input: &[u8]) -> Result<Self> {
2021-12-23 21:03:38 +01:00
let mut input = input.iter().copied();
2021-09-15 17:49:31 -07:00
2022-01-28 01:38:17 +01:00
let blind = deserialize_scalar::<CS::Group, _>(&mut input)?;
let blinded_element = deserialize_elem::<CS::Group, _>(&mut input)?;
2021-09-15 17:49:31 -07:00
Ok(Self {
blind,
blinded_element,
})
}
}
2022-02-13 04:00:11 -08:00
/// Length of [`PoprfClient`] in bytes for serialization.
pub type PoprfClientLen<CS> = Sum<
<<CS as CipherSuite>::Group as Group>::ScalarLen,
<<CS as CipherSuite>::Group as Group>::ElemLen,
>;
impl<CS: CipherSuite> PoprfClient<CS>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
/// Serialization into bytes
pub fn serialize(&self) -> GenericArray<u8, PoprfClientLen<CS>>
where
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
PoprfClientLen<CS>: ArrayLength<u8>,
{
<CS::Group as Group>::serialize_scalar(self.blind)
.concat(<CS::Group as Group>::serialize_elem(self.blinded_element))
}
/// Deserialization from bytes
///
/// # Errors
/// [`Error::Deserialization`] if failed to deserialize `input`.
pub fn deserialize(input: &[u8]) -> Result<Self> {
let mut input = input.iter().copied();
let blind = deserialize_scalar::<CS::Group, _>(&mut input)?;
let blinded_element = deserialize_elem::<CS::Group, _>(&mut input)?;
Ok(Self {
blind,
blinded_element,
})
}
}
2022-01-21 22:52:09 +01:00
2022-02-13 04:00:11 -08:00
/// Length of [`OprfServer`] in bytes for serialization.
pub type OprfServerLen<CS> = <<CS as CipherSuite>::Group as Group>::ScalarLen;
impl<CS: CipherSuite> OprfServer<CS>
2022-01-21 22:52:09 +01:00
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
2021-09-15 17:49:31 -07:00
/// Serialization into bytes
2022-02-13 04:00:11 -08:00
pub fn serialize(&self) -> GenericArray<u8, OprfServerLen<CS>> {
2022-01-21 22:52:09 +01:00
CS::Group::serialize_scalar(self.sk)
2021-09-15 17:49:31 -07:00
}
/// Deserialization from bytes
2022-01-25 05:55:02 +01:00
///
/// # Errors
/// [`Error::Deserialization`] if failed to deserialize `input`.
2021-12-25 22:54:27 +01:00
pub fn deserialize(input: &[u8]) -> Result<Self> {
2021-12-23 21:03:38 +01:00
let mut input = input.iter().copied();
2021-09-15 17:49:31 -07:00
2022-01-28 01:38:17 +01:00
let sk = deserialize_scalar::<CS::Group, _>(&mut input)?;
2021-09-15 17:49:31 -07:00
2022-01-21 22:52:09 +01:00
Ok(Self { sk })
2021-09-15 17:49:31 -07:00
}
}
2022-02-13 04:00:11 -08:00
/// Length of [`VoprfServer`] in bytes for serialization.
pub type VoprfServerLen<CS> = Sum<
<<CS as CipherSuite>::Group as Group>::ScalarLen,
<<CS as CipherSuite>::Group as Group>::ElemLen,
>;
impl<CS: CipherSuite> VoprfServer<CS>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
/// Serialization into bytes
pub fn serialize(&self) -> GenericArray<u8, VoprfServerLen<CS>>
where
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
VoprfServerLen<CS>: ArrayLength<u8>,
{
CS::Group::serialize_scalar(self.sk).concat(CS::Group::serialize_elem(self.pk))
}
/// Deserialization from bytes
///
/// # Errors
/// [`Error::Deserialization`] if failed to deserialize `input`.
pub fn deserialize(input: &[u8]) -> Result<Self> {
let mut input = input.iter().copied();
let sk = deserialize_scalar::<CS::Group, _>(&mut input)?;
let pk = deserialize_elem::<CS::Group, _>(&mut input)?;
Ok(Self { sk, pk })
}
}
/// Length of [`PoprfServer`] in bytes for serialization.
pub type PoprfServerLen<CS> = Sum<
2022-01-21 22:52:09 +01:00
<<CS as CipherSuite>::Group as Group>::ScalarLen,
<<CS as CipherSuite>::Group as Group>::ElemLen,
>;
2022-02-13 04:00:11 -08:00
impl<CS: CipherSuite> PoprfServer<CS>
2022-01-21 22:52:09 +01:00
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
2021-09-15 17:49:31 -07:00
/// Serialization into bytes
2022-02-13 04:00:11 -08:00
pub fn serialize(&self) -> GenericArray<u8, PoprfServerLen<CS>>
2021-12-23 21:03:38 +01:00
where
2022-01-21 22:52:09 +01:00
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
2022-02-13 04:00:11 -08:00
PoprfServerLen<CS>: ArrayLength<u8>,
2021-12-23 21:03:38 +01:00
{
2022-01-21 22:52:09 +01:00
CS::Group::serialize_scalar(self.sk).concat(CS::Group::serialize_elem(self.pk))
2021-09-15 17:49:31 -07:00
}
/// Deserialization from bytes
2022-01-25 05:55:02 +01:00
///
/// # Errors
/// [`Error::Deserialization`] if failed to deserialize `input`.
2021-12-25 22:54:27 +01:00
pub fn deserialize(input: &[u8]) -> Result<Self> {
2021-12-23 21:03:38 +01:00
let mut input = input.iter().copied();
2021-09-15 17:49:31 -07:00
2022-01-28 01:38:17 +01:00
let sk = deserialize_scalar::<CS::Group, _>(&mut input)?;
let pk = deserialize_elem::<CS::Group, _>(&mut input)?;
2021-09-15 17:49:31 -07:00
2022-01-21 22:52:09 +01:00
Ok(Self { sk, pk })
2021-09-15 17:49:31 -07:00
}
}
2022-01-21 22:52:09 +01:00
/// Length of [`Proof`] in bytes for serialization.
pub type ProofLen<CS> = Sum<
<<CS as CipherSuite>::Group as Group>::ScalarLen,
<<CS as CipherSuite>::Group as Group>::ScalarLen,
>;
impl<CS: CipherSuite> Proof<CS>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
2021-09-15 17:49:31 -07:00
/// Serialization into bytes
2022-01-21 22:52:09 +01:00
pub fn serialize(&self) -> GenericArray<u8, ProofLen<CS>>
2021-12-23 21:03:38 +01:00
where
2022-01-21 22:52:09 +01:00
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ScalarLen>,
ProofLen<CS>: ArrayLength<u8>,
2021-12-23 21:03:38 +01:00
{
2022-01-21 22:52:09 +01:00
CS::Group::serialize_scalar(self.c_scalar)
.concat(CS::Group::serialize_scalar(self.s_scalar))
2021-09-15 17:49:31 -07:00
}
/// Deserialization from bytes
2022-01-25 05:55:02 +01:00
///
/// # Errors
/// [`Error::Deserialization`] if failed to deserialize `input`.
2021-12-25 22:54:27 +01:00
pub fn deserialize(input: &[u8]) -> Result<Self> {
2021-12-23 21:03:38 +01:00
let mut input = input.iter().copied();
2022-01-28 01:38:17 +01:00
let c_scalar = deserialize_scalar::<CS::Group, _>(&mut input)?;
let s_scalar = deserialize_scalar::<CS::Group, _>(&mut input)?;
2021-12-23 21:03:38 +01:00
2022-01-21 22:52:09 +01:00
Ok(Proof { c_scalar, s_scalar })
2021-09-15 17:49:31 -07:00
}
}
2022-01-21 22:52:09 +01:00
/// Length of [`BlindedElement`] in bytes for serialization.
pub type BlindedElementLen<CS> = <<CS as CipherSuite>::Group as Group>::ElemLen;
impl<CS: CipherSuite> BlindedElement<CS>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
2021-09-15 17:49:31 -07:00
/// Serialization into bytes
2022-01-21 22:52:09 +01:00
pub fn serialize(&self) -> GenericArray<u8, BlindedElementLen<CS>> {
CS::Group::serialize_elem(self.0)
2021-09-15 17:49:31 -07:00
}
/// Deserialization from bytes
2022-01-25 05:55:02 +01:00
///
/// # Errors
/// [`Error::Deserialization`] if failed to deserialize `input`.
2021-12-25 22:54:27 +01:00
pub fn deserialize(input: &[u8]) -> Result<Self> {
2021-12-23 21:03:38 +01:00
let mut input = input.iter().copied();
2022-01-28 01:38:17 +01:00
let value = deserialize_elem::<CS::Group, _>(&mut input)?;
2021-12-23 21:03:38 +01:00
2022-01-21 22:52:09 +01:00
Ok(Self(value))
2021-09-15 17:49:31 -07:00
}
}
2022-01-21 22:52:09 +01:00
/// Length of [`EvaluationElement`] in bytes for serialization.
pub type EvaluationElementLen<CS> = <<CS as CipherSuite>::Group as Group>::ElemLen;
impl<CS: CipherSuite> EvaluationElement<CS>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
2021-09-15 17:49:31 -07:00
/// Serialization into bytes
2022-01-21 22:52:09 +01:00
pub fn serialize(&self) -> GenericArray<u8, EvaluationElementLen<CS>> {
CS::Group::serialize_elem(self.0)
2021-09-15 17:49:31 -07:00
}
/// Deserialization from bytes
2022-01-25 05:55:02 +01:00
///
/// # Errors
/// [`Error::Deserialization`] if failed to deserialize `input`.
2021-12-25 22:54:27 +01:00
pub fn deserialize(input: &[u8]) -> Result<Self> {
2021-12-23 21:03:38 +01:00
let mut input = input.iter().copied();
2022-01-28 01:38:17 +01:00
let value = deserialize_elem::<CS::Group, _>(&mut input)?;
2021-12-23 21:03:38 +01:00
2022-01-21 22:52:09 +01:00
Ok(Self(value))
2021-09-15 17:49:31 -07:00
}
}
2021-12-25 22:54:27 +01:00
2022-01-28 01:38:17 +01:00
fn deserialize_elem<G: Group, I: Iterator<Item = u8>>(input: &mut I) -> Result<G::Elem> {
let input = input.by_ref().take(G::ElemLen::USIZE);
GenericArray::<_, G::ElemLen>::from_exact_iter(input)
.ok_or(Error::Deserialization)
.and_then(|bytes| G::deserialize_elem(&bytes))
}
fn deserialize_scalar<G: Group, I: Iterator<Item = u8>>(input: &mut I) -> Result<G::Scalar> {
let input = input.by_ref().take(G::ScalarLen::USIZE);
GenericArray::<_, G::ScalarLen>::from_exact_iter(input)
.ok_or(Error::Deserialization)
.and_then(|bytes| G::deserialize_scalar(&bytes))
}
#[cfg(feature = "serde")]
pub(crate) mod serde {
use core::marker::PhantomData;
use generic_array::GenericArray;
use serde::de::{Deserializer, Error};
use serde::ser::Serializer;
use serde::{Deserialize, Serialize};
use crate::Group;
pub(crate) struct Element<G: Group>(PhantomData<G>);
impl<'de, G: Group> Element<G> {
pub(crate) fn deserialize<D>(deserializer: D) -> Result<G::Elem, D::Error>
where
D: Deserializer<'de>,
{
GenericArray::<_, G::ElemLen>::deserialize(deserializer)
.and_then(|bytes| G::deserialize_elem(&bytes).map_err(D::Error::custom))
}
pub(crate) fn serialize<S>(self_: &G::Elem, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
G::serialize_elem(*self_).serialize(serializer)
}
}
pub(crate) struct Scalar<G: Group>(PhantomData<G>);
impl<'de, G: Group> Scalar<G> {
pub(crate) fn deserialize<D>(deserializer: D) -> Result<G::Scalar, D::Error>
where
D: Deserializer<'de>,
{
GenericArray::<_, G::ScalarLen>::deserialize(deserializer)
.and_then(|bytes| G::deserialize_scalar(&bytes).map_err(D::Error::custom))
}
pub(crate) fn serialize<S>(self_: &G::Scalar, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
G::serialize_scalar(*self_).serialize(serializer)
}
}
2021-12-25 22:54:27 +01:00
}