Skip to content
This repository was archived by the owner on Nov 30, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ Cargo.lock
#fuzz
fuzz/hfuzz_target
fuzz/hfuzz_workspace

*~
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ script:
- cargo test --verbose
- cargo test --verbose --features "serde"
- cargo build --verbose --features "fuzztarget"
- cargo build --verbose --no-default-features
- if [ "$(rustup show | grep default | grep beta)" != "" ]; then cargo install --force cargo-web && cargo web build --target=asmjs-unknown-emscripten && cargo web test --target=asmjs-unknown-emscripten --nodejs; fi
- if [ "$(rustup show | grep default | grep stable)" != "" ]; then cd fuzz && cargo test --verbose && ./travis-fuzz.sh; fi
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 0.6.0 - 2019-07-10

* Add `no_std` support, rearrange traits to not depend on `io::Write`

# 0.5.0 - 2019-06-28

* Fix panic when parsing hashes that contain multibyte characters
Expand Down
9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bitcoin_hashes"
version = "0.5.0"
version = "0.6.0"
authors = ["Andrew Poelstra <[email protected]>"]
license = "CC0-1.0"
description = "Hash functions used by rust-bitcoin which support rustc 1.14.0"
Expand All @@ -13,17 +13,18 @@ name = "bitcoin_hashes"
path = "src/lib.rs"

[features]
default = []
default = [ "std" ]
std = ["byteorder/std", "serde/std"]
unstable = [] # for benchmarking
fuzztarget = [] # used by other rust-bitcoin projects to make hashes almost-noops, DON'T USE THIS

[dev-dependencies]
serde_test = "1.0"

[dependencies]
byteorder = "1.2"
byteorder = { version = "1.2", default-features = false }

[dependencies.serde]
version = "1.0"
optional = true

default-features = false
18 changes: 9 additions & 9 deletions src/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,26 @@ pub fn fixed_time_eq(a: &[u8], b: &[u8]) -> bool {

let mut r: u8 = 0;
for i in 0..count {
let mut rs = unsafe { ::std::ptr::read_volatile(&r) };
let mut rs = unsafe { ::core::ptr::read_volatile(&r) };
rs |= lhs[i] ^ rhs[i];
unsafe { ::std::ptr::write_volatile(&mut r, rs); }
unsafe { ::core::ptr::write_volatile(&mut r, rs); }
}
{
let mut t = unsafe { ::std::ptr::read_volatile(&r) };
let mut t = unsafe { ::core::ptr::read_volatile(&r) };
t |= t >> 4;
unsafe { ::std::ptr::write_volatile(&mut r, t); }
unsafe { ::core::ptr::write_volatile(&mut r, t); }
}
{
let mut t = unsafe { ::std::ptr::read_volatile(&r) };
let mut t = unsafe { ::core::ptr::read_volatile(&r) };
t |= t >> 2;
unsafe { ::std::ptr::write_volatile(&mut r, t); }
unsafe { ::core::ptr::write_volatile(&mut r, t); }
}
{
let mut t = unsafe { ::std::ptr::read_volatile(&r) };
let mut t = unsafe { ::core::ptr::read_volatile(&r) };
t |= t >> 1;
unsafe { ::std::ptr::write_volatile(&mut r, t); }
unsafe { ::core::ptr::write_volatile(&mut r, t); }
}
unsafe { (::std::ptr::read_volatile(&r) & 1) == 0 }
unsafe { (::core::ptr::read_volatile(&r) & 1) == 0 }
}

#[test]
Expand Down
16 changes: 1 addition & 15 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
//! # Error Type
//!

use std::{error, fmt};
use core::fmt;

/// Hex decoding error
#[derive(Copy, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -44,17 +44,3 @@ impl fmt::Display for Error {
}
}

impl error::Error for Error {
fn cause(&self) -> Option<&error::Error> {
None
}

fn description(&self) -> &str {
match *self {
Error::InvalidChar(_) => "invalid hex character",
Error::OddLengthString(_) => "odd hex string length",
Error::InvalidLength(_, _) => "bad hex string length",
}
}
}

19 changes: 9 additions & 10 deletions src/hash160.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

//! # HASH160 (SHA256 then RIPEMD160)

use std::str;
use core::str;

use sha256;
use ripemd160;
Expand Down Expand Up @@ -84,11 +84,10 @@ impl HashTrait for Hash {

#[cfg(test)]
mod tests {
use std::io::Write;

use hash160;
use hex::{FromHex, ToHex};
use Hash;
use HashEngine;

#[derive(Clone)]
struct Test {
Expand All @@ -110,12 +109,12 @@ mod tests {
0xb8, 0x5d, 0xf1, 0x69, 0xc1, 0x8a, 0x3c, 0x69, 0x7f,
0xbb, 0x2d, 0xc4, 0xec, 0xef, 0x94, 0xac, 0x55, 0xfe,
0x81, 0x64, 0xcc, 0xf9, 0x82, 0xa1, 0x38, 0x69, 0x1a,
0x55, 0x19,
0x55, 0x19,
],
output: vec![
0xda, 0x0b, 0x34, 0x52, 0xb0, 0x6f, 0xe3, 0x41,
0x62, 0x6a, 0xd0, 0x94, 0x9c, 0x18, 0x3f, 0xbd,
0xa5, 0x67, 0x68, 0x26,
0xa5, 0x67, 0x68, 0x26,
],
output_str: "da0b3452b06fe341626ad0949c183fbda5676826",
},
Expand All @@ -131,7 +130,7 @@ mod tests {
// Hash through engine, checking that we can input byte by byte
let mut engine = hash160::Hash::engine();
for ch in test.input {
engine.write_all(&[ch]).expect("write to engine");
engine.input(&[ch]);
}
let manual_hash = Hash::from_engine(engine);
assert_eq!(hash, manual_hash);
Expand Down Expand Up @@ -160,18 +159,18 @@ mod tests {

#[cfg(all(test, feature="unstable"))]
mod benches {
use std::io::Write;
use test::Bencher;

use hash160;
use Hash;
use HashEngine;

#[bench]
pub fn hash160_10(bh: & mut Bencher) {
let mut engine = hash160::Hash::engine();
let bytes = [1u8; 10];
bh.iter( || {
engine.write_all(&bytes).expect("write");
engine.input(&bytes);
});
bh.bytes = bytes.len() as u64;
}
Expand All @@ -181,7 +180,7 @@ mod benches {
let mut engine = hash160::Hash::engine();
let bytes = [1u8; 1024];
bh.iter( || {
engine.write_all(&bytes).expect("write");
engine.input(&bytes);
});
bh.bytes = bytes.len() as u64;
}
Expand All @@ -191,7 +190,7 @@ mod benches {
let mut engine = hash160::Hash::engine();
let bytes = [1u8; 65536];
bh.iter( || {
engine.write_all(&bytes).expect("write");
engine.input(&bytes);
});
bh.bytes = bytes.len() as u64;
}
Expand Down
13 changes: 8 additions & 5 deletions src/hex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
//! # Hex encoding and decoding
//!

use std::fmt;
use std::str;
use core::{fmt, str};
use {Error, Hash};

/// Trait for objects that can be serialized as hex strings
#[cfg(any(test, feature = "std"))]
pub trait ToHex {
/// Hex representation of the object
fn to_hex(&self) -> String;
Expand All @@ -39,6 +39,7 @@ pub trait FromHex: Sized {
}
}

#[cfg(any(test, feature = "std"))]
impl<T: fmt::LowerHex> ToHex for T {
/// Outputs the hash in hexadecimal form
fn to_hex(&self) -> String {
Expand Down Expand Up @@ -152,9 +153,10 @@ pub fn format_hex_reverse(data: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
Ok(())
}

#[cfg(any(test, feature = "std"))]
impl ToHex for [u8] {
fn to_hex(&self) -> String {
use std::fmt::Write;
use core::fmt::Write;
let mut ret = String::with_capacity(2 * self.len());
for ch in self {
write!(ret, "{:02x}", ch).expect("writing to string");
Expand All @@ -163,6 +165,7 @@ impl ToHex for [u8] {
}
}

#[cfg(any(test, feature = "std"))]
impl FromHex for Vec<u8> {
fn from_byte_iter<I>(iter: I) -> Result<Self, Error>
where I: Iterator<Item=Result<u8, Error>> +
Expand Down Expand Up @@ -217,9 +220,9 @@ impl_fromhex_array!(512);

#[cfg(test)]
mod tests {
use std::fmt;
use core::fmt;

use super::{format_hex, format_hex_reverse, ToHex, FromHex};
use super::{format_hex, format_hex_reverse, FromHex, ToHex};
use Error;

#[test]
Expand Down
14 changes: 4 additions & 10 deletions src/hmac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

//! # HMAC support

use std::{borrow, fmt, io, ops, str};
use core::{borrow, fmt, ops, str};
#[cfg(feature="serde")]
use serde::{Serialize, Serializer, Deserialize, Deserializer};

Expand Down Expand Up @@ -99,15 +99,9 @@ impl<T: Hash> HashEngine for HmacEngine<T> {
}

const BLOCK_SIZE: usize = T::Engine::BLOCK_SIZE;
}

impl<T: Hash> io::Write for HmacEngine<T> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.iengine.write(buf)
}

fn flush(&mut self) -> io::Result<()> {
self.iengine.flush()

fn input(&mut self, buf: &[u8]) {
self.iengine.input(buf)
}
}

Expand Down
20 changes: 9 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,18 @@
#![deny(unused_mut)]
#![deny(missing_docs)]

#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
#![cfg_attr(all(test, feature = "unstable"), feature(test))]
#[cfg(all(test, feature = "unstable"))] extern crate test;

#[cfg(any(test, feature="std"))] extern crate core;
#[cfg(feature="serde")] extern crate serde;
#[cfg(all(test,feature="serde"))] extern crate serde_test;
extern crate byteorder;

#[macro_use] mod util;
#[macro_use] mod serde_macros;
#[cfg(any(test, feature = "std"))] mod std_impls;
pub mod error;
pub mod hex;
pub mod hash160;
Expand All @@ -48,15 +51,15 @@ pub mod sha256d;
pub mod siphash24;
pub mod cmp;

use std::{borrow, fmt, hash, io, ops};
use core::{borrow, fmt, hash, ops};

pub use hmac::{Hmac, HmacEngine};
pub use error::Error;

/// A hashing engine which bytes can be serialized into. It is expected
/// to implement the `io::Write` trait, but to never return errors under
/// any conditions.
pub trait HashEngine: Clone + io::Write {
pub trait HashEngine: Clone {
/// Byte array representing the internal state of the hash engine
type MidState;

Expand All @@ -67,11 +70,8 @@ pub trait HashEngine: Clone + io::Write {
/// Length of the hash's internal block size, in bytes
const BLOCK_SIZE: usize;

/// Add data to the hash engine without any error return type to deal with
#[inline(always)]
fn input(&mut self, data: &[u8]) {
self.write_all(data).expect("hash returned error");
}
/// Add data to the hash engine
fn input(&mut self, data: &[u8]);
}

/// Trait which applies to hashes of all types
Expand All @@ -82,7 +82,7 @@ pub trait Hash: Copy + Clone + PartialEq + Eq + Default + PartialOrd + Ord +
ops::Index<ops::RangeTo<usize>, Output = [u8]> +
ops::Index<ops::Range<usize>, Output = [u8]> +
ops::Index<usize, Output = u8> +
hex::ToHex + borrow::Borrow<[u8]>
borrow::Borrow<[u8]>
{
/// A hashing engine which bytes can be serialized into. It is expected
/// to implement the `io::Write` trait, and to never return errors under
Expand All @@ -106,10 +106,8 @@ pub trait Hash: Copy + Clone + PartialEq + Eq + Default + PartialOrd + Ord +

/// Hashes some bytes
fn hash(data: &[u8]) -> Self {
use std::io::Write;

let mut engine = Self::engine();
engine.write_all(data).unwrap();
engine.input(data);
Self::from_engine(engine)
}

Expand Down
Loading