blob: db9ccc1285b15e5747ac573e938070c79900ef60 [file] [log] [blame]
Yingdi Yude222c72014-08-15 16:06:52 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2014 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#ifndef NDN_UTIL_DIGEST_HPP
23#define NDN_UTIL_DIGEST_HPP
24
25#include "../encoding/buffer.hpp"
26#include "../encoding/block.hpp"
27#include "../security/cryptopp.hpp"
28#include "concepts.hpp"
29
30namespace ndn {
31namespace util {
32
33/**
34 * @brief provides a digest calculation
35 *
36 * Take SHA256 as an example:
37 *
38 * Digest<CryptoPP::SHA256> digest;
39 * digest.update(buf1, size1);
40 * digest.update(buf2, size2);
41 * ...
42 * ConstBufferPtr result = digest.computeDigest();
43 *
44 * @sa http://redmine.named-data.net/issues/1934
45 */
46template<typename Hash>
47class Digest
48{
49public:
50 BOOST_CONCEPT_ASSERT((Hashable<Hash>));
51
52 typedef Hash HashFunction;
53
54 class Error : public std::runtime_error
55 {
56 public:
57 explicit
58 Error(const std::string& what)
59 : std::runtime_error(what)
60 {
61 }
62 };
63
64 Digest();
65
66 /**
67 * @brief Discard the current state and start a new digest.
68 */
69 void
70 reset();
71
72 /**
73 * @brief Check if digest is empty.
74 *
75 * An empty digest means nothing has been taken into calculation.
76 */
77 bool
78 empty() const
79 {
80 return !m_isInProcess;
81 }
82
83 /**
84 * @brief Obtain the digest
85 *
86 * Note this digest is finalized once this method is invoked.
87 */
88 ConstBufferPtr
89 computeDigest();
90
91 /**
92 * @brief Check if supplied digest equal to this digest
93 *
94 * Note that this method will invoke computeDigest().
95 * Once this method is invoked, both this digest and the supplied digest are finalized.
96 */
97 bool
98 operator==(Digest<Hash>& digest);
99
100 /**
101 * @brief Check if supplied digest is not equal to this digest
102 *
103 * Note that this method will invoke computeDigest().
104 * Once this method is invoked, both this digest and the supplied digest are finalized.
105 */
106 bool
107 operator!=(Digest<Hash>& digest)
108 {
109 return !(*this == digest);
110 }
111
112 /**
113 * @brief Add existing digest to digest calculation
114 * @param src digest to combine with
115 *
116 * The result of this combination is hash (hash (...))
117 * Note that this method will invoke computeDigest().
118 * Once this method is invoked, the supplied digest is fixed.
119 */
120 Digest<Hash>&
121 operator<<(Digest<Hash>& src);
122
123 /**
124 * @brief Add string to digest calculation
125 * @param str string to put into digest
126 */
127 Digest<Hash>&
128 operator<<(const std::string& str);
129
130 /**
131 * @brief Add block to digest calculation
132 * @param block to put into digest
133 */
134 Digest<Hash>&
135 operator<<(const Block& block);
136
137 /**
138 * @brief Add uint64_t value to digest calculation
139 * @param value uint64_t value to put into digest
140 */
141 Digest<Hash>&
142 operator<<(uint64_t value);
143
144 /**
145 * @brief Add a buffer to digest calculation
146 *
147 * Update the state of the digest if it is not finalized
148 * and mark the digest as InProcess.
149 *
150 * @param buffer the input buffer
151 * @param size the size of the input buffer.
152 * @throws Error if the digest has been finalized.
153 */
154 void
155 update(const uint8_t* buffer, size_t size);
156
157 /**
158 * @brief Compute one-time digest
159 * @param buffer the input buffer
160 * @param size the size of the input buffer.
161 * @return digest computed according to the HashAlgorithm
162 */
163 static ConstBufferPtr
164 computeDigest(const uint8_t* buffer, size_t size);
165
Yingdi Yu9ad2d722014-08-30 16:13:57 -0700166 /**
167 * @brief Convert digest to std::string
168 *
169 * Note that this method will invoke computeDigest().
170 * Once this method is invoked, the digest is finalized.
171 */
172 std::string
173 toString();
Yingdi Yude222c72014-08-15 16:06:52 -0700174
175private:
176 /**
177 * @brief Finalize digest.
178 *
179 * All subsequent calls to "operator<<" will throw an exception
180 */
181 void
182 finalize();
183
184private:
185 Hash m_hash;
186 BufferPtr m_buffer;
187 bool m_isInProcess;
188 bool m_isFinalized;
189};
190
Yingdi Yu9ad2d722014-08-30 16:13:57 -0700191template<typename Hash>
192std::ostream&
193operator<<(std::ostream& os, Digest<Hash>& digest);
194
Yingdi Yude222c72014-08-15 16:06:52 -0700195/**
196 * @brief A digest using SHA256 as the hash function.
197 */
198typedef Digest<CryptoPP::SHA256> Sha256;
199
200} // namespace util
201} // namespace ndn
202
203#endif // NDN_UTIL_DIGEST_HPP