|
1 | 1 | /* |
2 | 2 | * SHA1 Wikipedia Page: http://en.wikipedia.org/wiki/SHA-1 |
3 | | - * |
| 3 | + * |
4 | 4 | * Copyright (c) 2012-22 SAURAV MOHAPATRA <[email protected]> |
5 | 5 | * |
6 | 6 | * Permission to use, copy, modify, and distribute this software for any |
|
16 | 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 | 17 | */ |
18 | 18 |
|
19 | | -/** |
| 19 | +/** |
20 | 20 | * \file TinySHA1.hpp |
21 | 21 | * \author SAURAV MOHAPATRA <[email protected]> |
22 | 22 | * \date 2012-22 |
|
39 | 39 | */ |
40 | 40 | namespace sha1 |
41 | 41 | { |
42 | | - /** |
43 | | - * \class SHA1 |
44 | | - * \brief A tiny SHA1 algorithm implementation used internally in the |
45 | | - * Crow server (specifically in crow/websocket.h). |
46 | | - */ |
47 | | - class SHA1 |
48 | | - { |
49 | | - public: |
50 | | - typedef uint32_t digest32_t[5]; |
51 | | - typedef uint8_t digest8_t[20]; |
52 | | - inline static uint32_t LeftRotate(uint32_t value, size_t count) { |
53 | | - return (value << count) ^ (value >> (32-count)); |
54 | | - } |
55 | | - SHA1(){ reset(); } |
56 | | - virtual ~SHA1() {} |
57 | | - SHA1(const SHA1& s) { *this = s; } |
58 | | - const SHA1& operator = (const SHA1& s) { |
59 | | - memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t)); |
60 | | - memcpy(m_block, s.m_block, 64); |
61 | | - m_blockByteIndex = s.m_blockByteIndex; |
62 | | - m_byteCount = s.m_byteCount; |
63 | | - return *this; |
64 | | - } |
65 | | - SHA1& reset() { |
66 | | - m_digest[0] = 0x67452301; |
67 | | - m_digest[1] = 0xEFCDAB89; |
68 | | - m_digest[2] = 0x98BADCFE; |
69 | | - m_digest[3] = 0x10325476; |
70 | | - m_digest[4] = 0xC3D2E1F0; |
71 | | - m_blockByteIndex = 0; |
72 | | - m_byteCount = 0; |
73 | | - return *this; |
74 | | - } |
75 | | - SHA1& processByte(uint8_t octet) { |
76 | | - this->m_block[this->m_blockByteIndex++] = octet; |
77 | | - ++this->m_byteCount; |
78 | | - if(m_blockByteIndex == 64) { |
79 | | - this->m_blockByteIndex = 0; |
80 | | - processBlock(); |
81 | | - } |
82 | | - return *this; |
83 | | - } |
84 | | - SHA1& processBlock(const void* const start, const void* const end) { |
85 | | - const uint8_t* begin = static_cast<const uint8_t*>(start); |
86 | | - const uint8_t* finish = static_cast<const uint8_t*>(end); |
87 | | - while(begin != finish) { |
88 | | - processByte(*begin); |
89 | | - begin++; |
90 | | - } |
91 | | - return *this; |
92 | | - } |
93 | | - SHA1& processBytes(const void* const data, size_t len) { |
94 | | - const uint8_t* block = static_cast<const uint8_t*>(data); |
95 | | - processBlock(block, block + len); |
96 | | - return *this; |
97 | | - } |
98 | | - const uint32_t* getDigest(digest32_t digest) { |
99 | | - size_t bitCount = this->m_byteCount * 8; |
100 | | - processByte(0x80); |
101 | | - if (this->m_blockByteIndex > 56) { |
102 | | - while (m_blockByteIndex != 0) { |
103 | | - processByte(0); |
104 | | - } |
105 | | - while (m_blockByteIndex < 56) { |
106 | | - processByte(0); |
107 | | - } |
108 | | - } else { |
109 | | - while (m_blockByteIndex < 56) { |
110 | | - processByte(0); |
111 | | - } |
112 | | - } |
113 | | - processByte(0); |
114 | | - processByte(0); |
115 | | - processByte(0); |
116 | | - processByte(0); |
117 | | - processByte( static_cast<unsigned char>((bitCount>>24) & 0xFF)); |
118 | | - processByte( static_cast<unsigned char>((bitCount>>16) & 0xFF)); |
119 | | - processByte( static_cast<unsigned char>((bitCount>>8 ) & 0xFF)); |
120 | | - processByte( static_cast<unsigned char>((bitCount) & 0xFF)); |
121 | | - |
122 | | - memcpy(digest, m_digest, 5 * sizeof(uint32_t)); |
123 | | - return digest; |
124 | | - } |
125 | | - const uint8_t* getDigestBytes(digest8_t digest) { |
126 | | - digest32_t d32; |
127 | | - getDigest(d32); |
128 | | - size_t di = 0; |
129 | | - digest[di++] = ((d32[0] >> 24) & 0xFF); |
130 | | - digest[di++] = ((d32[0] >> 16) & 0xFF); |
131 | | - digest[di++] = ((d32[0] >> 8) & 0xFF); |
132 | | - digest[di++] = ((d32[0]) & 0xFF); |
133 | | - |
134 | | - digest[di++] = ((d32[1] >> 24) & 0xFF); |
135 | | - digest[di++] = ((d32[1] >> 16) & 0xFF); |
136 | | - digest[di++] = ((d32[1] >> 8) & 0xFF); |
137 | | - digest[di++] = ((d32[1]) & 0xFF); |
138 | | - |
139 | | - digest[di++] = ((d32[2] >> 24) & 0xFF); |
140 | | - digest[di++] = ((d32[2] >> 16) & 0xFF); |
141 | | - digest[di++] = ((d32[2] >> 8) & 0xFF); |
142 | | - digest[di++] = ((d32[2]) & 0xFF); |
143 | | - |
144 | | - digest[di++] = ((d32[3] >> 24) & 0xFF); |
145 | | - digest[di++] = ((d32[3] >> 16) & 0xFF); |
146 | | - digest[di++] = ((d32[3] >> 8) & 0xFF); |
147 | | - digest[di++] = ((d32[3]) & 0xFF); |
148 | | - |
149 | | - digest[di++] = ((d32[4] >> 24) & 0xFF); |
150 | | - digest[di++] = ((d32[4] >> 16) & 0xFF); |
151 | | - digest[di++] = ((d32[4] >> 8) & 0xFF); |
152 | | - digest[di++] = ((d32[4]) & 0xFF); |
153 | | - return digest; |
154 | | - } |
155 | | - |
156 | | - protected: |
157 | | - void processBlock() { |
158 | | - uint32_t w[80]; |
159 | | - for (size_t i = 0; i < 16; i++) { |
160 | | - w[i] = (m_block[i*4 + 0] << 24); |
161 | | - w[i] |= (m_block[i*4 + 1] << 16); |
162 | | - w[i] |= (m_block[i*4 + 2] << 8); |
163 | | - w[i] |= (m_block[i*4 + 3]); |
164 | | - } |
165 | | - for (size_t i = 16; i < 80; i++) { |
166 | | - w[i] = LeftRotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1); |
167 | | - } |
168 | | - |
169 | | - uint32_t a = m_digest[0]; |
170 | | - uint32_t b = m_digest[1]; |
171 | | - uint32_t c = m_digest[2]; |
172 | | - uint32_t d = m_digest[3]; |
173 | | - uint32_t e = m_digest[4]; |
174 | | - |
175 | | - for (std::size_t i=0; i<80; ++i) { |
176 | | - uint32_t f = 0; |
177 | | - uint32_t k = 0; |
178 | | - |
179 | | - if (i<20) { |
180 | | - f = (b & c) | (~b & d); |
181 | | - k = 0x5A827999; |
182 | | - } else if (i<40) { |
183 | | - f = b ^ c ^ d; |
184 | | - k = 0x6ED9EBA1; |
185 | | - } else if (i<60) { |
186 | | - f = (b & c) | (b & d) | (c & d); |
187 | | - k = 0x8F1BBCDC; |
188 | | - } else { |
189 | | - f = b ^ c ^ d; |
190 | | - k = 0xCA62C1D6; |
191 | | - } |
192 | | - uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i]; |
193 | | - e = d; |
194 | | - d = c; |
195 | | - c = LeftRotate(b, 30); |
196 | | - b = a; |
197 | | - a = temp; |
198 | | - } |
199 | | - |
200 | | - m_digest[0] += a; |
201 | | - m_digest[1] += b; |
202 | | - m_digest[2] += c; |
203 | | - m_digest[3] += d; |
204 | | - m_digest[4] += e; |
205 | | - } |
206 | | - private: |
207 | | - digest32_t m_digest; |
208 | | - uint8_t m_block[64]; |
209 | | - size_t m_blockByteIndex; |
210 | | - size_t m_byteCount; |
211 | | - }; |
| 42 | + /** |
| 43 | + * \class SHA1 |
| 44 | + * \brief A tiny SHA1 algorithm implementation used internally in the |
| 45 | + * Crow server (specifically in crow/websocket.h). |
| 46 | + */ |
| 47 | + class SHA1 |
| 48 | + { |
| 49 | + public: |
| 50 | + typedef uint32_t digest32_t[5]; |
| 51 | + typedef uint8_t digest8_t[20]; |
| 52 | + inline static uint32_t LeftRotate(uint32_t value, size_t count) { |
| 53 | + return (value << count) ^ (value >> (32-count)); |
| 54 | + } |
| 55 | + SHA1(){ reset(); } |
| 56 | + virtual ~SHA1() {} |
| 57 | + SHA1(const SHA1& s) { *this = s; } |
| 58 | + const SHA1& operator = (const SHA1& s) { |
| 59 | + memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t)); |
| 60 | + memcpy(m_block, s.m_block, 64); |
| 61 | + m_blockByteIndex = s.m_blockByteIndex; |
| 62 | + m_byteCount = s.m_byteCount; |
| 63 | + return *this; |
| 64 | + } |
| 65 | + SHA1& reset() { |
| 66 | + m_digest[0] = 0x67452301; |
| 67 | + m_digest[1] = 0xEFCDAB89; |
| 68 | + m_digest[2] = 0x98BADCFE; |
| 69 | + m_digest[3] = 0x10325476; |
| 70 | + m_digest[4] = 0xC3D2E1F0; |
| 71 | + m_blockByteIndex = 0; |
| 72 | + m_byteCount = 0; |
| 73 | + return *this; |
| 74 | + } |
| 75 | + SHA1& processByte(uint8_t octet) { |
| 76 | + this->m_block[this->m_blockByteIndex++] = octet; |
| 77 | + ++this->m_byteCount; |
| 78 | + if(m_blockByteIndex == 64) { |
| 79 | + this->m_blockByteIndex = 0; |
| 80 | + processBlock(); |
| 81 | + } |
| 82 | + return *this; |
| 83 | + } |
| 84 | + SHA1& processBlock(const void* const start, const void* const end) { |
| 85 | + const uint8_t* begin = static_cast<const uint8_t*>(start); |
| 86 | + const uint8_t* finish = static_cast<const uint8_t*>(end); |
| 87 | + while(begin != finish) { |
| 88 | + processByte(*begin); |
| 89 | + begin++; |
| 90 | + } |
| 91 | + return *this; |
| 92 | + } |
| 93 | + SHA1& processBytes(const void* const data, size_t len) { |
| 94 | + const uint8_t* block = static_cast<const uint8_t*>(data); |
| 95 | + processBlock(block, block + len); |
| 96 | + return *this; |
| 97 | + } |
| 98 | + const uint32_t* getDigest(digest32_t digest) { |
| 99 | + size_t bitCount = this->m_byteCount * 8; |
| 100 | + processByte(0x80); |
| 101 | + if (this->m_blockByteIndex > 56) { |
| 102 | + while (m_blockByteIndex != 0) { |
| 103 | + processByte(0); |
| 104 | + } |
| 105 | + while (m_blockByteIndex < 56) { |
| 106 | + processByte(0); |
| 107 | + } |
| 108 | + } else { |
| 109 | + while (m_blockByteIndex < 56) { |
| 110 | + processByte(0); |
| 111 | + } |
| 112 | + } |
| 113 | + processByte(0); |
| 114 | + processByte(0); |
| 115 | + processByte(0); |
| 116 | + processByte(0); |
| 117 | + processByte( static_cast<unsigned char>((bitCount>>24) & 0xFF)); |
| 118 | + processByte( static_cast<unsigned char>((bitCount>>16) & 0xFF)); |
| 119 | + processByte( static_cast<unsigned char>((bitCount>>8 ) & 0xFF)); |
| 120 | + processByte( static_cast<unsigned char>((bitCount) & 0xFF)); |
| 121 | + |
| 122 | + memcpy(digest, m_digest, 5 * sizeof(uint32_t)); |
| 123 | + return digest; |
| 124 | + } |
| 125 | + const uint8_t* getDigestBytes(digest8_t digest) { |
| 126 | + digest32_t d32; |
| 127 | + getDigest(d32); |
| 128 | + size_t di = 0; |
| 129 | + digest[di++] = ((d32[0] >> 24) & 0xFF); |
| 130 | + digest[di++] = ((d32[0] >> 16) & 0xFF); |
| 131 | + digest[di++] = ((d32[0] >> 8) & 0xFF); |
| 132 | + digest[di++] = ((d32[0]) & 0xFF); |
| 133 | + |
| 134 | + digest[di++] = ((d32[1] >> 24) & 0xFF); |
| 135 | + digest[di++] = ((d32[1] >> 16) & 0xFF); |
| 136 | + digest[di++] = ((d32[1] >> 8) & 0xFF); |
| 137 | + digest[di++] = ((d32[1]) & 0xFF); |
| 138 | + |
| 139 | + digest[di++] = ((d32[2] >> 24) & 0xFF); |
| 140 | + digest[di++] = ((d32[2] >> 16) & 0xFF); |
| 141 | + digest[di++] = ((d32[2] >> 8) & 0xFF); |
| 142 | + digest[di++] = ((d32[2]) & 0xFF); |
| 143 | + |
| 144 | + digest[di++] = ((d32[3] >> 24) & 0xFF); |
| 145 | + digest[di++] = ((d32[3] >> 16) & 0xFF); |
| 146 | + digest[di++] = ((d32[3] >> 8) & 0xFF); |
| 147 | + digest[di++] = ((d32[3]) & 0xFF); |
| 148 | + |
| 149 | + digest[di++] = ((d32[4] >> 24) & 0xFF); |
| 150 | + digest[di++] = ((d32[4] >> 16) & 0xFF); |
| 151 | + digest[di++] = ((d32[4] >> 8) & 0xFF); |
| 152 | + digest[di++] = ((d32[4]) & 0xFF); |
| 153 | + return digest; |
| 154 | + } |
| 155 | + |
| 156 | + protected: |
| 157 | + void processBlock() { |
| 158 | + uint32_t w[80]; |
| 159 | + for (size_t i = 0; i < 16; i++) { |
| 160 | + w[i] = (m_block[i*4 + 0] << 24); |
| 161 | + w[i] |= (m_block[i*4 + 1] << 16); |
| 162 | + w[i] |= (m_block[i*4 + 2] << 8); |
| 163 | + w[i] |= (m_block[i*4 + 3]); |
| 164 | + } |
| 165 | + for (size_t i = 16; i < 80; i++) { |
| 166 | + w[i] = LeftRotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1); |
| 167 | + } |
| 168 | + |
| 169 | + uint32_t a = m_digest[0]; |
| 170 | + uint32_t b = m_digest[1]; |
| 171 | + uint32_t c = m_digest[2]; |
| 172 | + uint32_t d = m_digest[3]; |
| 173 | + uint32_t e = m_digest[4]; |
| 174 | + |
| 175 | + for (std::size_t i=0; i<80; ++i) { |
| 176 | + uint32_t f = 0; |
| 177 | + uint32_t k = 0; |
| 178 | + |
| 179 | + if (i<20) { |
| 180 | + f = (b & c) | (~b & d); |
| 181 | + k = 0x5A827999; |
| 182 | + } else if (i<40) { |
| 183 | + f = b ^ c ^ d; |
| 184 | + k = 0x6ED9EBA1; |
| 185 | + } else if (i<60) { |
| 186 | + f = (b & c) | (b & d) | (c & d); |
| 187 | + k = 0x8F1BBCDC; |
| 188 | + } else { |
| 189 | + f = b ^ c ^ d; |
| 190 | + k = 0xCA62C1D6; |
| 191 | + } |
| 192 | + uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i]; |
| 193 | + e = d; |
| 194 | + d = c; |
| 195 | + c = LeftRotate(b, 30); |
| 196 | + b = a; |
| 197 | + a = temp; |
| 198 | + } |
| 199 | + |
| 200 | + m_digest[0] += a; |
| 201 | + m_digest[1] += b; |
| 202 | + m_digest[2] += c; |
| 203 | + m_digest[3] += d; |
| 204 | + m_digest[4] += e; |
| 205 | + } |
| 206 | + private: |
| 207 | + digest32_t m_digest; |
| 208 | + uint8_t m_block[64]; |
| 209 | + size_t m_blockByteIndex; |
| 210 | + size_t m_byteCount; |
| 211 | + }; |
212 | 212 | } |
213 | 213 | #endif |
0 commit comments