Skip to content

Commit

Permalink
refactor: use k256 and simplify bip32
Browse files Browse the repository at this point in the history
  • Loading branch information
James Prestwich committed Jan 5, 2021
1 parent ca69d8c commit 8ed0d5a
Show file tree
Hide file tree
Showing 37 changed files with 3,567 additions and 1,506 deletions.
45 changes: 45 additions & 0 deletions bip32-old/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[package]
name = "coins-bip32"
version = "0.1.0-beta.0"
authors = ["James Prestwich <james@prestwi.ch>"]
edition = "2018"
description = "Bip32 (and related BIPs) in Rust"
repository = "https://github.com/summa-tx/bitcoins-rs"
license = "MIT OR Apache-2.0"

[dependencies]
thiserror = "1.0"
hmac = "0.7.1"
sha2 = "0.8.0"
bs58 = "0.3.0"
lazy_static = "1.4.0"
coins-core = { path = "../core"}
serde = "1.0.105"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies.secp256k1]
version = "0.17.2"
features = ["recovery"]

[target.'cfg(target_arch = "wasm32")'.dependencies.libsecp256k1]
git = "https://github.com/paritytech/libsecp256k1.git"
default-features = false
features = ["std", "hmac"]

[target.'cfg(target_arch = "wasm32")'.dependencies.libsecp256k1-core]
git = "https://github.com/paritytech/libsecp256k1.git"
default-features = false
features = ["std"]

[dev-dependencies]
hex = "0.4.2"
criterion = "0.3.1"

[features]
default = ["mainnet"]
rust-secp-static-context = ["libsecp256k1/static-context"]
mainnet = []
testnet = []

[[bench]]
name = "bench"
harness = false
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
235 changes: 235 additions & 0 deletions bip32-old/src/defaults.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
use serde::{de::Visitor, ser::SerializeStruct};

use crate::enc::XKeyEncoder;

/// The default encoder, selected by feature flag
#[cfg(feature = "mainnet")]
pub type Encoder = crate::enc::MainnetEncoder;

/// The default encoder, selected by feature flag
#[cfg(feature = "testnet")]
pub type Encoder = crate::enc::TestnetEncoder;

impl std::str::FromStr for crate::XPriv {
type Err = crate::Bip32Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Encoder::xpriv_from_base58(s, Some(&crate::curve::BACKEND))
}
}

impl std::str::FromStr for crate::XPub {
type Err = crate::Bip32Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Encoder::xpub_from_base58(s, Some(&crate::curve::BACKEND))
}
}

impl serde::Serialize for crate::XPub {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let encoded =
Encoder::xpub_to_base58(self).map_err(|e| serde::ser::Error::custom(e.to_string()))?;
serializer.serialize_str(&encoded)
}
}

impl<'de> serde::Deserialize<'de> for crate::XPub {
fn deserialize<D>(deserializer: D) -> Result<crate::XPub, D::Error>
where
D: serde::Deserializer<'de>,
{
let s: &str = serde::Deserialize::deserialize(deserializer)?;
Encoder::xpub_from_base58(s, Some(crate::Secp256k1::static_ref()))
.map_err(|e| serde::de::Error::custom(e.to_string()))
}
}

impl serde::Serialize for crate::XPriv {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let encoded =
Encoder::xpriv_to_base58(self).map_err(|e| serde::ser::Error::custom(e.to_string()))?;
serializer.serialize_str(&encoded)
}
}

impl<'de> serde::Deserialize<'de> for crate::XPriv {
fn deserialize<D>(deserializer: D) -> Result<crate::XPriv, D::Error>
where
D: serde::Deserializer<'de>,
{
let s: &str = serde::Deserialize::deserialize(deserializer)?;
Encoder::xpriv_from_base58(s, Some(crate::Secp256k1::static_ref()))
.map_err(|e| serde::de::Error::custom(e.to_string()))
}
}

impl serde::Serialize for crate::DerivedXPriv {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut state = serializer.serialize_struct("DerivedXPriv", 2)?;
state.serialize_field("derivation", &self.derivation)?;
state.serialize_field("xpriv", &self.xpriv)?;
state.end()
}
}

struct DerivedXPrivVisitor;

impl<'de> Visitor<'de> for DerivedXPrivVisitor {
type Value = crate::DerivedXPriv;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("struct DerivedXPriv")
}

fn visit_seq<V>(self, mut seq: V) -> Result<crate::DerivedXPriv, V::Error>
where
V: serde::de::SeqAccess<'de>,
{
let xpriv = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
let derivation = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
Ok(crate::DerivedXPriv { xpriv, derivation })
}

fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
where
V: serde::de::MapAccess<'de>,
{
let mut xpriv = None;
let mut derivation = None;

#[derive(serde::Deserialize)]
#[serde(field_identifier, rename_all = "lowercase")]
enum Field {
XPriv,
Derivation,
}

while let Some(key) = map.next_key()? {
match key {
Field::XPriv => {
if xpriv.is_some() {
return Err(serde::de::Error::duplicate_field("xpriv"));
}
xpriv = Some(map.next_value()?);
}
Field::Derivation => {
if derivation.is_some() {
return Err(serde::de::Error::duplicate_field("derivation"));
}
derivation = Some(map.next_value()?);
}
}
}

let xpriv = xpriv.ok_or_else(|| serde::de::Error::missing_field("xpriv"))?;
let derivation = derivation.ok_or_else(|| serde::de::Error::missing_field("derivation"))?;

Ok(crate::DerivedXPriv { xpriv, derivation })
}
}

impl<'de> serde::Deserialize<'de> for crate::DerivedXPriv {
fn deserialize<D>(deserializer: D) -> Result<crate::DerivedXPriv, D::Error>
where
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &["xpriv", "derivation"];
deserializer.deserialize_struct("Duration", FIELDS, DerivedXPrivVisitor)
}
}

impl serde::Serialize for crate::DerivedXPub {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut state = serializer.serialize_struct("DerivedXPub", 2)?;
state.serialize_field("derivation", &self.derivation)?;
state.serialize_field("xpub", &self.xpub)?;
state.end()
}
}

struct DerivedXPubVisitor;

impl<'de> Visitor<'de> for DerivedXPubVisitor {
type Value = crate::DerivedXPub;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("struct DerivedXPub")
}

fn visit_seq<V>(self, mut seq: V) -> Result<crate::DerivedXPub, V::Error>
where
V: serde::de::SeqAccess<'de>,
{
let xpub = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
let derivation = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
Ok(crate::DerivedXPub { xpub, derivation })
}

fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
where
V: serde::de::MapAccess<'de>,
{
let mut xpub = None;
let mut derivation = None;

#[derive(serde::Deserialize)]
#[serde(field_identifier, rename_all = "lowercase")]
enum Field {
XPub,
Derivation,
}

while let Some(key) = map.next_key()? {
match key {
Field::XPub => {
if xpub.is_some() {
return Err(serde::de::Error::duplicate_field("xpub"));
}
xpub = Some(map.next_value()?);
}
Field::Derivation => {
if derivation.is_some() {
return Err(serde::de::Error::duplicate_field("derivation"));
}
derivation = Some(map.next_value()?);
}
}
}

let xpub = xpub.ok_or_else(|| serde::de::Error::missing_field("xpub"))?;
let derivation = derivation.ok_or_else(|| serde::de::Error::missing_field("derivation"))?;

Ok(crate::DerivedXPub { xpub, derivation })
}
}

impl<'de> serde::Deserialize<'de> for crate::DerivedXPub {
fn deserialize<D>(deserializer: D) -> Result<crate::DerivedXPub, D::Error>
where
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &["xpub", "derivation"];
deserializer.deserialize_struct("Duration", FIELDS, DerivedXPubVisitor)
}
}
Loading

0 comments on commit 8ed0d5a

Please sign in to comment.