General improvements (#56)
* Apply Rust traits to all public types and other improvements * Move methods into appropriate section * Check for zero scalars * Change element and scalar de/serialization from `GenericArray` to slice * Customize `serde` serialization
This commit is contained in:
@@ -89,7 +89,7 @@ where
|
||||
result
|
||||
}
|
||||
|
||||
fn deserialize_elem(element_bits: &GenericArray<u8, Self::ElemLen>) -> Result<Self::Elem> {
|
||||
fn deserialize_elem(element_bits: &[u8]) -> Result<Self::Elem> {
|
||||
PublicKey::<Self>::from_sec1_bytes(element_bits)
|
||||
.map(|public_key| public_key.to_projective())
|
||||
.map_err(|_| Error::Deserialization)
|
||||
@@ -103,6 +103,10 @@ where
|
||||
Option::from(scalar.invert()).unwrap()
|
||||
}
|
||||
|
||||
fn is_zero_scalar(scalar: Self::Scalar) -> subtle::Choice {
|
||||
scalar.is_zero()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn zero_scalar() -> Self::Scalar {
|
||||
Scalar::<Self>::zero()
|
||||
@@ -112,7 +116,7 @@ where
|
||||
scalar.into()
|
||||
}
|
||||
|
||||
fn deserialize_scalar(scalar_bits: &GenericArray<u8, Self::ScalarLen>) -> Result<Self::Scalar> {
|
||||
fn deserialize_scalar(scalar_bits: &[u8]) -> Result<Self::Scalar> {
|
||||
SecretKey::<Self>::from_be_bytes(scalar_bits)
|
||||
.map(|secret_key| *secret_key.to_nonzero_scalar())
|
||||
.map_err(|_| Error::Deserialization)
|
||||
|
||||
+6
-3
@@ -20,7 +20,7 @@ use generic_array::{ArrayLength, GenericArray};
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
#[cfg(feature = "ristretto255")]
|
||||
pub use ristretto::Ristretto255;
|
||||
use subtle::ConstantTimeEq;
|
||||
use subtle::{Choice, ConstantTimeEq};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use crate::voprf::Mode;
|
||||
@@ -93,7 +93,7 @@ pub trait Group {
|
||||
/// # Errors
|
||||
/// [`Error::Deserialization`](crate::Error::Deserialization) if the element
|
||||
/// is not a valid point on the group or the identity element.
|
||||
fn deserialize_elem(element_bits: &GenericArray<u8, Self::ElemLen>) -> Result<Self::Elem>;
|
||||
fn deserialize_elem(element_bits: &[u8]) -> Result<Self::Elem>;
|
||||
|
||||
/// picks a scalar at random
|
||||
fn random_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar;
|
||||
@@ -101,6 +101,9 @@ pub trait Group {
|
||||
/// The multiplicative inverse of this scalar
|
||||
fn invert_scalar(scalar: Self::Scalar) -> Self::Scalar;
|
||||
|
||||
/// Returns `true` if the scalar is zero.
|
||||
fn is_zero_scalar(scalar: Self::Scalar) -> Choice;
|
||||
|
||||
/// Returns the scalar representing zero
|
||||
#[cfg(test)]
|
||||
fn zero_scalar() -> Self::Scalar;
|
||||
@@ -114,7 +117,7 @@ pub trait Group {
|
||||
/// # Errors
|
||||
/// [`Error::Deserialization`](crate::Error::Deserialization) if the scalar
|
||||
/// is not a valid point on the group or zero.
|
||||
fn deserialize_scalar(scalar_bits: &GenericArray<u8, Self::ScalarLen>) -> Result<Self::Scalar>;
|
||||
fn deserialize_scalar(scalar_bits: &[u8]) -> Result<Self::Scalar>;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
+14
-3
@@ -16,12 +16,16 @@ use generic_array::sequence::Concat;
|
||||
use generic_array::typenum::{IsLess, IsLessOrEqual, U256, U32, U64};
|
||||
use generic_array::GenericArray;
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
use subtle::ConstantTimeEq;
|
||||
|
||||
use super::{Group, STR_HASH_TO_GROUP, STR_HASH_TO_SCALAR};
|
||||
use crate::voprf::{self, Mode};
|
||||
use crate::{CipherSuite, Error, InternalError, Result};
|
||||
|
||||
/// [`Group`] implementation for Ristretto255.
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
// `cfg` here is only needed because of a bug in Rust's crate feature documentation. See: https://github.com/rust-lang/rust/issues/83428
|
||||
#[cfg(feature = "ristretto255")]
|
||||
pub struct Ristretto255;
|
||||
|
||||
#[cfg(feature = "ristretto255-ciphersuite")]
|
||||
@@ -99,7 +103,7 @@ impl Group for Ristretto255 {
|
||||
elem.compress().to_bytes().into()
|
||||
}
|
||||
|
||||
fn deserialize_elem(element_bits: &GenericArray<u8, Self::ElemLen>) -> Result<Self::Elem> {
|
||||
fn deserialize_elem(element_bits: &[u8]) -> Result<Self::Elem> {
|
||||
CompressedRistretto::from_slice(element_bits)
|
||||
.decompress()
|
||||
.filter(|point| point != &RistrettoPoint::identity())
|
||||
@@ -124,6 +128,10 @@ impl Group for Ristretto255 {
|
||||
scalar.invert()
|
||||
}
|
||||
|
||||
fn is_zero_scalar(scalar: Self::Scalar) -> subtle::Choice {
|
||||
scalar.ct_eq(&Scalar::zero())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn zero_scalar() -> Self::Scalar {
|
||||
Scalar::zero()
|
||||
@@ -133,8 +141,11 @@ impl Group for Ristretto255 {
|
||||
scalar.to_bytes().into()
|
||||
}
|
||||
|
||||
fn deserialize_scalar(scalar_bits: &GenericArray<u8, Self::ScalarLen>) -> Result<Self::Scalar> {
|
||||
Scalar::from_canonical_bytes((*scalar_bits).into())
|
||||
fn deserialize_scalar(scalar_bits: &[u8]) -> Result<Self::Scalar> {
|
||||
scalar_bits
|
||||
.try_into()
|
||||
.ok()
|
||||
.and_then(Scalar::from_canonical_bytes)
|
||||
.filter(|scalar| scalar != &Scalar::zero())
|
||||
.ok_or(Error::Deserialization)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user