ViennaCL - The Vienna Computing Library  1.6.1
Free open-source GPU-accelerated linear algebra and solver library.
sha1.hpp
Go to the documentation of this file.
1 /*
2 *
3 * TinySHA1 - a header only implementation of the SHA1 algorithm in C++. Based
4 * on the implementation in boost::uuid::details.
5 *
6 * SHA1 Wikipedia Page: http://en.wikipedia.org/wiki/SHA-1
7 *
8 * Copyright (c) 2012-22 SAURAV MOHAPATRA <mohaps@gmail.com>
9 *
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22 #ifndef VIENNACL_TOOLS_SHA1_HPP_
23 #define VIENNACL_TOOLS_SHA1_HPP_
24 #include <cstdio>
25 #include <cstdlib>
26 #include <cstring>
27 #include <iomanip>
28 #include <sstream>
29 #include <stdint.h>
30 namespace viennacl
31 {
32 namespace tools
33 {
34 
35 namespace detail
36 {
37 
38  class sha1
39  {
40  public:
41  typedef uint32_t digest32_t[5];
42  typedef uint8_t digest8_t[20];
43  inline static uint32_t LeftRotate(uint32_t value, vcl_size_t count) {
44  return (value << count) ^ (value >> (32-count));
45  }
46  sha1(){ reset(); }
47  virtual ~sha1() {}
48  sha1(const sha1& s) { *this = s; }
49  const sha1& operator = (const sha1& s) {
50  memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t));
51  memcpy(m_block, s.m_block, 64);
52  m_blockByteIndex = s.m_blockByteIndex;
53  m_byteCount = s.m_byteCount;
54  return *this;
55  }
56  sha1& reset() {
57  m_digest[0] = 0x67452301;
58  m_digest[1] = 0xEFCDAB89;
59  m_digest[2] = 0x98BADCFE;
60  m_digest[3] = 0x10325476;
61  m_digest[4] = 0xC3D2E1F0;
62  m_blockByteIndex = 0;
63  m_byteCount = 0;
64  return *this;
65  }
66  sha1& processByte(uint8_t octet) {
67  this->m_block[this->m_blockByteIndex++] = octet;
68  ++this->m_byteCount;
69  if (m_blockByteIndex == 64) {
70  this->m_blockByteIndex = 0;
71  processBlock();
72  }
73  return *this;
74  }
75  sha1& processBlock(const void* const start, const void* const end) {
76  const uint8_t* begin = static_cast<const uint8_t*>(start);
77  const uint8_t* finish = static_cast<const uint8_t*>(end);
78  while (begin != finish) {
79  processByte(*begin);
80  begin++;
81  }
82  return *this;
83  }
84  sha1& processBytes(const void* const data, vcl_size_t len) {
85  const uint8_t* block = static_cast<const uint8_t*>(data);
86  processBlock(block, block + len);
87  return *this;
88  }
89  const uint32_t* getDigest(digest32_t digest) {
90  vcl_size_t bitCount = this->m_byteCount * 8;
91  processByte(0x80);
92  if (this->m_blockByteIndex > 56) {
93  while (m_blockByteIndex != 0) {
94  processByte(0);
95  }
96  while (m_blockByteIndex < 56) {
97  processByte(0);
98  }
99  } else {
100  while (m_blockByteIndex < 56) {
101  processByte(0);
102  }
103  }
104  processByte(0);
105  processByte(0);
106  processByte(0);
107  processByte(0);
108  processByte( static_cast<unsigned char>((bitCount>>24) & 0xFF));
109  processByte( static_cast<unsigned char>((bitCount>>16) & 0xFF));
110  processByte( static_cast<unsigned char>((bitCount>>8 ) & 0xFF));
111  processByte( static_cast<unsigned char>((bitCount) & 0xFF));
112 
113  memcpy(digest, m_digest, 5 * sizeof(uint32_t));
114  return digest;
115  }
116  const uint8_t* getDigestBytes(digest8_t digest) {
117  digest32_t d32;
118  getDigest(d32);
119  vcl_size_t di = 0;
120  digest[di++] = static_cast<uint8_t>((d32[0] >> 24) & 0xFF);
121  digest[di++] = static_cast<uint8_t>((d32[0] >> 16) & 0xFF);
122  digest[di++] = static_cast<uint8_t>((d32[0] >> 8) & 0xFF);
123  digest[di++] = static_cast<uint8_t>((d32[0]) & 0xFF);
124 
125  digest[di++] = static_cast<uint8_t>((d32[1] >> 24) & 0xFF);
126  digest[di++] = static_cast<uint8_t>((d32[1] >> 16) & 0xFF);
127  digest[di++] = static_cast<uint8_t>((d32[1] >> 8) & 0xFF);
128  digest[di++] = static_cast<uint8_t>((d32[1]) & 0xFF);
129 
130  digest[di++] = static_cast<uint8_t>((d32[2] >> 24) & 0xFF);
131  digest[di++] = static_cast<uint8_t>((d32[2] >> 16) & 0xFF);
132  digest[di++] = static_cast<uint8_t>((d32[2] >> 8) & 0xFF);
133  digest[di++] = static_cast<uint8_t>((d32[2]) & 0xFF);
134 
135  digest[di++] = static_cast<uint8_t>((d32[3] >> 24) & 0xFF);
136  digest[di++] = static_cast<uint8_t>((d32[3] >> 16) & 0xFF);
137  digest[di++] = static_cast<uint8_t>((d32[3] >> 8) & 0xFF);
138  digest[di++] = static_cast<uint8_t>((d32[3]) & 0xFF);
139 
140  digest[di++] = static_cast<uint8_t>((d32[4] >> 24) & 0xFF);
141  digest[di++] = static_cast<uint8_t>((d32[4] >> 16) & 0xFF);
142  digest[di++] = static_cast<uint8_t>((d32[4] >> 8) & 0xFF);
143  digest[di++] = static_cast<uint8_t>((d32[4]) & 0xFF);
144  return digest;
145  }
146 
147  protected:
148  void processBlock() {
149  uint32_t w[80];
150  for (vcl_size_t i = 0; i < 16; i++) {
151  w[i] = static_cast<uint32_t>(m_block[i*4 + 0] << 24);
152  w[i] |= static_cast<uint32_t>(m_block[i*4 + 1] << 16);
153  w[i] |= static_cast<uint32_t>(m_block[i*4 + 2] << 8);
154  w[i] |= static_cast<uint32_t>(m_block[i*4 + 3]);
155  }
156  for (vcl_size_t i = 16; i < 80; i++) {
157  w[i] = LeftRotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1);
158  }
159 
160  uint32_t a = m_digest[0];
161  uint32_t b = m_digest[1];
162  uint32_t c = m_digest[2];
163  uint32_t d = m_digest[3];
164  uint32_t e = m_digest[4];
165 
166  for (vcl_size_t i=0; i<80; ++i) {
167  uint32_t f = 0;
168  uint32_t k = 0;
169 
170  if (i<20) {
171  f = (b & c) | (~b & d);
172  k = 0x5A827999;
173  } else if (i<40) {
174  f = b ^ c ^ d;
175  k = 0x6ED9EBA1;
176  } else if (i<60) {
177  f = (b & c) | (b & d) | (c & d);
178  k = 0x8F1BBCDC;
179  } else {
180  f = b ^ c ^ d;
181  k = 0xCA62C1D6;
182  }
183  uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i];
184  e = d;
185  d = c;
186  c = LeftRotate(b, 30);
187  b = a;
188  a = temp;
189  }
190 
191  m_digest[0] += a;
192  m_digest[1] += b;
193  m_digest[2] += c;
194  m_digest[3] += d;
195  m_digest[4] += e;
196  }
197  private:
198  digest32_t m_digest;
199  uint8_t m_block[64];
200  vcl_size_t m_blockByteIndex;
201  vcl_size_t m_byteCount;
202  };
203 
204 }
205 
206 inline std::string sha1(std::string const & src)
207 {
209  sha1.processBytes(src.c_str(),src.size());
210 
211  uint32_t hash[5];
212  sha1.getDigest(hash);
213 
214  std::ostringstream oss;
215  for (int i = 0; i < 5; ++i)
216  oss << std::hex << std::setfill('0') << std::setw(8) << hash[i];
217 
218  return oss.str();
219 }
220 
221 }
222 }
223 #endif
const uint8_t * getDigestBytes(digest8_t digest)
Definition: sha1.hpp:116
void finish()
Synchronizes the execution. finish() will only return after all compute kernels (CUDA, OpenCL) have completed.
Definition: memory.hpp:54
Main namespace in ViennaCL. Holds all the basic types such as vector, matrix, etc. and defines operations upon them.
Definition: cpu_ram.hpp:29
const uint32_t * getDigest(digest32_t digest)
Definition: sha1.hpp:89
const sha1 & operator=(const sha1 &s)
Definition: sha1.hpp:49
Definition: blas3.hpp:36
result_of::size_type< T >::type start(T const &obj)
Definition: start.hpp:44
std::size_t vcl_size_t
Definition: forwards.h:74
sha1 & processBytes(const void *const data, vcl_size_t len)
Definition: sha1.hpp:84
Reference counting class for the shared_ptr implementation.
Definition: shared_ptr.hpp:39
std::string sha1(std::string const &src)
Definition: sha1.hpp:206
static uint32_t LeftRotate(uint32_t value, vcl_size_t count)
Definition: sha1.hpp:43
sha1 & processBlock(const void *const start, const void *const end)
Definition: sha1.hpp:75
sha1 & processByte(uint8_t octet)
Definition: sha1.hpp:66
sha1(const sha1 &s)
Definition: sha1.hpp:48