A fine-tuned implementation of the SHA256 hashing algorithm.

Dependents:   EntropySource Wallet_v1

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SHA256.h Source File

SHA256.h

00001 // Author: Remco Bloemen
00002 // Based on:
00003 //   http://en.wikipedia.org/wiki/SHA-2
00004 //   http://www.iwar.org.uk/comsec/resources/cipher/sha256-384-512.pdf
00005 //   OpenSSL optimizations
00006 
00007 #pragma once
00008 #include <string.h>
00009 #include <string>
00010 
00011 /// Class to quickly compute SHA-256 hashes
00012 ///
00013 /// This class has been heavily optimized for speed
00014 /// at a slight expense of code size.
00015 ///
00016 /// Example usage:
00017 /// @code
00018 ///   SHA256 hash;
00019 ///   hash.append("The quick brown fox jumps over the lazy dog.");
00020 ///   hash.finalize();
00021 ///   std::cout << "Digest: " << hash.hexString() << std::endl;
00022 /// @endcode
00023 class SHA256 {
00024 public:
00025 
00026     //// Create a new instance, ready for appending
00027     SHA256() { reset(); }
00028     
00029     /// Reset this instance so you can calculate a new hash
00030     void reset();
00031     
00032     /// Append data to the hash
00033     ///
00034     /// Note: due to word-allignment optimizations
00035     /// the function may read up to three bytes beyond
00036     /// the end of data.
00037     ///
00038     /// @param data the bytes to be added.
00039     /// @param size the number of bytes to read from data, but see the note.
00040     void append(const char* data, int size);
00041     
00042     /// Append a single byte
00043     ///
00044     /// Avoid this function if performance is important.
00045     ///
00046     /// @param c the character to be appended.
00047     void append(char c) { append(&c, 1); }
00048     
00049     /// Append a zero terminated string
00050     ///
00051     /// The terminating zero itself is not appended.
00052     ///
00053     /// @param str the zero terminated string to be appended.
00054     void append(const char* str) { append(str, strlen(str)); }
00055     
00056     /// Append a std::string
00057     ///
00058     /// @param str The std::string to be appended.
00059     void append(const std::string& str) { append(str.data(), str.length()); }
00060     
00061     /// Append the required padding and compute the final digest
00062     ///
00063     /// Always call this function first before requesting the digest.
00064     ///
00065     /// After finalization you must call reset() before you can append again.
00066     ///
00067     /// However, you can do this:
00068     /// @code
00069     ///   SHA256 A, AB;
00070     ///   A.append("First part");
00071     ///   AB = A;
00072     ///   A.finalize();
00073     ///   do_something(A.digest());
00074     ///   AB.append("Second part");
00075     ///   AB.finalize();
00076     ///   do_something(AB.digest());
00077     /// @endcode
00078     void finalize();
00079     
00080     /// Returns a pointer to the 32 bytes of the digest
00081     ///
00082     /// @returns a pointer to a non-zero-terminated block of
00083     /// 32 bytes containting the digest.
00084     const char* digest() { return reinterpret_cast<char*>(hash); }
00085     
00086     /// Return the digest as a binary std::string
00087     ///
00088     /// Avoid this function if performance is important,
00089     /// the std::string constructor will make a copy of the
00090     /// digest internally, doing a malloc and memcpy.
00091     ///
00092     /// @returns a std::string containing the digest as raw binary bits.
00093     std::string binString() { return std::string(digest(), 32); }
00094     
00095     /// Return the digest as a hexadecimal std::string
00096     ///
00097     /// In addition to the note for binaryString, this function
00098     /// also does conversion.
00099     ///
00100     /// @returns a std::string containing the digest in hexadecimal ascii.
00101     std::string hexString();
00102     
00103 protected:
00104     int length;
00105     unsigned int hash[8];
00106     unsigned int w[16];
00107     void process_chunk();
00108 };
00109