ViennaCL - The Vienna Computing Library  1.7.0
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 
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  }
80  sha1& processByte(uint8_t octet) {
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  }
130  const uint8_t* getDigestBytes(digest8_t digest) {
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.
Main namespace in ViennaCL. Holds all the basic types such as vector, matrix, etc. and defines operations upon them.
Definition: cpu_ram.hpp:34
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
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: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