Document all Errors (#55)

* Document all `Error`s

* Fix inaccuracies
This commit is contained in:
daxpedda
2022-01-24 20:55:02 -08:00
committed by GitHub
parent 16e072dcd4
commit b01b8ed409
9 changed files with 249 additions and 125 deletions
+14 -7
View File
@@ -21,7 +21,7 @@ use rand_core::{CryptoRng, RngCore};
use super::Group;
use crate::group::{STR_HASH_TO_GROUP, STR_HASH_TO_SCALAR};
use crate::voprf::{self, Mode};
use crate::{CipherSuite, Error, Result};
use crate::{CipherSuite, Error, InternalError, Result};
impl<C> Group for C
where
@@ -41,7 +41,10 @@ where
// Implements the `hash_to_curve()` function from
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3
fn hash_to_curve<CS: CipherSuite>(msg: &[&[u8]], mode: Mode) -> Result<Self::Elem>
fn hash_to_curve<CS: CipherSuite>(
input: &[&[u8]],
mode: Mode,
) -> Result<Self::Elem, InternalError>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
@@ -49,11 +52,15 @@ where
let dst =
GenericArray::from(STR_HASH_TO_GROUP).concat(voprf::get_context_string::<CS>(mode));
Self::hash_from_bytes::<ExpandMsgXmd<CS::Hash>>(msg, &dst).map_err(|_| Error::PointError)
Self::hash_from_bytes::<ExpandMsgXmd<CS::Hash>>(input, &dst)
.map_err(|_| InternalError::Input)
}
// Implements the `HashToScalar()` function
fn hash_to_scalar<CS: CipherSuite>(input: &[&[u8]], mode: Mode) -> Result<Self::Scalar>
fn hash_to_scalar<CS: CipherSuite>(
input: &[&[u8]],
mode: Mode,
) -> Result<Self::Scalar, InternalError>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
@@ -62,7 +69,7 @@ where
GenericArray::from(STR_HASH_TO_SCALAR).concat(voprf::get_context_string::<CS>(mode));
<Self as GroupDigest>::hash_to_scalar::<ExpandMsgXmd<CS::Hash>>(input, &dst)
.map_err(|_| Error::PointError)
.map_err(|_| InternalError::Input)
}
fn base_elem() -> Self::Elem {
@@ -85,7 +92,7 @@ where
fn deserialize_elem(element_bits: &GenericArray<u8, Self::ElemLen>) -> Result<Self::Elem> {
PublicKey::<Self>::from_sec1_bytes(element_bits)
.map(|public_key| public_key.to_projective())
.map_err(|_| Error::PointError)
.map_err(|_| Error::Deserialization)
}
fn random_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
@@ -108,6 +115,6 @@ where
fn deserialize_scalar(scalar_bits: &GenericArray<u8, Self::ScalarLen>) -> Result<Self::Scalar> {
SecretKey::<Self>::from_be_bytes(scalar_bits)
.map(|secret_key| *secret_key.to_nonzero_scalar())
.map_err(|_| Error::ScalarError)
.map_err(|_| Error::Deserialization)
}
}
+26 -4
View File
@@ -24,7 +24,7 @@ use subtle::ConstantTimeEq;
use zeroize::Zeroize;
use crate::voprf::Mode;
use crate::{CipherSuite, Result};
use crate::{CipherSuite, InternalError, Result};
pub(crate) const STR_HASH_TO_SCALAR: [u8; 13] = *b"HashToScalar-";
pub(crate) const STR_HASH_TO_GROUP: [u8; 12] = *b"HashToGroup-";
@@ -52,14 +52,28 @@ pub trait Group {
/// The byte length necessary to represent scalars
type ScalarLen: ArrayLength<u8> + 'static;
/// transforms a password and domain separation tag (DST) into a curve point
fn hash_to_curve<CS: CipherSuite>(msg: &[&[u8]], mode: Mode) -> Result<Self::Elem>
/// Transforms a password and domain separation tag (DST) into a curve point
///
/// # Errors
/// [`Error::Input`](crate::Error::Input) if the `input` is empty or longer
/// then [`u16::MAX`].
fn hash_to_curve<CS: CipherSuite>(
input: &[&[u8]],
mode: Mode,
) -> Result<Self::Elem, InternalError>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>;
/// Hashes a slice of pseudo-random bytes to a scalar
fn hash_to_scalar<CS: CipherSuite>(input: &[&[u8]], mode: Mode) -> Result<Self::Scalar>
///
/// # Errors
/// [`Error::Input`](crate::Error::Input) if the `input` is empty or longer
/// then [`u16::MAX`].
fn hash_to_scalar<CS: CipherSuite>(
input: &[&[u8]],
mode: Mode,
) -> Result<Self::Scalar, InternalError>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>;
@@ -75,6 +89,10 @@ pub trait Group {
/// Return an element from its fixed-length bytes representation. If the
/// element is the identity element, return an error.
///
/// # 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>;
/// picks a scalar at random
@@ -92,6 +110,10 @@ pub trait Group {
/// Return a scalar from its fixed-length bytes representation. If the
/// scalar is zero or invalid, then return an error.
///
/// # 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>;
}
+14 -8
View File
@@ -19,7 +19,7 @@ use rand_core::{CryptoRng, RngCore};
use super::{Group, STR_HASH_TO_GROUP, STR_HASH_TO_SCALAR};
use crate::voprf::{self, Mode};
use crate::{CipherSuite, Error, Result};
use crate::{CipherSuite, Error, InternalError, Result};
/// [`Group`] implementation for Ristretto255.
pub struct Ristretto255;
@@ -46,7 +46,10 @@ impl Group for Ristretto255 {
// Implements the `hash_to_ristretto255()` function from
// https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-10.txt
fn hash_to_curve<CS: CipherSuite>(msg: &[&[u8]], mode: Mode) -> Result<Self::Elem>
fn hash_to_curve<CS: CipherSuite>(
input: &[&[u8]],
mode: Mode,
) -> Result<Self::Elem, InternalError>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
@@ -55,8 +58,8 @@ impl Group for Ristretto255 {
GenericArray::from(STR_HASH_TO_GROUP).concat(voprf::get_context_string::<Self>(mode));
let mut uniform_bytes = GenericArray::<_, U64>::default();
ExpandMsgXmd::<CS::Hash>::expand_message(msg, &dst, 64)
.map_err(|_| Error::PointError)?
ExpandMsgXmd::<CS::Hash>::expand_message(input, &dst, 64)
.map_err(|_| InternalError::Input)?
.fill_bytes(&mut uniform_bytes);
Ok(RistrettoPoint::from_uniform_bytes(&uniform_bytes.into()))
@@ -64,7 +67,10 @@ impl Group for Ristretto255 {
// Implements the `HashToScalar()` function from
// https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-07.html#section-4.1
fn hash_to_scalar<'a, CS: CipherSuite>(input: &[&[u8]], mode: Mode) -> Result<Self::Scalar>
fn hash_to_scalar<'a, CS: CipherSuite>(
input: &[&[u8]],
mode: Mode,
) -> Result<Self::Scalar, InternalError>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
@@ -74,7 +80,7 @@ impl Group for Ristretto255 {
let mut uniform_bytes = GenericArray::<_, U64>::default();
ExpandMsgXmd::<CS::Hash>::expand_message(input, &dst, 64)
.map_err(|_| Error::PointError)?
.map_err(|_| InternalError::Input)?
.fill_bytes(&mut uniform_bytes);
Ok(Scalar::from_bytes_mod_order_wide(&uniform_bytes.into()))
@@ -97,7 +103,7 @@ impl Group for Ristretto255 {
CompressedRistretto::from_slice(element_bits)
.decompress()
.filter(|point| point != &RistrettoPoint::identity())
.ok_or(Error::PointError)
.ok_or(Error::Deserialization)
}
fn random_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
@@ -130,6 +136,6 @@ impl Group for Ristretto255 {
fn deserialize_scalar(scalar_bits: &GenericArray<u8, Self::ScalarLen>) -> Result<Self::Scalar> {
Scalar::from_canonical_bytes((*scalar_bits).into())
.filter(|scalar| scalar != &Scalar::zero())
.ok_or(Error::ScalarError)
.ok_or(Error::Deserialization)
}
}
+2 -2
View File
@@ -34,7 +34,7 @@ fn test_group_properties() -> Result<()> {
fn test_identity_element_error<G: Group>() -> Result<()> {
let identity = G::identity_elem();
let result = G::deserialize_elem(&G::serialize_elem(identity));
assert!(matches!(result, Err(Error::PointError)));
assert!(matches!(result, Err(Error::Deserialization)));
Ok(())
}
@@ -43,7 +43,7 @@ fn test_identity_element_error<G: Group>() -> Result<()> {
fn test_zero_scalar_error<G: Group>() -> Result<()> {
let zero_scalar = G::zero_scalar();
let result = G::deserialize_scalar(&G::serialize_scalar(zero_scalar));
assert!(matches!(result, Err(Error::ScalarError)));
assert!(matches!(result, Err(Error::Deserialization)));
Ok(())
}