Group trait overhaul part 2 (#53)

* Rely on elliptic-curve for hash-to-curve and P-256 implementations

* Update MSRV

* Remove unnecessary `#[macro_use]`

* Re-introduce `CipherSuite`

* Provide types for length shortcuts

* Remove `SUITE_ID` from `Group`

* Blanket implementation for RustCrypto `Curve`s

* Remove the p256 crate feature

* Rename `ristretto_*` crate features to `ristretto-*` for consistency

* Remove unnecessary allowed Clippy lints

* Remove some unnecessary constraints
This commit is contained in:
daxpedda
2022-01-21 13:52:09 -08:00
committed by GitHub
parent 652fd1d1d0
commit 16e072dcd4
15 changed files with 1038 additions and 1643 deletions
+107 -69
View File
@@ -8,18 +8,17 @@
//! Handles the serialization of each of the components used in the VOPRF
//! protocol
use core::marker::PhantomData;
use core::ops::Add;
use digest::core_api::BlockSizeUser;
use digest::{Digest, FixedOutputReset};
use digest::OutputSizeUser;
use generic_array::sequence::Concat;
use generic_array::typenum::Sum;
use generic_array::typenum::{IsLess, IsLessOrEqual, Sum, U256};
use generic_array::{ArrayLength, GenericArray};
use crate::{
BlindedElement, Error, EvaluationElement, Group, NonVerifiableClient, NonVerifiableServer,
Proof, Result, VerifiableClient, VerifiableServer,
BlindedElement, CipherSuite, Error, EvaluationElement, Group, NonVerifiableClient,
NonVerifiableServer, Proof, Result, VerifiableClient, VerifiableServer,
};
//////////////////////////////////////////////////////////
@@ -27,154 +26,193 @@ use crate::{
// ==================================================== //
//////////////////////////////////////////////////////////
impl<G: Group, H: BlockSizeUser + Digest + FixedOutputReset> NonVerifiableClient<G, H> {
/// 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>,
{
/// Serialization into bytes
pub fn serialize(&self) -> GenericArray<u8, G::ScalarLen> {
G::serialize_scalar(self.blind)
pub fn serialize(&self) -> GenericArray<u8, NonVerifiableClientLen<CS>> {
CS::Group::serialize_scalar(self.blind)
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self> {
let mut input = input.iter().copied();
let blind = G::deserialize_scalar(&deserialize(&mut input)?)?;
let blind = CS::Group::deserialize_scalar(&deserialize(&mut input)?)?;
Ok(Self {
blind,
hash: PhantomData,
})
Ok(Self { blind })
}
}
impl<G: Group, H: BlockSizeUser + Digest + FixedOutputReset> VerifiableClient<G, H> {
/// 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>,
{
/// Serialization into bytes
pub fn serialize(&self) -> GenericArray<u8, Sum<G::ScalarLen, G::ElemLen>>
pub fn serialize(&self) -> GenericArray<u8, VerifiableClientLen<CS>>
where
G::ScalarLen: Add<G::ElemLen>,
Sum<G::ScalarLen, G::ElemLen>: ArrayLength<u8>,
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
VerifiableClientLen<CS>: ArrayLength<u8>,
{
G::serialize_scalar(self.blind).concat(G::serialize_elem(self.blinded_element))
<CS::Group as Group>::serialize_scalar(self.blind)
.concat(<CS::Group as Group>::serialize_elem(self.blinded_element))
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self> {
let mut input = input.iter().copied();
let blind = G::deserialize_scalar(&deserialize(&mut input)?)?;
let blinded_element = G::deserialize_elem(&deserialize(&mut input)?)?;
let blind = CS::Group::deserialize_scalar(&deserialize(&mut input)?)?;
let blinded_element = CS::Group::deserialize_elem(&deserialize(&mut input)?)?;
Ok(Self {
blind,
blinded_element,
hash: PhantomData,
})
}
}
impl<G: Group, H: BlockSizeUser + Digest + FixedOutputReset> NonVerifiableServer<G, H> {
/// 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>,
{
/// Serialization into bytes
pub fn serialize(&self) -> GenericArray<u8, G::ScalarLen> {
G::serialize_scalar(self.sk)
pub fn serialize(&self) -> GenericArray<u8, NonVerifiableServerLen<CS>> {
CS::Group::serialize_scalar(self.sk)
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self> {
let mut input = input.iter().copied();
let sk = G::deserialize_scalar(&deserialize(&mut input)?)?;
let sk = CS::Group::deserialize_scalar(&deserialize(&mut input)?)?;
Ok(Self {
sk,
hash: PhantomData,
})
Ok(Self { sk })
}
}
impl<G: Group, H: BlockSizeUser + Digest + FixedOutputReset> VerifiableServer<G, H> {
/// 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>,
{
/// Serialization into bytes
pub fn serialize(&self) -> GenericArray<u8, Sum<G::ScalarLen, G::ElemLen>>
pub fn serialize(&self) -> GenericArray<u8, VerifiableServerLen<CS>>
where
G::ScalarLen: Add<G::ElemLen>,
Sum<G::ScalarLen, G::ElemLen>: ArrayLength<u8>,
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
VerifiableServerLen<CS>: ArrayLength<u8>,
{
G::serialize_scalar(self.sk).concat(G::serialize_elem(self.pk))
CS::Group::serialize_scalar(self.sk).concat(CS::Group::serialize_elem(self.pk))
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self> {
let mut input = input.iter().copied();
let sk = G::deserialize_scalar(&deserialize(&mut input)?)?;
let pk = G::deserialize_elem(&deserialize(&mut input)?)?;
let sk = CS::Group::deserialize_scalar(&deserialize(&mut input)?)?;
let pk = CS::Group::deserialize_elem(&deserialize(&mut input)?)?;
Ok(Self {
sk,
pk,
hash: PhantomData,
})
Ok(Self { sk, pk })
}
}
impl<G: Group, H: BlockSizeUser + Digest + FixedOutputReset> Proof<G, H> {
/// 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>,
{
/// Serialization into bytes
pub fn serialize(&self) -> GenericArray<u8, Sum<G::ScalarLen, G::ScalarLen>>
pub fn serialize(&self) -> GenericArray<u8, ProofLen<CS>>
where
G::ScalarLen: Add<G::ScalarLen>,
Sum<G::ScalarLen, G::ScalarLen>: ArrayLength<u8>,
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ScalarLen>,
ProofLen<CS>: ArrayLength<u8>,
{
G::serialize_scalar(self.c_scalar).concat(G::serialize_scalar(self.s_scalar))
CS::Group::serialize_scalar(self.c_scalar)
.concat(CS::Group::serialize_scalar(self.s_scalar))
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self> {
let mut input = input.iter().copied();
let c_scalar = G::deserialize_scalar(&deserialize(&mut input)?)?;
let s_scalar = G::deserialize_scalar(&deserialize(&mut input)?)?;
let c_scalar = CS::Group::deserialize_scalar(&deserialize(&mut input)?)?;
let s_scalar = CS::Group::deserialize_scalar(&deserialize(&mut input)?)?;
Ok(Proof {
c_scalar,
s_scalar,
hash: PhantomData,
})
Ok(Proof { c_scalar, s_scalar })
}
}
impl<G: Group, H: BlockSizeUser + Digest + FixedOutputReset> BlindedElement<G, H> {
/// 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>,
{
/// Serialization into bytes
pub fn serialize(&self) -> GenericArray<u8, G::ElemLen> {
G::serialize_elem(self.value)
pub fn serialize(&self) -> GenericArray<u8, BlindedElementLen<CS>> {
CS::Group::serialize_elem(self.0)
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self> {
let mut input = input.iter().copied();
let value = G::deserialize_elem(&deserialize(&mut input)?)?;
let value = CS::Group::deserialize_elem(&deserialize(&mut input)?)?;
Ok(Self {
value,
hash: PhantomData,
})
Ok(Self(value))
}
}
impl<G: Group, H: BlockSizeUser + Digest + FixedOutputReset> EvaluationElement<G, H> {
/// 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>,
{
/// Serialization into bytes
pub fn serialize(&self) -> GenericArray<u8, G::ElemLen> {
G::serialize_elem(self.value)
pub fn serialize(&self) -> GenericArray<u8, EvaluationElementLen<CS>> {
CS::Group::serialize_elem(self.0)
}
/// Deserialization from bytes
pub fn deserialize(input: &[u8]) -> Result<Self> {
let mut input = input.iter().copied();
let value = G::deserialize_elem(&deserialize(&mut input)?)?;
let value = CS::Group::deserialize_elem(&deserialize(&mut input)?)?;
Ok(Self {
value,
hash: PhantomData,
})
Ok(Self(value))
}
}