]> git.proxmox.com Git - rustc.git/blame - vendor/digest/src/dev.rs
New upstream version 1.44.1+dfsg1
[rustc.git] / vendor / digest / src / dev.rs
CommitLineData
ba9703b0 1use super::{Input, VariableOutput, ExtendableOutput, Reset, XofReader};
9fa01778
XL
2use core::fmt::Debug;
3
9fa01778 4#[macro_export]
ba9703b0
XL
5macro_rules! new_test {
6 ($name:ident, $test_name:expr, $hasher:ty, $test_func:ident) => {
7 #[test]
8 fn $name() {
9 use digest::blobby::Blob2Iterator;
10 let data = include_bytes!(concat!("data/", $test_name, ".blb"));
11
12 for (i, row) in Blob2Iterator::new(data).unwrap().enumerate() {
13 let input = row[0];
14 let output = row[1];
15 if let Some(desc) = $test_func::<$hasher>(input, output) {
16 panic!("\n\
17 Failed test №{}: {}\n\
18 input:\t{:?}\n\
19 output:\t{:?}\n",
20 i, desc, input, output,
21 );
22 }
23 }
24 }
25 }
9fa01778
XL
26}
27
ba9703b0
XL
28// module to separate Digest from other traits
29mod foo {
30 use super::super::Digest;
31 use core::fmt::Debug;
32
33 pub fn digest_test<D>(input: &[u8], output: &[u8]) -> Option<&'static str>
34 where D: Digest + Debug + Clone
35 {
36 let mut hasher = D::new();
37 // Test that it works when accepting the message all at once
38 hasher.input(input);
39 let mut hasher2 = hasher.clone();
40 if hasher.result().as_slice() != output {
41 return Some("whole message");
42 }
9fa01778 43
ba9703b0
XL
44 // Test if reset works correctly
45 hasher2.reset();
46 hasher2.input(input);
47 if hasher2.result().as_slice() != output {
48 return Some("whole message after reset");
49 }
9fa01778 50
ba9703b0
XL
51 // Test that it works when accepting the message in pieces
52 let mut hasher = D::new();
53 let len = input.len();
9fa01778
XL
54 let mut left = len;
55 while left > 0 {
56 let take = (left + 1) / 2;
ba9703b0 57 hasher.input(&input[len - left..take + len - left]);
9fa01778
XL
58 left = left - take;
59 }
ba9703b0
XL
60 if hasher.result().as_slice() != output {
61 return Some("message in pieces");
62 }
63
64 // Test processing byte-by-byte
65 let mut hasher = D::new();
66 for chunk in input.chunks(1) {
67 hasher.input(chunk)
68 }
69 if hasher.result().as_slice() != output {
70 return Some("message byte-by-byte");
71 }
72 None
73 }
9fa01778 74
9fa01778 75
ba9703b0
XL
76 pub fn one_million_a<D>(expected: &[u8])
77 where D: Digest + Debug + Clone
78 {
79 let mut sh = D::new();
80 for _ in 0..50_000 {
81 sh.input(&[b'a'; 10]);
82 }
83 sh.input(&[b'a'; 500_000][..]);
84 let out = sh.result();
85 assert_eq!(out[..], expected[..]);
9fa01778
XL
86 }
87}
88
ba9703b0
XL
89pub use self::foo::{digest_test, one_million_a};
90
91pub fn xof_test<D>(input: &[u8], output: &[u8])
92 -> Option<&'static str>
93 where D: Input + ExtendableOutput + Default + Debug + Reset + Clone
9fa01778 94{
ba9703b0 95 let mut hasher = D::default();
9fa01778
XL
96 let mut buf = [0u8; 1024];
97 // Test that it works when accepting the message all at once
ba9703b0 98 hasher.input(input);
9fa01778 99
ba9703b0
XL
100 let mut hasher2 = hasher.clone();
101 {
102 let out = &mut buf[..output.len()];
103 hasher.xof_result().read(out);
9fa01778 104
ba9703b0 105 if out != output { return Some("whole message"); }
9fa01778
XL
106 }
107
ba9703b0
XL
108 // Test if hasher resets correctly
109 hasher2.reset();
110 hasher2.input(input);
9fa01778 111
ba9703b0
XL
112 {
113 let out = &mut buf[..output.len()];
114 hasher2.xof_result().read(out);
9fa01778 115
ba9703b0 116 if out != output { return Some("whole message after reset"); }
9fa01778 117 }
9fa01778 118
ba9703b0
XL
119 // Test if hasher accepts message in pieces correctly
120 let mut hasher = D::default();
121 let len = input.len();
122 let mut left = len;
123 while left > 0 {
124 let take = (left + 1) / 2;
125 hasher.input(&input[len - left..take + len - left]);
126 left = left - take;
9fa01778
XL
127 }
128
ba9703b0
XL
129 {
130 let out = &mut buf[..output.len()];
131 hasher.xof_result().read(out);
132 if out != output { return Some("message in pieces"); }
133 }
9fa01778 134
ba9703b0
XL
135 // Test reading from reader byte by byte
136 let mut hasher = D::default();
137 hasher.input(input);
9fa01778 138
ba9703b0
XL
139 let mut reader = hasher.xof_result();
140 let out = &mut buf[..output.len()];
141 for chunk in out.chunks_mut(1) {
142 reader.read(chunk);
9fa01778
XL
143 }
144
ba9703b0
XL
145 if out != output { return Some("message in pieces"); }
146 None
147}
148
149pub fn variable_test<D>(input: &[u8], output: &[u8])
150 -> Option<&'static str>
151 where D: Input + VariableOutput + Reset + Debug + Clone
152{
153 let mut hasher = D::new(output.len()).unwrap();
154 let mut buf = [0u8; 128];
155 let buf = &mut buf[..output.len()];
156 // Test that it works when accepting the message all at once
157 hasher.input(input);
158 let mut hasher2 = hasher.clone();
159 hasher.variable_result(|res| buf.copy_from_slice(res));
160 if buf != output { return Some("whole message"); }
9fa01778 161
ba9703b0
XL
162 // Test if reset works correctly
163 hasher2.reset();
164 hasher2.input(input);
165 hasher2.variable_result(|res| buf.copy_from_slice(res));
166 if buf != output { return Some("whole message after reset"); }
9fa01778 167
ba9703b0
XL
168 // Test that it works when accepting the message in pieces
169 let mut hasher = D::new(output.len()).unwrap();
170 let len = input.len();
171 let mut left = len;
172 while left > 0 {
173 let take = (left + 1) / 2;
174 hasher.input(&input[len - left..take + len - left]);
175 left = left - take;
9fa01778 176 }
ba9703b0
XL
177 hasher.variable_result(|res| buf.copy_from_slice(res));
178 if buf != output { return Some("message in pieces"); }
9fa01778 179
ba9703b0
XL
180 // Test processing byte-by-byte
181 let mut hasher = D::new(output.len()).unwrap();
182 for chunk in input.chunks(1) {
183 hasher.input(chunk)
9fa01778 184 }
ba9703b0
XL
185 hasher.variable_result(|res| buf.copy_from_slice(res));
186 if buf != output { return Some("message byte-by-byte"); }
187 None
9fa01778
XL
188}
189
190
191#[macro_export]
ba9703b0 192macro_rules! bench {
9fa01778
XL
193 ($name:ident, $engine:path, $bs:expr) => {
194 #[bench]
195 fn $name(b: &mut Bencher) {
196 let mut d = <$engine>::default();
197 let data = [0; $bs];
198
199 b.iter(|| {
ba9703b0 200 d.input(&data[..]);
9fa01778
XL
201 });
202
203 b.bytes = $bs;
204 }
205 };
206
207 ($engine:path) => {
208 extern crate test;
209
210 use test::Bencher;
211 use digest::Digest;
212
ba9703b0
XL
213 bench!(bench1_10, $engine, 10);
214 bench!(bench2_100, $engine, 100);
215 bench!(bench3_1000, $engine, 1000);
216 bench!(bench4_10000, $engine, 10000);
9fa01778
XL
217 }
218}