Skip to content

Commit e75679e

Browse files
authored
p256: add serde Serialize/Deserialize impls (#465)
Adds impls of `serde` traits for the following types: - `AffinePoint` - `Scalar`
1 parent 388b62b commit e75679e

File tree

3 files changed

+88
-2
lines changed

3 files changed

+88
-2
lines changed

p256/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ digest = ["ecdsa-core/digest", "ecdsa-core/hazmat"]
4040
ecdh = ["arithmetic", "elliptic-curve/ecdh"]
4141
ecdsa = ["arithmetic", "ecdsa-core/sign", "ecdsa-core/verify", "sha256"]
4242
jwk = ["elliptic-curve/jwk"]
43-
pem = ["elliptic-curve/pem", "pkcs8"]
43+
pem = ["elliptic-curve/pem", "ecdsa-core/pem", "pkcs8"]
4444
pkcs8 = ["elliptic-curve/pkcs8"]
4545
serde = ["ecdsa-core/serde", "elliptic-curve/serde", "sec1/serde"]
4646
sha256 = ["digest", "sha2"]

p256/src/arithmetic/affine.rs

+44-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ use elliptic_curve::{
1111
sec1::{self, FromEncodedPoint, ToCompactEncodedPoint, ToEncodedPoint},
1212
subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption},
1313
zeroize::DefaultIsZeroes,
14-
AffineArithmetic, AffineXCoordinate, Curve, DecompactPoint, DecompressPoint,
14+
AffineArithmetic, AffineXCoordinate, Curve, DecompactPoint, DecompressPoint, Error, Result,
1515
};
1616

17+
#[cfg(feature = "serde")]
18+
use elliptic_curve::serde::{de, ser, Deserialize, Serialize};
19+
1720
impl AffineArithmetic for NistP256 {
1821
type AffinePoint = AffinePoint;
1922
}
@@ -251,6 +254,22 @@ impl ToCompactEncodedPoint<NistP256> for AffinePoint {
251254
}
252255
}
253256

257+
impl TryFrom<EncodedPoint> for AffinePoint {
258+
type Error = Error;
259+
260+
fn try_from(point: EncodedPoint) -> Result<AffinePoint> {
261+
AffinePoint::try_from(&point)
262+
}
263+
}
264+
265+
impl TryFrom<&EncodedPoint> for AffinePoint {
266+
type Error = Error;
267+
268+
fn try_from(point: &EncodedPoint) -> Result<AffinePoint> {
269+
Option::from(AffinePoint::from_encoded_point(point)).ok_or(Error)
270+
}
271+
}
272+
254273
impl From<AffinePoint> for EncodedPoint {
255274
/// Returns the SEC1 compressed encoding of this point.
256275
fn from(affine_point: AffinePoint) -> EncodedPoint {
@@ -286,6 +305,30 @@ impl Neg for AffinePoint {
286305
}
287306
}
288307

308+
#[cfg(feature = "serde")]
309+
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
310+
impl Serialize for AffinePoint {
311+
fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
312+
where
313+
S: ser::Serializer,
314+
{
315+
self.to_encoded_point(true).serialize(serializer)
316+
}
317+
}
318+
319+
#[cfg(feature = "serde")]
320+
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
321+
impl<'de> Deserialize<'de> for AffinePoint {
322+
fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
323+
where
324+
D: de::Deserializer<'de>,
325+
{
326+
EncodedPoint::deserialize(deserializer)?
327+
.try_into()
328+
.map_err(de::Error::custom)
329+
}
330+
}
331+
289332
#[cfg(test)]
290333
mod tests {
291334
use super::AffinePoint;

p256/src/arithmetic/scalar.rs

+43
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ use elliptic_curve::{
2424
#[cfg(feature = "bits")]
2525
use {crate::ScalarBits, elliptic_curve::group::ff::PrimeFieldBits};
2626

27+
#[cfg(feature = "serde")]
28+
use elliptic_curve::serde::{de, ser, Deserialize, Serialize};
29+
2730
/// Array containing 4 x 64-bit unsigned integers.
2831
// TODO(tarcieri): replace this entirely with `U256`
2932
type U64x4 = [u64; 4];
@@ -573,6 +576,24 @@ impl From<ScalarCore<NistP256>> for Scalar {
573576
}
574577
}
575578

579+
impl From<&ScalarCore<NistP256>> for Scalar {
580+
fn from(scalar: &ScalarCore<NistP256>) -> Scalar {
581+
Scalar(*scalar.as_uint())
582+
}
583+
}
584+
585+
impl From<Scalar> for ScalarCore<NistP256> {
586+
fn from(scalar: Scalar) -> ScalarCore<NistP256> {
587+
ScalarCore::from(&scalar)
588+
}
589+
}
590+
591+
impl From<&Scalar> for ScalarCore<NistP256> {
592+
fn from(scalar: &Scalar) -> ScalarCore<NistP256> {
593+
ScalarCore::new(scalar.0).unwrap()
594+
}
595+
}
596+
576597
impl From<Scalar> for U256 {
577598
fn from(scalar: Scalar) -> U256 {
578599
scalar.0
@@ -749,6 +770,28 @@ impl From<&SecretKey> for Scalar {
749770
}
750771
}
751772

773+
#[cfg(feature = "serde")]
774+
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
775+
impl Serialize for Scalar {
776+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
777+
where
778+
S: ser::Serializer,
779+
{
780+
ScalarCore::from(self).serialize(serializer)
781+
}
782+
}
783+
784+
#[cfg(feature = "serde")]
785+
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
786+
impl<'de> Deserialize<'de> for Scalar {
787+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
788+
where
789+
D: de::Deserializer<'de>,
790+
{
791+
Ok(ScalarCore::deserialize(deserializer)?.into())
792+
}
793+
}
794+
752795
/// Convert to a [`U64x4`] array.
753796
// TODO(tarcieri): implement all algorithms in terms of `U256`?
754797
#[cfg(target_pointer_width = "32")]

0 commit comments

Comments
 (0)