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 serialize
::hex
::ToHex
;
17 /// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian
19 fn write_u32_be(dst
: &mut[u8], input
: u32) {
20 dst
[0] = (input
>> 24) as u8;
21 dst
[1] = (input
>> 16) as u8;
22 dst
[2] = (input
>> 8) as u8;
26 /// Read the value of a vector of bytes as a u32 value in big-endian format.
27 fn read_u32_be(input
: &[u8]) -> u32 {
28 (input
[0] as u32) << 24 |
29 (input
[1] as u32) << 16 |
30 (input
[2] as u32) << 8 |
34 /// Read a vector of bytes into a vector of u32s. The values are read in big-endian format.
35 fn read_u32v_be(dst
: &mut[u32], input
: &[u8]) {
36 assert
!(dst
.len() * 4 == input
.len());
38 for chunk
in input
.chunks(4) {
39 dst
[pos
] = read_u32_be(chunk
);
45 /// Convert the value in bytes to the number of bits, a tuple where the 1st item is the
46 /// high-order value and the 2nd item is the low order value.
47 fn to_bits(self) -> (Self, Self);
51 fn to_bits(self) -> (u64, u64) {
52 (self >> 61, self << 3)
56 /// Adds the specified number of bytes to the bit count. panic!() if this would cause numeric
58 fn add_bytes_to_bits(bits
: u64, bytes
: u64) -> u64 {
59 let (new_high_bits
, new_low_bits
) = bytes
.to_bits();
61 if new_high_bits
> 0 {
62 panic
!("numeric overflow occurred.")
65 match bits
.checked_add(new_low_bits
) {
67 None
=> panic
!("numeric overflow occurred.")
71 /// A FixedBuffer, likes its name implies, is a fixed size buffer. When the buffer becomes full, it
72 /// must be processed. The input() method takes care of processing and then clearing the buffer
73 /// automatically. However, other methods do not and require the caller to process the buffer. Any
74 /// method that modifies the buffer directory or provides the caller with bytes that can be modified
75 /// results in those bytes being marked as used by the buffer.
77 /// Input a vector of bytes. If the buffer becomes full, process it with the provided
78 /// function and then clear the buffer.
79 fn input
<F
>(&mut self, input
: &[u8], func
: F
) where
85 /// Zero the buffer up until the specified index. The buffer position currently must not be
86 /// greater than that index.
87 fn zero_until(&mut self, idx
: usize);
89 /// Get a slice of the buffer of the specified size. There must be at least that many bytes
90 /// remaining in the buffer.
91 fn next
<'s
>(&'s
mut self, len
: usize) -> &'s
mut [u8];
93 /// Get the current buffer. The buffer must already be full. This clears the buffer as well.
94 fn full_buffer
<'s
>(&'s
mut self) -> &'s
[u8];
96 /// Get the current position of the buffer.
97 fn position(&self) -> usize;
99 /// Get the number of bytes remaining in the buffer until it is full.
100 fn remaining(&self) -> usize;
102 /// Get the size of the buffer
103 fn size(&self) -> usize;
106 /// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize.
107 struct FixedBuffer64
{
113 /// Create a new FixedBuffer64
114 fn new() -> FixedBuffer64
{
122 impl FixedBuffer
for FixedBuffer64
{
123 fn input
<F
>(&mut self, input
: &[u8], mut func
: F
) where
128 let size
= self.size();
130 // If there is already data in the buffer, copy as much as we can into it and process
131 // the data if the buffer becomes full.
132 if self.buffer_idx
!= 0 {
133 let buffer_remaining
= size
- self.buffer_idx
;
134 if input
.len() >= buffer_remaining
{
135 self.buffer
[self.buffer_idx
..size
]
136 .copy_from_slice(&input
[..buffer_remaining
]);
139 i
+= buffer_remaining
;
141 self.buffer
[self.buffer_idx
..self.buffer_idx
+ input
.len()]
142 .copy_from_slice(input
);
143 self.buffer_idx
+= input
.len();
148 // While we have at least a full buffer size chunk's worth of data, process that data
149 // without copying it into the buffer
150 while input
.len() - i
>= size
{
151 func(&input
[i
..i
+ size
]);
155 // Copy any input data into the buffer. At this point in the method, the amount of
156 // data left in the input vector will be less than the buffer size and the buffer will
158 let input_remaining
= input
.len() - i
;
159 self.buffer
[..input_remaining
].copy_from_slice(&input
[i
..]);
160 self.buffer_idx
+= input_remaining
;
163 fn reset(&mut self) {
167 fn zero_until(&mut self, idx
: usize) {
168 assert
!(idx
>= self.buffer_idx
);
169 for slot
in self.buffer
[self.buffer_idx
..idx
].iter_mut() {
172 self.buffer_idx
= idx
;
175 fn next
<'s
>(&'s
mut self, len
: usize) -> &'s
mut [u8] {
176 self.buffer_idx
+= len
;
177 &mut self.buffer
[self.buffer_idx
- len
..self.buffer_idx
]
180 fn full_buffer
<'s
>(&'s
mut self) -> &'s
[u8] {
181 assert
!(self.buffer_idx
== 64);
186 fn position(&self) -> usize { self.buffer_idx }
188 fn remaining(&self) -> usize { 64 - self.buffer_idx }
190 fn size(&self) -> usize { 64 }
193 /// The StandardPadding trait adds a method useful for Sha256 to a FixedBuffer struct.
194 trait StandardPadding
{
195 /// Add padding to the buffer. The buffer must not be full when this method is called and is
196 /// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least
197 /// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled
198 /// with zeros again until only rem bytes are remaining.
199 fn standard_padding
<F
>(&mut self, rem
: usize, func
: F
) where F
: FnMut(&[u8]);
202 impl <T
: FixedBuffer
> StandardPadding
for T
{
203 fn standard_padding
<F
>(&mut self, rem
: usize, mut func
: F
) where F
: FnMut(&[u8]) {
204 let size
= self.size();
206 self.next(1)[0] = 128;
208 if self.remaining() < rem
{
209 self.zero_until(size
);
210 func(self.full_buffer());
213 self.zero_until(size
- rem
);
217 /// The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2
218 /// family of digest functions.
220 /// Provide message data.
224 /// * input - A vector of message data
225 fn input(&mut self, input
: &[u8]);
227 /// Retrieve the digest result. This method may be called multiple times.
231 /// * out - the vector to hold the result. Must be large enough to contain output_bits().
232 fn result(&mut self, out
: &mut [u8]);
234 /// Reset the digest. This method must be called after result() and before supplying more
238 /// Get the output size in bits.
239 fn output_bits(&self) -> usize;
241 /// Convenience function that feeds a string into a digest.
245 /// * `input` The string to feed into the digest
246 fn input_str(&mut self, input
: &str) {
247 self.input(input
.as_bytes());
250 /// Convenience function that retrieves the result of a digest as a
251 /// newly allocated vec of bytes.
252 fn result_bytes(&mut self) -> Vec
<u8> {
253 let mut buf
= vec
![0; (self.output_bits()+7)/8];
254 self.result(&mut buf
);
258 /// Convenience function that retrieves the result of a digest as a
259 /// String in hexadecimal format.
260 fn result_str(&mut self) -> String
{
261 self.result_bytes().to_hex().to_string()
265 // A structure that represents that state of a digest computation for the SHA-2 512 family of digest
267 struct Engine256State
{
278 impl Engine256State
{
279 fn new(h
: &[u32; 8]) -> Engine256State
{
292 fn reset(&mut self, h
: &[u32; 8]) {
303 fn process_block(&mut self, data
: &[u8]) {
304 fn ch(x
: u32, y
: u32, z
: u32) -> u32 {
305 ((x
& y
) ^
((!x
) & z
))
308 fn maj(x
: u32, y
: u32, z
: u32) -> u32 {
309 ((x
& y
) ^
(x
& z
) ^
(y
& z
))
312 fn sum0(x
: u32) -> u32 {
313 ((x
>> 2) | (x
<< 30)) ^
((x
>> 13) | (x
<< 19)) ^
((x
>> 22) | (x
<< 10))
316 fn sum1(x
: u32) -> u32 {
317 ((x
>> 6) | (x
<< 26)) ^
((x
>> 11) | (x
<< 21)) ^
((x
>> 25) | (x
<< 7))
320 fn sigma0(x
: u32) -> u32 {
321 ((x
>> 7) | (x
<< 25)) ^
((x
>> 18) | (x
<< 14)) ^
(x
>> 3)
324 fn sigma1(x
: u32) -> u32 {
325 ((x
>> 17) | (x
<< 15)) ^
((x
>> 19) | (x
<< 13)) ^
(x
>> 10)
339 // Sha-512 and Sha-256 use basically the same calculations which are implemented
340 // by these macros. Inlining the calculations seems to result in better generated code.
341 macro_rules
! schedule_round
{ ($t
:expr
) => (
342 w
[$t
] = sigma1(w
[$t
- 2]).wrapping_add(w
[$t
- 7])
343 .wrapping_add(sigma0(w
[$t
- 15])).wrapping_add(w
[$t
- 16]);
347 macro_rules
! sha2_round
{
348 ($A
:ident
, $B
:ident
, $C
:ident
, $D
:ident
,
349 $E
:ident
, $F
:ident
, $G
:ident
, $H
:ident
, $K
:ident
, $t
:expr
) => (
351 $H
= $H
.wrapping_add(sum1($E
)).wrapping_add(ch($E
, $F
, $G
))
352 .wrapping_add($K
[$t
]).wrapping_add(w
[$t
]);
353 $D
= $D
.wrapping_add($H
);
354 $H
= $H
.wrapping_add(sum0($A
)).wrapping_add(maj($A
, $B
, $C
));
359 read_u32v_be(&mut w
[0..16], data
);
361 // Putting the message schedule inside the same loop as the round calculations allows for
362 // the compiler to generate better code.
363 for t
in (0..48).step_by(8) {
364 schedule_round
!(t
+ 16);
365 schedule_round
!(t
+ 17);
366 schedule_round
!(t
+ 18);
367 schedule_round
!(t
+ 19);
368 schedule_round
!(t
+ 20);
369 schedule_round
!(t
+ 21);
370 schedule_round
!(t
+ 22);
371 schedule_round
!(t
+ 23);
373 sha2_round
!(a
, b
, c
, d
, e
, f
, g
, h
, K32
, t
);
374 sha2_round
!(h
, a
, b
, c
, d
, e
, f
, g
, K32
, t
+ 1);
375 sha2_round
!(g
, h
, a
, b
, c
, d
, e
, f
, K32
, t
+ 2);
376 sha2_round
!(f
, g
, h
, a
, b
, c
, d
, e
, K32
, t
+ 3);
377 sha2_round
!(e
, f
, g
, h
, a
, b
, c
, d
, K32
, t
+ 4);
378 sha2_round
!(d
, e
, f
, g
, h
, a
, b
, c
, K32
, t
+ 5);
379 sha2_round
!(c
, d
, e
, f
, g
, h
, a
, b
, K32
, t
+ 6);
380 sha2_round
!(b
, c
, d
, e
, f
, g
, h
, a
, K32
, t
+ 7);
383 for t
in (48..64).step_by(8) {
384 sha2_round
!(a
, b
, c
, d
, e
, f
, g
, h
, K32
, t
);
385 sha2_round
!(h
, a
, b
, c
, d
, e
, f
, g
, K32
, t
+ 1);
386 sha2_round
!(g
, h
, a
, b
, c
, d
, e
, f
, K32
, t
+ 2);
387 sha2_round
!(f
, g
, h
, a
, b
, c
, d
, e
, K32
, t
+ 3);
388 sha2_round
!(e
, f
, g
, h
, a
, b
, c
, d
, K32
, t
+ 4);
389 sha2_round
!(d
, e
, f
, g
, h
, a
, b
, c
, K32
, t
+ 5);
390 sha2_round
!(c
, d
, e
, f
, g
, h
, a
, b
, K32
, t
+ 6);
391 sha2_round
!(b
, c
, d
, e
, f
, g
, h
, a
, K32
, t
+ 7);
394 self.h0
= self.h0
.wrapping_add(a
);
395 self.h1
= self.h1
.wrapping_add(b
);
396 self.h2
= self.h2
.wrapping_add(c
);
397 self.h3
= self.h3
.wrapping_add(d
);
398 self.h4
= self.h4
.wrapping_add(e
);
399 self.h5
= self.h5
.wrapping_add(f
);
400 self.h6
= self.h6
.wrapping_add(g
);
401 self.h7
= self.h7
.wrapping_add(h
);
405 static K32
: [u32; 64] = [
406 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
407 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
408 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
409 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
410 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
411 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
412 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
413 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
414 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
415 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
416 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
417 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
418 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
419 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
420 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
421 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
424 // A structure that keeps track of the state of the Sha-256 operation and contains the logic
425 // necessary to perform the final calculations.
428 buffer
: FixedBuffer64
,
429 state
: Engine256State
,
434 fn new(h
: &[u32; 8]) -> Engine256
{
437 buffer
: FixedBuffer64
::new(),
438 state
: Engine256State
::new(h
),
443 fn reset(&mut self, h
: &[u32; 8]) {
444 self.length_bits
= 0;
447 self.finished
= false;
450 fn input(&mut self, input
: &[u8]) {
451 assert
!(!self.finished
);
452 // Assumes that input.len() can be converted to u64 without overflow
453 self.length_bits
= add_bytes_to_bits(self.length_bits
, input
.len() as u64);
454 let self_state
= &mut self.state
;
455 self.buffer
.input(input
, |input
: &[u8]| { self_state.process_block(input) }
);
458 fn finish(&mut self) {
460 let self_state
= &mut self.state
;
461 self.buffer
.standard_padding(8, |input
: &[u8]| { self_state.process_block(input) }
);
462 write_u32_be(self.buffer
.next(4), (self.length_bits
>> 32) as u32 );
463 write_u32_be(self.buffer
.next(4), self.length_bits
as u32);
464 self_state
.process_block(self.buffer
.full_buffer());
466 self.finished
= true;
471 /// The SHA-256 hash algorithm
477 /// Construct a new instance of a SHA-256 digest.
478 /// Do not – under any circumstances – use this where timing attacks might be possible!
479 pub fn new() -> Sha256
{
481 engine
: Engine256
::new(&H256
)
486 impl Digest
for Sha256
{
487 fn input(&mut self, d
: &[u8]) {
488 self.engine
.input(d
);
491 fn result(&mut self, out
: &mut [u8]) {
492 self.engine
.finish();
494 write_u32_be(&mut out
[0..4], self.engine
.state
.h0
);
495 write_u32_be(&mut out
[4..8], self.engine
.state
.h1
);
496 write_u32_be(&mut out
[8..12], self.engine
.state
.h2
);
497 write_u32_be(&mut out
[12..16], self.engine
.state
.h3
);
498 write_u32_be(&mut out
[16..20], self.engine
.state
.h4
);
499 write_u32_be(&mut out
[20..24], self.engine
.state
.h5
);
500 write_u32_be(&mut out
[24..28], self.engine
.state
.h6
);
501 write_u32_be(&mut out
[28..32], self.engine
.state
.h7
);
504 fn reset(&mut self) {
505 self.engine
.reset(&H256
);
508 fn output_bits(&self) -> usize { 256 }
511 static H256
: [u32; 8] = [
524 #![allow(deprecated)]
528 use self::rand
::isaac
::IsaacRng
;
529 use serialize
::hex
::FromHex
;
531 use super::{Digest, Sha256}
;
533 // A normal addition - no overflow occurs
535 fn test_add_bytes_to_bits_ok() {
536 assert
!(super::add_bytes_to_bits(100, 10) == 180);
539 // A simple failure case - adding 1 to the max value
542 fn test_add_bytes_to_bits_overflow() {
543 super::add_bytes_to_bits(u64::MAX
, 1);
551 fn test_hash
<D
: Digest
>(sh
: &mut D
, tests
: &[Test
]) {
552 // Test that it works when accepting the message all at once
555 sh
.input_str(&t
.input
);
556 let out_str
= sh
.result_str();
557 assert
!(out_str
== t
.output_str
);
560 // Test that it works when accepting the message in pieces
563 let len
= t
.input
.len();
566 let take
= (left
+ 1) / 2;
567 sh
.input_str(&t
.input
[len
- left
..take
+ len
- left
]);
570 let out_str
= sh
.result_str();
571 assert
!(out_str
== t
.output_str
);
577 // Examples from wikipedia
578 let wikipedia_tests
= vec
!(
580 input
: "".to_string(),
581 output_str
: "e3b0c44298fc1c149afb\
582 f4c8996fb92427ae41e4649b934ca495991b7852b855".to_string()
585 input
: "The quick brown fox jumps over the lazy \
587 output_str
: "d7a8fbb307d7809469ca\
588 9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592".to_string()
591 input
: "The quick brown fox jumps over the lazy \
593 output_str
: "ef537f25c895bfa78252\
594 6529a9b63d97aa631564d5d789c2b765448c8635fb6c".to_string()
597 let tests
= wikipedia_tests
;
599 let mut sh
: Box
<_
> = box Sha256
::new();
601 test_hash(&mut *sh
, &tests
);
604 /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is
606 fn test_digest_1million_random
<D
: Digest
>(digest
: &mut D
, blocksize
: usize, expected
: &str) {
607 let total_size
= 1000000;
608 let buffer
= vec
![b'a'
; blocksize
* 2];
609 let mut rng
= IsaacRng
::new_unseeded();
614 while count
< total_size
{
615 let next
: usize = rng
.gen_range(0, 2 * blocksize
+ 1);
616 let remaining
= total_size
- count
;
617 let size
= if next
> remaining { remaining }
else { next }
;
618 digest
.input(&buffer
[..size
]);
622 let result_str
= digest
.result_str();
623 let result_bytes
= digest
.result_bytes();
625 assert_eq
!(expected
, result_str
);
627 let expected_vec
: Vec
<u8> = expected
.from_hex()
631 assert_eq
!(expected_vec
, result_bytes
);
635 fn test_1million_random_sha256() {
636 let mut sh
= Sha256
::new();
637 test_digest_1million_random(
640 "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
647 use self::test
::Bencher
;
648 use super::{Sha256, Digest}
;
651 pub fn sha256_10(b
: &mut Bencher
) {
652 let mut sh
= Sha256
::new();
657 b
.bytes
= bytes
.len() as u64;
661 pub fn sha256_1k(b
: &mut Bencher
) {
662 let mut sh
= Sha256
::new();
663 let bytes
= [1; 1024];
667 b
.bytes
= bytes
.len() as u64;
671 pub fn sha256_64k(b
: &mut Bencher
) {
672 let mut sh
= Sha256
::new();
673 let bytes
= [1; 65536];
677 b
.bytes
= bytes
.len() as u64;