A fine-tuned implementation of the SHA256 hashing algorithm.
Dependents: EntropySource Wallet_v1
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
Generated on Fri Jul 15 2022 02:57:12 by 1.7.2