Merge pull request #47 from apoelstra/no-num
Remove some dependencies; bump major version number
This commit is contained in:
commit
279e6dec28
10
Cargo.toml
10
Cargo.toml
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "bitcoin"
|
name = "bitcoin"
|
||||||
version = "0.10.9"
|
version = "0.11.0"
|
||||||
authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>"]
|
authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>"]
|
||||||
license = "CC0-1.0"
|
license = "CC0-1.0"
|
||||||
homepage = "https://github.com/apoelstra/rust-bitcoin/"
|
homepage = "https://github.com/apoelstra/rust-bitcoin/"
|
||||||
|
@ -23,15 +23,13 @@ broken_consensus_code = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1.1"
|
byteorder = "1.1"
|
||||||
num = "0.1"
|
|
||||||
rand = "0.3"
|
rand = "0.3"
|
||||||
rust-crypto = "0.2"
|
rust-crypto = "0.2"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
secp256k1 = "0.6"
|
|
||||||
serde = "0.6"
|
serde = "0.6"
|
||||||
strason = "0.3"
|
strason = "0.3"
|
||||||
|
|
||||||
[dependencies.jsonrpc]
|
[dependencies.secp256k1]
|
||||||
version = "0.8" # for serde macros
|
version = "0.8"
|
||||||
default-features = false
|
features = [ "rand", "serde" ]
|
||||||
|
|
||||||
|
|
|
@ -71,4 +71,13 @@ cross-chain atomic swaps) are more likely to be accepted than things which
|
||||||
support only a single blockchain.
|
support only a single blockchain.
|
||||||
|
|
||||||
|
|
||||||
|
## Release Notes
|
||||||
|
|
||||||
|
I will try to document all breaking changes here so that people upgrading will know
|
||||||
|
what they need to change.
|
||||||
|
|
||||||
|
### 0.11
|
||||||
|
|
||||||
|
Remove `num` dependency at Matt's request; agree this is obnoxious to require all
|
||||||
|
downstream users to also have a `num` dependency just so they can use `Uint256::from_u64`.
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
//! these blocks and the blockchain.
|
//! these blocks and the blockchain.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use num::{FromPrimitive, Zero};
|
|
||||||
|
|
||||||
use util;
|
use util;
|
||||||
use util::Error::{SpvBadTarget, SpvBadProofOfWork};
|
use util::Error::{SpvBadTarget, SpvBadProofOfWork};
|
||||||
use util::hash::Sha256dHash;
|
use util::hash::Sha256dHash;
|
||||||
|
@ -90,9 +88,9 @@ impl BlockHeader {
|
||||||
|
|
||||||
// The mantissa is signed but may not be negative
|
// The mantissa is signed but may not be negative
|
||||||
if mant > 0x7FFFFF {
|
if mant > 0x7FFFFF {
|
||||||
Zero::zero()
|
Default::default()
|
||||||
} else {
|
} else {
|
||||||
<Uint256 as FromPrimitive>::from_u64(mant as u64).unwrap() << (expt as usize)
|
Uint256::from_u64(mant as u64).unwrap() << (expt as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
//! blockchain.
|
//! blockchain.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use num::{FromPrimitive, Zero};
|
|
||||||
use std::{marker, ptr};
|
use std::{marker, ptr};
|
||||||
|
|
||||||
use blockdata::block::{Block, BlockHeader};
|
use blockdata::block::{Block, BlockHeader};
|
||||||
|
@ -348,7 +347,7 @@ impl Blockchain {
|
||||||
let genesis = genesis_block(network);
|
let genesis = genesis_block(network);
|
||||||
let genhash = genesis.header.bitcoin_hash();
|
let genhash = genesis.header.bitcoin_hash();
|
||||||
let new_node = Box::new(BlockchainNode {
|
let new_node = Box::new(BlockchainNode {
|
||||||
total_work: Zero::zero(),
|
total_work: Default::default(),
|
||||||
required_difficulty: genesis.header.target(),
|
required_difficulty: genesis.header.target(),
|
||||||
block: genesis,
|
block: genesis,
|
||||||
height: 0,
|
height: 0,
|
||||||
|
@ -444,7 +443,7 @@ impl Blockchain {
|
||||||
// Compute new target
|
// Compute new target
|
||||||
let mut target = unsafe { (*prev).block.header.target() };
|
let mut target = unsafe { (*prev).block.header.target() };
|
||||||
target = target.mul_u32(timespan);
|
target = target.mul_u32(timespan);
|
||||||
target = target / FromPrimitive::from_u64(DIFFCHANGE_TIMESPAN as u64).unwrap();
|
target = target / Uint256::from_u64(DIFFCHANGE_TIMESPAN as u64).unwrap();
|
||||||
// Clamp below MAX_TARGET (difficulty 1)
|
// Clamp below MAX_TARGET (difficulty 1)
|
||||||
let max = max_target(self.network);
|
let max = max_target(self.network);
|
||||||
if target > max { target = max };
|
if target > max { target = max };
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use num::FromPrimitive;
|
|
||||||
|
|
||||||
use blockdata::opcodes;
|
use blockdata::opcodes;
|
||||||
use blockdata::script;
|
use blockdata::script;
|
||||||
|
@ -44,7 +43,7 @@ pub static DIFFCHANGE_TIMESPAN: u32 = 14 * 24 * 3600;
|
||||||
|
|
||||||
/// In Bitcoind this is insanely described as ~((u256)0 >> 32)
|
/// In Bitcoind this is insanely described as ~((u256)0 >> 32)
|
||||||
pub fn max_target(_: Network) -> Uint256 {
|
pub fn max_target(_: Network) -> Uint256 {
|
||||||
<Uint256 as FromPrimitive>::from_u64(0xFFFF).unwrap() << 208
|
Uint256::from_u64(0xFFFF).unwrap() << 208
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The maximum value allowed in an output (useful for sanity checking,
|
/// The maximum value allowed in an output (useful for sanity checking,
|
||||||
|
|
|
@ -282,3 +282,303 @@ macro_rules! hex_script (($s:expr) => (Script::from($s.from_hex().unwrap())));
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
macro_rules! hex_hash (($s:expr) => (Sha256dHash::from(&$s.from_hex().unwrap()[..])));
|
macro_rules! hex_hash (($s:expr) => (Sha256dHash::from(&$s.from_hex().unwrap()[..])));
|
||||||
|
|
||||||
|
|
||||||
|
// Macros to replace serde's codegen while that is not stable
|
||||||
|
// Taken from rust-jsonrpc 8a50735712cb7870990314cc150ab9c2955dbfd5
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! __rust_jsonrpc_internal__define_anything_type {
|
||||||
|
() => (
|
||||||
|
struct Anything;
|
||||||
|
struct AnythingVisitor;
|
||||||
|
impl ::serde::de::Visitor for AnythingVisitor {
|
||||||
|
type Value = Anything;
|
||||||
|
|
||||||
|
fn visit_bool<E>(&mut self, _: bool) -> Result<Anything, E> { Ok(Anything) }
|
||||||
|
fn visit_i64<E>(&mut self, _: i64) -> Result<Anything, E> { Ok(Anything) }
|
||||||
|
fn visit_u64<E>(&mut self, _: u64) -> Result<Anything, E> { Ok(Anything) }
|
||||||
|
fn visit_f64<E>(&mut self, _: f64) -> Result<Anything, E> { Ok(Anything) }
|
||||||
|
fn visit_str<E>(&mut self, _: &str) -> Result<Anything, E> { Ok(Anything) }
|
||||||
|
fn visit_string<E>(&mut self, _: String) -> Result<Anything, E> { Ok(Anything) }
|
||||||
|
fn visit_unit<E>(&mut self) -> Result<Anything, E> { Ok(Anything) }
|
||||||
|
fn visit_none<E>(&mut self) -> Result<Anything, E> { Ok(Anything) }
|
||||||
|
|
||||||
|
fn visit_some<D: ::serde::de::Deserializer>(&mut self, d: &mut D) -> Result<Anything, D::Error> {
|
||||||
|
serde::de::Deserialize::deserialize(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<V: ::serde::de::SeqVisitor>(&mut self, v: V) -> Result<Anything, V::Error> {
|
||||||
|
let _: Vec<Anything> = try!(::serde::de::impls::VecVisitor::new().visit_seq(v));
|
||||||
|
Ok(Anything)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_map<V: ::serde::de::MapVisitor>(&mut self, mut v: V) -> Result<Anything, V::Error> {
|
||||||
|
while let Some((Anything, Anything)) = try!(v.visit()) { }
|
||||||
|
try!(v.end());
|
||||||
|
Ok(Anything)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::serde::Deserialize for Anything {
|
||||||
|
fn deserialize<D>(deserializer: &mut D) -> Result<Anything, D::Error>
|
||||||
|
where D: ::serde::de::Deserializer
|
||||||
|
{
|
||||||
|
deserializer.visit(AnythingVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! serde_struct_impl {
|
||||||
|
($name:ident, $($fe:ident $(<- $alt:expr)*),*) => (
|
||||||
|
impl ::serde::Deserialize for $name {
|
||||||
|
fn deserialize<D>(deserializer: &mut D) -> Result<$name, D::Error>
|
||||||
|
where D: serde::de::Deserializer
|
||||||
|
{
|
||||||
|
// begin type defs
|
||||||
|
__rust_jsonrpc_internal__define_anything_type!();
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
enum Enum { Unknown__Field, $($fe),* }
|
||||||
|
|
||||||
|
struct EnumVisitor;
|
||||||
|
impl ::serde::de::Visitor for EnumVisitor {
|
||||||
|
type Value = Enum;
|
||||||
|
|
||||||
|
fn visit_str<E>(&mut self, value: &str) -> Result<Enum, E>
|
||||||
|
where E: ::serde::de::Error
|
||||||
|
{
|
||||||
|
match value {
|
||||||
|
$(
|
||||||
|
stringify!($fe) => Ok(Enum::$fe)
|
||||||
|
$(, $alt => Ok(Enum::$fe))*
|
||||||
|
),*,
|
||||||
|
_ => Ok(Enum::Unknown__Field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::serde::Deserialize for Enum {
|
||||||
|
fn deserialize<D>(deserializer: &mut D) -> Result<Enum, D::Error>
|
||||||
|
where D: ::serde::de::Deserializer
|
||||||
|
{
|
||||||
|
deserializer.visit_str(EnumVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Visitor;
|
||||||
|
|
||||||
|
impl ::serde::de::Visitor for Visitor {
|
||||||
|
type Value = $name;
|
||||||
|
|
||||||
|
fn visit_map<V>(&mut self, mut v: V) -> Result<$name, V::Error>
|
||||||
|
where V: ::serde::de::MapVisitor
|
||||||
|
{
|
||||||
|
$(let mut $fe = None;)*
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match try!(v.visit_key()) {
|
||||||
|
Some(Enum::Unknown__Field) => { let _: Anything = try!(v.visit_value()); }
|
||||||
|
$(Some(Enum::$fe) => { $fe = Some(try!(v.visit_value())); })*
|
||||||
|
None => { break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(let $fe = match $fe {
|
||||||
|
Some(x) => x,
|
||||||
|
None => try!(v.missing_field(stringify!($fe))),
|
||||||
|
};)*
|
||||||
|
try!(v.end());
|
||||||
|
Ok($name{ $($fe: $fe),* })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// end type defs
|
||||||
|
|
||||||
|
static FIELDS: &'static [&'static str] = &[$(stringify!($fe)),*];
|
||||||
|
|
||||||
|
deserializer.visit_struct(stringify!($name), FIELDS, Visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::serde::Serialize for $name {
|
||||||
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
|
where S: ::serde::Serializer
|
||||||
|
{
|
||||||
|
// begin type defs
|
||||||
|
#[repr(u16)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
enum State { $($fe),* , Finished }
|
||||||
|
|
||||||
|
struct MapVisitor<'a> {
|
||||||
|
value: &'a $name,
|
||||||
|
state: State,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ::serde::ser::MapVisitor for MapVisitor<'a> {
|
||||||
|
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
|
||||||
|
where S: ::serde::Serializer
|
||||||
|
{
|
||||||
|
match self.state {
|
||||||
|
$(State::$fe => {
|
||||||
|
self.state = unsafe { ::std::mem::transmute(self.state as u16 + 1) };
|
||||||
|
// Use the last alternate name for serialization; in the common case
|
||||||
|
// with zero or one alternates this does the RIght Thing
|
||||||
|
let names = [stringify!($fe), $($alt),*];
|
||||||
|
Ok(Some(try!(serializer.visit_struct_elt(names[names.len() - 1], &self.value.$fe))))
|
||||||
|
})*
|
||||||
|
State::Finished => {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// end type defs
|
||||||
|
|
||||||
|
serializer.visit_struct(stringify!($name), MapVisitor {
|
||||||
|
value: self,
|
||||||
|
state: unsafe { ::std::mem::transmute(0u16) },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! serde_struct_enum_impl {
|
||||||
|
($name:ident,
|
||||||
|
$($varname:ident, $structname:ident, $($fe:ident $(<- $alt:expr)*),*);*
|
||||||
|
) => (
|
||||||
|
impl ::serde::Deserialize for $name {
|
||||||
|
fn deserialize<D>(deserializer: &mut D) -> Result<$name, D::Error>
|
||||||
|
where D: serde::de::Deserializer
|
||||||
|
{
|
||||||
|
// start type defs
|
||||||
|
__rust_jsonrpc_internal__define_anything_type!();
|
||||||
|
|
||||||
|
$(#[allow(non_camel_case_types)] enum $varname { $($fe),* })*
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
enum Enum { Unknown__Field, $($varname($varname)),* }
|
||||||
|
|
||||||
|
struct EnumVisitor;
|
||||||
|
impl ::serde::de::Visitor for EnumVisitor {
|
||||||
|
type Value = Enum;
|
||||||
|
|
||||||
|
fn visit_str<E>(&mut self, value: &str) -> Result<Enum, E>
|
||||||
|
where E: ::serde::de::Error
|
||||||
|
{
|
||||||
|
$($(
|
||||||
|
if value == stringify!($fe) $(|| value == $alt)* {
|
||||||
|
Ok(Enum::$varname($varname::$fe))
|
||||||
|
} else)*)* {
|
||||||
|
Ok(Enum::Unknown__Field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::serde::Deserialize for Enum {
|
||||||
|
fn deserialize<D>(deserializer: &mut D) -> Result<Enum, D::Error>
|
||||||
|
where D: ::serde::de::Deserializer
|
||||||
|
{
|
||||||
|
deserializer.visit_str(EnumVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Visitor;
|
||||||
|
|
||||||
|
impl ::serde::de::Visitor for Visitor {
|
||||||
|
type Value = $name;
|
||||||
|
|
||||||
|
#[allow(non_snake_case)] //for $structname
|
||||||
|
#[allow(unused_assignments)] // for `$fe = None` hack
|
||||||
|
fn visit_map<V>(&mut self, mut v: V) -> Result<$name, V::Error>
|
||||||
|
where V: ::serde::de::MapVisitor
|
||||||
|
{
|
||||||
|
$(
|
||||||
|
$(let mut $fe = None;)*
|
||||||
|
// In case of multiple variants having the same field, some of
|
||||||
|
// the above lets will get shadowed. We therefore need to tell
|
||||||
|
// rustc its type, since it otherwise cannot infer it, causing
|
||||||
|
// a compilation error. Hence this hack, which the denizens of
|
||||||
|
// #rust and I had a good laugh over:
|
||||||
|
if false { let _ = $structname { $($fe: $fe.unwrap()),* }; }
|
||||||
|
// The above expression moved $fe so we have to reassign it :)
|
||||||
|
$($fe = None;)*
|
||||||
|
)*
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match try!(v.visit_key()) {
|
||||||
|
Some(Enum::Unknown__Field) => { let _: Anything = try!(v.visit_value()); }
|
||||||
|
$($(Some(Enum::$varname($varname::$fe)) => {
|
||||||
|
$fe = Some(try!(v.visit_value())); })*)*
|
||||||
|
None => { break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to find a variant for which we have all fields
|
||||||
|
$(
|
||||||
|
let mut $structname = true;
|
||||||
|
$(if $fe.is_none() { $structname = false })*
|
||||||
|
// if we found one, success. extra fields is not an error,
|
||||||
|
// it'd be too much of a PITA to manage overlapping field
|
||||||
|
// sets otherwise.
|
||||||
|
if $structname {
|
||||||
|
$(let $fe = $fe.unwrap();)*
|
||||||
|
try!(v.end());
|
||||||
|
return Ok($name::$varname($structname { $($fe: $fe),* }))
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
// If we get here we failed
|
||||||
|
Err(::serde::de::Error::syntax("did not get all fields"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// end type defs
|
||||||
|
|
||||||
|
static FIELDS: &'static [&'static str] = &[$($(stringify!($fe)),*),*];
|
||||||
|
|
||||||
|
deserializer.visit_struct(stringify!($name), FIELDS, Visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// impl Serialize (and Deserialize, tho we don't need it) for the underlying structs
|
||||||
|
$( serde_struct_impl!($structname, $($fe $(<- $alt)*),*); )*
|
||||||
|
// call serialize on the right one
|
||||||
|
impl ::serde::Serialize for $name {
|
||||||
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
|
where S: ::serde::Serializer
|
||||||
|
{
|
||||||
|
match *self {
|
||||||
|
$($name::$varname(ref x) => x.serialize(serializer)),*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use serde;
|
||||||
|
|
||||||
|
pub struct Variant1 {
|
||||||
|
success: bool,
|
||||||
|
success_message: String
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Variant2 {
|
||||||
|
success: bool,
|
||||||
|
errors: Vec<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Reply {
|
||||||
|
Good(Variant1),
|
||||||
|
Bad(Variant2),
|
||||||
|
}
|
||||||
|
serde_struct_enum_impl!(Reply,
|
||||||
|
Good, Variant1, success, success_message;
|
||||||
|
Bad, Variant2, success, errors
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,6 @@
|
||||||
|
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
extern crate crypto;
|
extern crate crypto;
|
||||||
#[macro_use] extern crate jsonrpc;
|
|
||||||
extern crate num;
|
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate rustc_serialize as serialize;
|
extern crate rustc_serialize as serialize;
|
||||||
extern crate secp256k1;
|
extern crate secp256k1;
|
||||||
|
|
|
@ -55,11 +55,14 @@ impl Address {
|
||||||
/// Creates an address from a public key
|
/// Creates an address from a public key
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_key(network: Network, pk: &PublicKey, compressed: bool) -> Address {
|
pub fn from_key(network: Network, pk: &PublicKey, compressed: bool) -> Address {
|
||||||
let secp = Secp256k1::without_caps();
|
|
||||||
Address {
|
Address {
|
||||||
ty: Type::PubkeyHash,
|
ty: Type::PubkeyHash,
|
||||||
network: network,
|
network: network,
|
||||||
hash: Hash160::from_data(&pk.serialize_vec(&secp, compressed)[..])
|
hash: if compressed {
|
||||||
|
Hash160::from_data(&pk.serialize()[..])
|
||||||
|
} else {
|
||||||
|
Hash160::from_data(&pk.serialize_uncompressed()[..])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,7 @@ impl ExtendedPrivKey {
|
||||||
ChildNumber::Normal(n) => {
|
ChildNumber::Normal(n) => {
|
||||||
if n >= (1 << 31) { return Err(Error::InvalidChildNumber(i)) }
|
if n >= (1 << 31) { return Err(Error::InvalidChildNumber(i)) }
|
||||||
// Non-hardened key: compute public data and use that
|
// Non-hardened key: compute public data and use that
|
||||||
hmac.input(&PublicKey::from_secret_key(secp, &self.secret_key).unwrap().serialize_vec(secp, true)[..]);
|
hmac.input(&PublicKey::from_secret_key(secp, &self.secret_key).unwrap().serialize()[..]);
|
||||||
BigEndian::write_u32(&mut be_n, n);
|
BigEndian::write_u32(&mut be_n, n);
|
||||||
}
|
}
|
||||||
ChildNumber::Hardened(n) => {
|
ChildNumber::Hardened(n) => {
|
||||||
|
@ -243,7 +243,7 @@ impl ExtendedPrivKey {
|
||||||
let pk = ExtendedPubKey::from_private(secp, self);
|
let pk = ExtendedPubKey::from_private(secp, self);
|
||||||
// Do SHA256 of just the ECDSA pubkey
|
// Do SHA256 of just the ECDSA pubkey
|
||||||
let mut sha2 = Sha256::new();
|
let mut sha2 = Sha256::new();
|
||||||
sha2.input(&pk.public_key.serialize_vec(secp, true)[..]);
|
sha2.input(&pk.public_key.serialize()[..]);
|
||||||
sha2.result(&mut sha2_res);
|
sha2.result(&mut sha2_res);
|
||||||
// do RIPEMD160
|
// do RIPEMD160
|
||||||
let mut ripemd = Ripemd160::new();
|
let mut ripemd = Ripemd160::new();
|
||||||
|
@ -284,7 +284,7 @@ impl ExtendedPubKey {
|
||||||
}
|
}
|
||||||
ChildNumber::Normal(n) => {
|
ChildNumber::Normal(n) => {
|
||||||
let mut hmac = Hmac::new(Sha512::new(), &self.chain_code[..]);
|
let mut hmac = Hmac::new(Sha512::new(), &self.chain_code[..]);
|
||||||
hmac.input(&self.public_key.serialize_vec(secp, true)[..]);
|
hmac.input(&self.public_key.serialize()[..]);
|
||||||
let mut be_n = [0; 4];
|
let mut be_n = [0; 4];
|
||||||
BigEndian::write_u32(&mut be_n, n);
|
BigEndian::write_u32(&mut be_n, n);
|
||||||
hmac.input(&be_n);
|
hmac.input(&be_n);
|
||||||
|
@ -317,12 +317,11 @@ impl ExtendedPubKey {
|
||||||
|
|
||||||
/// Returns the HASH160 of the chaincode
|
/// Returns the HASH160 of the chaincode
|
||||||
pub fn identifier(&self) -> [u8; 20] {
|
pub fn identifier(&self) -> [u8; 20] {
|
||||||
let s = Secp256k1::with_caps(secp256k1::ContextFlag::None);
|
|
||||||
let mut sha2_res = [0; 32];
|
let mut sha2_res = [0; 32];
|
||||||
let mut ripemd_res = [0; 20];
|
let mut ripemd_res = [0; 20];
|
||||||
// Do SHA256 of just the ECDSA pubkey
|
// Do SHA256 of just the ECDSA pubkey
|
||||||
let mut sha2 = Sha256::new();
|
let mut sha2 = Sha256::new();
|
||||||
sha2.input(&self.public_key.serialize_vec(&s, true)[..]);
|
sha2.input(&self.public_key.serialize()[..]);
|
||||||
sha2.result(&mut sha2_res);
|
sha2.result(&mut sha2_res);
|
||||||
// do RIPEMD160
|
// do RIPEMD160
|
||||||
let mut ripemd = Ripemd160::new();
|
let mut ripemd = Ripemd160::new();
|
||||||
|
@ -395,7 +394,6 @@ impl FromBase58 for ExtendedPrivKey {
|
||||||
|
|
||||||
impl ToBase58 for ExtendedPubKey {
|
impl ToBase58 for ExtendedPubKey {
|
||||||
fn base58_layout(&self) -> Vec<u8> {
|
fn base58_layout(&self) -> Vec<u8> {
|
||||||
let s = Secp256k1::with_caps(secp256k1::ContextFlag::None);
|
|
||||||
let mut ret = Vec::with_capacity(78);
|
let mut ret = Vec::with_capacity(78);
|
||||||
ret.extend(match self.network {
|
ret.extend(match self.network {
|
||||||
Network::Bitcoin => [0x04u8, 0x88, 0xB2, 0x1E],
|
Network::Bitcoin => [0x04u8, 0x88, 0xB2, 0x1E],
|
||||||
|
@ -414,7 +412,7 @@ impl ToBase58 for ExtendedPubKey {
|
||||||
}
|
}
|
||||||
ret.extend(be_n.iter().cloned());
|
ret.extend(be_n.iter().cloned());
|
||||||
ret.extend(self.chain_code[..].iter().cloned());
|
ret.extend(self.chain_code[..].iter().cloned());
|
||||||
ret.extend(self.public_key.serialize_vec(&s, true)[..].iter().cloned());
|
ret.extend(self.public_key.serialize()[..].iter().cloned());
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
//! at http://blockstream.com/sidechains.pdf for details of
|
//! at http://blockstream.com/sidechains.pdf for details of
|
||||||
//! what this does.
|
//! what this does.
|
||||||
|
|
||||||
use secp256k1::{self, ContextFlag, Secp256k1};
|
use secp256k1::{self, Secp256k1};
|
||||||
use secp256k1::key::{PublicKey, SecretKey};
|
use secp256k1::key::{PublicKey, SecretKey};
|
||||||
use blockdata::{opcodes, script};
|
use blockdata::{opcodes, script};
|
||||||
use crypto::{hmac, sha2};
|
use crypto::{hmac, sha2};
|
||||||
|
@ -109,7 +109,6 @@ pub struct Template(Vec<TemplateElement>);
|
||||||
impl Template {
|
impl Template {
|
||||||
/// Instantiate a template
|
/// Instantiate a template
|
||||||
pub fn to_script(&self, keys: &[PublicKey]) -> Result<script::Script, Error> {
|
pub fn to_script(&self, keys: &[PublicKey]) -> Result<script::Script, Error> {
|
||||||
let secp = Secp256k1::with_caps(ContextFlag::None);
|
|
||||||
let mut key_index = 0;
|
let mut key_index = 0;
|
||||||
let mut ret = script::Builder::new();
|
let mut ret = script::Builder::new();
|
||||||
for elem in &self.0 {
|
for elem in &self.0 {
|
||||||
|
@ -120,7 +119,7 @@ impl Template {
|
||||||
return Err(Error::TooFewKeys(key_index));
|
return Err(Error::TooFewKeys(key_index));
|
||||||
}
|
}
|
||||||
key_index += 1;
|
key_index += 1;
|
||||||
ret.push_slice(&keys[key_index - 1].serialize_vec(&secp, true)[..])
|
ret.push_slice(&keys[key_index - 1].serialize()[..])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,7 +170,7 @@ pub fn tweak_keys(secp: &Secp256k1, keys: &[PublicKey], contract: &[u8]) -> Resu
|
||||||
let mut ret = Vec::with_capacity(keys.len());
|
let mut ret = Vec::with_capacity(keys.len());
|
||||||
for mut key in keys.iter().cloned() {
|
for mut key in keys.iter().cloned() {
|
||||||
let mut hmac_raw = [0; 32];
|
let mut hmac_raw = [0; 32];
|
||||||
let mut hmac = hmac::Hmac::new(sha2::Sha256::new(), &key.serialize_vec(secp, true));
|
let mut hmac = hmac::Hmac::new(sha2::Sha256::new(), &key.serialize());
|
||||||
hmac.input(contract);
|
hmac.input(contract);
|
||||||
hmac.raw_result(&mut hmac_raw);
|
hmac.raw_result(&mut hmac_raw);
|
||||||
let hmac_sk = try!(SecretKey::from_slice(secp, &hmac_raw).map_err(Error::BadTweak));
|
let hmac_sk = try!(SecretKey::from_slice(secp, &hmac_raw).map_err(Error::BadTweak));
|
||||||
|
@ -184,7 +183,7 @@ pub fn tweak_keys(secp: &Secp256k1, keys: &[PublicKey], contract: &[u8]) -> Resu
|
||||||
/// Compute a tweak from some given data for the given public key
|
/// Compute a tweak from some given data for the given public key
|
||||||
pub fn compute_tweak(secp: &Secp256k1, pk: &PublicKey, contract: &[u8]) -> Result<SecretKey, Error> {
|
pub fn compute_tweak(secp: &Secp256k1, pk: &PublicKey, contract: &[u8]) -> Result<SecretKey, Error> {
|
||||||
let mut hmac_raw = [0; 32];
|
let mut hmac_raw = [0; 32];
|
||||||
let mut hmac = hmac::Hmac::new(sha2::Sha256::new(), &pk.serialize_vec(secp, true));
|
let mut hmac = hmac::Hmac::new(sha2::Sha256::new(), &pk.serialize());
|
||||||
hmac.input(contract);
|
hmac.input(contract);
|
||||||
hmac.raw_result(&mut hmac_raw);
|
hmac.raw_result(&mut hmac_raw);
|
||||||
SecretKey::from_slice(secp, &hmac_raw).map_err(Error::BadTweak)
|
SecretKey::from_slice(secp, &hmac_raw).map_err(Error::BadTweak)
|
||||||
|
|
|
@ -429,11 +429,11 @@ impl <T: BitcoinHash> MerkleRoot for Vec<T> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use num::FromPrimitive;
|
|
||||||
use strason;
|
use strason;
|
||||||
|
|
||||||
use network::encodable::VarInt;
|
use network::encodable::VarInt;
|
||||||
use network::serialize::{serialize, deserialize};
|
use network::serialize::{serialize, deserialize};
|
||||||
|
use util::uint::{Uint128, Uint256};
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -515,8 +515,8 @@ mod tests {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0]);
|
0, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
assert_eq!(Some(one.into_le()), FromPrimitive::from_u64(1));
|
assert_eq!(Some(one.into_le()), Uint256::from_u64(1));
|
||||||
assert_eq!(Some(one.into_le().low_128()), FromPrimitive::from_u64(1));
|
assert_eq!(Some(one.into_le().low_128()), Uint128::from_u64(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,12 @@ pub trait BitArray {
|
||||||
|
|
||||||
/// Trailing zeros
|
/// Trailing zeros
|
||||||
fn trailing_zeros(&self) -> usize;
|
fn trailing_zeros(&self) -> usize;
|
||||||
|
|
||||||
|
/// Create all-zeros value
|
||||||
|
fn zero() -> Self;
|
||||||
|
|
||||||
|
/// Create value represeting one
|
||||||
|
fn one() -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A general error code
|
/// A general error code
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::marker;
|
use std::marker;
|
||||||
use std::{cmp, fmt, ops, ptr};
|
use std::{cmp, fmt, ops, ptr};
|
||||||
use num::{Zero, One};
|
|
||||||
|
|
||||||
use network::encodable::{ConsensusDecodable, ConsensusEncodable};
|
use network::encodable::{ConsensusDecodable, ConsensusEncodable};
|
||||||
use network::serialize::{SimpleDecoder, SimpleEncoder};
|
use network::serialize::{SimpleDecoder, SimpleEncoder};
|
||||||
|
@ -39,7 +38,7 @@ pub struct PatriciaTree<K: Copy, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, V> PatriciaTree<K, V>
|
impl<K, V> PatriciaTree<K, V>
|
||||||
where K: Copy + BitArray + cmp::Eq + Zero + One +
|
where K: Copy + BitArray + cmp::Eq +
|
||||||
ops::BitXor<K, Output=K> +
|
ops::BitXor<K, Output=K> +
|
||||||
ops::Add<K, Output=K> +
|
ops::Add<K, Output=K> +
|
||||||
ops::Shr<usize, Output=K> +
|
ops::Shr<usize, Output=K> +
|
||||||
|
@ -51,7 +50,7 @@ impl<K, V> PatriciaTree<K, V>
|
||||||
data: None,
|
data: None,
|
||||||
child_l: None,
|
child_l: None,
|
||||||
child_r: None,
|
child_r: None,
|
||||||
skip_prefix: Zero::zero(),
|
skip_prefix: BitArray::zero(),
|
||||||
skip_len: 0
|
skip_len: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,7 +220,7 @@ impl<K, V> PatriciaTree<K, V>
|
||||||
/// Return value is (deletable, actual return value), where `deletable` is true
|
/// Return value is (deletable, actual return value), where `deletable` is true
|
||||||
/// is true when the entire node can be deleted (i.e. it has no children)
|
/// is true when the entire node can be deleted (i.e. it has no children)
|
||||||
fn recurse<K, V>(tree: &mut PatriciaTree<K, V>, key: &K, key_len: usize) -> (bool, Option<V>)
|
fn recurse<K, V>(tree: &mut PatriciaTree<K, V>, key: &K, key_len: usize) -> (bool, Option<V>)
|
||||||
where K: Copy + BitArray + cmp::Eq + Zero + One +
|
where K: Copy + BitArray + cmp::Eq +
|
||||||
ops::Add<K, Output=K> +
|
ops::Add<K, Output=K> +
|
||||||
ops::Shr<usize, Output=K> +
|
ops::Shr<usize, Output=K> +
|
||||||
ops::Shl<usize, Output=K>
|
ops::Shl<usize, Output=K>
|
||||||
|
@ -255,9 +254,9 @@ impl<K, V> PatriciaTree<K, V>
|
||||||
tree.data = data;
|
tree.data = data;
|
||||||
tree.child_l = child_l;
|
tree.child_l = child_l;
|
||||||
tree.child_r = child_r;
|
tree.child_r = child_r;
|
||||||
let new_bit = if bit { let ret: K = One::one();
|
let new_bit = if bit { let ret: K = BitArray::one();
|
||||||
ret << (tree.skip_len as usize) }
|
ret << (tree.skip_len as usize) }
|
||||||
else { Zero::zero() };
|
else { BitArray::zero() };
|
||||||
tree.skip_prefix = tree.skip_prefix +
|
tree.skip_prefix = tree.skip_prefix +
|
||||||
new_bit +
|
new_bit +
|
||||||
(skip_prefix << (1 + tree.skip_len as usize));
|
(skip_prefix << (1 + tree.skip_len as usize));
|
||||||
|
@ -314,9 +313,9 @@ impl<K, V> PatriciaTree<K, V>
|
||||||
tree.data = data;
|
tree.data = data;
|
||||||
tree.child_l = child_l;
|
tree.child_l = child_l;
|
||||||
tree.child_r = child_r;
|
tree.child_r = child_r;
|
||||||
let new_bit = if bit { let ret: K = One::one();
|
let new_bit = if bit { let ret: K = BitArray::one();
|
||||||
ret << (tree.skip_len as usize) }
|
ret << (tree.skip_len as usize) }
|
||||||
else { Zero::zero() };
|
else { BitArray::zero() };
|
||||||
tree.skip_prefix = tree.skip_prefix +
|
tree.skip_prefix = tree.skip_prefix +
|
||||||
new_bit +
|
new_bit +
|
||||||
(skip_prefix << (1 + tree.skip_len as usize));
|
(skip_prefix << (1 + tree.skip_len as usize));
|
||||||
|
@ -545,18 +544,16 @@ impl<'a, K: Copy, V> Iterator for MutItems<'a, K, V> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use num::Zero;
|
|
||||||
use num::FromPrimitive;
|
|
||||||
|
|
||||||
use network::serialize::{deserialize, serialize};
|
use network::serialize::{deserialize, serialize};
|
||||||
use util::hash::Sha256dHash;
|
use util::hash::Sha256dHash;
|
||||||
use util::uint::Uint128;
|
use util::uint::Uint128;
|
||||||
use util::uint::Uint256;
|
use util::uint::Uint256;
|
||||||
use util::patricia_tree::PatriciaTree;
|
use util::patricia_tree::PatriciaTree;
|
||||||
|
use util::BitArray;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn patricia_single_insert_lookup_delete_test() {
|
fn patricia_single_insert_lookup_delete_test() {
|
||||||
let mut key: Uint256 = FromPrimitive::from_u64(0xDEADBEEFDEADBEEF).unwrap();
|
let mut key = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
|
||||||
key = key + (key << 64);
|
key = key + (key << 64);
|
||||||
|
|
||||||
let mut tree = PatriciaTree::new();
|
let mut tree = PatriciaTree::new();
|
||||||
|
@ -622,14 +619,14 @@ mod tests {
|
||||||
// Do the actual test -- note that we also test insertion and deletion
|
// Do the actual test -- note that we also test insertion and deletion
|
||||||
// at the root here.
|
// at the root here.
|
||||||
for i in 0u32..10 {
|
for i in 0u32..10 {
|
||||||
tree.insert(&Zero::zero(), i as usize, i);
|
tree.insert(&BitArray::zero(), i as usize, i);
|
||||||
}
|
}
|
||||||
for i in 0u32..10 {
|
for i in 0u32..10 {
|
||||||
let m = tree.lookup(&Zero::zero(), i as usize);
|
let m = tree.lookup(&BitArray::zero(), i as usize);
|
||||||
assert_eq!(m, Some(&i));
|
assert_eq!(m, Some(&i));
|
||||||
}
|
}
|
||||||
for i in 0u32..10 {
|
for i in 0u32..10 {
|
||||||
let m = tree.delete(&Zero::zero(), i as usize);
|
let m = tree.delete(&BitArray::zero(), i as usize);
|
||||||
assert_eq!(m, Some(i));
|
assert_eq!(m, Some(i));
|
||||||
}
|
}
|
||||||
// Check that the chunder was unharmed
|
// Check that the chunder was unharmed
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use num::{FromPrimitive, Zero, One};
|
|
||||||
|
|
||||||
use util::BitArray;
|
use util::BitArray;
|
||||||
|
|
||||||
|
@ -71,31 +70,18 @@ macro_rules! construct_uint {
|
||||||
}
|
}
|
||||||
$name(ret) + $name(carry)
|
$name(ret) + $name(carry)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl FromPrimitive for $name {
|
/// Create an object from a given unsigned 64-bit integer
|
||||||
#[inline]
|
pub fn from_u64(init: u64) -> Option<$name> {
|
||||||
fn from_u64(init: u64) -> Option<$name> {
|
|
||||||
let mut ret = [0; $n_words];
|
let mut ret = [0; $n_words];
|
||||||
ret[0] = init;
|
ret[0] = init;
|
||||||
Some($name(ret))
|
Some($name(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
/// Create an object from a given signed 64-bit integer
|
||||||
fn from_i64(init: i64) -> Option<$name> {
|
pub fn from_i64(init: i64) -> Option<$name> {
|
||||||
assert!(init >= 0);
|
assert!(init >= 0);
|
||||||
FromPrimitive::from_u64(init as u64)
|
$name::from_u64(init as u64)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Zero for $name {
|
|
||||||
fn zero() -> $name { $name([0; $n_words]) }
|
|
||||||
fn is_zero(&self) -> bool { self.0.iter().all(|&n| n == 0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl One for $name {
|
|
||||||
fn one() -> $name {
|
|
||||||
$name({ let mut ret = [0; $n_words]; ret[0] = 1; ret })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +110,7 @@ macro_rules! construct_uint {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sub(self, other: $name) -> $name {
|
fn sub(self, other: $name) -> $name {
|
||||||
self + !other + One::one()
|
self + !other + BitArray::one()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,6 +198,17 @@ macro_rules! construct_uint {
|
||||||
}
|
}
|
||||||
(0x40 * ($n_words - 1)) + arr[$n_words - 1].trailing_zeros() as usize
|
(0x40 * ($n_words - 1)) + arr[$n_words - 1].trailing_zeros() as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn zero() -> $name { $name([0; $n_words]) }
|
||||||
|
fn one() -> $name {
|
||||||
|
$name({ let mut ret = [0; $n_words]; ret[0] = 1; ret })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::std::default::Default for $name {
|
||||||
|
fn default() -> $name {
|
||||||
|
BitArray::zero()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::ops::BitAnd<$name> for $name {
|
impl ::std::ops::BitAnd<$name> for $name {
|
||||||
|
@ -375,22 +372,20 @@ impl Uint256 {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use num::FromPrimitive;
|
|
||||||
|
|
||||||
use network::serialize::{deserialize, serialize};
|
use network::serialize::{deserialize, serialize};
|
||||||
use util::uint::Uint256;
|
use util::uint::Uint256;
|
||||||
use util::BitArray;
|
use util::BitArray;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn uint256_bits_test() {
|
pub fn uint256_bits_test() {
|
||||||
assert_eq!(<Uint256 as FromPrimitive>::from_u64(255).unwrap().bits(), 8);
|
assert_eq!(Uint256::from_u64(255).unwrap().bits(), 8);
|
||||||
assert_eq!(<Uint256 as FromPrimitive>::from_u64(256).unwrap().bits(), 9);
|
assert_eq!(Uint256::from_u64(256).unwrap().bits(), 9);
|
||||||
assert_eq!(<Uint256 as FromPrimitive>::from_u64(300).unwrap().bits(), 9);
|
assert_eq!(Uint256::from_u64(300).unwrap().bits(), 9);
|
||||||
assert_eq!(<Uint256 as FromPrimitive>::from_u64(60000).unwrap().bits(), 16);
|
assert_eq!(Uint256::from_u64(60000).unwrap().bits(), 16);
|
||||||
assert_eq!(<Uint256 as FromPrimitive>::from_u64(70000).unwrap().bits(), 17);
|
assert_eq!(Uint256::from_u64(70000).unwrap().bits(), 17);
|
||||||
|
|
||||||
// Try to read the following lines out loud quickly
|
// Try to read the following lines out loud quickly
|
||||||
let mut shl = <Uint256 as FromPrimitive>::from_u64(70000).unwrap();
|
let mut shl = Uint256::from_u64(70000).unwrap();
|
||||||
shl = shl << 100;
|
shl = shl << 100;
|
||||||
assert_eq!(shl.bits(), 117);
|
assert_eq!(shl.bits(), 117);
|
||||||
shl = shl << 100;
|
shl = shl << 100;
|
||||||
|
@ -399,11 +394,11 @@ mod tests {
|
||||||
assert_eq!(shl.bits(), 0);
|
assert_eq!(shl.bits(), 0);
|
||||||
|
|
||||||
// Bit set check
|
// Bit set check
|
||||||
assert!(!<Uint256 as FromPrimitive>::from_u64(10).unwrap().bit(0));
|
assert!(!Uint256::from_u64(10).unwrap().bit(0));
|
||||||
assert!(<Uint256 as FromPrimitive>::from_u64(10).unwrap().bit(1));
|
assert!(Uint256::from_u64(10).unwrap().bit(1));
|
||||||
assert!(!<Uint256 as FromPrimitive>::from_u64(10).unwrap().bit(2));
|
assert!(!Uint256::from_u64(10).unwrap().bit(2));
|
||||||
assert!(<Uint256 as FromPrimitive>::from_u64(10).unwrap().bit(3));
|
assert!(Uint256::from_u64(10).unwrap().bit(3));
|
||||||
assert!(!<Uint256 as FromPrimitive>::from_u64(10).unwrap().bit(4));
|
assert!(!Uint256::from_u64(10).unwrap().bit(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -425,7 +420,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn uint256_arithmetic_test() {
|
pub fn uint256_arithmetic_test() {
|
||||||
let init = <Uint256 as FromPrimitive>::from_u64(0xDEADBEEFDEADBEEF).unwrap();
|
let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
|
||||||
let copy = init;
|
let copy = init;
|
||||||
|
|
||||||
let add = init + copy;
|
let add = init + copy;
|
||||||
|
@ -446,17 +441,17 @@ mod tests {
|
||||||
let mult = sub.mul_u32(300);
|
let mult = sub.mul_u32(300);
|
||||||
assert_eq!(mult, Uint256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0]));
|
assert_eq!(mult, Uint256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0]));
|
||||||
// Division
|
// Division
|
||||||
assert_eq!(<Uint256 as FromPrimitive>::from_u64(105).unwrap() /
|
assert_eq!(Uint256::from_u64(105).unwrap() /
|
||||||
<Uint256 as FromPrimitive>::from_u64(5).unwrap(),
|
Uint256::from_u64(5).unwrap(),
|
||||||
<Uint256 as FromPrimitive>::from_u64(21).unwrap());
|
Uint256::from_u64(21).unwrap());
|
||||||
let div = mult / <Uint256 as FromPrimitive>::from_u64(300).unwrap();
|
let div = mult / Uint256::from_u64(300).unwrap();
|
||||||
assert_eq!(div, Uint256([0x9F30411021524112u64, 0x0001BD5B7DDFBD5A, 0, 0]));
|
assert_eq!(div, Uint256([0x9F30411021524112u64, 0x0001BD5B7DDFBD5A, 0, 0]));
|
||||||
// TODO: bit inversion
|
// TODO: bit inversion
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn uint256_bitslice_test() {
|
pub fn uint256_bitslice_test() {
|
||||||
let init = <Uint256 as FromPrimitive>::from_u64(0xDEADBEEFDEADBEEF).unwrap();
|
let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
|
||||||
let add = init + (init << 64);
|
let add = init + (init << 64);
|
||||||
assert_eq!(add.bit_slice(64, 128), init);
|
assert_eq!(add.bit_slice(64, 128), init);
|
||||||
assert_eq!(add.mask(64), init);
|
assert_eq!(add.mask(64), init);
|
||||||
|
@ -466,7 +461,7 @@ mod tests {
|
||||||
pub fn uint256_extreme_bitshift_test() {
|
pub fn uint256_extreme_bitshift_test() {
|
||||||
// Shifting a u64 by 64 bits gives an undefined value, so make sure that
|
// Shifting a u64 by 64 bits gives an undefined value, so make sure that
|
||||||
// we're doing the Right Thing here
|
// we're doing the Right Thing here
|
||||||
let init = <Uint256 as FromPrimitive>::from_u64(0xDEADBEEFDEADBEEF).unwrap();
|
let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
|
||||||
|
|
||||||
assert_eq!(init << 64, Uint256([0, 0xDEADBEEFDEADBEEF, 0, 0]));
|
assert_eq!(init << 64, Uint256([0, 0xDEADBEEFDEADBEEF, 0, 0]));
|
||||||
let add = (init << 64) + init;
|
let add = (init << 64) + init;
|
||||||
|
|
Loading…
Reference in New Issue