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-21 22:52:09 +01:00
|
|
|
use generic_array::typenum::{IsLess, IsLessOrEqual, Sum, 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-01-21 22:52:09 +01:00
|
|
|
BlindedElement, CipherSuite, Error, EvaluationElement, Group, NonVerifiableClient,
|
|
|
|
|
NonVerifiableServer, Proof, Result, VerifiableClient, VerifiableServer,
|
2021-12-23 01:17:03 +01:00
|
|
|
};
|
|
|
|
|
|
2021-09-15 17:49:31 -07:00
|
|
|
//////////////////////////////////////////////////////////
|
|
|
|
|
// Serialization and Deserialization for High-Level API //
|
|
|
|
|
// ==================================================== //
|
|
|
|
|
//////////////////////////////////////////////////////////
|
|
|
|
|
|
2022-01-21 22:52:09 +01:00
|
|
|
/// Length of [`NonVerifiableClient`] in bytes for serialization.
|
|
|
|
|
pub type NonVerifiableClientLen<CS> = <<CS as CipherSuite>::Group as Group>::ScalarLen;
|
|
|
|
|
|
|
|
|
|
impl<CS: CipherSuite> NonVerifiableClient<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, NonVerifiableClientLen<CS>> {
|
|
|
|
|
CS::Group::serialize_scalar(self.blind)
|
2021-09-15 17:49:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Deserialization from bytes
|
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-21 22:52:09 +01:00
|
|
|
let blind = CS::Group::deserialize_scalar(&deserialize(&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-01-21 22:52:09 +01:00
|
|
|
/// Length of [`VerifiableClient`] in bytes for serialization.
|
|
|
|
|
pub type VerifiableClientLen<CS> = Sum<
|
|
|
|
|
<<CS as CipherSuite>::Group as Group>::ScalarLen,
|
|
|
|
|
<<CS as CipherSuite>::Group as Group>::ElemLen,
|
|
|
|
|
>;
|
|
|
|
|
|
|
|
|
|
impl<CS: CipherSuite> VerifiableClient<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, VerifiableClientLen<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>,
|
|
|
|
|
VerifiableClientLen<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
|
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-21 22:52:09 +01:00
|
|
|
let blind = CS::Group::deserialize_scalar(&deserialize(&mut input)?)?;
|
|
|
|
|
let blinded_element = CS::Group::deserialize_elem(&deserialize(&mut input)?)?;
|
2021-09-15 17:49:31 -07:00
|
|
|
|
|
|
|
|
Ok(Self {
|
|
|
|
|
blind,
|
|
|
|
|
blinded_element,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-21 22:52:09 +01:00
|
|
|
/// Length of [`NonVerifiableServer`] in bytes for serialization.
|
|
|
|
|
pub type NonVerifiableServerLen<CS> = <<CS as CipherSuite>::Group as Group>::ScalarLen;
|
|
|
|
|
|
|
|
|
|
impl<CS: CipherSuite> NonVerifiableServer<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, NonVerifiableServerLen<CS>> {
|
|
|
|
|
CS::Group::serialize_scalar(self.sk)
|
2021-09-15 17:49:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Deserialization from bytes
|
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-21 22:52:09 +01:00
|
|
|
let sk = CS::Group::deserialize_scalar(&deserialize(&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-01-21 22:52:09 +01:00
|
|
|
/// Length of [`VerifiableServer`] in bytes for serialization.
|
|
|
|
|
pub type VerifiableServerLen<CS> = Sum<
|
|
|
|
|
<<CS as CipherSuite>::Group as Group>::ScalarLen,
|
|
|
|
|
<<CS as CipherSuite>::Group as Group>::ElemLen,
|
|
|
|
|
>;
|
|
|
|
|
|
|
|
|
|
impl<CS: CipherSuite> VerifiableServer<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, VerifiableServerLen<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>,
|
|
|
|
|
VerifiableServerLen<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
|
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-21 22:52:09 +01:00
|
|
|
let sk = CS::Group::deserialize_scalar(&deserialize(&mut input)?)?;
|
|
|
|
|
let pk = CS::Group::deserialize_elem(&deserialize(&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
|
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-21 22:52:09 +01:00
|
|
|
let c_scalar = CS::Group::deserialize_scalar(&deserialize(&mut input)?)?;
|
|
|
|
|
let s_scalar = CS::Group::deserialize_scalar(&deserialize(&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
|
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-21 22:52:09 +01:00
|
|
|
let value = CS::Group::deserialize_elem(&deserialize(&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
|
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-21 22:52:09 +01:00
|
|
|
let value = CS::Group::deserialize_elem(&deserialize(&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
|
|
|
|
|
|
|
|
fn deserialize<L: ArrayLength<u8>>(
|
|
|
|
|
input: &mut impl Iterator<Item = u8>,
|
|
|
|
|
) -> Result<GenericArray<u8, L>> {
|
|
|
|
|
let input = input.by_ref().take(L::USIZE);
|
|
|
|
|
GenericArray::from_exact_iter(input).ok_or(Error::SizeError)
|
|
|
|
|
}
|