A fine-tuned implementation of the SHA256 hashing algorithm.

Dependents:   EntropySource Wallet_v1

SHA256.h

Committer:
Remco
Date:
2011-06-20
Revision:
3:f19b10394f9c
Parent:
2:1991439ea6b8
Child:
4:81678751d669

File content as of revision 3:f19b10394f9c:

// Author: Remco Bloemen
// Based on:
//   http://en.wikipedia.org/wiki/SHA-2
//   http://www.iwar.org.uk/comsec/resources/cipher/sha256-384-512.pdf
//   OpenSSL optimizations

#pragma once
#include <string.h>
#include <string>

/// Class to quickly compute SHA-256 hashes
///
/// This class has been heavily optimized for speed
/// at a slight expense of code size.
class SHA256 {
public:
    //// Create a new instance, ready for appending
    SHA256() { reset(); }
    
    /// Reset this instance so you can calculate a new hash
    void reset();
    
    /// Append data to the hash
    ///
    /// Note: due to word-allignment optimizations
    /// the function may read up to three bytes beyond
    /// the end of data.
    ///
    /// @param data The bytes to be added.
    /// @param size The number of bytes to read from data, but see the note.
    void append(const char* data, int size);
    
    /// Append a single byte.
    /// Avoid this function if performance is important.
    void append(char c) { append(&c, 1); }
    
    /// Append a zero terminated string
    /// The terminating zero itself is not appended.
    void append(const char* str) { append(str, strlen(str)); }
    
    /// Append a std::string
    void append(const std::string& str) { append(str.data(), str.length()); }
    
    /// Append the required padding and compute the final digest
    /// Always call this function first before requesting the digest
    ///
    /// After finalization you must call reset() before you can append again.
    /// However, you can do this:
    ///   SHA256 hash1, hash1and2;
    ///   hash1.append("First part");
    ///   hash1and2 = hash1;
    ///   hash1.finalize();
    ///   hash1and2.append("Second part");
    ///   hash1and2.finalize();
    void finalize();
    
    /// Returns a pointer to the 32 bytes of the digest
    const char* digest() { return reinterpret_cast<char*>(hash); }
    
    /// Return the digest as a binary std::string
    ///
    /// Avoid this function if performance is important,
    /// the std::string constructor will make a copy of the
    /// digest internally, doing a malloc and memcpy.
    std::string binString() { return std::string(digest(), 32); }
    
    /// Return the digest as a hexadecimal std::string
    ///
    /// In addition to the note for binaryString, this function
    /// also does conversion.
    std::string hexString();

private:
    void process_chunk();
    int length;
    unsigned int hash[8];
    unsigned int w[16];
};