// boost/uuid/sha1.hpp header file  ----------------------------------------------//

// Copyright 2007 Andy Tompkins.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

// Revision History
//  29 May 2007 - Initial Revision
//  25 Feb 2008 - moved to namespace boost::uuids::detail

// This is a byte oriented implementation
// Note: this implementation does not handle message longer than
//       2^32 bytes.

#ifndef BOOST_UUID_SHA1_H
#define BOOST_UUID_SHA1_H

#include <boost/static_assert.hpp>
#include <cstddef>

#ifdef BOOST_NO_STDC_NAMESPACE
namespace std {
    using ::size_t;
} // namespace std
#endif

namespace boost {
namespace uuids {
namespace detail {

BOOST_STATIC_ASSERT(sizeof(unsigned char)*8 == 8);
BOOST_STATIC_ASSERT(sizeof(unsigned int)*8 == 32);

inline unsigned int left_rotate(unsigned int x, std::size_t n)
{
    return (x<<n) ^ (x>> (32-n));
}

class sha1
{
public:
    typedef unsigned int(&digest_type)[5];
public:
    sha1();

    void reset();

    void process_byte(unsigned char byte);
    void process_block(void const* bytes_begin, void const* bytes_end);
    void process_bytes(void const* buffer, std::size_t byte_count);

    void get_digest(digest_type digest);

private:
    void process_block();

private:
    unsigned int h_[5];

    unsigned char block_[64];

    std::size_t block_byte_index_;
    std::size_t byte_count_;
};

inline sha1::sha1()
{
    reset();
}

inline void sha1::reset()
{
    h_[0] = 0x67452301;
    h_[1] = 0xEFCDAB89;
    h_[2] = 0x98BADCFE;
    h_[3] = 0x10325476;
    h_[4] = 0xC3D2E1F0;

    block_byte_index_ = 0;
    byte_count_ = 0;
}

inline void sha1::process_byte(unsigned char byte)
{
    block_[block_byte_index_++] = byte;
    ++byte_count_;
    if (block_byte_index_ == 64) {
        block_byte_index_ = 0;
        process_block();
    }
}

inline void sha1::process_block(void const* bytes_begin, void const* bytes_end)
{
    unsigned char const* begin = static_cast<unsigned char const*>(bytes_begin);
    unsigned char const* end = static_cast<unsigned char const*>(bytes_end);
    for(; begin != end; ++begin) {
        process_byte(*begin);
    }
}

inline void sha1::process_bytes(void const* buffer, std::size_t byte_count)
{
    unsigned char const* b = static_cast<unsigned char const*>(buffer);
    process_block(b, b+byte_count);
}

inline void sha1::process_block()
{
    unsigned int w[80];
    for (std::size_t i=0; i<16; ++i) {
        w[i]  = (block_[i*4 + 0] << 24);
        w[i] |= (block_[i*4 + 1] << 16);
        w[i] |= (block_[i*4 + 2] << 8);
        w[i] |= (block_[i*4 + 3]);
    }
    for (std::size_t i=16; i<80; ++i) {
        w[i] = left_rotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1);
    }

    unsigned int a = h_[0];
    unsigned int b = h_[1];
    unsigned int c = h_[2];
    unsigned int d = h_[3];
    unsigned int e = h_[4];

    for (std::size_t i=0; i<80; ++i) {
        unsigned int f;
        unsigned int k;

        if (i<20) {
            f = (b & c) | (~b & d);
            k = 0x5A827999;
        } else if (i<40) {
            f = b ^ c ^ d;
            k = 0x6ED9EBA1;
        } else if (i<60) {
            f = (b & c) | (b & d) | (c & d);
            k = 0x8F1BBCDC;
        } else {
            f = b ^ c ^ d;
            k = 0xCA62C1D6;
        }

        unsigned temp = left_rotate(a, 5) + f + e + k + w[i];
        e = d;
        d = c;
        c = left_rotate(b, 30);
        b = a;
        a = temp;
    }

    h_[0] += a;
    h_[1] += b;
    h_[2] += c;
    h_[3] += d;
    h_[4] += e;
}

inline void sha1::get_digest(digest_type digest)
{
    std::size_t bit_count = byte_count_*8;

    // append the bit '1' to the message
    process_byte(0x80);

    // append k bits '0', where k is the minimum number >= 0
    // such that the resulting message length is congruent to 56 (mod 64)
    // check if there is enough space for padding and bit_count
    if (block_byte_index_ > 56) {
        // finish this block
        while (block_byte_index_ != 0) {
            process_byte(0);
        }

        // one more block
        while (block_byte_index_ < 56) {
            process_byte(0);
        }
    } else {
        while (block_byte_index_ < 56) {
            process_byte(0);
        }
    }

    // append length of message (before pre-processing) 
    // as a 64-bit big-endian integer
    process_byte(0);
    process_byte(0);
    process_byte(0);
    process_byte(0);
    process_byte( static_cast<unsigned char>((bit_count>>24) & 0xFF));
    process_byte( static_cast<unsigned char>((bit_count>>16) & 0xFF));
    process_byte( static_cast<unsigned char>((bit_count>>8 ) & 0xFF));
    process_byte( static_cast<unsigned char>((bit_count)     & 0xFF));

    // get final digest
    digest[0] = h_[0];
    digest[1] = h_[1];
    digest[2] = h_[2];
    digest[3] = h_[3];
    digest[4] = h_[4];
}

}}} // namespace boost::uuids::detail

#endif
