diff --git a/src/bls12_381/ec.rs b/src/bls12_381/ec.rs index d4e1131..7eabb53 100644 --- a/src/bls12_381/ec.rs +++ b/src/bls12_381/ec.rs @@ -760,6 +760,45 @@ pub mod g1 { res } + + fn from_raw_uncompressed_le_unchecked( + encoded: &Self::Uncompressed, + _infinity: bool + ) -> Result { + let copy = encoded.0; + if copy.iter().all(|b| *b == 0) { + return Ok(Self::zero()); + } + + let mut x = FqRepr([0; 6]); + let mut y = FqRepr([0; 6]); + + { + let mut reader = ©[..]; + x.read_be(&mut reader).unwrap(); + y.read_be(&mut reader).unwrap(); + } + + Ok(G1Affine { + x: Fq::from_raw_repr(x).map_err(|e| { + GroupDecodingError::CoordinateDecodingError("x coordinate", e) + })?, + y: Fq::from_raw_repr(y).map_err(|e| { + GroupDecodingError::CoordinateDecodingError("y coordinate", e) + })?, + infinity: false, + }) + } + + fn from_raw_uncompressed_le(encoded: &Self::Uncompressed, _infinity: bool) -> Result { + let affine = Self::from_raw_uncompressed_le_unchecked(&encoded, _infinity)?; + + if !affine.is_on_curve() { + Err(GroupDecodingError::NotOnCurve) + } else { + Ok(affine) + } + } } #[derive(Copy, Clone)] diff --git a/src/bn256/ec.rs b/src/bn256/ec.rs index ab58e29..e60f757 100644 --- a/src/bn256/ec.rs +++ b/src/bn256/ec.rs @@ -652,6 +652,47 @@ pub mod g1 { res } + + /// Creates a point from raw encoded coordinates without checking on curve + fn from_raw_uncompressed_le_unchecked( + encoded: &Self::Uncompressed, + _infinity: bool + ) -> Result { + let copy = encoded.0; + + if copy.iter().all(|b| *b == 0) { + return Ok(Self::zero()); + } + + let mut x = FqRepr([0; 4]); + let mut y = FqRepr([0; 4]); + + { + let mut reader = ©[..]; + x.read_be(&mut reader).unwrap(); + y.read_be(&mut reader).unwrap(); + } + + Ok(G1Affine { + x: Fq::from_raw_repr(x).map_err(|e| { + GroupDecodingError::CoordinateDecodingError("x coordinate", e) + })?, + y: Fq::from_raw_repr(y).map_err(|e| { + GroupDecodingError::CoordinateDecodingError("y coordinate", e) + })?, + infinity: false, + }) + } + + fn from_raw_uncompressed_le(encoded: &Self::Uncompressed, _infinity: bool) -> Result { + let affine = Self::from_raw_uncompressed_le_unchecked(&encoded, _infinity)?; + + if !affine.is_on_curve() { + Err(GroupDecodingError::NotOnCurve) + } else { + Ok(affine) + } + } } #[derive(Copy, Clone)] diff --git a/src/lib.rs b/src/lib.rs index f6f1df6..8d7053f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -246,6 +246,12 @@ pub trait RawEncodable: CurveAffine { /// Converts this element into its uncompressed encoding, so long as it's not /// the point at infinity. Leaves coordinates in Montgommery form fn into_raw_uncompressed_le(&self) -> Self::Uncompressed; + + /// Creates a point from raw encoded coordinates without checking on curve + fn from_raw_uncompressed_le_unchecked(encoded: &Self::Uncompressed, infinity: bool) -> Result; + + /// Creates a point from raw encoded coordinates + fn from_raw_uncompressed_le(encoded: &Self::Uncompressed, infinity: bool) -> Result; } /// An encoded elliptic curve point, which should essentially wrap a `[u8; N]`.