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:
daxpedda
2022-01-27 16:38:17 -08:00
committed by GitHub
parent b01b8ed409
commit b59b359aa3
9 changed files with 351 additions and 245 deletions
+6 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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)
}