]> git.lizzy.rs Git - rust.git/blob - src/librustc_back/sha2.rs
Kill RacyCell in favor of marking SyncSender explicitly Send.
[rust.git] / src / librustc_back / sha2.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! This module implements only the Sha256 function since that is all that is needed for internal
12 //! use. This implementation is not intended for external use or for any use where security is
13 //! important.
14
15 #![allow(deprecated)] // to_be32
16
17 use std::iter::{range_step, repeat};
18 use std::num::Int;
19 use std::slice::bytes::{MutableByteVector, copy_memory};
20 use serialize::hex::ToHex;
21
22 /// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian
23 /// format.
24 fn write_u32_be(dst: &mut[u8], input: u32) {
25     dst[0] = (input >> 24) as u8;
26     dst[1] = (input >> 16) as u8;
27     dst[2] = (input >> 8) as u8;
28     dst[3] = input as u8;
29 }
30
31 /// Read the value of a vector of bytes as a u32 value in big-endian format.
32 fn read_u32_be(input: &[u8]) -> u32 {
33     return
34         (input[0] as u32) << 24 |
35         (input[1] as u32) << 16 |
36         (input[2] as u32) << 8 |
37         (input[3] as u32);
38 }
39
40 /// Read a vector of bytes into a vector of u32s. The values are read in big-endian format.
41 fn read_u32v_be(dst: &mut[u32], input: &[u8]) {
42     assert!(dst.len() * 4 == input.len());
43     let mut pos = 0u;
44     for chunk in input.chunks(4) {
45         dst[pos] = read_u32_be(chunk);
46         pos += 1;
47     }
48 }
49
50 trait ToBits {
51     /// Convert the value in bytes to the number of bits, a tuple where the 1st item is the
52     /// high-order value and the 2nd item is the low order value.
53     fn to_bits(self) -> (Self, Self);
54 }
55
56 impl ToBits for u64 {
57     fn to_bits(self) -> (u64, u64) {
58         return (self >> 61, self << 3);
59     }
60 }
61
62 /// Adds the specified number of bytes to the bit count. panic!() if this would cause numeric
63 /// overflow.
64 fn add_bytes_to_bits<T: Int + ToBits>(bits: T, bytes: T) -> T {
65     let (new_high_bits, new_low_bits) = bytes.to_bits();
66
67     if new_high_bits > Int::zero() {
68         panic!("numeric overflow occurred.")
69     }
70
71     match bits.checked_add(new_low_bits) {
72         Some(x) => return x,
73         None => panic!("numeric overflow occurred.")
74     }
75 }
76
77 /// A FixedBuffer, likes its name implies, is a fixed size buffer. When the buffer becomes full, it
78 /// must be processed. The input() method takes care of processing and then clearing the buffer
79 /// automatically. However, other methods do not and require the caller to process the buffer. Any
80 /// method that modifies the buffer directory or provides the caller with bytes that can be modified
81 /// results in those bytes being marked as used by the buffer.
82 trait FixedBuffer {
83     /// Input a vector of bytes. If the buffer becomes full, process it with the provided
84     /// function and then clear the buffer.
85     fn input<F>(&mut self, input: &[u8], func: F) where
86         F: FnMut(&[u8]);
87
88     /// Reset the buffer.
89     fn reset(&mut self);
90
91     /// Zero the buffer up until the specified index. The buffer position currently must not be
92     /// greater than that index.
93     fn zero_until(&mut self, idx: uint);
94
95     /// Get a slice of the buffer of the specified size. There must be at least that many bytes
96     /// remaining in the buffer.
97     fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8];
98
99     /// Get the current buffer. The buffer must already be full. This clears the buffer as well.
100     fn full_buffer<'s>(&'s mut self) -> &'s [u8];
101
102     /// Get the current position of the buffer.
103     fn position(&self) -> uint;
104
105     /// Get the number of bytes remaining in the buffer until it is full.
106     fn remaining(&self) -> uint;
107
108     /// Get the size of the buffer
109     fn size(&self) -> uint;
110 }
111
112 /// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize.
113 struct FixedBuffer64 {
114     buffer: [u8; 64],
115     buffer_idx: uint,
116 }
117
118 impl FixedBuffer64 {
119     /// Create a new FixedBuffer64
120     fn new() -> FixedBuffer64 {
121         return FixedBuffer64 {
122             buffer: [0u8; 64],
123             buffer_idx: 0
124         };
125     }
126 }
127
128 impl FixedBuffer for FixedBuffer64 {
129     fn input<F>(&mut self, input: &[u8], mut func: F) where
130         F: FnMut(&[u8]),
131     {
132         let mut i = 0;
133
134         let size = self.size();
135
136         // If there is already data in the buffer, copy as much as we can into it and process
137         // the data if the buffer becomes full.
138         if self.buffer_idx != 0 {
139             let buffer_remaining = size - self.buffer_idx;
140             if input.len() >= buffer_remaining {
141                     copy_memory(
142                         self.buffer.slice_mut(self.buffer_idx, size),
143                         &input[..buffer_remaining]);
144                 self.buffer_idx = 0;
145                 func(&self.buffer);
146                 i += buffer_remaining;
147             } else {
148                 copy_memory(
149                     self.buffer.slice_mut(self.buffer_idx, self.buffer_idx + input.len()),
150                     input);
151                 self.buffer_idx += input.len();
152                 return;
153             }
154         }
155
156         // While we have at least a full buffer size chunk's worth of data, process that data
157         // without copying it into the buffer
158         while input.len() - i >= size {
159             func(&input[i..(i + size)]);
160             i += size;
161         }
162
163         // Copy any input data into the buffer. At this point in the method, the amount of
164         // data left in the input vector will be less than the buffer size and the buffer will
165         // be empty.
166         let input_remaining = input.len() - i;
167         copy_memory(
168             self.buffer.slice_to_mut(input_remaining),
169             &input[i..]);
170         self.buffer_idx += input_remaining;
171     }
172
173     fn reset(&mut self) {
174         self.buffer_idx = 0;
175     }
176
177     fn zero_until(&mut self, idx: uint) {
178         assert!(idx >= self.buffer_idx);
179         self.buffer.slice_mut(self.buffer_idx, idx).set_memory(0);
180         self.buffer_idx = idx;
181     }
182
183     fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8] {
184         self.buffer_idx += len;
185         return self.buffer.slice_mut(self.buffer_idx - len, self.buffer_idx);
186     }
187
188     fn full_buffer<'s>(&'s mut self) -> &'s [u8] {
189         assert!(self.buffer_idx == 64);
190         self.buffer_idx = 0;
191         return &self.buffer[..64];
192     }
193
194     fn position(&self) -> uint { self.buffer_idx }
195
196     fn remaining(&self) -> uint { 64 - self.buffer_idx }
197
198     fn size(&self) -> uint { 64 }
199 }
200
201 /// The StandardPadding trait adds a method useful for Sha256 to a FixedBuffer struct.
202 trait StandardPadding {
203     /// Add padding to the buffer. The buffer must not be full when this method is called and is
204     /// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least
205     /// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled
206     /// with zeros again until only rem bytes are remaining.
207     fn standard_padding<F>(&mut self, rem: uint, func: F) where F: FnMut(&[u8]);
208 }
209
210 impl <T: FixedBuffer> StandardPadding for T {
211     fn standard_padding<F>(&mut self, rem: uint, mut func: F) where F: FnMut(&[u8]) {
212         let size = self.size();
213
214         self.next(1)[0] = 128;
215
216         if self.remaining() < rem {
217             self.zero_until(size);
218             func(self.full_buffer());
219         }
220
221         self.zero_until(size - rem);
222     }
223 }
224
225 /// The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2
226 /// family of digest functions.
227 pub trait Digest {
228     /// Provide message data.
229     ///
230     /// # Arguments
231     ///
232     /// * input - A vector of message data
233     fn input(&mut self, input: &[u8]);
234
235     /// Retrieve the digest result. This method may be called multiple times.
236     ///
237     /// # Arguments
238     ///
239     /// * out - the vector to hold the result. Must be large enough to contain output_bits().
240     fn result(&mut self, out: &mut [u8]);
241
242     /// Reset the digest. This method must be called after result() and before supplying more
243     /// data.
244     fn reset(&mut self);
245
246     /// Get the output size in bits.
247     fn output_bits(&self) -> uint;
248
249     /// Convenience function that feeds a string into a digest.
250     ///
251     /// # Arguments
252     ///
253     /// * `input` The string to feed into the digest
254     fn input_str(&mut self, input: &str) {
255         self.input(input.as_bytes());
256     }
257
258     /// Convenience function that retrieves the result of a digest as a
259     /// newly allocated vec of bytes.
260     fn result_bytes(&mut self) -> Vec<u8> {
261         let mut buf: Vec<u8> = repeat(0u8).take((self.output_bits()+7)/8).collect();
262         self.result(buf.as_mut_slice());
263         buf
264     }
265
266     /// Convenience function that retrieves the result of a digest as a
267     /// String in hexadecimal format.
268     fn result_str(&mut self) -> String {
269         self.result_bytes().to_hex().to_string()
270     }
271 }
272
273 // A structure that represents that state of a digest computation for the SHA-2 512 family of digest
274 // functions
275 struct Engine256State {
276     h0: u32,
277     h1: u32,
278     h2: u32,
279     h3: u32,
280     h4: u32,
281     h5: u32,
282     h6: u32,
283     h7: u32,
284 }
285
286 impl Engine256State {
287     fn new(h: &[u32; 8]) -> Engine256State {
288         return Engine256State {
289             h0: h[0],
290             h1: h[1],
291             h2: h[2],
292             h3: h[3],
293             h4: h[4],
294             h5: h[5],
295             h6: h[6],
296             h7: h[7]
297         };
298     }
299
300     fn reset(&mut self, h: &[u32; 8]) {
301         self.h0 = h[0];
302         self.h1 = h[1];
303         self.h2 = h[2];
304         self.h3 = h[3];
305         self.h4 = h[4];
306         self.h5 = h[5];
307         self.h6 = h[6];
308         self.h7 = h[7];
309     }
310
311     fn process_block(&mut self, data: &[u8]) {
312         fn ch(x: u32, y: u32, z: u32) -> u32 {
313             ((x & y) ^ ((!x) & z))
314         }
315
316         fn maj(x: u32, y: u32, z: u32) -> u32 {
317             ((x & y) ^ (x & z) ^ (y & z))
318         }
319
320         fn sum0(x: u32) -> u32 {
321             ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10))
322         }
323
324         fn sum1(x: u32) -> u32 {
325             ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7))
326         }
327
328         fn sigma0(x: u32) -> u32 {
329             ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3)
330         }
331
332         fn sigma1(x: u32) -> u32 {
333             ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10)
334         }
335
336         let mut a = self.h0;
337         let mut b = self.h1;
338         let mut c = self.h2;
339         let mut d = self.h3;
340         let mut e = self.h4;
341         let mut f = self.h5;
342         let mut g = self.h6;
343         let mut h = self.h7;
344
345         let mut w = [0u32; 64];
346
347         // Sha-512 and Sha-256 use basically the same calculations which are implemented
348         // by these macros. Inlining the calculations seems to result in better generated code.
349         macro_rules! schedule_round { ($t:expr) => (
350                 w[$t] = sigma1(w[$t - 2]) + w[$t - 7] + sigma0(w[$t - 15]) + w[$t - 16];
351                 )
352         }
353
354         macro_rules! sha2_round {
355             ($A:ident, $B:ident, $C:ident, $D:ident,
356              $E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
357                 {
358                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + w[$t];
359                     $D += $H;
360                     $H += sum0($A) + maj($A, $B, $C);
361                 }
362              )
363         }
364
365         read_u32v_be(w.slice_mut(0, 16), data);
366
367         // Putting the message schedule inside the same loop as the round calculations allows for
368         // the compiler to generate better code.
369         for t in range_step(0u, 48, 8) {
370             schedule_round!(t + 16);
371             schedule_round!(t + 17);
372             schedule_round!(t + 18);
373             schedule_round!(t + 19);
374             schedule_round!(t + 20);
375             schedule_round!(t + 21);
376             schedule_round!(t + 22);
377             schedule_round!(t + 23);
378
379             sha2_round!(a, b, c, d, e, f, g, h, K32, t);
380             sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
381             sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
382             sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
383             sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
384             sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
385             sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
386             sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
387         }
388
389         for t in range_step(48u, 64, 8) {
390             sha2_round!(a, b, c, d, e, f, g, h, K32, t);
391             sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
392             sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
393             sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
394             sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
395             sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
396             sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
397             sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
398         }
399
400         self.h0 += a;
401         self.h1 += b;
402         self.h2 += c;
403         self.h3 += d;
404         self.h4 += e;
405         self.h5 += f;
406         self.h6 += g;
407         self.h7 += h;
408     }
409 }
410
411 static K32: [u32; 64] = [
412     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
413     0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
414     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
415     0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
416     0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
417     0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
418     0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
419     0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
420     0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
421     0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
422     0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
423     0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
424     0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
425     0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
426     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
427     0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
428 ];
429
430 // A structure that keeps track of the state of the Sha-256 operation and contains the logic
431 // necessary to perform the final calculations.
432 struct Engine256 {
433     length_bits: u64,
434     buffer: FixedBuffer64,
435     state: Engine256State,
436     finished: bool,
437 }
438
439 impl Engine256 {
440     fn new(h: &[u32; 8]) -> Engine256 {
441         return Engine256 {
442             length_bits: 0,
443             buffer: FixedBuffer64::new(),
444             state: Engine256State::new(h),
445             finished: false
446         }
447     }
448
449     fn reset(&mut self, h: &[u32; 8]) {
450         self.length_bits = 0;
451         self.buffer.reset();
452         self.state.reset(h);
453         self.finished = false;
454     }
455
456     fn input(&mut self, input: &[u8]) {
457         assert!(!self.finished);
458         // Assumes that input.len() can be converted to u64 without overflow
459         self.length_bits = add_bytes_to_bits(self.length_bits, input.len() as u64);
460         let self_state = &mut self.state;
461         self.buffer.input(input, |input: &[u8]| { self_state.process_block(input) });
462     }
463
464     fn finish(&mut self) {
465         if self.finished {
466             return;
467         }
468
469         let self_state = &mut self.state;
470         self.buffer.standard_padding(8, |input: &[u8]| { self_state.process_block(input) });
471         write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32 );
472         write_u32_be(self.buffer.next(4), self.length_bits as u32);
473         self_state.process_block(self.buffer.full_buffer());
474
475         self.finished = true;
476     }
477 }
478
479 /// The SHA-256 hash algorithm
480 pub struct Sha256 {
481     engine: Engine256
482 }
483
484 impl Sha256 {
485     /// Construct a new instance of a SHA-256 digest.
486     pub fn new() -> Sha256 {
487         Sha256 {
488             engine: Engine256::new(&H256)
489         }
490     }
491 }
492
493 impl Digest for Sha256 {
494     fn input(&mut self, d: &[u8]) {
495         self.engine.input(d);
496     }
497
498     fn result(&mut self, out: &mut [u8]) {
499         self.engine.finish();
500
501         write_u32_be(out.slice_mut(0, 4), self.engine.state.h0);
502         write_u32_be(out.slice_mut(4, 8), self.engine.state.h1);
503         write_u32_be(out.slice_mut(8, 12), self.engine.state.h2);
504         write_u32_be(out.slice_mut(12, 16), self.engine.state.h3);
505         write_u32_be(out.slice_mut(16, 20), self.engine.state.h4);
506         write_u32_be(out.slice_mut(20, 24), self.engine.state.h5);
507         write_u32_be(out.slice_mut(24, 28), self.engine.state.h6);
508         write_u32_be(out.slice_mut(28, 32), self.engine.state.h7);
509     }
510
511     fn reset(&mut self) {
512         self.engine.reset(&H256);
513     }
514
515     fn output_bits(&self) -> uint { 256 }
516 }
517
518 static H256: [u32; 8] = [
519     0x6a09e667,
520     0xbb67ae85,
521     0x3c6ef372,
522     0xa54ff53a,
523     0x510e527f,
524     0x9b05688c,
525     0x1f83d9ab,
526     0x5be0cd19
527 ];
528
529 #[cfg(test)]
530 mod tests {
531     extern crate rand;
532
533     use self::rand::Rng;
534     use self::rand::isaac::IsaacRng;
535     use serialize::hex::FromHex;
536     use std::iter::repeat;
537     use std::num::Int;
538     use super::{Digest, Sha256, FixedBuffer};
539
540     // A normal addition - no overflow occurs
541     #[test]
542     fn test_add_bytes_to_bits_ok() {
543         assert!(super::add_bytes_to_bits::<u64>(100, 10) == 180);
544     }
545
546     // A simple failure case - adding 1 to the max value
547     #[test]
548     #[should_fail]
549     fn test_add_bytes_to_bits_overflow() {
550         super::add_bytes_to_bits::<u64>(Int::max_value(), 1);
551     }
552
553     struct Test {
554         input: String,
555         output_str: String,
556     }
557
558     fn test_hash<D: Digest>(sh: &mut D, tests: &[Test]) {
559         // Test that it works when accepting the message all at once
560         for t in tests.iter() {
561             sh.reset();
562             sh.input_str(t.input.as_slice());
563             let out_str = sh.result_str();
564             assert!(out_str == t.output_str);
565         }
566
567         // Test that it works when accepting the message in pieces
568         for t in tests.iter() {
569             sh.reset();
570             let len = t.input.len();
571             let mut left = len;
572             while left > 0u {
573                 let take = (left + 1u) / 2u;
574                 sh.input_str(t.input
575                               .slice(len - left, take + len - left));
576                 left = left - take;
577             }
578             let out_str = sh.result_str();
579             assert!(out_str == t.output_str);
580         }
581     }
582
583     #[test]
584     fn test_sha256() {
585         // Examples from wikipedia
586         let wikipedia_tests = vec!(
587             Test {
588                 input: "".to_string(),
589                 output_str: "e3b0c44298fc1c149afb\
590             f4c8996fb92427ae41e4649b934ca495991b7852b855".to_string()
591             },
592             Test {
593                 input: "The quick brown fox jumps over the lazy \
594                         dog".to_string(),
595                 output_str: "d7a8fbb307d7809469ca\
596             9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592".to_string()
597             },
598             Test {
599                 input: "The quick brown fox jumps over the lazy \
600                         dog.".to_string(),
601                 output_str: "ef537f25c895bfa78252\
602             6529a9b63d97aa631564d5d789c2b765448c8635fb6c".to_string()
603             });
604
605         let tests = wikipedia_tests;
606
607         let mut sh = box Sha256::new();
608
609         test_hash(&mut *sh, tests.as_slice());
610     }
611
612     /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is
613     /// correct.
614     fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: uint, expected: &str) {
615         let total_size = 1000000;
616         let buffer: Vec<u8> = repeat('a' as u8).take(blocksize * 2).collect();
617         let mut rng = IsaacRng::new_unseeded();
618         let mut count = 0;
619
620         digest.reset();
621
622         while count < total_size {
623             let next: uint = rng.gen_range(0, 2 * blocksize + 1);
624             let remaining = total_size - count;
625             let size = if next > remaining { remaining } else { next };
626             digest.input(buffer.slice_to(size));
627             count += size;
628         }
629
630         let result_str = digest.result_str();
631         let result_bytes = digest.result_bytes();
632
633         assert_eq!(expected, result_str.as_slice());
634
635         let expected_vec: Vec<u8> = expected.from_hex()
636                                             .unwrap()
637                                             .into_iter()
638                                             .collect();
639         assert_eq!(expected_vec, result_bytes);
640     }
641
642     #[test]
643     fn test_1million_random_sha256() {
644         let mut sh = Sha256::new();
645         test_digest_1million_random(
646             &mut sh,
647             64,
648             "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
649     }
650 }
651
652 #[cfg(test)]
653 mod bench {
654     extern crate test;
655     use self::test::Bencher;
656     use super::{Sha256, FixedBuffer, Digest};
657
658     #[bench]
659     pub fn sha256_10(b: &mut Bencher) {
660         let mut sh = Sha256::new();
661         let bytes = [1u8; 10];
662         b.iter(|| {
663             sh.input(&bytes);
664         });
665         b.bytes = bytes.len() as u64;
666     }
667
668     #[bench]
669     pub fn sha256_1k(b: &mut Bencher) {
670         let mut sh = Sha256::new();
671         let bytes = [1u8; 1024];
672         b.iter(|| {
673             sh.input(&bytes);
674         });
675         b.bytes = bytes.len() as u64;
676     }
677
678     #[bench]
679     pub fn sha256_64k(b: &mut Bencher) {
680         let mut sh = Sha256::new();
681         let bytes = [1u8; 65536];
682         b.iter(|| {
683             sh.input(&bytes);
684         });
685         b.bytes = bytes.len() as u64;
686     }
687 }