hash.h 4.66 KB
Newer Older
Pieter Wuille's avatar
Pieter Wuille committed
1
// Copyright (c) 2009-2010 Satoshi Nakamoto
super3's avatar
super3 committed
2
// Copyright (c) 2009-2013 The Bitcoin developers
Pieter Wuille's avatar
Pieter Wuille committed
3
4
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5

Pieter Wuille's avatar
Pieter Wuille committed
6
7
8
#ifndef BITCOIN_HASH_H
#define BITCOIN_HASH_H

9
#include "crypto/sha2.h"
10
#include "crypto/ripemd160.h"
Pieter Wuille's avatar
Pieter Wuille committed
11
#include "serialize.h"
12
13
#include "uint256.h"
#include "version.h"
Pieter Wuille's avatar
Pieter Wuille committed
14

15
#include <vector>
Pieter Wuille's avatar
Pieter Wuille committed
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */
class CHash256 {
private:
    CSHA256 sha;
public:
    void Finalize(unsigned char *hash) {
        unsigned char buf[32];
        sha.Finalize(buf);
        sha.Reset().Write(buf, 32).Finalize(hash);
    }

    CHash256& Write(const unsigned char *data, size_t len) {
        sha.Write(data, len);
        return *this;
    }

    CHash256& Reset() {
        sha.Reset();
        return *this;
    }
};

/** A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160). */
class CHash160 {
private:
    CSHA256 sha;
public:
    void Finalize(unsigned char *hash) {
        unsigned char buf[32];
        sha.Finalize(buf);
47
        CRIPEMD160().Write(buf, 32).Finalize(hash);
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    }

    CHash160& Write(const unsigned char *data, size_t len) {
        sha.Write(data, len);
        return *this;
    }

    CHash160& Reset() {
        sha.Reset();
        return *this;
    }
};

/** Compute the 256-bit hash of an object. */
Pieter Wuille's avatar
Pieter Wuille committed
62
63
64
template<typename T1>
inline uint256 Hash(const T1 pbegin, const T1 pend)
{
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    static const unsigned char pblank[1] = {};
    uint256 result;
    CHash256().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
              .Finalize((unsigned char*)&result);
    return result;
}

/** Compute the 256-bit hash of the concatenation of two objects. */
template<typename T1, typename T2>
inline uint256 Hash(const T1 p1begin, const T1 p1end,
                    const T2 p2begin, const T2 p2end) {
    static const unsigned char pblank[1] = {};
    uint256 result;
    CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]))
              .Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]))
              .Finalize((unsigned char*)&result);
    return result;
}

/** Compute the 256-bit hash of the concatenation of three objects. */
template<typename T1, typename T2, typename T3>
inline uint256 Hash(const T1 p1begin, const T1 p1end,
                    const T2 p2begin, const T2 p2end,
                    const T3 p3begin, const T3 p3end) {
    static const unsigned char pblank[1] = {};
    uint256 result;
    CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]))
              .Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]))
              .Write(p3begin == p3end ? pblank : (const unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0]))
              .Finalize((unsigned char*)&result);
    return result;
}

/** Compute the 160-bit hash an object. */
template<typename T1>
inline uint160 Hash160(const T1 pbegin, const T1 pend)
{
    static unsigned char pblank[1] = {};
    uint160 result;
    CHash160().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
              .Finalize((unsigned char*)&result);
    return result;
}

/** Compute the 160-bit hash of a vector. */
inline uint160 Hash160(const std::vector<unsigned char>& vch)
{
    return Hash160(vch.begin(), vch.end());
Pieter Wuille's avatar
Pieter Wuille committed
113
114
}

115
/** A writer stream (for serialization) that computes a 256-bit hash. */
Pieter Wuille's avatar
Pieter Wuille committed
116
117
118
class CHashWriter
{
private:
119
    CHash256 ctx;
Pieter Wuille's avatar
Pieter Wuille committed
120
121
122
123
124

public:
    int nType;
    int nVersion;

125
    CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {}
Pieter Wuille's avatar
Pieter Wuille committed
126
127

    CHashWriter& write(const char *pch, size_t size) {
128
        ctx.Write((const unsigned char*)pch, size);
Pieter Wuille's avatar
Pieter Wuille committed
129
130
131
132
133
        return (*this);
    }

    // invalidates the object
    uint256 GetHash() {
134
135
136
        uint256 result;
        ctx.Finalize((unsigned char*)&result);
        return result;
Pieter Wuille's avatar
Pieter Wuille committed
137
138
139
140
141
142
143
144
145
146
    }

    template<typename T>
    CHashWriter& operator<<(const T& obj) {
        // Serialize to this stream
        ::Serialize(*this, obj, nType, nVersion);
        return (*this);
    }
};

147
/** Compute the 256-bit hash of an object's serialization. */
Pieter Wuille's avatar
Pieter Wuille committed
148
149
150
151
152
153
154
155
template<typename T>
uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
{
    CHashWriter ss(nType, nVersion);
    ss << obj;
    return ss.GetHash();
}

156
157
unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash);

Pieter Wuille's avatar
Pieter Wuille committed
158
#endif