sha/utils.rs
1use std::default::Default;
2use std::io::prelude::*;
3use std::io;
4use bswap;
5
6pub trait Reset {
7 fn reset(&mut self);
8}
9
10pub trait Digest: Default + Reset + Read + Write {
11
12 fn digest(&mut self, msg: &[u8]) -> &mut Self {
13 self.reset();
14 self.write_all(msg).unwrap();
15 self.flush().unwrap();
16 self
17 }
18
19 fn to_bytes_len(&mut self, len: usize) -> Vec<u8> {
20 let mut bytes: Vec<u8> = Vec::with_capacity(len);
21 unsafe { bytes.set_len(len); };
22 self.read(&mut bytes[..]).unwrap();
23 bytes
24 }
25
26 fn to_hex_len(&mut self, len: usize) -> String {
27 bswap::u8::encode_hex(self.to_bytes_len(len).as_ref())
28 }
29}
30
31pub trait DigestExt: Digest {
32 // required
33 fn default_len() -> usize;
34
35 fn to_bytes(&mut self) -> Vec<u8> {
36 self.to_bytes_len(<Self as DigestExt>::default_len())
37 }
38
39 fn to_hex(&mut self) -> String {
40 bswap::u8::encode_hex(self.to_bytes().as_ref())
41 }
42}
43
44//
45// Library
46//
47//
48//
49///// A Pad can return a ReadPad.
50//pub trait Pad {
51// type Output: ReadPad;
52//
53// fn block_len(&self) -> usize;
54// fn pad(&self, len: usize) -> <Self as Pad>::Output;
55//}
56
57/// A ReadPad can read to a buffer.
58pub trait ReadPad {
59 fn read_pad(&self, buf: &mut Vec<u8>) -> io::Result<usize>;
60}
61
62pub trait ReadPadBlocksExt: Read + Sized {
63 fn pad_blocks<P: ReadPad, F: Fn(usize) -> P>(
64 self, block_len: usize, padder: F) -> PadBlocks<Self, P, F> {
65 let mut buf = Vec::with_capacity(2*block_len);
66 buf.resize(block_len, 0);
67
68 PadBlocks {
69 inner: self,
70 padder: padder,
71 block_len: block_len,
72 buf: buf,
73 len: 0,
74 finished: false,
75 }
76 }
77}
78impl<T: Read> ReadPadBlocksExt for T {}
79
80pub struct PadBlocks<I: Read, P: ReadPad, F: Fn(usize) -> P> {
81 inner: I,
82 padder: F,
83 block_len: usize,
84 buf: Vec<u8>,
85 len: usize,
86 finished: bool,
87}
88
89impl<I: Read, P: ReadPad, F: Fn(usize) -> P> PadBlocks<I, P, F> {
90
91 fn fill_buf(&mut self) -> io::Result<&[u8]> {
92 if self.finished {
93 if self.buf.len() > self.block_len && self.len > 0 {
94 self.len = 0;
95 return Ok(&self.buf[self.block_len..self.block_len*2]);
96 }
97 return Ok(&self.buf[0..0]);
98 }
99
100 self.buf.clear();
101 unsafe { self.buf.set_len(self.block_len); };
102 let mut len = try!(self.inner.read(&mut self.buf[..]));
103 self.len += len;
104
105 if len < self.block_len {
106 unsafe { self.buf.set_len(len); };
107 let reader: P = (self.padder)(self.len);
108 len += try!(reader.read_pad(&mut self.buf));
109 //assert_eq!(self.buf.len(), self.block_len);
110 self.finished = true;
111 }
112
113 if len < self.block_len && len > 0 {
114 return Err(io::Error::new(
115 io::ErrorKind::BrokenPipe,
116 "unable to read block to end"));
117 }
118
119 Ok(&self.buf[..self.block_len])
120 }
121}
122
123//trait BorrowIterator {
124// type Item: ?Sized;
125// fn next(&mut self) -> Option<&Self::Item>;
126//}
127
128impl<I: Read, P: ReadPad, F: Fn(usize) -> P> Iterator for PadBlocks< I, P, F> {
129 type Item = Vec<u8>;
130
131 fn next(&mut self) -> Option<Vec<u8>> {
132 let buf = self.fill_buf().unwrap();
133 if buf.len() == 0 { return None };
134 let mut vec = Vec::new();
135 vec.extend_from_slice(buf);
136 Some(vec)
137 }
138}
139
140pub struct StdPad {
141 prefix: u8,
142 suffix: Vec<u8>,
143 block_len: usize,
144}
145
146impl StdPad {
147 pub fn new(suffix: Vec<u8>, block_len: usize) -> StdPad {
148 StdPad {
149 prefix: 0x80,
150 suffix: suffix,
151 block_len: block_len,
152 }
153 }
154 pub fn with_prefix(prefix: u8, suffix: Vec<u8>, block_len: usize) -> StdPad {
155 StdPad {
156 prefix: prefix,
157 suffix: suffix,
158 block_len: block_len,
159 }
160 }
161}
162
163impl ReadPad for StdPad {
164
165 fn read_pad(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
166 let len = buf.len() + 1 + self.suffix.len();
167 let big = if len > self.block_len {2} else {1};
168 let written = self.block_len*big - buf.len();
169
170 buf.push(self.prefix);
171 buf.resize(self.block_len*big - self.suffix.len(), 0);
172 try!(Write::write(buf, &self.suffix[..]));
173
174 Ok(written)
175 }
176}
177
178
179//
180//
181//
182//
183//
184//
185//
186//
187//
188//
189//pub trait Pad {
190// type Output: ReadPad;
191//
192// /// A Pad can return a ReadPad.
193// fn pad(&self, len: usize) -> <Self as Pad>::Output;
194//}
195//
196//pub trait ReadPad {
197//
198// /// A ReadPad can read to a buffer.
199// fn read_pad(&self, buf: &mut Vec<u8>) -> io::Result<usize>;
200//}
201//
202//pub trait ReadPadBlocksExt: Read + Sized {
203// fn pad_blocks<'a, P: Pad>(&'a mut self, block_len: usize, padder: &'a P) -> PadBlocks<'a, Self, P> {
204// let mut buf = Vec::with_capacity(2*block_len);
205// buf.resize(block_len, 0);
206//
207// PadBlocks {
208// inner: self,
209// padder: padder,
210// block_len: block_len,
211// buf: buf,
212// len: 0,
213// }
214// }
215//}
216//
217//impl<T: Read> ReadPadBlocksExt for T {}
218//
219//pub struct PadBlocks<'a, I: 'a + Read, P: 'a + Pad> {
220// inner: &'a mut I,
221// padder: P,
222// block_len: usize,
223// buf: Vec<u8>,
224// len: usize,
225//}
226//
227//macro_rules! try_or_none {
228// ($expr:expr) => (match $expr {
229// Ok(val) => val,
230// Err(err) => {
231// return None
232// }
233// })
234//}
235//
236//impl<'a, I: Read, P: Pad> Iterator for PadBlocks<'a, I, P> {
237// type Item = &'a [u8];
238//
239// fn next(&mut self) -> Option<&'a [u8]> {
240// let len = try_or_none!(self.inner.read(&mut self.buf[..]));
241// self.len += len;
242//
243// if len < self.block_len {
244// unsafe { self.buf.set_len(len); };
245// let reader: <P as Pad>::Output = self.padder.pad(self.len);
246// self.len += try_or_none!(reader.read_pad(&mut self.buf));
247// assert_eq!(self.buf.len(), self.block_len);
248// }
249//
250// if len < self.block_len && len > 0 {
251// return None;
252// //return Err(io::Error::new(
253// // io::ErrorKind::BrokenPipe,
254// // "unable to read block to end", None));
255// }
256//
257// Some(&self.buf[..])
258// }
259//}
260// //impl<'a> ReadBlock for io::Chain<io::Cursor<&'a [u8]>, StdPad> {
261// // type Block = [u8; 64];
262// //
263// // fn read_block(&mut self, block: &mut <Self as ReadBlock>::Block) -> io::Result<usize> {
264// // Ok(size)
265// // }
266// //}
267//
268//pub struct StdPad {
269// prefix: u8,
270// suffix: Vec<u8>,
271// block_len: usize,
272//}
273//
274//impl StdPad {
275// pub fn new(suffix: Vec<u8>, block_len: usize) -> StdPad {
276// StdPad {
277// prefix: 0x80,
278// suffix: suffix,
279// block_len: block_len,
280// }
281// }
282//}
283//
284//impl ReadPad for StdPad {
285// fn read_pad(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
286// let len = buf.len() + 1 + self.suffix.len();
287// let big = if len > self.block_len {2} else {1};
288//
289// buf.push(self.prefix);
290// buf.resize(self.block_len*big - self.suffix.len(), 0);
291// Write::write(buf, &self.suffix[..]);
292// }
293//}
294
295//impl<'a> Read for StdPad<'a> {
296//
297// fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
298// use std::slice::bytes::{MutableByteVector, copy_memory};
299//
300// if self.pos == 0 {
301// self.block_len = buf.len();
302// }
303//
304// let rem_len = self.len % self.block_len;
305// let nblocks = if rem_len + 9 > self.block_len {2} else {1};
306// let mut pad_len = nblocks*self.block_len - rem_len;
307//
308// if pad_len <= self.pos {
309// return Ok(0);
310// }
311//
312// if pad_len > buf.len() {
313// if self.pos == 0 {
314// pad_len -= self.block_len;
315//
316// // prefix
317// buf[0] = 0x80;
318//
319// // padding
320// (&mut buf[1 .. pad_len]).set_memory(0);
321// } else {
322// pad_len = self.block_len;
323//
324// // padding
325// (&mut buf[0 .. pad_len - 8]).set_memory(0);
326//
327// // suffix
328// let mut suffix = [0u8; 8];
329// beu64::encode(&mut suffix[..], (8*self.len) as u64);
330// copy_memory(&mut buf[pad_len - 8 .. pad_len], &suffix[..]);
331// }
332// } else {
333//
334// // prefix
335// buf[0] = 0x80;
336//
337// // padding
338// (&mut buf[1 .. pad_len - 8]).set_memory(0);
339//
340// // suffix
341// let mut suffix = [0u8; 8];
342// beu64::encode(&mut suffix[..], (8*self.len) as u64);
343// copy_memory(&mut buf[pad_len - 8 .. pad_len], &suffix[..]);
344// }
345//
346// self.pos += pad_len;
347// Ok(pad_len)
348// }
349//}