Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion elliptic-curve-crate/src/weierstrass/point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
//! <https://www.secg.org/sec1-v2.pdf>

use super::Curve;
use crate::ScalarBytes;
use core::ops::Add;
use generic_array::{typenum::U1, ArrayLength, GenericArray};
use generic_array::{
typenum::{Unsigned, U1},
ArrayLength, GenericArray,
};

/// Size of a compressed elliptic curve point for the given curve when
/// serialized using `Elliptic-Curve-Point-to-Octet-String` encoding
Expand Down Expand Up @@ -39,6 +43,19 @@ impl<C: Curve> CompressedPoint<C>
where
CompressedPointSize<C::ScalarSize>: ArrayLength<u8>,
{
/// Compress and serialize an elliptic curve point from its affine coordinates
pub fn from_affine_coords(
x: &ScalarBytes<C::ScalarSize>,
y: &ScalarBytes<C::ScalarSize>,
) -> Self {
// Is the y-coordinate odd in the SEC-1 sense: `self mod 2 == 1`?
let is_y_odd = y.as_ref().last().expect("last byte") & 1 == 1;
let mut bytes = GenericArray::default();
bytes[0] = if is_y_odd { 0x03 } else { 0x02 };
bytes[1..].copy_from_slice(x);
Self { bytes }
}

/// Create a new compressed elliptic curve point
pub fn from_bytes<B>(into_bytes: B) -> Option<Self>
where
Expand Down Expand Up @@ -114,6 +131,19 @@ where
<C::ScalarSize as Add>::Output: Add<U1>,
UncompressedPointSize<C::ScalarSize>: ArrayLength<u8>,
{
/// Serialize an elliptic curve point from its affine coordinates
pub fn from_affine_coords(
x: &ScalarBytes<C::ScalarSize>,
y: &ScalarBytes<C::ScalarSize>,
) -> Self {
let scalar_size = C::ScalarSize::to_usize();
let mut bytes = GenericArray::default();
bytes[0] = 0x04;
bytes[1..(scalar_size + 1)].copy_from_slice(x);
bytes[(scalar_size + 1)..].copy_from_slice(y);
Self { bytes }
}

/// Create a new uncompressed elliptic curve point
pub fn from_bytes<B>(into_bytes: B) -> Option<Self>
where
Expand Down
26 changes: 8 additions & 18 deletions k256/src/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pub use self::scalar::Scalar;
use core::convert::TryInto;
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use elliptic_curve::{
generic_array::GenericArray,
subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption},
weierstrass::FixedBaseScalarMul,
};
Expand Down Expand Up @@ -141,29 +140,20 @@ impl AffinePoint {
impl From<AffinePoint> for CompressedPoint {
/// Returns the SEC-1 compressed encoding of this point.
fn from(affine_point: AffinePoint) -> CompressedPoint {
let mut encoded = [0; 33];
encoded[0] = if affine_point.y.is_odd().into() {
0x03
} else {
0x02
};
encoded[1..33].copy_from_slice(&affine_point.x.to_bytes());

CompressedPoint::from_bytes(GenericArray::clone_from_slice(&encoded[..]))
.expect("we encoded it correctly")
CompressedPoint::from_affine_coords(
&affine_point.x.to_bytes().into(),
&affine_point.y.to_bytes().into(),
)
}
}

impl From<AffinePoint> for UncompressedPoint {
/// Returns the SEC-1 uncompressed encoding of this point.
fn from(affine_point: AffinePoint) -> UncompressedPoint {
let mut encoded = [0; 65];
encoded[0] = 0x04;
encoded[1..33].copy_from_slice(&affine_point.x.to_bytes());
encoded[33..65].copy_from_slice(&affine_point.y.to_bytes());

UncompressedPoint::from_bytes(GenericArray::clone_from_slice(&encoded[..]))
.expect("we encoded it correctly")
UncompressedPoint::from_affine_coords(
&affine_point.x.to_bytes().into(),
&affine_point.y.to_bytes().into(),
)
}
}

Expand Down
26 changes: 8 additions & 18 deletions p256/src/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pub use self::scalar::Scalar;
use core::convert::TryInto;
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use elliptic_curve::{
generic_array::GenericArray,
subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption},
weierstrass::FixedBaseScalarMul,
};
Expand Down Expand Up @@ -147,29 +146,20 @@ impl AffinePoint {
impl From<AffinePoint> for CompressedPoint {
/// Returns the SEC-1 compressed encoding of this point.
fn from(affine_point: AffinePoint) -> CompressedPoint {
let mut encoded = [0; 33];
encoded[0] = if affine_point.y.is_odd().into() {
0x03
} else {
0x02
};
encoded[1..33].copy_from_slice(&affine_point.x.to_bytes());

CompressedPoint::from_bytes(GenericArray::clone_from_slice(&encoded[..]))
.expect("we encoded it correctly")
CompressedPoint::from_affine_coords(
&affine_point.x.to_bytes().into(),
&affine_point.y.to_bytes().into(),
)
}
}

impl From<AffinePoint> for UncompressedPoint {
/// Returns the SEC-1 uncompressed encoding of this point.
fn from(affine_point: AffinePoint) -> UncompressedPoint {
let mut encoded = [0; 65];
encoded[0] = 0x04;
encoded[1..33].copy_from_slice(&affine_point.x.to_bytes());
encoded[33..65].copy_from_slice(&affine_point.y.to_bytes());

UncompressedPoint::from_bytes(GenericArray::clone_from_slice(&encoded[..]))
.expect("we encoded it correctly")
UncompressedPoint::from_affine_coords(
&affine_point.x.to_bytes().into(),
&affine_point.y.to_bytes().into(),
)
}
}

Expand Down