reject identity in Group::deserialize (#145)

This commit is contained in:
Conrado Gouvea 2022-10-04 16:05:58 -03:00 committed by GitHub
parent be43c4a082
commit bea4ef0687
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 2 deletions

View File

@ -30,4 +30,7 @@ pub enum Error {
/// This scalar MUST NOT be zero.
#[error("Invalid for this scalar to be zero.")]
InvalidZeroScalar,
/// This element MUST NOT be the identity.
#[error("Invalid for this element to be the identity.")]
InvalidIdentityElement,
}

View File

@ -4,6 +4,7 @@
use p256::{
elliptic_curve::{
group::prime::PrimeCurveAffine,
hash2curve::{hash_to_field, ExpandMsgXmd},
sec1::{FromEncodedPoint, ToEncodedPoint},
Field as FFField, PrimeField,
@ -128,7 +129,16 @@ impl Group for P256Group {
p256::EncodedPoint::from_bytes(buf).map_err(|_| Error::MalformedElement)?;
match Option::<AffinePoint>::from(AffinePoint::from_encoded_point(&encoded_point)) {
Some(point) => Ok(ProjectivePoint::from(point)),
Some(point) => {
if point.is_identity().into() {
// This is actually impossible since the identity is encoded a a single byte
// which will never happen since we receive a 33-byte buffer.
// We leave the check for consistency.
Err(Error::InvalidIdentityElement)
} else {
Ok(ProjectivePoint::from(point))
}
}
None => Err(Error::MalformedElement),
}
}

View File

@ -1,3 +1,4 @@
use frost_core::{Ciphersuite, Group};
use frost_p256::*;
use rand::thread_rng;
@ -25,3 +26,13 @@ fn check_bad_batch_verify() {
frost_core::tests::batch::bad_batch_verify::<P256Sha256, _>(rng);
}
#[test]
fn check_deserialize_identity() {
// The identity is actually encoded as a single byte; but the API does not
// allow us to change that. Try to send something similar.
let encoded_identity = [0u8; 33];
let r = <<P256Sha256 as Ciphersuite>::Group as Group>::deserialize(&encoded_identity);
assert_eq!(r, Err(Error::MalformedElement));
}

View File

@ -101,7 +101,13 @@ impl Group for RistrettoGroup {
fn deserialize(buf: &Self::Serialization) -> Result<Self::Element, Error> {
match CompressedRistretto::from_slice(buf.as_ref()).decompress() {
Some(point) => Ok(point),
Some(point) => {
if point == Self::identity() {
Err(Error::InvalidIdentityElement)
} else {
Ok(point)
}
}
None => Err(Error::MalformedElement),
}
}

View File

@ -1,3 +1,5 @@
use curve25519_dalek::{ristretto::RistrettoPoint, traits::Identity};
use frost_core::{Ciphersuite, Group};
use frost_ristretto255::*;
use rand::thread_rng;
@ -21,3 +23,11 @@ fn check_bad_batch_verify() {
frost_core::tests::batch::bad_batch_verify::<Ristretto255Sha512, _>(rng);
}
#[test]
fn check_deserialize_identity() {
let encoded_identity = RistrettoPoint::identity().compress().to_bytes();
let r = <<Ristretto255Sha512 as Ciphersuite>::Group as Group>::deserialize(&encoded_identity);
assert_eq!(r, Err(Error::InvalidIdentityElement));
}