Skip to content

Commit

Permalink
Merge pull request #2 from dfns/serde
Browse files Browse the repository at this point in the history
Add `serde` support
  • Loading branch information
survived authored Feb 13, 2024
2 parents 6c6e5bf + 2c56587 commit 274696d
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 0 deletions.
106 changes: 106 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ sha2 = { version = "0.10", default-features = false }
subtle = { version = "2", default-features = false }
generic-array = "0.14"

serde = { version = "1", default-features = false, features = ["derive"], optional = true }

[dev-dependencies]
hex-literal = "0.4"

Expand All @@ -21,6 +23,7 @@ std = []
curve-secp256k1 = ["generic-ec/curve-secp256k1"]
curve-secp256r1 = ["generic-ec/curve-secp256r1"]
all-curves = ["curve-secp256k1", "curve-secp256r1"]
serde = ["dep:serde", "generic-ec/serde"]

[[test]]
name = "test_vectors"
Expand Down
60 changes: 60 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ pub const H: u32 = 1 << 31;

/// Child index, whether hardened or not
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize), serde(into = "u32"))]
#[cfg_attr(feature = "serde", derive(serde::Deserialize), serde(from = "u32"))]
pub enum ChildIndex {
/// Hardened index
Hardened(HardenedIndex),
Expand All @@ -95,14 +97,23 @@ pub enum ChildIndex {

/// Child index in range $2^{31} \le i < 2^{32}$ corresponing to a hardened wallet
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize), serde(into = "u32"))]
#[cfg_attr(feature = "serde", derive(serde::Deserialize), serde(try_from = "u32"))]
pub struct HardenedIndex(u32);

/// Child index in range $0 \le i < 2^{31}$ corresponing to a non-hardened wallet
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize), serde(into = "u32"))]
#[cfg_attr(feature = "serde", derive(serde::Deserialize), serde(try_from = "u32"))]
pub struct NonHardenedIndex(u32);

/// Extended public key
#[derive(Clone, Copy, Debug)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(bound = "")
)]
pub struct ExtendedPublicKey<E: Curve> {
/// The public key that can be used for signature verification
pub public_key: Point<E>,
Expand All @@ -112,6 +123,11 @@ pub struct ExtendedPublicKey<E: Curve> {

/// Extended secret key
#[derive(Clone, Debug)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(bound = "")
)]
pub struct ExtendedSecretKey<E: Curve> {
/// The secret key that can be used for signing
pub secret_key: SecretScalar<E>,
Expand All @@ -131,6 +147,11 @@ pub struct ExtendedKeyPair<E: Curve> {
/// It contains an already derived child public key as it needs to be derived
/// in process of calculating the shift value
#[derive(Clone, Copy, Debug)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(bound = "")
)]
pub struct DerivedShift<E: Curve> {
/// Derived shift
pub shift: Scalar<E>,
Expand Down Expand Up @@ -200,6 +221,24 @@ impl TryFrom<u32> for NonHardenedIndex {
}
}
}
impl From<ChildIndex> for u32 {
fn from(value: ChildIndex) -> Self {
match value {
ChildIndex::Hardened(v) => v.0,
ChildIndex::NonHardened(v) => v.0,
}
}
}
impl From<HardenedIndex> for u32 {
fn from(value: HardenedIndex) -> Self {
value.0
}
}
impl From<NonHardenedIndex> for u32 {
fn from(value: NonHardenedIndex) -> Self {
value.0
}
}
impl core::str::FromStr for ChildIndex {
type Err = core::num::ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Expand Down Expand Up @@ -261,6 +300,27 @@ impl<E: Curve> ExtendedKeyPair<E> {
}
}

#[cfg(feature = "serde")]
impl<E: Curve> serde::Serialize for ExtendedKeyPair<E> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.secret_key.serialize(serializer)
}
}

#[cfg(feature = "serde")]
impl<'de, E: Curve> serde::Deserialize<'de> for ExtendedKeyPair<E> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let secret_key = ExtendedSecretKey::<E>::deserialize(deserializer)?;
Ok(secret_key.into())
}
}

/// Marker for a curve supported by SLIP10 specs and this library
///
/// Only implement this trait for the curves that are supported by SLIP10 specs.
Expand Down

0 comments on commit 274696d

Please sign in to comment.