A fine-tuned implementation of the SHA256 hashing algorithm.
Dependents: EntropySource Wallet_v1
SHA256.h@5:246096ab9e56, 2011-06-20 (annotated)
- Committer:
- Remco
- Date:
- Mon Jun 20 11:11:10 2011 +0000
- Revision:
- 5:246096ab9e56
- Parent:
- 4:81678751d669
- Child:
- 6:c0ed1bf37651
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Remco | 0:772b6de3a841 | 1 | // Author: Remco Bloemen |
Remco | 0:772b6de3a841 | 2 | // Based on: |
Remco | 0:772b6de3a841 | 3 | // http://en.wikipedia.org/wiki/SHA-2 |
Remco | 0:772b6de3a841 | 4 | // http://www.iwar.org.uk/comsec/resources/cipher/sha256-384-512.pdf |
Remco | 3:f19b10394f9c | 5 | // OpenSSL optimizations |
Remco | 0:772b6de3a841 | 6 | |
Remco | 3:f19b10394f9c | 7 | #pragma once |
Remco | 0:772b6de3a841 | 8 | #include <string.h> |
Remco | 0:772b6de3a841 | 9 | #include <string> |
Remco | 0:772b6de3a841 | 10 | |
Remco | 3:f19b10394f9c | 11 | /// Class to quickly compute SHA-256 hashes |
Remco | 3:f19b10394f9c | 12 | /// |
Remco | 3:f19b10394f9c | 13 | /// This class has been heavily optimized for speed |
Remco | 3:f19b10394f9c | 14 | /// at a slight expense of code size. |
Remco | 5:246096ab9e56 | 15 | /// |
Remco | 5:246096ab9e56 | 16 | /// Example usage: |
Remco | 5:246096ab9e56 | 17 | /// @code |
Remco | 5:246096ab9e56 | 18 | /// SHA256 hash; |
Remco | 5:246096ab9e56 | 19 | /// hash.append("The quick brown fox jumps over the lazy dog."); |
Remco | 5:246096ab9e56 | 20 | /// hash.finalize(); |
Remco | 5:246096ab9e56 | 21 | /// std::cout << "Digest: " << hash.hexString() << std::endl; |
Remco | 5:246096ab9e56 | 22 | /// @endcode |
Remco | 0:772b6de3a841 | 23 | class SHA256 { |
Remco | 0:772b6de3a841 | 24 | public: |
Remco | 5:246096ab9e56 | 25 | |
Remco | 3:f19b10394f9c | 26 | //// Create a new instance, ready for appending |
Remco | 0:772b6de3a841 | 27 | SHA256() { reset(); } |
Remco | 3:f19b10394f9c | 28 | |
Remco | 3:f19b10394f9c | 29 | /// Reset this instance so you can calculate a new hash |
Remco | 0:772b6de3a841 | 30 | void reset(); |
Remco | 3:f19b10394f9c | 31 | |
Remco | 3:f19b10394f9c | 32 | /// Append data to the hash |
Remco | 3:f19b10394f9c | 33 | /// |
Remco | 3:f19b10394f9c | 34 | /// Note: due to word-allignment optimizations |
Remco | 3:f19b10394f9c | 35 | /// the function may read up to three bytes beyond |
Remco | 3:f19b10394f9c | 36 | /// the end of data. |
Remco | 3:f19b10394f9c | 37 | /// |
Remco | 5:246096ab9e56 | 38 | /// @param data the bytes to be added. |
Remco | 5:246096ab9e56 | 39 | /// @param size the number of bytes to read from data, but see the note. |
Remco | 0:772b6de3a841 | 40 | void append(const char* data, int size); |
Remco | 3:f19b10394f9c | 41 | |
Remco | 4:81678751d669 | 42 | /// Append a single byte |
Remco | 4:81678751d669 | 43 | /// |
Remco | 3:f19b10394f9c | 44 | /// Avoid this function if performance is important. |
Remco | 4:81678751d669 | 45 | /// |
Remco | 5:246096ab9e56 | 46 | /// @param c the character to be appended. |
Remco | 3:f19b10394f9c | 47 | void append(char c) { append(&c, 1); } |
Remco | 3:f19b10394f9c | 48 | |
Remco | 3:f19b10394f9c | 49 | /// Append a zero terminated string |
Remco | 4:81678751d669 | 50 | /// |
Remco | 3:f19b10394f9c | 51 | /// The terminating zero itself is not appended. |
Remco | 4:81678751d669 | 52 | /// |
Remco | 5:246096ab9e56 | 53 | /// @param str the zero terminated string to be appended. |
Remco | 0:772b6de3a841 | 54 | void append(const char* str) { append(str, strlen(str)); } |
Remco | 3:f19b10394f9c | 55 | |
Remco | 3:f19b10394f9c | 56 | /// Append a std::string |
Remco | 4:81678751d669 | 57 | /// |
Remco | 4:81678751d669 | 58 | /// @param str The std::string to be appended. |
Remco | 0:772b6de3a841 | 59 | void append(const std::string& str) { append(str.data(), str.length()); } |
Remco | 3:f19b10394f9c | 60 | |
Remco | 3:f19b10394f9c | 61 | /// Append the required padding and compute the final digest |
Remco | 4:81678751d669 | 62 | /// |
Remco | 4:81678751d669 | 63 | /// Always call this function first before requesting the digest. |
Remco | 3:f19b10394f9c | 64 | /// |
Remco | 3:f19b10394f9c | 65 | /// After finalization you must call reset() before you can append again. |
Remco | 4:81678751d669 | 66 | /// |
Remco | 3:f19b10394f9c | 67 | /// However, you can do this: |
Remco | 4:81678751d669 | 68 | /// @code |
Remco | 5:246096ab9e56 | 69 | /// SHA256 A, AB; |
Remco | 5:246096ab9e56 | 70 | /// A.append("First part"); |
Remco | 5:246096ab9e56 | 71 | /// AB = A; |
Remco | 5:246096ab9e56 | 72 | /// A.finalize(); |
Remco | 5:246096ab9e56 | 73 | /// do_something(A.digest()); |
Remco | 5:246096ab9e56 | 74 | /// AB.append("Second part"); |
Remco | 5:246096ab9e56 | 75 | /// AB.finalize(); |
Remco | 5:246096ab9e56 | 76 | /// do_something(AB.digest()); |
Remco | 4:81678751d669 | 77 | /// @endcode |
Remco | 0:772b6de3a841 | 78 | void finalize(); |
Remco | 3:f19b10394f9c | 79 | |
Remco | 3:f19b10394f9c | 80 | /// Returns a pointer to the 32 bytes of the digest |
Remco | 4:81678751d669 | 81 | /// |
Remco | 4:81678751d669 | 82 | /// @returns a pointer to a non-zero-terminated block of |
Remco | 4:81678751d669 | 83 | /// 32 bytes containting the digest. |
Remco | 0:772b6de3a841 | 84 | const char* digest() { return reinterpret_cast<char*>(hash); } |
Remco | 3:f19b10394f9c | 85 | |
Remco | 3:f19b10394f9c | 86 | /// Return the digest as a binary std::string |
Remco | 3:f19b10394f9c | 87 | /// |
Remco | 3:f19b10394f9c | 88 | /// Avoid this function if performance is important, |
Remco | 3:f19b10394f9c | 89 | /// the std::string constructor will make a copy of the |
Remco | 3:f19b10394f9c | 90 | /// digest internally, doing a malloc and memcpy. |
Remco | 4:81678751d669 | 91 | /// |
Remco | 4:81678751d669 | 92 | /// @returns a std::string containing the digest as raw binary bits. |
Remco | 3:f19b10394f9c | 93 | std::string binString() { return std::string(digest(), 32); } |
Remco | 3:f19b10394f9c | 94 | |
Remco | 3:f19b10394f9c | 95 | /// Return the digest as a hexadecimal std::string |
Remco | 3:f19b10394f9c | 96 | /// |
Remco | 3:f19b10394f9c | 97 | /// In addition to the note for binaryString, this function |
Remco | 3:f19b10394f9c | 98 | /// also does conversion. |
Remco | 4:81678751d669 | 99 | /// |
Remco | 4:81678751d669 | 100 | /// @returns a std::string containing the digest in hexadecimal ascii. |
Remco | 3:f19b10394f9c | 101 | std::string hexString(); |
Remco | 3:f19b10394f9c | 102 | |
Remco | 0:772b6de3a841 | 103 | private: |
Remco | 0:772b6de3a841 | 104 | void process_chunk(); |
Remco | 0:772b6de3a841 | 105 | int length; |
Remco | 0:772b6de3a841 | 106 | unsigned int hash[8]; |
Remco | 2:1991439ea6b8 | 107 | unsigned int w[16]; |
Remco | 0:772b6de3a841 | 108 | }; |
Remco | 0:772b6de3a841 | 109 |