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:
+107
-69
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user