Merge pull request #337 from TheBlueMatt/2019-10-less-deps
Drop hex and byteorder (non-test) deps (and disable useless lints)
This commit is contained in:
commit
3e1e4f92b7
|
@ -17,19 +17,19 @@ path = "src/lib.rs"
|
||||||
[features]
|
[features]
|
||||||
fuzztarget = ["secp256k1/fuzztarget", "bitcoin_hashes/fuzztarget"]
|
fuzztarget = ["secp256k1/fuzztarget", "bitcoin_hashes/fuzztarget"]
|
||||||
unstable = []
|
unstable = []
|
||||||
use-serde = ["serde", "bitcoin_hashes/serde", "secp256k1/serde"]
|
|
||||||
rand = ["secp256k1/rand"]
|
rand = ["secp256k1/rand"]
|
||||||
|
use-serde = ["hex", "serde", "bitcoin_hashes/serde", "secp256k1/serde"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bech32 = "0.7.1"
|
bech32 = "0.7.1"
|
||||||
byteorder = "1.2"
|
|
||||||
bitcoin_hashes = "0.7"
|
bitcoin_hashes = "0.7"
|
||||||
bitcoinconsensus = { version = "0.17", optional = true }
|
bitcoinconsensus = { version = "0.17", optional = true }
|
||||||
serde = { version = "1", optional = true }
|
serde = { version = "1", optional = true }
|
||||||
|
hex = { version = "=0.3.2", optional = true }
|
||||||
secp256k1 = "0.15"
|
secp256k1 = "0.15"
|
||||||
hex = "=0.3.2"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
hex = "=0.3.2"
|
||||||
serde_derive = "<1.0.99"
|
serde_derive = "<1.0.99"
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
serde_test = "1"
|
serde_test = "1"
|
||||||
|
|
|
@ -165,15 +165,13 @@ impl BlockHeader {
|
||||||
|
|
||||||
/// Checks that the proof-of-work for the block is valid.
|
/// Checks that the proof-of-work for the block is valid.
|
||||||
pub fn validate_pow(&self, required_target: &Uint256) -> Result<(), util::Error> {
|
pub fn validate_pow(&self, required_target: &Uint256) -> Result<(), util::Error> {
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
|
||||||
|
|
||||||
let target = &self.target();
|
let target = &self.target();
|
||||||
if target != required_target {
|
if target != required_target {
|
||||||
return Err(BlockBadTarget);
|
return Err(BlockBadTarget);
|
||||||
}
|
}
|
||||||
let data: [u8; 32] = self.bitcoin_hash().into_inner();
|
let data: [u8; 32] = self.bitcoin_hash().into_inner();
|
||||||
let mut ret = [0u64; 4];
|
let mut ret = [0u64; 4];
|
||||||
LittleEndian::read_u64_into(&data, &mut ret);
|
util::endian::bytes_to_u64_slice_le(&data, &mut ret);
|
||||||
let hash = &Uint256(ret);
|
let hash = &Uint256(ret);
|
||||||
if hash <= target { Ok(()) } else { Err(BlockBadProofOfWork) }
|
if hash <= target { Ok(()) } else { Err(BlockBadProofOfWork) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,13 +23,13 @@
|
||||||
//! This module provides the structures and functions needed to support transactions.
|
//! This module provides the structures and functions needed to support transactions.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use byteorder::{LittleEndian, WriteBytesExt};
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::{fmt, io};
|
use std::{fmt, io};
|
||||||
|
|
||||||
use hashes::{self, sha256d, Hash};
|
use hashes::{self, sha256d, Hash};
|
||||||
use hashes::hex::FromHex;
|
use hashes::hex::FromHex;
|
||||||
|
|
||||||
|
use util::endian;
|
||||||
use util::hash::BitcoinHash;
|
use util::hash::BitcoinHash;
|
||||||
#[cfg(feature="bitcoinconsensus")] use blockdata::script;
|
#[cfg(feature="bitcoinconsensus")] use blockdata::script;
|
||||||
use blockdata::script::Script;
|
use blockdata::script::Script;
|
||||||
|
@ -358,7 +358,7 @@ impl Transaction {
|
||||||
};
|
};
|
||||||
// hash the result
|
// hash the result
|
||||||
let mut raw_vec = serialize(&tx);
|
let mut raw_vec = serialize(&tx);
|
||||||
raw_vec.write_u32::<LittleEndian>(sighash_u32).unwrap();
|
raw_vec.extend_from_slice(&endian::u32_to_array_le(sighash_u32));
|
||||||
sha256d::Hash::hash(&raw_vec)
|
sha256d::Hash::hash(&raw_vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,12 +35,12 @@ use std::error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{Cursor, Read, Write};
|
use std::io::{Cursor, Read, Write};
|
||||||
use byteorder::{LittleEndian, WriteBytesExt, ReadBytesExt};
|
use hashes::hex::ToHex;
|
||||||
use hex::encode as hex_encode;
|
|
||||||
|
|
||||||
use hashes::{sha256d, Hash as HashTrait};
|
use hashes::{sha256d, Hash as HashTrait};
|
||||||
use secp256k1;
|
use secp256k1;
|
||||||
|
|
||||||
|
use util::endian;
|
||||||
use util::base58;
|
use util::base58;
|
||||||
use util::psbt;
|
use util::psbt;
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ impl fmt::Display for Error {
|
||||||
Error::Psbt(ref e) => fmt::Display::fmt(e, f),
|
Error::Psbt(ref e) => fmt::Display::fmt(e, f),
|
||||||
Error::UnexpectedNetworkMagic { expected: ref e, actual: ref a } => write!(f, "{}: expected {}, actual {}", error::Error::description(self), e, a),
|
Error::UnexpectedNetworkMagic { expected: ref e, actual: ref a } => write!(f, "{}: expected {}, actual {}", error::Error::description(self), e, a),
|
||||||
Error::OversizedVectorAllocation { requested: ref r, max: ref m } => write!(f, "{}: requested {}, maximum {}", error::Error::description(self), r, m),
|
Error::OversizedVectorAllocation { requested: ref r, max: ref m } => write!(f, "{}: requested {}, maximum {}", error::Error::description(self), r, m),
|
||||||
Error::InvalidChecksum { expected: ref e, actual: ref a } => write!(f, "{}: expected {}, actual {}", error::Error::description(self), hex_encode(e), hex_encode(a)),
|
Error::InvalidChecksum { expected: ref e, actual: ref a } => write!(f, "{}: expected {}, actual {}", error::Error::description(self), e[..].to_hex(), a[..].to_hex()),
|
||||||
Error::UnknownNetworkMagic(ref m) => write!(f, "{}: {}", error::Error::description(self), m),
|
Error::UnknownNetworkMagic(ref m) => write!(f, "{}: {}", error::Error::description(self), m),
|
||||||
Error::ParseFailed(ref e) => write!(f, "{}: {}", error::Error::description(self), e),
|
Error::ParseFailed(ref e) => write!(f, "{}: {}", error::Error::description(self), e),
|
||||||
Error::UnsupportedSegwitFlag(ref swflag) => write!(f, "{}: {}", error::Error::description(self), swflag),
|
Error::UnsupportedSegwitFlag(ref swflag) => write!(f, "{}: {}", error::Error::description(self), swflag),
|
||||||
|
@ -189,7 +189,7 @@ pub fn serialize<T: Encodable + ?Sized>(data: &T) -> Vec<u8> {
|
||||||
|
|
||||||
/// Encode an object into a hex-encoded string
|
/// Encode an object into a hex-encoded string
|
||||||
pub fn serialize_hex<T: Encodable + ?Sized>(data: &T) -> String {
|
pub fn serialize_hex<T: Encodable + ?Sized>(data: &T) -> String {
|
||||||
hex_encode(serialize(data))
|
serialize(data)[..].to_hex()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserialize an object from a vector, will error if said deserialization
|
/// Deserialize an object from a vector, will error if said deserialization
|
||||||
|
@ -276,39 +276,42 @@ macro_rules! encoder_fn {
|
||||||
($name:ident, $val_type:ty, $writefn:ident) => {
|
($name:ident, $val_type:ty, $writefn:ident) => {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $name(&mut self, v: $val_type) -> Result<(), Error> {
|
fn $name(&mut self, v: $val_type) -> Result<(), Error> {
|
||||||
WriteBytesExt::$writefn::<LittleEndian>(self, v).map_err(Error::Io)
|
self.write_all(&endian::$writefn(v)).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! decoder_fn {
|
macro_rules! decoder_fn {
|
||||||
($name:ident, $val_type:ty, $readfn:ident) => {
|
($name:ident, $val_type:ty, $readfn:ident, $byte_len: expr) => {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $name(&mut self) -> Result<$val_type, Error> {
|
fn $name(&mut self) -> Result<$val_type, Error> {
|
||||||
ReadBytesExt::$readfn::<LittleEndian>(self).map_err(Error::Io)
|
assert_eq!(::std::mem::size_of::<$val_type>(), $byte_len); // size_of isn't a constfn in 1.22
|
||||||
|
let mut val = [0; $byte_len];
|
||||||
|
self.read_exact(&mut val[..]).map_err(Error::Io)?;
|
||||||
|
Ok(endian::$readfn(&val))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: Write> WriteExt for W {
|
impl<W: Write> WriteExt for W {
|
||||||
encoder_fn!(emit_u64, u64, write_u64);
|
encoder_fn!(emit_u64, u64, u64_to_array_le);
|
||||||
encoder_fn!(emit_u32, u32, write_u32);
|
encoder_fn!(emit_u32, u32, u32_to_array_le);
|
||||||
encoder_fn!(emit_u16, u16, write_u16);
|
encoder_fn!(emit_u16, u16, u16_to_array_le);
|
||||||
encoder_fn!(emit_i64, i64, write_i64);
|
encoder_fn!(emit_i64, i64, i64_to_array_le);
|
||||||
encoder_fn!(emit_i32, i32, write_i32);
|
encoder_fn!(emit_i32, i32, i32_to_array_le);
|
||||||
encoder_fn!(emit_i16, i16, write_i16);
|
encoder_fn!(emit_i16, i16, i16_to_array_le);
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn emit_i8(&mut self, v: i8) -> Result<(), Error> {
|
fn emit_i8(&mut self, v: i8) -> Result<(), Error> {
|
||||||
self.write_i8(v).map_err(Error::Io)
|
self.write_all(&[v as u8]).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn emit_u8(&mut self, v: u8) -> Result<(), Error> {
|
fn emit_u8(&mut self, v: u8) -> Result<(), Error> {
|
||||||
self.write_u8(v).map_err(Error::Io)
|
self.write_all(&[v]).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn emit_bool(&mut self, v: bool) -> Result<(), Error> {
|
fn emit_bool(&mut self, v: bool) -> Result<(), Error> {
|
||||||
self.write_i8(if v {1} else {0}).map_err(Error::Io)
|
self.write_all(&[if v {1} else {0}]).map_err(Error::Io)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn emit_slice(&mut self, v: &[u8]) -> Result<(), Error> {
|
fn emit_slice(&mut self, v: &[u8]) -> Result<(), Error> {
|
||||||
|
@ -317,20 +320,24 @@ impl<W: Write> WriteExt for W {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read> ReadExt for R {
|
impl<R: Read> ReadExt for R {
|
||||||
decoder_fn!(read_u64, u64, read_u64);
|
decoder_fn!(read_u64, u64, slice_to_u64_le, 8);
|
||||||
decoder_fn!(read_u32, u32, read_u32);
|
decoder_fn!(read_u32, u32, slice_to_u32_le, 4);
|
||||||
decoder_fn!(read_u16, u16, read_u16);
|
decoder_fn!(read_u16, u16, slice_to_u16_le, 2);
|
||||||
decoder_fn!(read_i64, i64, read_i64);
|
decoder_fn!(read_i64, i64, slice_to_i64_le, 8);
|
||||||
decoder_fn!(read_i32, i32, read_i32);
|
decoder_fn!(read_i32, i32, slice_to_i32_le, 4);
|
||||||
decoder_fn!(read_i16, i16, read_i16);
|
decoder_fn!(read_i16, i16, slice_to_i16_le, 2);
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_u8(&mut self) -> Result<u8, Error> {
|
fn read_u8(&mut self) -> Result<u8, Error> {
|
||||||
ReadBytesExt::read_u8(self).map_err(Error::Io)
|
let mut slice = [0u8; 1];
|
||||||
|
self.read_exact(&mut slice)?;
|
||||||
|
Ok(slice[0])
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_i8(&mut self) -> Result<i8, Error> {
|
fn read_i8(&mut self) -> Result<i8, Error> {
|
||||||
ReadBytesExt::read_i8(self).map_err(Error::Io)
|
let mut slice = [0u8; 1];
|
||||||
|
self.read_exact(&mut slice)?;
|
||||||
|
Ok(slice[0] as i8)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_bool(&mut self) -> Result<bool, Error> {
|
fn read_bool(&mut self) -> Result<bool, Error> {
|
||||||
|
|
|
@ -45,14 +45,18 @@
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
|
|
||||||
|
// In general, rust is absolutely horrid at supporting users doing things like,
|
||||||
|
// for example, compiling Rust code for real environments. Disable useless lints
|
||||||
|
// that don't do anything but annoy us and cant actually ever be resolved.
|
||||||
|
#![allow(bare_trait_objects)]
|
||||||
|
#![allow(ellipsis_inclusive_range_patterns)]
|
||||||
|
|
||||||
// Re-exported dependencies.
|
// Re-exported dependencies.
|
||||||
pub extern crate bitcoin_hashes as hashes;
|
pub extern crate bitcoin_hashes as hashes;
|
||||||
pub extern crate secp256k1;
|
pub extern crate secp256k1;
|
||||||
pub extern crate bech32;
|
pub extern crate bech32;
|
||||||
|
|
||||||
extern crate byteorder;
|
#[cfg(any(test, feature = "serde"))] extern crate hex;
|
||||||
extern crate hex;
|
|
||||||
#[cfg(feature = "serde")] extern crate serde;
|
#[cfg(feature = "serde")] extern crate serde;
|
||||||
#[cfg(all(test, feature = "serde"))] #[macro_use] extern crate serde_derive; // for 1.22.0 compat
|
#[cfg(all(test, feature = "serde"))] #[macro_use] extern crate serde_derive; // for 1.22.0 compat
|
||||||
#[cfg(all(test, feature = "serde"))] extern crate serde_json;
|
#[cfg(all(test, feature = "serde"))] extern crate serde_json;
|
||||||
|
|
|
@ -23,7 +23,6 @@ use network::constants;
|
||||||
use consensus::{Encodable, Decodable, ReadExt};
|
use consensus::{Encodable, Decodable, ReadExt};
|
||||||
use consensus::encode;
|
use consensus::encode;
|
||||||
use std::io;
|
use std::io;
|
||||||
use byteorder::WriteBytesExt;
|
|
||||||
use network::message_network::RejectReason::{MALFORMED, INVALID, OBSOLETE, DUPLICATE, NONSTANDARD, DUST, CHECKPOINT, FEE};
|
use network::message_network::RejectReason::{MALFORMED, INVALID, OBSOLETE, DUPLICATE, NONSTANDARD, DUST, CHECKPOINT, FEE};
|
||||||
use hashes::sha256d;
|
use hashes::sha256d;
|
||||||
|
|
||||||
|
@ -107,7 +106,7 @@ pub enum RejectReason {
|
||||||
|
|
||||||
impl Encodable for RejectReason {
|
impl Encodable for RejectReason {
|
||||||
fn consensus_encode<W: io::Write>(&self, mut e: W) -> Result<usize, encode::Error> {
|
fn consensus_encode<W: io::Write>(&self, mut e: W) -> Result<usize, encode::Error> {
|
||||||
e.write_u8(*self as u8)?;
|
e.write_all(&[*self as u8])?;
|
||||||
Ok(1)
|
Ok(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
|
|
||||||
use std::{error, fmt, str, slice, iter};
|
use std::{error, fmt, str, slice, iter};
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
|
||||||
|
|
||||||
use hashes::{sha256d, Hash};
|
use hashes::{sha256d, Hash};
|
||||||
|
|
||||||
|
use util::endian;
|
||||||
|
|
||||||
/// An error that might occur during base58 decoding
|
/// An error that might occur during base58 decoding
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
@ -162,8 +162,8 @@ pub fn from_check(data: &str) -> Result<Vec<u8>, Error> {
|
||||||
return Err(Error::TooShort(ret.len()));
|
return Err(Error::TooShort(ret.len()));
|
||||||
}
|
}
|
||||||
let ck_start = ret.len() - 4;
|
let ck_start = ret.len() - 4;
|
||||||
let expected = LittleEndian::read_u32(&sha256d::Hash::hash(&ret[..ck_start])[..4]);
|
let expected = endian::slice_to_u32_le(&sha256d::Hash::hash(&ret[..ck_start])[..4]);
|
||||||
let actual = LittleEndian::read_u32(&ret[ck_start..(ck_start + 4)]);
|
let actual = endian::slice_to_u32_le(&ret[ck_start..(ck_start + 4)]);
|
||||||
if expected != actual {
|
if expected != actual {
|
||||||
return Err(Error::BadChecksum(expected, actual));
|
return Err(Error::BadChecksum(expected, actual));
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,13 +51,13 @@ use std::fmt::{Display, Formatter};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use hashes::{Hash, sha256d, siphash24};
|
use hashes::{Hash, sha256d, siphash24};
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
|
||||||
|
|
||||||
use blockdata::block::Block;
|
use blockdata::block::Block;
|
||||||
use blockdata::script::Script;
|
use blockdata::script::Script;
|
||||||
use blockdata::transaction::OutPoint;
|
use blockdata::transaction::OutPoint;
|
||||||
use consensus::{Decodable, Encodable};
|
use consensus::{Decodable, Encodable};
|
||||||
use consensus::encode::VarInt;
|
use consensus::encode::VarInt;
|
||||||
|
use util::endian;
|
||||||
use util::hash::BitcoinHash;
|
use util::hash::BitcoinHash;
|
||||||
|
|
||||||
/// Golomb encoding parameter as in BIP-158, see also https://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845
|
/// Golomb encoding parameter as in BIP-158, see also https://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845
|
||||||
|
@ -155,8 +155,8 @@ impl<'a> BlockFilterWriter<'a> {
|
||||||
/// Create a block filter writer
|
/// Create a block filter writer
|
||||||
pub fn new(writer: &'a mut io::Write, block: &'a Block) -> BlockFilterWriter<'a> {
|
pub fn new(writer: &'a mut io::Write, block: &'a Block) -> BlockFilterWriter<'a> {
|
||||||
let block_hash_as_int = block.bitcoin_hash().into_inner();
|
let block_hash_as_int = block.bitcoin_hash().into_inner();
|
||||||
let k0 = LittleEndian::read_u64(&block_hash_as_int[0..8]);
|
let k0 = endian::slice_to_u64_le(&block_hash_as_int[0..8]);
|
||||||
let k1 = LittleEndian::read_u64(&block_hash_as_int[8..16]);
|
let k1 = endian::slice_to_u64_le(&block_hash_as_int[8..16]);
|
||||||
let writer = GCSFilterWriter::new(writer, k0, k1, M, P);
|
let writer = GCSFilterWriter::new(writer, k0, k1, M, P);
|
||||||
BlockFilterWriter { block, writer }
|
BlockFilterWriter { block, writer }
|
||||||
}
|
}
|
||||||
|
@ -208,8 +208,8 @@ impl BlockFilterReader {
|
||||||
/// Create a block filter reader
|
/// Create a block filter reader
|
||||||
pub fn new(block_hash: &sha256d::Hash) -> BlockFilterReader {
|
pub fn new(block_hash: &sha256d::Hash) -> BlockFilterReader {
|
||||||
let block_hash_as_int = block_hash.into_inner();
|
let block_hash_as_int = block_hash.into_inner();
|
||||||
let k0 = LittleEndian::read_u64(&block_hash_as_int[0..8]);
|
let k0 = endian::slice_to_u64_le(&block_hash_as_int[0..8]);
|
||||||
let k1 = LittleEndian::read_u64(&block_hash_as_int[8..16]);
|
let k1 = endian::slice_to_u64_le(&block_hash_as_int[8..16]);
|
||||||
BlockFilterReader { reader: GCSFilterReader::new(k0, k1, M, P) }
|
BlockFilterReader { reader: GCSFilterReader::new(k0, k1, M, P) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,17 +17,15 @@
|
||||||
//! at https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
|
//! at https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
|
||||||
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::io::Cursor;
|
|
||||||
use std::{error, fmt};
|
use std::{error, fmt};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
#[cfg(feature = "serde")] use serde;
|
#[cfg(feature = "serde")] use serde;
|
||||||
|
|
||||||
use byteorder::{BigEndian, ByteOrder, ReadBytesExt};
|
|
||||||
use hashes::{hex, hash160, sha512, Hash, HashEngine, Hmac, HmacEngine};
|
use hashes::{hex, hash160, sha512, Hash, HashEngine, Hmac, HmacEngine};
|
||||||
use secp256k1::{self, Secp256k1};
|
use secp256k1::{self, Secp256k1};
|
||||||
|
|
||||||
use network::constants::Network;
|
use network::constants::Network;
|
||||||
use util::base58;
|
use util::{base58, endian};
|
||||||
use util::key::{PublicKey, PrivateKey};
|
use util::key::{PublicKey, PrivateKey};
|
||||||
|
|
||||||
/// A chain code
|
/// A chain code
|
||||||
|
@ -448,7 +446,6 @@ impl ExtendedPrivKey {
|
||||||
/// Private->Private child key derivation
|
/// Private->Private child key derivation
|
||||||
pub fn ckd_priv<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>, i: ChildNumber) -> Result<ExtendedPrivKey, Error> {
|
pub fn ckd_priv<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>, i: ChildNumber) -> Result<ExtendedPrivKey, Error> {
|
||||||
let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(&self.chain_code[..]);
|
let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(&self.chain_code[..]);
|
||||||
let mut be_n = [0; 4];
|
|
||||||
match i {
|
match i {
|
||||||
ChildNumber::Normal {..} => {
|
ChildNumber::Normal {..} => {
|
||||||
// Non-hardened key: compute public data and use that
|
// Non-hardened key: compute public data and use that
|
||||||
|
@ -460,9 +457,8 @@ impl ExtendedPrivKey {
|
||||||
hmac_engine.input(&self.private_key[..]);
|
hmac_engine.input(&self.private_key[..]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BigEndian::write_u32(&mut be_n, u32::from(i));
|
|
||||||
|
|
||||||
hmac_engine.input(&be_n);
|
hmac_engine.input(&endian::u32_to_array_be(u32::from(i)));
|
||||||
let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
|
let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
|
||||||
let mut sk = PrivateKey {
|
let mut sk = PrivateKey {
|
||||||
compressed: true,
|
compressed: true,
|
||||||
|
@ -529,9 +525,7 @@ impl ExtendedPubKey {
|
||||||
ChildNumber::Normal { index: n } => {
|
ChildNumber::Normal { index: n } => {
|
||||||
let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(&self.chain_code[..]);
|
let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(&self.chain_code[..]);
|
||||||
hmac_engine.input(&self.public_key.key.serialize()[..]);
|
hmac_engine.input(&self.public_key.key.serialize()[..]);
|
||||||
let mut be_n = [0; 4];
|
hmac_engine.input(&endian::u32_to_array_be(n));
|
||||||
BigEndian::write_u32(&mut be_n, n);
|
|
||||||
hmac_engine.input(&be_n);
|
|
||||||
|
|
||||||
let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
|
let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
|
||||||
|
|
||||||
|
@ -588,9 +582,7 @@ impl fmt::Display for ExtendedPrivKey {
|
||||||
}[..]);
|
}[..]);
|
||||||
ret[4] = self.depth as u8;
|
ret[4] = self.depth as u8;
|
||||||
ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);
|
ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);
|
||||||
|
ret[9..13].copy_from_slice(&endian::u32_to_array_be(u32::from(self.child_number)));
|
||||||
BigEndian::write_u32(&mut ret[9..13], u32::from(self.child_number));
|
|
||||||
|
|
||||||
ret[13..45].copy_from_slice(&self.chain_code[..]);
|
ret[13..45].copy_from_slice(&self.chain_code[..]);
|
||||||
ret[45] = 0;
|
ret[45] = 0;
|
||||||
ret[46..78].copy_from_slice(&self.private_key[..]);
|
ret[46..78].copy_from_slice(&self.private_key[..]);
|
||||||
|
@ -608,7 +600,7 @@ impl FromStr for ExtendedPrivKey {
|
||||||
return Err(base58::Error::InvalidLength(data.len()));
|
return Err(base58::Error::InvalidLength(data.len()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let cn_int: u32 = Cursor::new(&data[9..13]).read_u32::<BigEndian>().unwrap();
|
let cn_int: u32 = endian::slice_to_u32_be(&data[9..13]);
|
||||||
let child_number: ChildNumber = ChildNumber::from(cn_int);
|
let child_number: ChildNumber = ChildNumber::from(cn_int);
|
||||||
|
|
||||||
let network = if &data[0..4] == [0x04u8, 0x88, 0xAD, 0xE4] {
|
let network = if &data[0..4] == [0x04u8, 0x88, 0xAD, 0xE4] {
|
||||||
|
@ -647,9 +639,7 @@ impl fmt::Display for ExtendedPubKey {
|
||||||
}[..]);
|
}[..]);
|
||||||
ret[4] = self.depth as u8;
|
ret[4] = self.depth as u8;
|
||||||
ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);
|
ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);
|
||||||
|
ret[9..13].copy_from_slice(&endian::u32_to_array_be(u32::from(self.child_number)));
|
||||||
BigEndian::write_u32(&mut ret[9..13], u32::from(self.child_number));
|
|
||||||
|
|
||||||
ret[13..45].copy_from_slice(&self.chain_code[..]);
|
ret[13..45].copy_from_slice(&self.chain_code[..]);
|
||||||
ret[45..78].copy_from_slice(&self.public_key.key.serialize()[..]);
|
ret[45..78].copy_from_slice(&self.public_key.key.serialize()[..]);
|
||||||
fmt.write_str(&base58::check_encode_slice(&ret[..]))
|
fmt.write_str(&base58::check_encode_slice(&ret[..]))
|
||||||
|
@ -666,7 +656,7 @@ impl FromStr for ExtendedPubKey {
|
||||||
return Err(base58::Error::InvalidLength(data.len()));
|
return Err(base58::Error::InvalidLength(data.len()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let cn_int: u32 = Cursor::new(&data[9..13]).read_u32::<BigEndian>().unwrap();
|
let cn_int: u32 = endian::slice_to_u32_be(&data[9..13]);
|
||||||
let child_number: ChildNumber = ChildNumber::from(cn_int);
|
let child_number: ChildNumber = ChildNumber::from(cn_int);
|
||||||
|
|
||||||
Ok(ExtendedPubKey {
|
Ok(ExtendedPubKey {
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
macro_rules! define_slice_to_be {
|
||||||
|
($name: ident, $type: ty) => {
|
||||||
|
#[inline]
|
||||||
|
pub fn $name(slice: &[u8]) -> $type {
|
||||||
|
assert_eq!(slice.len(), ::std::mem::size_of::<$type>());
|
||||||
|
let mut res = 0;
|
||||||
|
for i in 0..::std::mem::size_of::<$type>() {
|
||||||
|
res |= (slice[i] as $type) << (::std::mem::size_of::<$type>() - i - 1)*8;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
macro_rules! define_slice_to_le {
|
||||||
|
($name: ident, $type: ty) => {
|
||||||
|
#[inline]
|
||||||
|
pub fn $name(slice: &[u8]) -> $type {
|
||||||
|
assert_eq!(slice.len(), ::std::mem::size_of::<$type>());
|
||||||
|
let mut res = 0;
|
||||||
|
for i in 0..::std::mem::size_of::<$type>() {
|
||||||
|
res |= (slice[i] as $type) << i*8;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
macro_rules! define_be_to_array {
|
||||||
|
($name: ident, $type: ty, $byte_len: expr) => {
|
||||||
|
#[inline]
|
||||||
|
pub fn $name(val: $type) -> [u8; $byte_len] {
|
||||||
|
assert_eq!(::std::mem::size_of::<$type>(), $byte_len); // size_of isn't a constfn in 1.22
|
||||||
|
let mut res = [0; $byte_len];
|
||||||
|
for i in 0..$byte_len {
|
||||||
|
res[i] = ((val >> ($byte_len - i - 1)*8) & 0xff) as u8;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
macro_rules! define_le_to_array {
|
||||||
|
($name: ident, $type: ty, $byte_len: expr) => {
|
||||||
|
#[inline]
|
||||||
|
pub fn $name(val: $type) -> [u8; $byte_len] {
|
||||||
|
assert_eq!(::std::mem::size_of::<$type>(), $byte_len); // size_of isn't a constfn in 1.22
|
||||||
|
let mut res = [0; $byte_len];
|
||||||
|
for i in 0..$byte_len {
|
||||||
|
res[i] = ((val >> i*8) & 0xff) as u8;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
define_slice_to_be!(slice_to_u32_be, u32);
|
||||||
|
define_be_to_array!(u32_to_array_be, u32, 4);
|
||||||
|
define_slice_to_le!(slice_to_u16_le, u16);
|
||||||
|
define_slice_to_le!(slice_to_u32_le, u32);
|
||||||
|
define_slice_to_le!(slice_to_u64_le, u64);
|
||||||
|
define_le_to_array!(u16_to_array_le, u16, 2);
|
||||||
|
define_le_to_array!(u32_to_array_le, u32, 4);
|
||||||
|
define_le_to_array!(u64_to_array_le, u64, 8);
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn i16_to_array_le(val: i16) -> [u8; 2] {
|
||||||
|
u16_to_array_le(val as u16)
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn slice_to_i16_le(slice: &[u8]) -> i16 {
|
||||||
|
slice_to_u16_le(slice) as i16
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn slice_to_i32_le(slice: &[u8]) -> i32 {
|
||||||
|
slice_to_u32_le(slice) as i32
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn i32_to_array_le(val: i32) -> [u8; 4] {
|
||||||
|
u32_to_array_le(val as u32)
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn slice_to_i64_le(slice: &[u8]) -> i64 {
|
||||||
|
slice_to_u64_le(slice) as i64
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn i64_to_array_le(val: i64) -> [u8; 8] {
|
||||||
|
u64_to_array_le(val as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! define_chunk_slice_to_int {
|
||||||
|
($name: ident, $type: ty, $converter: ident) => {
|
||||||
|
#[inline]
|
||||||
|
pub fn $name(inp: &[u8], outp: &mut [$type]) {
|
||||||
|
assert_eq!(inp.len(), outp.len() * ::std::mem::size_of::<$type>());
|
||||||
|
for (outp_val, data_bytes) in outp.iter_mut().zip(inp.chunks(::std::mem::size_of::<$type>())) {
|
||||||
|
*outp_val = $converter(data_bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
define_chunk_slice_to_int!(bytes_to_u64_slice_le, u64, slice_to_u64_le);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn endianness_test() {
|
||||||
|
assert_eq!(slice_to_u32_be(&[0xde, 0xad, 0xbe, 0xef]), 0xdeadbeef);
|
||||||
|
assert_eq!(u32_to_array_be(0xdeadbeef), [0xde, 0xad, 0xbe, 0xef]);
|
||||||
|
|
||||||
|
assert_eq!(slice_to_u16_le(&[0xad, 0xde]), 0xdead);
|
||||||
|
assert_eq!(slice_to_u32_le(&[0xef, 0xbe, 0xad, 0xde]), 0xdeadbeef);
|
||||||
|
assert_eq!(slice_to_u64_le(&[0xef, 0xbe, 0xad, 0xde, 0xfe, 0xca, 0xad, 0x1b]), 0x1badcafedeadbeef);
|
||||||
|
assert_eq!(u16_to_array_le(0xdead), [0xad, 0xde]);
|
||||||
|
assert_eq!(u32_to_array_le(0xdeadbeef), [0xef, 0xbe, 0xad, 0xde]);
|
||||||
|
assert_eq!(u64_to_array_le(0x1badcafedeadbeef), [0xef, 0xbe, 0xad, 0xde, 0xfe, 0xca, 0xad, 0x1b]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn endian_chunk_test() {
|
||||||
|
let inp = [0xef, 0xbe, 0xad, 0xde, 0xfe, 0xca, 0xad, 0x1b, 0xfe, 0xca, 0xad, 0x1b, 0xce, 0xfa, 0x01, 0x02];
|
||||||
|
let mut out = [0; 2];
|
||||||
|
bytes_to_u64_slice_le(&inp, &mut out);
|
||||||
|
assert_eq!(out, [0x1badcafedeadbeef, 0x0201face1badcafe]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,6 +30,8 @@ pub mod psbt;
|
||||||
pub mod uint;
|
pub mod uint;
|
||||||
pub mod bip158;
|
pub mod bip158;
|
||||||
|
|
||||||
|
pub(crate) mod endian;
|
||||||
|
|
||||||
use std::{error, fmt};
|
use std::{error, fmt};
|
||||||
|
|
||||||
use network;
|
use network;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
use std::{fmt, io};
|
use std::{fmt, io};
|
||||||
|
|
||||||
use consensus::encode::{self, Decodable, Encodable, VarInt, MAX_VEC_SIZE};
|
use consensus::encode::{self, Decodable, Encodable, VarInt, MAX_VEC_SIZE};
|
||||||
|
use hashes::hex::ToHex;
|
||||||
use util::psbt::Error;
|
use util::psbt::Error;
|
||||||
|
|
||||||
/// A PSBT key in its raw byte form.
|
/// A PSBT key in its raw byte form.
|
||||||
|
@ -46,7 +47,7 @@ impl fmt::Display for Key {
|
||||||
f,
|
f,
|
||||||
"type: {:#x}, key: {}",
|
"type: {:#x}, key: {}",
|
||||||
self.type_value,
|
self.type_value,
|
||||||
::hex::encode(&self.key)
|
self.key[..].to_hex()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue