From ca45ba162b82b196f54ec8aaf134737c5c526497 Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Fri, 1 Oct 2021 08:04:57 +0200 Subject: [PATCH] Fix related functions --- k256/src/arithmetic/affine.rs | 25 +++++++++++++++++++++++-- k256/src/arithmetic/projective.rs | 19 +++++++++++++++++-- p256/src/arithmetic/affine.rs | 25 +++++++++++++++++++++++-- p256/src/arithmetic/projective.rs | 9 +++++++-- 4 files changed, 70 insertions(+), 8 deletions(-) diff --git a/k256/src/arithmetic/affine.rs b/k256/src/arithmetic/affine.rs index dad385d38..2da4c5f93 100644 --- a/k256/src/arithmetic/affine.rs +++ b/k256/src/arithmetic/affine.rs @@ -171,6 +171,12 @@ impl GroupEncoding for AffinePoint { let is_compressed_point = y_is_odd | tag.ct_eq(&sec1::Tag::CompressedEvenY.into()); Self::decompress(FieldBytes::from_slice(&bytes[1..]), y_is_odd) .and_then(|point| CtOption::new(point, is_compressed_point)) + .or_else(|| { + CtOption::new( + AffinePoint::identity(), + tag.ct_eq(&sec1::Tag::Identity.into()), + ) + }) } fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption { @@ -179,7 +185,11 @@ impl GroupEncoding for AffinePoint { } fn to_bytes(&self) -> Self::Repr { - CompressedPoint::clone_from_slice(self.to_encoded_point(true).as_bytes()) + let bytes = self.to_encoded_point(true); + let bytes = bytes.as_bytes(); + let mut result = CompressedPoint::default(); + result[..bytes.len()].copy_from_slice(bytes); + result } } @@ -248,7 +258,7 @@ mod tests { use super::AffinePoint; use crate::EncodedPoint; use elliptic_curve::{ - group::prime::PrimeCurveAffine, + group::{prime::PrimeCurveAffine, GroupEncoding}, sec1::{FromEncodedPoint, ToEncodedPoint}, }; use hex_literal::hex; @@ -307,4 +317,15 @@ mod tests { let basepoint = AffinePoint::generator(); assert_eq!((-(-basepoint)), basepoint); } + + #[test] + fn identity_encoding() { + // This is technically an invalid SEC1 encoding, but is preferable to panicking. + assert_eq!([0; 33], AffinePoint::identity().to_bytes().as_slice()); + assert!(bool::from( + AffinePoint::from_bytes(&AffinePoint::identity().to_bytes()) + .unwrap() + .is_identity() + )) + } } diff --git a/k256/src/arithmetic/projective.rs b/k256/src/arithmetic/projective.rs index 87f4af92e..74d0b0f92 100644 --- a/k256/src/arithmetic/projective.rs +++ b/k256/src/arithmetic/projective.rs @@ -307,7 +307,11 @@ impl GroupEncoding for ProjectivePoint { } fn to_bytes(&self) -> Self::Repr { - CompressedPoint::clone_from_slice(self.to_affine().to_encoded_point(true).as_bytes()) + let bytes = self.to_affine().to_encoded_point(true); + let bytes = bytes.as_bytes(); + let mut result = CompressedPoint::default(); + result[..bytes.len()].copy_from_slice(bytes); + result } } @@ -512,7 +516,7 @@ mod tests { test_vectors::group::{ADD_TEST_VECTORS, MUL_TEST_VECTORS}, Scalar, }; - use elliptic_curve::group::{ff::PrimeField, prime::PrimeCurveAffine}; + use elliptic_curve::group::{ff::PrimeField, prime::PrimeCurveAffine, Group, GroupEncoding}; #[test] fn affine_to_projective() { @@ -663,4 +667,15 @@ mod tests { assert_eq!(res.y.to_bytes(), coords.1.into()); } } + + #[test] + fn identity_encoding() { + // This is technically an invalid SEC1 encoding, but is preferable to panicking. + assert_eq!([0; 33], ProjectivePoint::identity().to_bytes().as_slice()); + assert!(bool::from( + ProjectivePoint::from_bytes(&ProjectivePoint::identity().to_bytes()) + .unwrap() + .is_identity() + )) + } } diff --git a/p256/src/arithmetic/affine.rs b/p256/src/arithmetic/affine.rs index 4dae4e921..8f280d157 100644 --- a/p256/src/arithmetic/affine.rs +++ b/p256/src/arithmetic/affine.rs @@ -167,6 +167,12 @@ impl GroupEncoding for AffinePoint { let is_compressed_point = y_is_odd | tag.ct_eq(&sec1::Tag::CompressedEvenY.into()); Self::decompress(FieldBytes::from_slice(&bytes[1..]), y_is_odd) .and_then(|point| CtOption::new(point, is_compressed_point)) + .or_else(|| { + CtOption::new( + AffinePoint::identity(), + tag.ct_eq(&sec1::Tag::Identity.into()), + ) + }) } fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption { @@ -175,7 +181,11 @@ impl GroupEncoding for AffinePoint { } fn to_bytes(&self) -> Self::Repr { - CompressedPoint::clone_from_slice(self.to_encoded_point(true).as_bytes()) + let bytes = self.to_encoded_point(true); + let bytes = bytes.as_bytes(); + let mut result = CompressedPoint::default(); + result[..bytes.len()].copy_from_slice(bytes); + result } } @@ -283,7 +293,7 @@ mod tests { use super::AffinePoint; use crate::EncodedPoint; use elliptic_curve::{ - group::prime::PrimeCurveAffine, + group::{prime::PrimeCurveAffine, GroupEncoding}, sec1::{FromEncodedPoint, ToCompactEncodedPoint, ToEncodedPoint}, }; use hex_literal::hex; @@ -384,4 +394,15 @@ mod tests { let res = point.to_encoded_point(false); assert_eq!(res.as_bytes(), UNCOMPACT_BASEPOINT); } + + #[test] + fn identity_encoding() { + // This is technically an invalid SEC1 encoding, but is preferable to panicking. + assert_eq!([0; 33], AffinePoint::identity().to_bytes().as_slice()); + assert!(bool::from( + AffinePoint::from_bytes(&AffinePoint::identity().to_bytes()) + .unwrap() + .is_identity() + )) + } } diff --git a/p256/src/arithmetic/projective.rs b/p256/src/arithmetic/projective.rs index 24fc76191..71db51881 100644 --- a/p256/src/arithmetic/projective.rs +++ b/p256/src/arithmetic/projective.rs @@ -525,7 +525,7 @@ impl<'a> Neg for &'a ProjectivePoint { mod tests { use super::{AffinePoint, ProjectivePoint, Scalar}; use crate::test_vectors::group::{ADD_TEST_VECTORS, MUL_TEST_VECTORS}; - use elliptic_curve::group::{ff::PrimeField, prime::PrimeCurveAffine, GroupEncoding}; + use elliptic_curve::group::{ff::PrimeField, prime::PrimeCurveAffine, Group, GroupEncoding}; #[test] fn affine_to_projective() { @@ -671,8 +671,13 @@ mod tests { } #[test] - fn projective_identity_to_bytes() { + fn identity_encoding() { // This is technically an invalid SEC1 encoding, but is preferable to panicking. assert_eq!([0; 33], ProjectivePoint::identity().to_bytes().as_slice()); + assert!(bool::from( + ProjectivePoint::from_bytes(&ProjectivePoint::identity().to_bytes()) + .unwrap() + .is_identity() + )) } }