Skip to content

Commit 16cf1f7

Browse files
committed
Merge rust-bitcoin#3989: Do hashes file re-org
85e0330 Run the formatter (Tobin C. Harding) 7be0db7 hashes: Move bench and test code into files (Tobin C. Harding) 665fa9d hashes: Pull crypto out into submodule (Tobin C. Harding) 1bfd1e0 hashes: Make module subdirectories (Tobin C. Harding) Pull request description: This is an attempt at point 3 in rust-bitcoin#3961 (comment) However instead of using `api.rs` and `implementation.rs` it uses `crypto.rs` for the cryptography stuff and leaves the rest in `mod.rs`. This whole PR is internal changes only. Almost entirely code moves, review is easy if you have your `diff` configured nicely. ACKs for top commit: Kixunil: ACK 85e0330 apoelstra: ACK 85e0330; successfully ran local tests; look great! thanks! Tree-SHA512: e52e6410e86fc93ec34a72be8c64f02148f46958f8f5c1850075b1a7f41886c220f09144ccd05a98a551c356a5d25524c8884fc8578a205b27f385ec0725f13b
2 parents a380d4b + 85e0330 commit 16cf1f7

File tree

26 files changed

+1291
-1287
lines changed

26 files changed

+1291
-1287
lines changed

bitcoin/src/blockdata/script/instruction.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ impl Instruction<'_> {
4747
_ => None,
4848
}
4949
}
50-
Instruction::PushBytes(bytes) => super::read_scriptint_non_minimal(bytes.as_bytes()).ok(),
50+
Instruction::PushBytes(bytes) =>
51+
super::read_scriptint_non_minimal(bytes.as_bytes()).ok(),
5152
}
5253
}
5354

hashes/src/ripemd160/benches.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use test::Bencher;
2+
3+
use crate::{ripemd160, Hash, HashEngine};
4+
5+
#[bench]
6+
pub fn ripemd160_10(bh: &mut Bencher) {
7+
let mut engine = ripemd160::Hash::engine();
8+
let bytes = [1u8; 10];
9+
bh.iter(|| {
10+
engine.input(&bytes);
11+
});
12+
bh.bytes = bytes.len() as u64;
13+
}
14+
15+
#[bench]
16+
pub fn ripemd160_1k(bh: &mut Bencher) {
17+
let mut engine = ripemd160::Hash::engine();
18+
let bytes = [1u8; 1024];
19+
bh.iter(|| {
20+
engine.input(&bytes);
21+
});
22+
bh.bytes = bytes.len() as u64;
23+
}
24+
25+
#[bench]
26+
pub fn ripemd160_64k(bh: &mut Bencher) {
27+
let mut engine = ripemd160::Hash::engine();
28+
let bytes = [1u8; 65536];
29+
bh.iter(|| {
30+
engine.input(&bytes);
31+
});
32+
bh.bytes = bytes.len() as u64;
33+
}
Lines changed: 2 additions & 234 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,6 @@
11
// SPDX-License-Identifier: CC0-1.0
22

3-
//! RIPEMD160 implementation.
4-
5-
use core::cmp;
6-
7-
use crate::{incomplete_block_len, HashEngine as _};
8-
9-
crate::internal_macros::general_hash_type! {
10-
160,
11-
false,
12-
"Output of the RIPEMD160 hash function."
13-
}
14-
15-
#[cfg(not(hashes_fuzz))]
16-
fn from_engine(mut e: HashEngine) -> Hash {
17-
// pad buffer with a single 1-bit then all 0s, until there are exactly 8 bytes remaining
18-
let n_bytes_hashed = e.bytes_hashed;
19-
20-
let zeroes = [0; BLOCK_SIZE - 8];
21-
e.input(&[0x80]);
22-
if crate::incomplete_block_len(&e) > zeroes.len() {
23-
e.input(&zeroes);
24-
}
25-
let pad_length = zeroes.len() - incomplete_block_len(&e);
26-
e.input(&zeroes[..pad_length]);
27-
debug_assert_eq!(incomplete_block_len(&e), zeroes.len());
28-
29-
e.input(&(8 * n_bytes_hashed).to_le_bytes());
30-
debug_assert_eq!(incomplete_block_len(&e), 0);
31-
32-
Hash(e.midstate())
33-
}
34-
35-
#[cfg(hashes_fuzz)]
36-
fn from_engine(e: HashEngine) -> Hash {
37-
let mut res = e.midstate();
38-
res[0] ^= (e.bytes_hashed & 0xff) as u8;
39-
Hash(res)
40-
}
41-
42-
const BLOCK_SIZE: usize = 64;
43-
44-
/// Engine to compute RIPEMD160 hash function.
45-
#[derive(Clone)]
46-
pub struct HashEngine {
47-
buffer: [u8; BLOCK_SIZE],
48-
h: [u32; 5],
49-
bytes_hashed: u64,
50-
}
51-
52-
impl HashEngine {
53-
/// Constructs a new SHA256 hash engine.
54-
pub const fn new() -> Self {
55-
Self {
56-
h: [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0],
57-
bytes_hashed: 0,
58-
buffer: [0; BLOCK_SIZE],
59-
}
60-
}
61-
62-
#[cfg(not(hashes_fuzz))]
63-
fn midstate(&self) -> [u8; 20] {
64-
let mut ret = [0; 20];
65-
for (val, ret_bytes) in self.h.iter().zip(ret.chunks_exact_mut(4)) {
66-
ret_bytes.copy_from_slice(&(*val).to_le_bytes());
67-
}
68-
ret
69-
}
70-
71-
#[cfg(hashes_fuzz)]
72-
fn midstate(&self) -> [u8; 20] {
73-
let mut ret = [0; 20];
74-
ret.copy_from_slice(&self.buffer[..20]);
75-
ret
76-
}
77-
}
78-
79-
impl Default for HashEngine {
80-
fn default() -> Self { Self::new() }
81-
}
82-
83-
impl crate::HashEngine for HashEngine {
84-
const BLOCK_SIZE: usize = 64;
85-
86-
fn n_bytes_hashed(&self) -> u64 { self.bytes_hashed }
87-
88-
crate::internal_macros::engine_input_impl!();
89-
}
3+
use super::{HashEngine, BLOCK_SIZE};
904

915
#[cfg(feature = "small-hash")]
926
#[macro_use]
@@ -214,7 +128,7 @@ macro_rules! process_block(
214128
);
215129

216130
impl HashEngine {
217-
fn process_block(&mut self) {
131+
pub(super) fn process_block(&mut self) {
218132
debug_assert_eq!(self.buffer.len(), BLOCK_SIZE);
219133

220134
let mut w = [0u32; 16];
@@ -405,149 +319,3 @@ impl HashEngine {
405319
);
406320
}
407321
}
408-
409-
#[cfg(test)]
410-
mod tests {
411-
#[test]
412-
#[cfg(feature = "alloc")]
413-
fn test() {
414-
use alloc::string::ToString;
415-
416-
use crate::{ripemd160, HashEngine};
417-
418-
#[derive(Clone)]
419-
struct Test {
420-
input: &'static str,
421-
output: [u8; 20],
422-
output_str: &'static str,
423-
}
424-
425-
#[rustfmt::skip]
426-
let tests = [
427-
// Test messages from FIPS 180-1
428-
Test {
429-
input: "abc",
430-
output: [
431-
0x8e, 0xb2, 0x08, 0xf7,
432-
0xe0, 0x5d, 0x98, 0x7a,
433-
0x9b, 0x04, 0x4a, 0x8e,
434-
0x98, 0xc6, 0xb0, 0x87,
435-
0xf1, 0x5a, 0x0b, 0xfc,
436-
],
437-
output_str: "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"
438-
},
439-
Test {
440-
input:
441-
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
442-
output: [
443-
0x12, 0xa0, 0x53, 0x38,
444-
0x4a, 0x9c, 0x0c, 0x88,
445-
0xe4, 0x05, 0xa0, 0x6c,
446-
0x27, 0xdc, 0xf4, 0x9a,
447-
0xda, 0x62, 0xeb, 0x2b,
448-
],
449-
output_str: "12a053384a9c0c88e405a06c27dcf49ada62eb2b"
450-
},
451-
// Examples from wikipedia
452-
Test {
453-
input: "The quick brown fox jumps over the lazy dog",
454-
output: [
455-
0x37, 0xf3, 0x32, 0xf6,
456-
0x8d, 0xb7, 0x7b, 0xd9,
457-
0xd7, 0xed, 0xd4, 0x96,
458-
0x95, 0x71, 0xad, 0x67,
459-
0x1c, 0xf9, 0xdd, 0x3b,
460-
],
461-
output_str: "37f332f68db77bd9d7edd4969571ad671cf9dd3b",
462-
},
463-
Test {
464-
input: "The quick brown fox jumps over the lazy cog",
465-
output: [
466-
0x13, 0x20, 0x72, 0xdf,
467-
0x69, 0x09, 0x33, 0x83,
468-
0x5e, 0xb8, 0xb6, 0xad,
469-
0x0b, 0x77, 0xe7, 0xb6,
470-
0xf1, 0x4a, 0xca, 0xd7,
471-
],
472-
output_str: "132072df690933835eb8b6ad0b77e7b6f14acad7",
473-
},
474-
];
475-
476-
for mut test in tests {
477-
// Hash through high-level API, check hex encoding/decoding
478-
let hash = ripemd160::Hash::hash(test.input.as_bytes());
479-
assert_eq!(hash, test.output_str.parse::<ripemd160::Hash>().expect("parse hex"));
480-
assert_eq!(hash.as_byte_array(), &test.output);
481-
assert_eq!(hash.to_string(), test.output_str);
482-
assert_eq!(ripemd160::Hash::from_bytes_ref(&test.output), &hash);
483-
assert_eq!(ripemd160::Hash::from_bytes_mut(&mut test.output), &hash);
484-
485-
// Hash through engine, checking that we can input byte by byte
486-
let mut engine = ripemd160::Hash::engine();
487-
for ch in test.input.as_bytes() {
488-
engine.input(&[*ch]);
489-
}
490-
let manual_hash = ripemd160::Hash::from_engine(engine);
491-
assert_eq!(hash, manual_hash);
492-
assert_eq!(hash.to_byte_array(), test.output);
493-
}
494-
}
495-
496-
#[test]
497-
#[cfg(feature = "serde")]
498-
fn ripemd_serde() {
499-
use serde_test::{assert_tokens, Configure, Token};
500-
501-
use crate::ripemd160;
502-
503-
#[rustfmt::skip]
504-
static HASH_BYTES: [u8; 20] = [
505-
0x13, 0x20, 0x72, 0xdf,
506-
0x69, 0x09, 0x33, 0x83,
507-
0x5e, 0xb8, 0xb6, 0xad,
508-
0x0b, 0x77, 0xe7, 0xb6,
509-
0xf1, 0x4a, 0xca, 0xd7,
510-
];
511-
512-
let hash = ripemd160::Hash::from_slice(&HASH_BYTES).expect("right number of bytes");
513-
assert_tokens(&hash.compact(), &[Token::BorrowedBytes(&HASH_BYTES[..])]);
514-
assert_tokens(&hash.readable(), &[Token::Str("132072df690933835eb8b6ad0b77e7b6f14acad7")]);
515-
}
516-
}
517-
518-
#[cfg(bench)]
519-
mod benches {
520-
use test::Bencher;
521-
522-
use crate::{ripemd160, Hash, HashEngine};
523-
524-
#[bench]
525-
pub fn ripemd160_10(bh: &mut Bencher) {
526-
let mut engine = ripemd160::Hash::engine();
527-
let bytes = [1u8; 10];
528-
bh.iter(|| {
529-
engine.input(&bytes);
530-
});
531-
bh.bytes = bytes.len() as u64;
532-
}
533-
534-
#[bench]
535-
pub fn ripemd160_1k(bh: &mut Bencher) {
536-
let mut engine = ripemd160::Hash::engine();
537-
let bytes = [1u8; 1024];
538-
bh.iter(|| {
539-
engine.input(&bytes);
540-
});
541-
bh.bytes = bytes.len() as u64;
542-
}
543-
544-
#[bench]
545-
pub fn ripemd160_64k(bh: &mut Bencher) {
546-
let mut engine = ripemd160::Hash::engine();
547-
let bytes = [1u8; 65536];
548-
bh.iter(|| {
549-
engine.input(&bytes);
550-
});
551-
bh.bytes = bytes.len() as u64;
552-
}
553-
}

hashes/src/ripemd160/mod.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// SPDX-License-Identifier: CC0-1.0
2+
3+
//! RIPEMD160 implementation.
4+
5+
#[cfg(bench)]
6+
mod benches;
7+
mod crypto;
8+
#[cfg(bench)]
9+
mod tests;
10+
11+
use core::cmp;
12+
13+
use crate::{incomplete_block_len, HashEngine as _};
14+
15+
crate::internal_macros::general_hash_type! {
16+
160,
17+
false,
18+
"Output of the RIPEMD160 hash function."
19+
}
20+
21+
#[cfg(not(hashes_fuzz))]
22+
fn from_engine(mut e: HashEngine) -> Hash {
23+
// pad buffer with a single 1-bit then all 0s, until there are exactly 8 bytes remaining
24+
let n_bytes_hashed = e.bytes_hashed;
25+
26+
let zeroes = [0; BLOCK_SIZE - 8];
27+
e.input(&[0x80]);
28+
if crate::incomplete_block_len(&e) > zeroes.len() {
29+
e.input(&zeroes);
30+
}
31+
let pad_length = zeroes.len() - incomplete_block_len(&e);
32+
e.input(&zeroes[..pad_length]);
33+
debug_assert_eq!(incomplete_block_len(&e), zeroes.len());
34+
35+
e.input(&(8 * n_bytes_hashed).to_le_bytes());
36+
debug_assert_eq!(incomplete_block_len(&e), 0);
37+
38+
Hash(e.midstate())
39+
}
40+
41+
#[cfg(hashes_fuzz)]
42+
fn from_engine(e: HashEngine) -> Hash {
43+
let mut res = e.midstate();
44+
res[0] ^= (e.bytes_hashed & 0xff) as u8;
45+
Hash(res)
46+
}
47+
48+
const BLOCK_SIZE: usize = 64;
49+
50+
/// Engine to compute RIPEMD160 hash function.
51+
#[derive(Clone)]
52+
pub struct HashEngine {
53+
buffer: [u8; BLOCK_SIZE],
54+
h: [u32; 5],
55+
bytes_hashed: u64,
56+
}
57+
58+
impl HashEngine {
59+
/// Constructs a new SHA256 hash engine.
60+
pub const fn new() -> Self {
61+
Self {
62+
h: [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0],
63+
bytes_hashed: 0,
64+
buffer: [0; BLOCK_SIZE],
65+
}
66+
}
67+
68+
#[cfg(not(hashes_fuzz))]
69+
fn midstate(&self) -> [u8; 20] {
70+
let mut ret = [0; 20];
71+
for (val, ret_bytes) in self.h.iter().zip(ret.chunks_exact_mut(4)) {
72+
ret_bytes.copy_from_slice(&(*val).to_le_bytes());
73+
}
74+
ret
75+
}
76+
77+
#[cfg(hashes_fuzz)]
78+
fn midstate(&self) -> [u8; 20] {
79+
let mut ret = [0; 20];
80+
ret.copy_from_slice(&self.buffer[..20]);
81+
ret
82+
}
83+
}
84+
85+
impl Default for HashEngine {
86+
fn default() -> Self { Self::new() }
87+
}
88+
89+
impl crate::HashEngine for HashEngine {
90+
const BLOCK_SIZE: usize = 64;
91+
92+
fn n_bytes_hashed(&self) -> u64 { self.bytes_hashed }
93+
94+
crate::internal_macros::engine_input_impl!();
95+
}

0 commit comments

Comments
 (0)