Skip to content

Commit

Permalink
Use GenericArray for storing serialized points
Browse files Browse the repository at this point in the history
  • Loading branch information
Denis Varlakov committed Aug 26, 2021
1 parent 0bbaebc commit d973d16
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 58 deletions.
16 changes: 9 additions & 7 deletions src/elliptic/curves/bls12_381/g1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use std::fmt;

use ff_zeroize::PrimeField;
use generic_array::GenericArray;
use pairing_plus::bls12_381::{G1Compressed, G1Uncompressed, G1};
use pairing_plus::hash_to_curve::HashToCurve;
use pairing_plus::hash_to_field::ExpandMsgXmd;
Expand Down Expand Up @@ -72,8 +73,8 @@ impl ECPoint for G1Point {
type Scalar = FieldScalar;
type Underlying = PK;

type CompressedPoint = G1Compressed;
type UncompressedPoint = G1Uncompressed;
type CompressedPointLength = typenum::U48;
type UncompressedPointLength = typenum::U96;

fn zero() -> G1Point {
G1Point {
Expand Down Expand Up @@ -150,12 +151,12 @@ impl ECPoint for G1Point {
}
}

fn serialize_compressed(&self) -> Self::CompressedPoint {
G1Compressed::from_affine(self.ge)
fn serialize_compressed(&self) -> GenericArray<u8, Self::CompressedPointLength> {
*GenericArray::from_slice(G1Compressed::from_affine(self.ge).as_ref())
}

fn serialize_uncompressed(&self) -> Self::UncompressedPoint {
G1Uncompressed::from_affine(self.ge)
fn serialize_uncompressed(&self) -> GenericArray<u8, Self::UncompressedPointLength> {
*GenericArray::from_slice(G1Uncompressed::from_affine(self.ge).as_ref())
}

fn deserialize(bytes: &[u8]) -> Result<G1Point, DeserializationError> {
Expand Down Expand Up @@ -290,7 +291,8 @@ mod tests {
// Generate base_point2
let cs = &[1u8];
let msg = &[1u8];
let point = <G1 as HashToCurve<ExpandMsgXmd<old_sha2::Sha256>>>::hash_to_curve(msg, cs).into_affine();
let point = <G1 as HashToCurve<ExpandMsgXmd<old_sha2::Sha256>>>::hash_to_curve(msg, cs)
.into_affine();
assert!(point.in_subgroup());

// Print in uncompressed form
Expand Down
16 changes: 9 additions & 7 deletions src/elliptic/curves/bls12_381/g2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use std::fmt;

use ff_zeroize::{PrimeField, ScalarEngine};
use generic_array::GenericArray;
use pairing_plus::bls12_381::{G2Compressed, G2Uncompressed, G2};
use pairing_plus::hash_to_curve::HashToCurve;
use pairing_plus::hash_to_field::ExpandMsgXmd;
Expand Down Expand Up @@ -79,8 +80,8 @@ impl ECPoint for G2Point {
type Scalar = FieldScalar;
type Underlying = PK;

type CompressedPoint = G2Compressed;
type UncompressedPoint = G2Uncompressed;
type CompressedPointLength = typenum::U96;
type UncompressedPointLength = typenum::U192;

fn zero() -> G2Point {
G2Point {
Expand Down Expand Up @@ -157,12 +158,12 @@ impl ECPoint for G2Point {
}
}

fn serialize_compressed(&self) -> Self::CompressedPoint {
G2Compressed::from_affine(self.ge)
fn serialize_compressed(&self) -> GenericArray<u8, Self::CompressedPointLength> {
*GenericArray::from_slice(G2Compressed::from_affine(self.ge).as_ref())
}

fn serialize_uncompressed(&self) -> Self::UncompressedPoint {
G2Uncompressed::from_affine(self.ge)
fn serialize_uncompressed(&self) -> GenericArray<u8, Self::UncompressedPointLength> {
*GenericArray::from_slice(G2Uncompressed::from_affine(self.ge).as_ref())
}

fn deserialize(bytes: &[u8]) -> Result<G2Point, DeserializationError> {
Expand Down Expand Up @@ -292,7 +293,8 @@ mod tests {
// Generate base_point2
let cs = &[1u8];
let msg = &[1u8];
let point = <G2 as HashToCurve<ExpandMsgXmd<old_sha2::Sha256>>>::hash_to_curve(msg, cs).into_affine();
let point = <G2 as HashToCurve<ExpandMsgXmd<old_sha2::Sha256>>>::hash_to_curve(msg, cs)
.into_affine();
assert!(point.in_subgroup());

// Print in uncompressed form
Expand Down
12 changes: 6 additions & 6 deletions src/elliptic/curves/curve_ristretto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ impl ECPoint for RistrettoPoint {
type Scalar = RistrettoScalar;
type Underlying = PK;

type CompressedPoint = [u8; 32];
type UncompressedPoint = [u8; 32];
type CompressedPointLength = typenum::U32;
type UncompressedPointLength = typenum::U32;

fn zero() -> RistrettoPoint {
RistrettoPoint {
Expand Down Expand Up @@ -254,12 +254,12 @@ impl ECPoint for RistrettoPoint {
None
}

fn serialize_compressed(&self) -> Self::CompressedPoint {
self.ge.compress().to_bytes()
fn serialize_compressed(&self) -> GenericArray<u8, Self::CompressedPointLength> {
GenericArray::from(self.ge.compress().to_bytes())
}

fn serialize_uncompressed(&self) -> Self::UncompressedPoint {
self.ge.compress().to_bytes()
fn serialize_uncompressed(&self) -> GenericArray<u8, Self::UncompressedPointLength> {
GenericArray::from(self.ge.compress().to_bytes())
}

fn deserialize(bytes: &[u8]) -> Result<RistrettoPoint, DeserializationError> {
Expand Down
12 changes: 6 additions & 6 deletions src/elliptic/curves/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ impl ECPoint for Ed25519Point {
type Underlying = PK;
type Scalar = Ed25519Scalar;

type CompressedPoint = [u8; 32];
type UncompressedPoint = [u8; 32];
type CompressedPointLength = typenum::U32;
type UncompressedPointLength = typenum::U32;

fn zero() -> Ed25519Point {
*ZERO
Expand Down Expand Up @@ -362,12 +362,12 @@ impl ECPoint for Ed25519Point {
Some(PointCoords { x: xrecover(&y), y })
}

fn serialize_compressed(&self) -> Self::CompressedPoint {
self.ge.to_bytes()
fn serialize_compressed(&self) -> GenericArray<u8, Self::CompressedPointLength> {
GenericArray::from(self.ge.to_bytes())
}

fn serialize_uncompressed(&self) -> Self::UncompressedPoint {
self.ge.to_bytes()
fn serialize_uncompressed(&self) -> GenericArray<u8, Self::UncompressedPointLength> {
GenericArray::from(self.ge.to_bytes())
}

fn deserialize(bytes: &[u8]) -> Result<Ed25519Point, DeserializationError> {
Expand Down
37 changes: 26 additions & 11 deletions src/elliptic/curves/p256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ impl ECPoint for Secp256r1Point {
type Scalar = Secp256r1Scalar;
type Underlying = PK;

type CompressedPoint = EncodedPoint;
type UncompressedPoint = EncodedPoint;
type CompressedPointLength = typenum::U33;
type UncompressedPointLength = typenum::U65;

fn zero() -> Secp256r1Point {
Secp256r1Point {
Expand Down Expand Up @@ -280,20 +280,35 @@ impl ECPoint for Secp256r1Point {
Some(PointCoords { x, y })
}

fn serialize_compressed(&self) -> Self::CompressedPoint {
self.ge.to_encoded_point(true)
fn serialize_compressed(&self) -> GenericArray<u8, Self::CompressedPointLength> {
if self.is_zero() {
*GenericArray::from_slice(&[0u8; 33])
} else {
*GenericArray::from_slice(self.ge.to_encoded_point(true).as_ref())
}
}

fn serialize_uncompressed(&self) -> Self::UncompressedPoint {
self.ge.to_encoded_point(false)
fn serialize_uncompressed(&self) -> GenericArray<u8, Self::UncompressedPointLength> {
if self.is_zero() {
*GenericArray::from_slice(&[0u8; 65])
} else {
*GenericArray::from_slice(self.ge.to_encoded_point(false).as_ref())
}
}

fn deserialize(bytes: &[u8]) -> Result<Self, DeserializationError> {
let encoded = EncodedPoint::from_bytes(bytes).map_err(|_| DeserializationError)?;
Ok(Secp256r1Point {
purpose: "deserialize",
ge: AffinePoint::from_encoded_point(&encoded).ok_or(DeserializationError)?,
})
if bytes == [0; 33] || bytes == [0; 65] {
Ok(Secp256r1Point {
purpose: "deserialize",
ge: Self::zero().ge,
})
} else {
let encoded = EncodedPoint::from_bytes(bytes).map_err(|_| DeserializationError)?;
Ok(Secp256r1Point {
purpose: "deserialize",
ge: AffinePoint::from_encoded_point(&encoded).ok_or(DeserializationError)?,
})
}
}

fn check_point_order_equals_group_order(&self) -> bool {
Expand Down
16 changes: 8 additions & 8 deletions src/elliptic/curves/secp256_k1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,8 @@ impl ECPoint for Secp256k1Point {
type Scalar = Secp256k1Scalar;
type Underlying = Option<PK>;

type CompressedPoint = [u8; 33];
type UncompressedPoint = [u8; 65];
type CompressedPointLength = typenum::U33;
type UncompressedPointLength = typenum::U65;

fn zero() -> Secp256k1Point {
Secp256k1Point {
Expand Down Expand Up @@ -397,17 +397,17 @@ impl ECPoint for Secp256k1Point {
}
}

fn serialize_compressed(&self) -> Self::CompressedPoint {
fn serialize_compressed(&self) -> GenericArray<u8, Self::CompressedPointLength> {
match self.ge {
None => [0u8; 33],
Some(ge) => ge.serialize(),
None => *GenericArray::from_slice(&[0u8; 33]),
Some(ge) => *GenericArray::from_slice(&ge.serialize()),
}
}

fn serialize_uncompressed(&self) -> Self::UncompressedPoint {
fn serialize_uncompressed(&self) -> GenericArray<u8, Self::UncompressedPointLength> {
match self.ge {
None => [0u8; 65],
Some(ge) => ge.serialize_uncompressed(),
None => *GenericArray::from_slice(&[0u8; 65]),
Some(ge) => *GenericArray::from_slice(&ge.serialize_uncompressed()),
}
}

Expand Down
18 changes: 7 additions & 11 deletions src/elliptic/curves/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub trait ECScalar: Clone + PartialEq + fmt::Debug + 'static {
type Underlying;

// TODO: Replace with const generics once https://github.com/rust-lang/rust/issues/60551 is resolved
/// The byte length of the serialized scalar
/// The byte length of serialized scalar
type ScalarLength: ArrayLength<u8> + Unsigned;

/// Samples a random scalar
Expand Down Expand Up @@ -117,14 +117,10 @@ pub trait ECPoint: Zeroize + Clone + PartialEq + fmt::Debug + 'static {
/// Underlying curve implementation that can be retrieved in case of missing methods in this trait
type Underlying;

/// Point serialized in compressed form
///
/// Usually represented as byte array `[u8; COMPRESSED_LEN]`
type CompressedPoint: AsRef<[u8]>;
/// Point serialized in uncompressed form
///
/// Usually represented as byte array `[u8; UNCOMPRESSED_LEN]`
type UncompressedPoint: AsRef<[u8]>;
/// The byte length of point serialized in compressed form
type CompressedPointLength: ArrayLength<u8> + Unsigned;
/// The byte length of point serialized in uncompressed form
type UncompressedPointLength: ArrayLength<u8> + Unsigned;

/// Zero point
///
Expand Down Expand Up @@ -167,11 +163,11 @@ pub trait ECPoint: Zeroize + Clone + PartialEq + fmt::Debug + 'static {
/// Serializes point into bytes in compressed
///
/// Serialization must always succeed even if it's point at infinity.
fn serialize_compressed(&self) -> Self::CompressedPoint;
fn serialize_compressed(&self) -> GenericArray<u8, Self::CompressedPointLength>;
/// Serializes point into bytes in uncompressed
///
/// Serialization must always succeed even if it's point at infinity.
fn serialize_uncompressed(&self) -> Self::UncompressedPoint;
fn serialize_uncompressed(&self) -> GenericArray<u8, Self::UncompressedPointLength>;
/// Deserializes point from bytes
///
/// Whether point in compressed or uncompressed form will be deducted from its size
Expand Down
6 changes: 4 additions & 2 deletions src/elliptic/curves/wrappers/encoded_point.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use std::ops::Deref;

use generic_array::GenericArray;

use crate::elliptic::curves::{Curve, ECPoint};

/// Point encoded in (un)compressed form
pub struct EncodedPoint<E: Curve>(pub(super) EncodedPointChoice<E>);

pub(super) enum EncodedPointChoice<E: Curve> {
Compressed(<E::Point as ECPoint>::CompressedPoint),
Uncompressed(<E::Point as ECPoint>::UncompressedPoint),
Compressed(GenericArray<u8, <E::Point as ECPoint>::CompressedPointLength>),
Uncompressed(GenericArray<u8, <E::Point as ECPoint>::UncompressedPointLength>),
}

impl<E: Curve> Deref for EncodedPoint<E> {
Expand Down

0 comments on commit d973d16

Please sign in to comment.