A fine-tuned implementation of the SHA256 hashing algorithm.

Dependents:   EntropySource Wallet_v1

Committer:
Remco
Date:
Mon Jun 20 11:06:11 2011 +0000
Revision:
4:81678751d669
Parent:
3:f19b10394f9c
Child:
5:246096ab9e56

        

Who changed what in which revision?

UserRevisionLine numberNew 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 0:772b6de3a841 15 class SHA256 {
Remco 0:772b6de3a841 16 public:
Remco 3:f19b10394f9c 17 //// Create a new instance, ready for appending
Remco 0:772b6de3a841 18 SHA256() { reset(); }
Remco 3:f19b10394f9c 19
Remco 3:f19b10394f9c 20 /// Reset this instance so you can calculate a new hash
Remco 0:772b6de3a841 21 void reset();
Remco 3:f19b10394f9c 22
Remco 3:f19b10394f9c 23 /// Append data to the hash
Remco 3:f19b10394f9c 24 ///
Remco 3:f19b10394f9c 25 /// Note: due to word-allignment optimizations
Remco 3:f19b10394f9c 26 /// the function may read up to three bytes beyond
Remco 3:f19b10394f9c 27 /// the end of data.
Remco 3:f19b10394f9c 28 ///
Remco 3:f19b10394f9c 29 /// @param data The bytes to be added.
Remco 3:f19b10394f9c 30 /// @param size The number of bytes to read from data, but see the note.
Remco 0:772b6de3a841 31 void append(const char* data, int size);
Remco 3:f19b10394f9c 32
Remco 4:81678751d669 33 /// Append a single byte
Remco 4:81678751d669 34 ///
Remco 3:f19b10394f9c 35 /// Avoid this function if performance is important.
Remco 4:81678751d669 36 ///
Remco 4:81678751d669 37 /// @param c The character to be appended.
Remco 3:f19b10394f9c 38 void append(char c) { append(&c, 1); }
Remco 3:f19b10394f9c 39
Remco 3:f19b10394f9c 40 /// Append a zero terminated string
Remco 4:81678751d669 41 ///
Remco 3:f19b10394f9c 42 /// The terminating zero itself is not appended.
Remco 4:81678751d669 43 ///
Remco 4:81678751d669 44 /// @param str The zero terminated string to be appended.
Remco 0:772b6de3a841 45 void append(const char* str) { append(str, strlen(str)); }
Remco 3:f19b10394f9c 46
Remco 3:f19b10394f9c 47 /// Append a std::string
Remco 4:81678751d669 48 ///
Remco 4:81678751d669 49 /// @param str The std::string to be appended.
Remco 0:772b6de3a841 50 void append(const std::string& str) { append(str.data(), str.length()); }
Remco 3:f19b10394f9c 51
Remco 3:f19b10394f9c 52 /// Append the required padding and compute the final digest
Remco 4:81678751d669 53 ///
Remco 4:81678751d669 54 /// Always call this function first before requesting the digest.
Remco 3:f19b10394f9c 55 ///
Remco 3:f19b10394f9c 56 /// After finalization you must call reset() before you can append again.
Remco 4:81678751d669 57 ///
Remco 3:f19b10394f9c 58 /// However, you can do this:
Remco 4:81678751d669 59 /// @code
Remco 3:f19b10394f9c 60 /// SHA256 hash1, hash1and2;
Remco 3:f19b10394f9c 61 /// hash1.append("First part");
Remco 3:f19b10394f9c 62 /// hash1and2 = hash1;
Remco 3:f19b10394f9c 63 /// hash1.finalize();
Remco 3:f19b10394f9c 64 /// hash1and2.append("Second part");
Remco 3:f19b10394f9c 65 /// hash1and2.finalize();
Remco 4:81678751d669 66 /// @endcode
Remco 0:772b6de3a841 67 void finalize();
Remco 3:f19b10394f9c 68
Remco 3:f19b10394f9c 69 /// Returns a pointer to the 32 bytes of the digest
Remco 4:81678751d669 70 ///
Remco 4:81678751d669 71 /// @returns a pointer to a non-zero-terminated block of
Remco 4:81678751d669 72 /// 32 bytes containting the digest.
Remco 0:772b6de3a841 73 const char* digest() { return reinterpret_cast<char*>(hash); }
Remco 3:f19b10394f9c 74
Remco 3:f19b10394f9c 75 /// Return the digest as a binary std::string
Remco 3:f19b10394f9c 76 ///
Remco 3:f19b10394f9c 77 /// Avoid this function if performance is important,
Remco 3:f19b10394f9c 78 /// the std::string constructor will make a copy of the
Remco 3:f19b10394f9c 79 /// digest internally, doing a malloc and memcpy.
Remco 4:81678751d669 80 ///
Remco 4:81678751d669 81 /// @returns a std::string containing the digest as raw binary bits.
Remco 3:f19b10394f9c 82 std::string binString() { return std::string(digest(), 32); }
Remco 3:f19b10394f9c 83
Remco 3:f19b10394f9c 84 /// Return the digest as a hexadecimal std::string
Remco 3:f19b10394f9c 85 ///
Remco 3:f19b10394f9c 86 /// In addition to the note for binaryString, this function
Remco 3:f19b10394f9c 87 /// also does conversion.
Remco 4:81678751d669 88 ///
Remco 4:81678751d669 89 /// @returns a std::string containing the digest in hexadecimal ascii.
Remco 3:f19b10394f9c 90 std::string hexString();
Remco 3:f19b10394f9c 91
Remco 0:772b6de3a841 92 private:
Remco 0:772b6de3a841 93 void process_chunk();
Remco 0:772b6de3a841 94 int length;
Remco 0:772b6de3a841 95 unsigned int hash[8];
Remco 2:1991439ea6b8 96 unsigned int w[16];
Remco 0:772b6de3a841 97 };
Remco 0:772b6de3a841 98