Electroneum
TinySHA1.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 _TINY_SHA1_HPP_
23 #define _TINY_SHA1_HPP_
24 #include <cstdio>
25 #include <cstdlib>
26 #include <cstring>
27 #include <stdint.h>
28 namespace sha1
29 {
30  class SHA1
31  {
32  public:
33  typedef uint32_t digest32_t[5];
34  typedef uint8_t digest8_t[20];
35  inline static uint32_t LeftRotate(uint32_t value, size_t count) {
36  return (value << count) ^ (value >> (32-count));
37  }
38  SHA1(){ reset(); }
39  virtual ~SHA1() {}
40  SHA1(const SHA1& s) { *this = s; }
41  const SHA1& operator = (const SHA1& s) {
42  memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t));
43  memcpy(m_block, s.m_block, 64);
44  m_blockByteIndex = s.m_blockByteIndex;
45  m_byteCount = s.m_byteCount;
46  return *this;
47  }
48  SHA1& reset() {
49  m_digest[0] = 0x67452301;
50  m_digest[1] = 0xEFCDAB89;
51  m_digest[2] = 0x98BADCFE;
52  m_digest[3] = 0x10325476;
53  m_digest[4] = 0xC3D2E1F0;
54  m_blockByteIndex = 0;
55  m_byteCount = 0;
56  return *this;
57  }
58  SHA1& processByte(uint8_t octet) {
59  this->m_block[this->m_blockByteIndex++] = octet;
60  ++this->m_byteCount;
61  if(m_blockByteIndex == 64) {
62  this->m_blockByteIndex = 0;
63  processBlock();
64  }
65  return *this;
66  }
67  SHA1& processBlock(const void* const start, const void* const end) {
68  const uint8_t* begin = static_cast<const uint8_t*>(start);
69  const uint8_t* finish = static_cast<const uint8_t*>(end);
70  while(begin != finish) {
71  processByte(*begin);
72  begin++;
73  }
74  return *this;
75  }
76  SHA1& processBytes(const void* const data, size_t len) {
77  const uint8_t* block = static_cast<const uint8_t*>(data);
78  processBlock(block, block + len);
79  return *this;
80  }
81  const uint32_t* getDigest(digest32_t digest) {
82  size_t bitCount = this->m_byteCount * 8;
83  processByte(0x80);
84  if (this->m_blockByteIndex > 56) {
85  while (m_blockByteIndex != 0) {
86  processByte(0);
87  }
88  while (m_blockByteIndex < 56) {
89  processByte(0);
90  }
91  } else {
92  while (m_blockByteIndex < 56) {
93  processByte(0);
94  }
95  }
96  processByte(0);
97  processByte(0);
98  processByte(0);
99  processByte(0);
100  processByte( static_cast<unsigned char>((bitCount>>24) & 0xFF));
101  processByte( static_cast<unsigned char>((bitCount>>16) & 0xFF));
102  processByte( static_cast<unsigned char>((bitCount>>8 ) & 0xFF));
103  processByte( static_cast<unsigned char>((bitCount) & 0xFF));
104 
105  memcpy(digest, m_digest, 5 * sizeof(uint32_t));
106  return digest;
107  }
108  const uint8_t* getDigestBytes(digest8_t digest) {
109  digest32_t d32;
110  getDigest(d32);
111  size_t di = 0;
112  digest[di++] = ((d32[0] >> 24) & 0xFF);
113  digest[di++] = ((d32[0] >> 16) & 0xFF);
114  digest[di++] = ((d32[0] >> 8) & 0xFF);
115  digest[di++] = ((d32[0]) & 0xFF);
116 
117  digest[di++] = ((d32[1] >> 24) & 0xFF);
118  digest[di++] = ((d32[1] >> 16) & 0xFF);
119  digest[di++] = ((d32[1] >> 8) & 0xFF);
120  digest[di++] = ((d32[1]) & 0xFF);
121 
122  digest[di++] = ((d32[2] >> 24) & 0xFF);
123  digest[di++] = ((d32[2] >> 16) & 0xFF);
124  digest[di++] = ((d32[2] >> 8) & 0xFF);
125  digest[di++] = ((d32[2]) & 0xFF);
126 
127  digest[di++] = ((d32[3] >> 24) & 0xFF);
128  digest[di++] = ((d32[3] >> 16) & 0xFF);
129  digest[di++] = ((d32[3] >> 8) & 0xFF);
130  digest[di++] = ((d32[3]) & 0xFF);
131 
132  digest[di++] = ((d32[4] >> 24) & 0xFF);
133  digest[di++] = ((d32[4] >> 16) & 0xFF);
134  digest[di++] = ((d32[4] >> 8) & 0xFF);
135  digest[di++] = ((d32[4]) & 0xFF);
136  return digest;
137  }
138 
139  protected:
140  void processBlock() {
141  uint32_t w[80];
142  for (size_t i = 0; i < 16; i++) {
143  w[i] = (m_block[i*4 + 0] << 24);
144  w[i] |= (m_block[i*4 + 1] << 16);
145  w[i] |= (m_block[i*4 + 2] << 8);
146  w[i] |= (m_block[i*4 + 3]);
147  }
148  for (size_t i = 16; i < 80; i++) {
149  w[i] = LeftRotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1);
150  }
151 
152  uint32_t a = m_digest[0];
153  uint32_t b = m_digest[1];
154  uint32_t c = m_digest[2];
155  uint32_t d = m_digest[3];
156  uint32_t e = m_digest[4];
157 
158  for (std::size_t i=0; i<80; ++i) {
159  uint32_t f = 0;
160  uint32_t k = 0;
161 
162  if (i<20) {
163  f = (b & c) | (~b & d);
164  k = 0x5A827999;
165  } else if (i<40) {
166  f = b ^ c ^ d;
167  k = 0x6ED9EBA1;
168  } else if (i<60) {
169  f = (b & c) | (b & d) | (c & d);
170  k = 0x8F1BBCDC;
171  } else {
172  f = b ^ c ^ d;
173  k = 0xCA62C1D6;
174  }
175  uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i];
176  e = d;
177  d = c;
178  c = LeftRotate(b, 30);
179  b = a;
180  a = temp;
181  }
182 
183  m_digest[0] += a;
184  m_digest[1] += b;
185  m_digest[2] += c;
186  m_digest[3] += d;
187  m_digest[4] += e;
188  }
189  private:
191  uint8_t m_block[64];
193  size_t m_byteCount;
194  };
195 }
196 #endif
Definition: TinySHA1.hpp:30
int d
Definition: base.py:14
SHA1 & processBlock(const void *const start, const void *const end)
Definition: TinySHA1.hpp:67
Definition: TinySHA1.hpp:28
SHA1()
Definition: TinySHA1.hpp:38
const SHA1 & operator=(const SHA1 &s)
Definition: TinySHA1.hpp:41
Definition: d.py:1
SHA1 & reset()
Definition: TinySHA1.hpp:48
SHA1(const SHA1 &s)
Definition: TinySHA1.hpp:40
const uint32_t * getDigest(digest32_t digest)
Definition: TinySHA1.hpp:81
SHA1 & processBytes(const void *const data, size_t len)
Definition: TinySHA1.hpp:76
digest32_t m_digest
Definition: TinySHA1.hpp:190
int b
Definition: base.py:1
static uint32_t LeftRotate(uint32_t value, size_t count)
Definition: TinySHA1.hpp:35
SHA1 & processByte(uint8_t octet)
Definition: TinySHA1.hpp:58
size_t m_byteCount
Definition: TinySHA1.hpp:193
uint8_t digest8_t[20]
Definition: TinySHA1.hpp:34
string a
Definition: MakeCryptoOps.py:15
uint32_t digest32_t[5]
Definition: TinySHA1.hpp:33
size_t m_blockByteIndex
Definition: TinySHA1.hpp:192
void processBlock()
Definition: TinySHA1.hpp:140
virtual ~SHA1()
Definition: TinySHA1.hpp:39
const uint8_t * getDigestBytes(digest8_t digest)
Definition: TinySHA1.hpp:108
#define s(x, c)
Definition: aesb.c:46
uint8_t m_block[64]
Definition: TinySHA1.hpp:191