26 #ifndef CRYPTO3_DIGEST_HPP
27 #define CRYPTO3_DIGEST_HPP
31 #include <boost/static_assert.hpp>
32 #include <boost/assert.hpp>
34 #include <boost/container/small_vector.hpp>
36 #include <nil/crypto3/detail/pack.hpp>
37 #include <nil/crypto3/detail/octet.hpp>
71 template<std::
size_t DigestBits>
72 struct digest :
public boost::container::small_vector<octet_type, DigestBits / octet_bits> {
77 boost::container::small_vector<
octet_type, DigestBits / octet_bits>(sz, ot) {};
84 template<std::
size_t DigestBits,
typename OutputIterator>
85 OutputIterator
to_ascii(
const digest<DigestBits> &d, OutputIterator it) {
86 for (std::size_t j = 0; j < d.size(); ++j) {
88 *it++ =
"0123456789abcdef"[(b >> 4) & 0xF];
89 *it++ =
"0123456789abcdef"[(b >> 0) & 0xF];
94 template<std::
size_t DigestBits>
95 digest<DigestBits / 4 + 1>
c_str(
const digest<DigestBits> &d) {
96 digest<DigestBits / 4 + 1> s;
97 to_ascii<DigestBits>(d, std::back_inserter(s));
111 template<
unsigned NewBits,
unsigned OldBits>
112 digest<NewBits>
reserve(
const digest<OldBits> &od) {
114 unsigned bytes =
sizeof(
octet_type) * (NewBits < OldBits ? NewBits : OldBits) / octet_bits;
115 std::memcpy(nd.data(), od.data(), bytes);
127 template<std::
size_t DigestBits>
128 digest<DigestBits>
resize(
const digest<DigestBits> &od, std::size_t new_size) {
130 std::size_t old_size = od.size();
132 if (new_size == old_size)
135 digest<DigestBits> nd(new_size,
octet_type());
136 std::size_t bytes =
sizeof(
octet_type) * (old_size < new_size ? old_size : new_size);
137 std::memcpy(nd.data(), od.data(), bytes);
151 template<
unsigned NewBits,
unsigned OldBits>
152 digest<NewBits>
truncate(
const digest<OldBits> &od) {
153 BOOST_STATIC_ASSERT(NewBits <= OldBits);
154 return resize<NewBits>(od);
157 template<
unsigned DB1,
unsigned DB2>
158 bool operator==(
const digest<DB1> &a,
const digest<DB2> &b) {
159 unsigned const DB = DB1 < DB2 ? DB2 : DB1;
160 return resize<DB>(a).base_array() == resize<DB>(b).base_array();
163 template<
unsigned DB1,
unsigned DB2>
164 bool operator!=(
const digest<DB1> &a,
const digest<DB2> &b) {
168 template<
unsigned DB1,
unsigned DB2>
169 bool operator<(
const digest<DB1> &a,
const digest<DB2> &b) {
170 unsigned const DB = DB1 < DB2 ? DB2 : DB1;
171 return resize<DB>(a).base_array() < resize<DB>(b).base_array();
174 template<
unsigned DB1,
unsigned DB2>
175 bool operator>(
const digest<DB1> &a,
const digest<DB2> &b) {
179 template<
unsigned DB1,
unsigned DB2>
180 bool operator<=(
const digest<DB1> &a,
const digest<DB2> &b) {
184 template<
unsigned DB1,
unsigned DB2>
185 bool operator>=(
const digest<DB1> &a,
const digest<DB2> &b) {
189 template<
unsigned DB>
190 bool operator!=(digest<DB>
const &a,
char const *b) {
191 BOOST_ASSERT(std::strlen(b) == DB / 4);
192 return static_cast<bool>(std::strcmp(a.cstring().data(), b));
195 template<
unsigned DB>
196 bool operator==(digest<DB>
const &a,
char const *b) {
200 template<
unsigned DB>
201 bool operator!=(
char const *b, digest<DB>
const &a) {
205 template<
unsigned DB>
206 bool operator==(
char const *b, digest<DB>
const &a) {
210 template<
unsigned DB>
211 std::ostream &
operator<<(std::ostream &sink, digest<DB>
const &d) {
212 d.to_ascii(std::ostream_iterator<char>(sink));
216 template<
unsigned DB>
217 std::istream &
operator>>(std::istream &source, digest<DB> &d) {
218 std::array<char, DB / 4> a = {{}};
219 for (
unsigned i = 0; i < a.size(); ++i) {
221 if (!source.get(c)) {
222 source.setstate(std::ios::failbit);
225 if (!std::isxdigit(c, source.getloc())) {
227 source.setstate(std::ios::failbit);
231 if (std::isdigit(c, source.getloc())) {
234 a[i] = std::toupper(c, source.getloc()) -
'A' + 0xA;
237 detail::pack<stream_endian::big_bit, stream_endian::big_bit, 4, 8>(a.begin(), a.end(), d.begin());
244 template<std::
size_t DigestBits>
247 return std::string(cstr.begin(), cstr.begin() + cstr.size() - 1);
std::string to_string(const nil::crypto3::digest< DigestBits > &d)
Definition: block/include/nil/crypto3/detail/digest.hpp:248
OutputIterator to_ascii(const digest< DigestBits > &d, OutputIterator it)
Definition: block/include/nil/crypto3/detail/digest.hpp:86
digest< DigestBits/4+1 > c_str(const digest< DigestBits > &d)
Definition: block/include/nil/crypto3/detail/digest.hpp:98
boost::uint_t< octet_bits >::least octet_type
Definition: algebra/include/nil/crypto3/detail/octet.hpp:33
std::istream & operator>>(std::istream &source, digest< DB > &d)
Definition: block/include/nil/crypto3/detail/digest.hpp:220
bool operator>(const digest< DB1 > &a, const digest< DB2 > &b)
Definition: block/include/nil/crypto3/detail/digest.hpp:178
bool operator<(const digest< DB1 > &a, const digest< DB2 > &b)
Definition: block/include/nil/crypto3/detail/digest.hpp:172
bool operator!=(const secure_allocator< T > &, const secure_allocator< U > &)
Definition: secure_allocator.hpp:98
std::ostream & operator<<(std::ostream &sink, digest< DB > const &d)
Definition: block/include/nil/crypto3/detail/digest.hpp:214
bool operator==(const secure_allocator< T > &, const secure_allocator< U > &)
Definition: secure_allocator.hpp:93
digest< DigestBits > resize(const digest< DigestBits > &od, std::size_t new_size)
Definition: block/include/nil/crypto3/detail/digest.hpp:131
boost::container::small_vector< octet_type, DigestBits/octet_bits > digest
Definition: codec/include/nil/crypto3/detail/digest.hpp:71
digest< NewBits > truncate(const digest< OldBits > &od)
Definition: block/include/nil/crypto3/detail/digest.hpp:155
bool operator<=(const digest< DB1 > &a, const digest< DB2 > &b)
Definition: block/include/nil/crypto3/detail/digest.hpp:183
digest< NewBits > reserve(const digest< OldBits > &od)
Definition: block/include/nil/crypto3/detail/digest.hpp:115
bool operator>=(const digest< DB1 > &a, const digest< DB2 > &b)
Definition: block/include/nil/crypto3/detail/digest.hpp:188
Definition: block/include/nil/crypto3/detail/digest.hpp:72
digest()
Definition: hash/include/nil/crypto3/detail/digest.hpp:74
digest(std::size_t sz, octet_type ot)
Definition: hash/include/nil/crypto3/detail/digest.hpp:76