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.
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.
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
15 use std::slice::bytes::{MutableByteVector, copy_memory};
16 use serialize::hex::ToHex;
18 /// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian
20 fn write_u32_be(dst: &mut[u8], input: u32) {
21 dst[0] = (input >> 24) as u8;
22 dst[1] = (input >> 16) as u8;
23 dst[2] = (input >> 8) as u8;
27 /// Read the value of a vector of bytes as a u32 value in big-endian format.
28 fn read_u32_be(input: &[u8]) -> u32 {
30 (input[0] as u32) << 24 |
31 (input[1] as u32) << 16 |
32 (input[2] as u32) << 8 |
36 /// Read a vector of bytes into a vector of u32s. The values are read in big-endian format.
37 fn read_u32v_be(dst: &mut[u32], input: &[u8]) {
38 assert!(dst.len() * 4 == input.len());
40 for chunk in input.chunks(4) {
41 dst[pos] = read_u32_be(chunk);
47 /// Convert the value in bytes to the number of bits, a tuple where the 1st item is the
48 /// high-order value and the 2nd item is the low order value.
49 fn to_bits(self) -> (Self, Self);
53 fn to_bits(self) -> (u64, u64) {
54 return (self >> 61, self << 3);
58 /// Adds the specified number of bytes to the bit count. panic!() if this would cause numeric
60 fn add_bytes_to_bits(bits: u64, bytes: u64) -> u64 {
61 let (new_high_bits, new_low_bits) = bytes.to_bits();
63 if new_high_bits > 0 {
64 panic!("numeric overflow occurred.")
67 match bits.checked_add(new_low_bits) {
69 None => panic!("numeric overflow occurred.")
73 /// A FixedBuffer, likes its name implies, is a fixed size buffer. When the buffer becomes full, it
74 /// must be processed. The input() method takes care of processing and then clearing the buffer
75 /// automatically. However, other methods do not and require the caller to process the buffer. Any
76 /// method that modifies the buffer directory or provides the caller with bytes that can be modified
77 /// results in those bytes being marked as used by the buffer.
79 /// Input a vector of bytes. If the buffer becomes full, process it with the provided
80 /// function and then clear the buffer.
81 fn input<F>(&mut self, input: &[u8], func: F) where
87 /// Zero the buffer up until the specified index. The buffer position currently must not be
88 /// greater than that index.
89 fn zero_until(&mut self, idx: usize);
91 /// Get a slice of the buffer of the specified size. There must be at least that many bytes
92 /// remaining in the buffer.
93 fn next<'s>(&'s mut self, len: usize) -> &'s mut [u8];
95 /// Get the current buffer. The buffer must already be full. This clears the buffer as well.
96 fn full_buffer<'s>(&'s mut self) -> &'s [u8];
98 /// Get the current position of the buffer.
99 fn position(&self) -> usize;
101 /// Get the number of bytes remaining in the buffer until it is full.
102 fn remaining(&self) -> usize;
104 /// Get the size of the buffer
105 fn size(&self) -> usize;
108 /// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize.
109 struct FixedBuffer64 {
115 /// Create a new FixedBuffer64
116 fn new() -> FixedBuffer64 {
117 return FixedBuffer64 {
124 impl FixedBuffer for FixedBuffer64 {
125 fn input<F>(&mut self, input: &[u8], mut func: F) where
130 let size = self.size();
132 // If there is already data in the buffer, copy as much as we can into it and process
133 // the data if the buffer becomes full.
134 if self.buffer_idx != 0 {
135 let buffer_remaining = size - self.buffer_idx;
136 if input.len() >= buffer_remaining {
138 &input[..buffer_remaining],
139 &mut self.buffer[self.buffer_idx..size]);
142 i += buffer_remaining;
146 &mut self.buffer[self.buffer_idx..self.buffer_idx + input.len()]);
147 self.buffer_idx += input.len();
152 // While we have at least a full buffer size chunk's worth of data, process that data
153 // without copying it into the buffer
154 while input.len() - i >= size {
155 func(&input[i..i + size]);
159 // Copy any input data into the buffer. At this point in the method, the amount of
160 // data left in the input vector will be less than the buffer size and the buffer will
162 let input_remaining = input.len() - i;
165 &mut self.buffer[..input_remaining]);
166 self.buffer_idx += input_remaining;
169 fn reset(&mut self) {
173 fn zero_until(&mut self, idx: usize) {
174 assert!(idx >= self.buffer_idx);
175 self.buffer[self.buffer_idx..idx].set_memory(0);
176 self.buffer_idx = idx;
179 fn next<'s>(&'s mut self, len: usize) -> &'s mut [u8] {
180 self.buffer_idx += len;
181 return &mut self.buffer[self.buffer_idx - len..self.buffer_idx];
184 fn full_buffer<'s>(&'s mut self) -> &'s [u8] {
185 assert!(self.buffer_idx == 64);
187 return &self.buffer[..64];
190 fn position(&self) -> usize { self.buffer_idx }
192 fn remaining(&self) -> usize { 64 - self.buffer_idx }
194 fn size(&self) -> usize { 64 }
197 /// The StandardPadding trait adds a method useful for Sha256 to a FixedBuffer struct.
198 trait StandardPadding {
199 /// Add padding to the buffer. The buffer must not be full when this method is called and is
200 /// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least
201 /// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled
202 /// with zeros again until only rem bytes are remaining.
203 fn standard_padding<F>(&mut self, rem: usize, func: F) where F: FnMut(&[u8]);
206 impl <T: FixedBuffer> StandardPadding for T {
207 fn standard_padding<F>(&mut self, rem: usize, mut func: F) where F: FnMut(&[u8]) {
208 let size = self.size();
210 self.next(1)[0] = 128;
212 if self.remaining() < rem {
213 self.zero_until(size);
214 func(self.full_buffer());
217 self.zero_until(size - rem);
221 /// The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2
222 /// family of digest functions.
224 /// Provide message data.
228 /// * input - A vector of message data
229 fn input(&mut self, input: &[u8]);
231 /// Retrieve the digest result. This method may be called multiple times.
235 /// * out - the vector to hold the result. Must be large enough to contain output_bits().
236 fn result(&mut self, out: &mut [u8]);
238 /// Reset the digest. This method must be called after result() and before supplying more
242 /// Get the output size in bits.
243 fn output_bits(&self) -> usize;
245 /// Convenience function that feeds a string into a digest.
249 /// * `input` The string to feed into the digest
250 fn input_str(&mut self, input: &str) {
251 self.input(input.as_bytes());
254 /// Convenience function that retrieves the result of a digest as a
255 /// newly allocated vec of bytes.
256 fn result_bytes(&mut self) -> Vec<u8> {
257 let mut buf = vec![0; (self.output_bits()+7)/8];
258 self.result(&mut buf);
262 /// Convenience function that retrieves the result of a digest as a
263 /// String in hexadecimal format.
264 fn result_str(&mut self) -> String {
265 self.result_bytes().to_hex().to_string()
269 // A structure that represents that state of a digest computation for the SHA-2 512 family of digest
271 struct Engine256State {
282 impl Engine256State {
283 fn new(h: &[u32; 8]) -> Engine256State {
284 return Engine256State {
296 fn reset(&mut self, h: &[u32; 8]) {
307 fn process_block(&mut self, data: &[u8]) {
308 fn ch(x: u32, y: u32, z: u32) -> u32 {
309 ((x & y) ^ ((!x) & z))
312 fn maj(x: u32, y: u32, z: u32) -> u32 {
313 ((x & y) ^ (x & z) ^ (y & z))
316 fn sum0(x: u32) -> u32 {
317 ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10))
320 fn sum1(x: u32) -> u32 {
321 ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7))
324 fn sigma0(x: u32) -> u32 {
325 ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3)
328 fn sigma1(x: u32) -> u32 {
329 ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10)
343 // Sha-512 and Sha-256 use basically the same calculations which are implemented
344 // by these macros. Inlining the calculations seems to result in better generated code.
345 macro_rules! schedule_round { ($t:expr) => (
346 w[$t] = sigma1(w[$t - 2]).wrapping_add(w[$t - 7])
347 .wrapping_add(sigma0(w[$t - 15])).wrapping_add(w[$t - 16]);
351 macro_rules! sha2_round {
352 ($A:ident, $B:ident, $C:ident, $D:ident,
353 $E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
355 $H = $H.wrapping_add(sum1($E)).wrapping_add(ch($E, $F, $G))
356 .wrapping_add($K[$t]).wrapping_add(w[$t]);
357 $D = $D.wrapping_add($H);
358 $H = $H.wrapping_add(sum0($A)).wrapping_add(maj($A, $B, $C));
363 read_u32v_be(&mut w[0..16], data);
365 // Putting the message schedule inside the same loop as the round calculations allows for
366 // the compiler to generate better code.
367 for t in (0..48).step_by(8) {
368 schedule_round!(t + 16);
369 schedule_round!(t + 17);
370 schedule_round!(t + 18);
371 schedule_round!(t + 19);
372 schedule_round!(t + 20);
373 schedule_round!(t + 21);
374 schedule_round!(t + 22);
375 schedule_round!(t + 23);
377 sha2_round!(a, b, c, d, e, f, g, h, K32, t);
378 sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
379 sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
380 sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
381 sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
382 sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
383 sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
384 sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
387 for t in (48..64).step_by(8) {
388 sha2_round!(a, b, c, d, e, f, g, h, K32, t);
389 sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
390 sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
391 sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
392 sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
393 sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
394 sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
395 sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
398 self.h0 = self.h0.wrapping_add(a);
399 self.h1 = self.h1.wrapping_add(b);
400 self.h2 = self.h2.wrapping_add(c);
401 self.h3 = self.h3.wrapping_add(d);
402 self.h4 = self.h4.wrapping_add(e);
403 self.h5 = self.h5.wrapping_add(f);
404 self.h6 = self.h6.wrapping_add(g);
405 self.h7 = self.h7.wrapping_add(h);
409 static K32: [u32; 64] = [
410 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
411 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
412 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
413 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
414 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
415 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
416 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
417 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
418 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
419 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
420 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
421 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
422 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
423 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
424 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
425 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
428 // A structure that keeps track of the state of the Sha-256 operation and contains the logic
429 // necessary to perform the final calculations.
432 buffer: FixedBuffer64,
433 state: Engine256State,
438 fn new(h: &[u32; 8]) -> Engine256 {
441 buffer: FixedBuffer64::new(),
442 state: Engine256State::new(h),
447 fn reset(&mut self, h: &[u32; 8]) {
448 self.length_bits = 0;
451 self.finished = false;
454 fn input(&mut self, input: &[u8]) {
455 assert!(!self.finished);
456 // Assumes that input.len() can be converted to u64 without overflow
457 self.length_bits = add_bytes_to_bits(self.length_bits, input.len() as u64);
458 let self_state = &mut self.state;
459 self.buffer.input(input, |input: &[u8]| { self_state.process_block(input) });
462 fn finish(&mut self) {
467 let self_state = &mut self.state;
468 self.buffer.standard_padding(8, |input: &[u8]| { self_state.process_block(input) });
469 write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32 );
470 write_u32_be(self.buffer.next(4), self.length_bits as u32);
471 self_state.process_block(self.buffer.full_buffer());
473 self.finished = true;
477 /// The SHA-256 hash algorithm
483 /// Construct a new instance of a SHA-256 digest.
484 /// Do not – under any circumstances – use this where timing attacks might be possible!
485 pub fn new() -> Sha256 {
487 engine: Engine256::new(&H256)
492 impl Digest for Sha256 {
493 fn input(&mut self, d: &[u8]) {
494 self.engine.input(d);
497 fn result(&mut self, out: &mut [u8]) {
498 self.engine.finish();
500 write_u32_be(&mut out[0..4], self.engine.state.h0);
501 write_u32_be(&mut out[4..8], self.engine.state.h1);
502 write_u32_be(&mut out[8..12], self.engine.state.h2);
503 write_u32_be(&mut out[12..16], self.engine.state.h3);
504 write_u32_be(&mut out[16..20], self.engine.state.h4);
505 write_u32_be(&mut out[20..24], self.engine.state.h5);
506 write_u32_be(&mut out[24..28], self.engine.state.h6);
507 write_u32_be(&mut out[28..32], self.engine.state.h7);
510 fn reset(&mut self) {
511 self.engine.reset(&H256);
514 fn output_bits(&self) -> usize { 256 }
517 static H256: [u32; 8] = [
530 #![allow(deprecated)]
534 use self::rand::isaac::IsaacRng;
535 use serialize::hex::FromHex;
537 use super::{Digest, Sha256, FixedBuffer};
539 // A normal addition - no overflow occurs
541 fn test_add_bytes_to_bits_ok() {
542 assert!(super::add_bytes_to_bits(100, 10) == 180);
545 // A simple failure case - adding 1 to the max value
548 fn test_add_bytes_to_bits_overflow() {
549 super::add_bytes_to_bits(u64::MAX, 1);
557 fn test_hash<D: Digest>(sh: &mut D, tests: &[Test]) {
558 // Test that it works when accepting the message all at once
561 sh.input_str(&t.input);
562 let out_str = sh.result_str();
563 assert!(out_str == t.output_str);
566 // Test that it works when accepting the message in pieces
569 let len = t.input.len();
572 let take = (left + 1) / 2;
573 sh.input_str(&t.input[len - left..take + len - left]);
576 let out_str = sh.result_str();
577 assert!(out_str == t.output_str);
583 // Examples from wikipedia
584 let wikipedia_tests = vec!(
586 input: "".to_string(),
587 output_str: "e3b0c44298fc1c149afb\
588 f4c8996fb92427ae41e4649b934ca495991b7852b855".to_string()
591 input: "The quick brown fox jumps over the lazy \
593 output_str: "d7a8fbb307d7809469ca\
594 9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592".to_string()
597 input: "The quick brown fox jumps over the lazy \
599 output_str: "ef537f25c895bfa78252\
600 6529a9b63d97aa631564d5d789c2b765448c8635fb6c".to_string()
603 let tests = wikipedia_tests;
605 let mut sh: Box<_> = box Sha256::new();
607 test_hash(&mut *sh, &tests);
610 /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is
612 fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: usize, expected: &str) {
613 let total_size = 1000000;
614 let buffer = vec![b'a'; blocksize * 2];
615 let mut rng = IsaacRng::new_unseeded();
620 while count < total_size {
621 let next: usize = rng.gen_range(0, 2 * blocksize + 1);
622 let remaining = total_size - count;
623 let size = if next > remaining { remaining } else { next };
624 digest.input(&buffer[..size]);
628 let result_str = digest.result_str();
629 let result_bytes = digest.result_bytes();
631 assert_eq!(expected, result_str);
633 let expected_vec: Vec<u8> = expected.from_hex()
637 assert_eq!(expected_vec, result_bytes);
641 fn test_1million_random_sha256() {
642 let mut sh = Sha256::new();
643 test_digest_1million_random(
646 "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
653 use self::test::Bencher;
654 use super::{Sha256, FixedBuffer, Digest};
657 pub fn sha256_10(b: &mut Bencher) {
658 let mut sh = Sha256::new();
663 b.bytes = bytes.len() as u64;
667 pub fn sha256_1k(b: &mut Bencher) {
668 let mut sh = Sha256::new();
669 let bytes = [1; 1024];
673 b.bytes = bytes.len() as u64;
677 pub fn sha256_64k(b: &mut Bencher) {
678 let mut sh = Sha256::new();
679 let bytes = [1; 65536];
683 b.bytes = bytes.len() as u64;