Skip to content
This repository was archived by the owner on Nov 30, 2022. It is now read-only.

Commit 115266d

Browse files
authored
Add no_std support (#52)
Add `no_std` support
2 parents 39863ec + eac6cde commit 115266d

File tree

18 files changed

+333
-217
lines changed

18 files changed

+333
-217
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ Cargo.lock
77
#fuzz
88
fuzz/hfuzz_target
99
fuzz/hfuzz_workspace
10+
11+
*~

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ script:
1414
- cargo test --verbose
1515
- cargo test --verbose --features "serde"
1616
- cargo build --verbose --features "fuzztarget"
17+
- cargo build --verbose --no-default-features
1718
- 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
1819
- if [ "$(rustup show | grep default | grep stable)" != "" ]; then cd fuzz && cargo test --verbose && ./travis-fuzz.sh; fi

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 0.6.0 - 2019-07-10
2+
3+
* Add `no_std` support, rearrange traits to not depend on `io::Write`
4+
15
# 0.5.0 - 2019-06-28
26

37
* Fix panic when parsing hashes that contain multibyte characters

Cargo.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bitcoin_hashes"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
authors = ["Andrew Poelstra <[email protected]>"]
55
license = "CC0-1.0"
66
description = "Hash functions used by rust-bitcoin which support rustc 1.14.0"
@@ -13,17 +13,18 @@ name = "bitcoin_hashes"
1313
path = "src/lib.rs"
1414

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

2021
[dev-dependencies]
2122
serde_test = "1.0"
2223

2324
[dependencies]
24-
byteorder = "1.2"
25+
byteorder = { version = "1.2", default-features = false }
2526

2627
[dependencies.serde]
2728
version = "1.0"
2829
optional = true
29-
30+
default-features = false

src/cmp.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,26 @@ pub fn fixed_time_eq(a: &[u8], b: &[u8]) -> bool {
2020

2121
let mut r: u8 = 0;
2222
for i in 0..count {
23-
let mut rs = unsafe { ::std::ptr::read_volatile(&r) };
23+
let mut rs = unsafe { ::core::ptr::read_volatile(&r) };
2424
rs |= lhs[i] ^ rhs[i];
25-
unsafe { ::std::ptr::write_volatile(&mut r, rs); }
25+
unsafe { ::core::ptr::write_volatile(&mut r, rs); }
2626
}
2727
{
28-
let mut t = unsafe { ::std::ptr::read_volatile(&r) };
28+
let mut t = unsafe { ::core::ptr::read_volatile(&r) };
2929
t |= t >> 4;
30-
unsafe { ::std::ptr::write_volatile(&mut r, t); }
30+
unsafe { ::core::ptr::write_volatile(&mut r, t); }
3131
}
3232
{
33-
let mut t = unsafe { ::std::ptr::read_volatile(&r) };
33+
let mut t = unsafe { ::core::ptr::read_volatile(&r) };
3434
t |= t >> 2;
35-
unsafe { ::std::ptr::write_volatile(&mut r, t); }
35+
unsafe { ::core::ptr::write_volatile(&mut r, t); }
3636
}
3737
{
38-
let mut t = unsafe { ::std::ptr::read_volatile(&r) };
38+
let mut t = unsafe { ::core::ptr::read_volatile(&r) };
3939
t |= t >> 1;
40-
unsafe { ::std::ptr::write_volatile(&mut r, t); }
40+
unsafe { ::core::ptr::write_volatile(&mut r, t); }
4141
}
42-
unsafe { (::std::ptr::read_volatile(&r) & 1) == 0 }
42+
unsafe { (::core::ptr::read_volatile(&r) & 1) == 0 }
4343
}
4444

4545
#[test]

src/error.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
//! # Error Type
1616
//!
1717
18-
use std::{error, fmt};
18+
use core::fmt;
1919

2020
/// Hex decoding error
2121
#[derive(Copy, Clone, PartialEq, Eq)]
@@ -44,17 +44,3 @@ impl fmt::Display for Error {
4444
}
4545
}
4646

47-
impl error::Error for Error {
48-
fn cause(&self) -> Option<&error::Error> {
49-
None
50-
}
51-
52-
fn description(&self) -> &str {
53-
match *self {
54-
Error::InvalidChar(_) => "invalid hex character",
55-
Error::OddLengthString(_) => "odd hex string length",
56-
Error::InvalidLength(_, _) => "bad hex string length",
57-
}
58-
}
59-
}
60-

src/hash160.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
//! # HASH160 (SHA256 then RIPEMD160)
2121
22-
use std::str;
22+
use core::str;
2323

2424
use sha256;
2525
use ripemd160;
@@ -84,11 +84,10 @@ impl HashTrait for Hash {
8484

8585
#[cfg(test)]
8686
mod tests {
87-
use std::io::Write;
88-
8987
use hash160;
9088
use hex::{FromHex, ToHex};
9189
use Hash;
90+
use HashEngine;
9291

9392
#[derive(Clone)]
9493
struct Test {
@@ -110,12 +109,12 @@ mod tests {
110109
0xb8, 0x5d, 0xf1, 0x69, 0xc1, 0x8a, 0x3c, 0x69, 0x7f,
111110
0xbb, 0x2d, 0xc4, 0xec, 0xef, 0x94, 0xac, 0x55, 0xfe,
112111
0x81, 0x64, 0xcc, 0xf9, 0x82, 0xa1, 0x38, 0x69, 0x1a,
113-
0x55, 0x19,
112+
0x55, 0x19,
114113
],
115114
output: vec![
116115
0xda, 0x0b, 0x34, 0x52, 0xb0, 0x6f, 0xe3, 0x41,
117116
0x62, 0x6a, 0xd0, 0x94, 0x9c, 0x18, 0x3f, 0xbd,
118-
0xa5, 0x67, 0x68, 0x26,
117+
0xa5, 0x67, 0x68, 0x26,
119118
],
120119
output_str: "da0b3452b06fe341626ad0949c183fbda5676826",
121120
},
@@ -131,7 +130,7 @@ mod tests {
131130
// Hash through engine, checking that we can input byte by byte
132131
let mut engine = hash160::Hash::engine();
133132
for ch in test.input {
134-
engine.write_all(&[ch]).expect("write to engine");
133+
engine.input(&[ch]);
135134
}
136135
let manual_hash = Hash::from_engine(engine);
137136
assert_eq!(hash, manual_hash);
@@ -160,18 +159,18 @@ mod tests {
160159

161160
#[cfg(all(test, feature="unstable"))]
162161
mod benches {
163-
use std::io::Write;
164162
use test::Bencher;
165163

166164
use hash160;
167165
use Hash;
166+
use HashEngine;
168167

169168
#[bench]
170169
pub fn hash160_10(bh: & mut Bencher) {
171170
let mut engine = hash160::Hash::engine();
172171
let bytes = [1u8; 10];
173172
bh.iter( || {
174-
engine.write_all(&bytes).expect("write");
173+
engine.input(&bytes);
175174
});
176175
bh.bytes = bytes.len() as u64;
177176
}
@@ -181,7 +180,7 @@ mod benches {
181180
let mut engine = hash160::Hash::engine();
182181
let bytes = [1u8; 1024];
183182
bh.iter( || {
184-
engine.write_all(&bytes).expect("write");
183+
engine.input(&bytes);
185184
});
186185
bh.bytes = bytes.len() as u64;
187186
}
@@ -191,7 +190,7 @@ mod benches {
191190
let mut engine = hash160::Hash::engine();
192191
let bytes = [1u8; 65536];
193192
bh.iter( || {
194-
engine.write_all(&bytes).expect("write");
193+
engine.input(&bytes);
195194
});
196195
bh.bytes = bytes.len() as u64;
197196
}

src/hex.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
//! # Hex encoding and decoding
1616
//!
1717
18-
use std::fmt;
19-
use std::str;
18+
use core::{fmt, str};
2019
use {Error, Hash};
2120

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

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

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

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

218221
#[cfg(test)]
219222
mod tests {
220-
use std::fmt;
223+
use core::fmt;
221224

222-
use super::{format_hex, format_hex_reverse, ToHex, FromHex};
225+
use super::{format_hex, format_hex_reverse, FromHex, ToHex};
223226
use Error;
224227

225228
#[test]

src/hmac.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
//! # HMAC support
2121
22-
use std::{borrow, fmt, io, ops, str};
22+
use core::{borrow, fmt, ops, str};
2323
#[cfg(feature="serde")]
2424
use serde::{Serialize, Serializer, Deserialize, Deserializer};
2525

@@ -99,15 +99,9 @@ impl<T: Hash> HashEngine for HmacEngine<T> {
9999
}
100100

101101
const BLOCK_SIZE: usize = T::Engine::BLOCK_SIZE;
102-
}
103-
104-
impl<T: Hash> io::Write for HmacEngine<T> {
105-
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
106-
self.iengine.write(buf)
107-
}
108-
109-
fn flush(&mut self) -> io::Result<()> {
110-
self.iengine.flush()
102+
103+
fn input(&mut self, buf: &[u8]) {
104+
self.iengine.input(buf)
111105
}
112106
}
113107

src/lib.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,18 @@
2727
#![deny(unused_mut)]
2828
#![deny(missing_docs)]
2929

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

34+
#[cfg(any(test, feature="std"))] extern crate core;
3335
#[cfg(feature="serde")] extern crate serde;
3436
#[cfg(all(test,feature="serde"))] extern crate serde_test;
3537
extern crate byteorder;
3638

3739
#[macro_use] mod util;
3840
#[macro_use] mod serde_macros;
41+
#[cfg(any(test, feature = "std"))] mod std_impls;
3942
pub mod error;
4043
pub mod hex;
4144
pub mod hash160;
@@ -48,15 +51,15 @@ pub mod sha256d;
4851
pub mod siphash24;
4952
pub mod cmp;
5053

51-
use std::{borrow, fmt, hash, io, ops};
54+
use core::{borrow, fmt, hash, ops};
5255

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

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

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

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

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

107107
/// Hashes some bytes
108108
fn hash(data: &[u8]) -> Self {
109-
use std::io::Write;
110-
111109
let mut engine = Self::engine();
112-
engine.write_all(data).unwrap();
110+
engine.input(data);
113111
Self::from_engine(engine)
114112
}
115113

0 commit comments

Comments
 (0)