ViennaCL - The Vienna Computing Library  1.7.1
Free open-source GPU-accelerated linear algebra and solver library.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
30 #include "viennacl/forwards.h"
31 
32 namespace viennacl
33 {
34 namespace tools
35 {
36 
37 typedef signed char int8_t;
38 typedef unsigned char uint8_t;
39 typedef short int16_t;
40 typedef unsigned short uint16_t;
41 #if defined(_MSC_VER)
42 typedef __int32 int32_t;
43 typedef unsigned __int32 uint32_t;
44 #else
45 typedef int int32_t;
46 typedef unsigned int uint32_t;
47 #endif
48 
49 namespace detail
50 {
51 
52  class sha1
53  {
54  public:
55  typedef uint32_t digest32_t[5];
56  typedef uint8_t digest8_t[20];
57  inline static uint32_t LeftRotate(uint32_t value, vcl_size_t count) {
58  return (value << count) ^ (value >> (32-count));
59  }
60  sha1(){ reset(); }
61  virtual ~sha1() {}
62  sha1(const sha1& s) { *this = s; }
63  const sha1& operator = (const sha1& s) {
64  memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t));
65  memcpy(m_block, s.m_block, 64);
66  m_blockByteIndex = s.m_blockByteIndex;
67  m_byteCount = s.m_byteCount;
68  return *this;
69  }
70  sha1& reset() {
71  m_digest[0] = 0x67452301;
72  m_digest[1] = 0xEFCDAB89;
73  m_digest[2] = 0x98BADCFE;
74  m_digest[3] = 0x10325476;
75  m_digest[4] = 0xC3D2E1F0;
76  m_blockByteIndex = 0;
77  m_byteCount = 0;
78  return *this;
79  }
81  this->m_block[this->m_blockByteIndex++] = octet;
82  ++this->m_byteCount;
83  if (m_blockByteIndex == 64) {
84  this->m_blockByteIndex = 0;
85  processBlock();
86  }
87  return *this;
88  }
89  sha1& processBlock(const void* const start, const void* const end) {
90  const uint8_t* begin = static_cast<const uint8_t*>(start);
91  const uint8_t* finish = static_cast<const uint8_t*>(end);
92  while (begin != finish) {
93  processByte(*begin);
94  begin++;
95  }
96  return *this;
97  }
98  sha1& processBytes(const void* const data, vcl_size_t len) {
99  const uint8_t* block = static_cast<const uint8_t*>(data);
100  processBlock(block, block + len);
101  return *this;
102  }
103  const uint32_t* getDigest(digest32_t digest) {
104  vcl_size_t bitCount = this->m_byteCount * 8;
105  processByte(0x80);
106  if (this->m_blockByteIndex > 56) {
107  while (m_blockByteIndex != 0) {
108  processByte(0);
109  }
110  while (m_blockByteIndex < 56) {
111  processByte(0);
112  }
113  } else {
114  while (m_blockByteIndex < 56) {
115  processByte(0);
116  }
117  }
118  processByte(0);
119  processByte(0);
120  processByte(0);
121  processByte(0);
122  processByte( static_cast<unsigned char>((bitCount>>24) & 0xFF));
123  processByte( static_cast<unsigned char>((bitCount>>16) & 0xFF));
124  processByte( static_cast<unsigned char>((bitCount>>8 ) & 0xFF));
125  processByte( static_cast<unsigned char>((bitCount) & 0xFF));
126 
127  memcpy(digest, m_digest, 5 * sizeof(uint32_t));
128  return digest;
129  }
131  digest32_t d32;
132  getDigest(d32);
133  vcl_size_t di = 0;
134  digest[di++] = static_cast<uint8_t>((d32[0] >> 24) & 0xFF);
135  digest[di++] = static_cast<uint8_t>((d32[0] >> 16) & 0xFF);
136  digest[di++] = static_cast<uint8_t>((d32[0] >> 8) & 0xFF);
137  digest[di++] = static_cast<uint8_t>((d32[0]) & 0xFF);
138 
139  digest[di++] = static_cast<uint8_t>((d32[1] >> 24) & 0xFF);
140  digest[di++] = static_cast<uint8_t>((d32[1] >> 16) & 0xFF);
141  digest[di++] = static_cast<uint8_t>((d32[1] >> 8) & 0xFF);
142  digest[di++] = static_cast<uint8_t>((d32[1]) & 0xFF);
143 
144  digest[di++] = static_cast<uint8_t>((d32[2] >> 24) & 0xFF);
145  digest[di++] = static_cast<uint8_t>((d32[2] >> 16) & 0xFF);
146  digest[di++] = static_cast<uint8_t>((d32[2] >> 8) & 0xFF);
147  digest[di++] = static_cast<uint8_t>((d32[2]) & 0xFF);
148 
149  digest[di++] = static_cast<uint8_t>((d32[3] >> 24) & 0xFF);
150  digest[di++] = static_cast<uint8_t>((d32[3] >> 16) & 0xFF);
151  digest[di++] = static_cast<uint8_t>((d32[3] >> 8) & 0xFF);
152  digest[di++] = static_cast<uint8_t>((d32[3]) & 0xFF);
153 
154  digest[di++] = static_cast<uint8_t>((d32[4] >> 24) & 0xFF);
155  digest[di++] = static_cast<uint8_t>((d32[4] >> 16) & 0xFF);
156  digest[di++] = static_cast<uint8_t>((d32[4] >> 8) & 0xFF);
157  digest[di++] = static_cast<uint8_t>((d32[4]) & 0xFF);
158  return digest;
159  }
160 
161  protected:
162  void processBlock() {
163  uint32_t w[80];
164  for (vcl_size_t i = 0; i < 16; i++) {
165  w[i] = static_cast<uint32_t>(m_block[i*4 + 0] << 24);
166  w[i] |= static_cast<uint32_t>(m_block[i*4 + 1] << 16);
167  w[i] |= static_cast<uint32_t>(m_block[i*4 + 2] << 8);
168  w[i] |= static_cast<uint32_t>(m_block[i*4 + 3]);
169  }
170  for (vcl_size_t i = 16; i < 80; i++) {
171  w[i] = LeftRotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1);
172  }
173 
174  uint32_t a = m_digest[0];
175  uint32_t b = m_digest[1];
176  uint32_t c = m_digest[2];
177  uint32_t d = m_digest[3];
178  uint32_t e = m_digest[4];
179 
180  for (vcl_size_t i=0; i<80; ++i) {
181  uint32_t f = 0;
182  uint32_t k = 0;
183 
184  if (i<20) {
185  f = (b & c) | (~b & d);
186  k = 0x5A827999;
187  } else if (i<40) {
188  f = b ^ c ^ d;
189  k = 0x6ED9EBA1;
190  } else if (i<60) {
191  f = (b & c) | (b & d) | (c & d);
192  k = 0x8F1BBCDC;
193  } else {
194  f = b ^ c ^ d;
195  k = 0xCA62C1D6;
196  }
197  uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i];
198  e = d;
199  d = c;
200  c = LeftRotate(b, 30);
201  b = a;
202  a = temp;
203  }
204 
205  m_digest[0] += a;
206  m_digest[1] += b;
207  m_digest[2] += c;
208  m_digest[3] += d;
209  m_digest[4] += e;
210  }
211  private:
212  digest32_t m_digest;
213  uint8_t m_block[64];
214  vcl_size_t m_blockByteIndex;
215  vcl_size_t m_byteCount;
216  };
217 
218 }
219 
220 inline std::string sha1(std::string const & src)
221 {
223  sha1.processBytes(src.c_str(),src.size());
224 
225  uint32_t hash[5];
226  sha1.getDigest(hash);
227 
228  std::ostringstream oss;
229  for (int i = 0; i < 5; ++i)
230  oss << std::hex << std::setfill('0') << std::setw(8) << hash[i];
231 
232  return oss.str();
233 }
234 
235 }
236 }
237 #endif
const uint8_t * getDigestBytes(digest8_t digest)
Definition: sha1.hpp:130
void finish()
Synchronizes the execution. finish() will only return after all compute kernels (CUDA, OpenCL) have completed.
Definition: memory.hpp:54
This file provides the forward declarations for the main types used within ViennaCL.
short int16_t
Definition: sha1.hpp:39
unsigned int uint32_t
Definition: sha1.hpp:46
const uint32_t * getDigest(digest32_t digest)
Definition: sha1.hpp:103
const sha1 & operator=(const sha1 &s)
Definition: sha1.hpp:63
result_of::size_type< T >::type start(T const &obj)
Definition: start.hpp:44
std::size_t vcl_size_t
Definition: forwards.h:75
signed char int8_t
Definition: sha1.hpp:37
sha1 & processBytes(const void *const data, vcl_size_t len)
Definition: sha1.hpp:98
Reference counting class for the shared_ptr implementation.
Definition: shared_ptr.hpp:39
std::string sha1(std::string const &src)
Definition: sha1.hpp:220
unsigned short uint16_t
Definition: sha1.hpp:40
unsigned char uint8_t
Definition: sha1.hpp:38
static uint32_t LeftRotate(uint32_t value, vcl_size_t count)
Definition: sha1.hpp:57
sha1 & processBlock(const void *const start, const void *const end)
Definition: sha1.hpp:89
sha1 & processByte(uint8_t octet)
Definition: sha1.hpp:80
sha1(const sha1 &s)
Definition: sha1.hpp:62