Logo ROOT   6.18/05
Reference Guide
RSha256.hxx
Go to the documentation of this file.
1// Author: Danilo Piparo May 2018
2// Inspired by public domain code of Igor Pavlov: https://github.com/jb55/sha256.c
3
4/*************************************************************************
5 * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#ifndef ROOT_RSHA
13#define ROOT_RSHA
14
15#include "Rtypes.h"
16
17#include <iostream>
18#include <stdlib.h>
19#include <stdint.h>
20
21
22namespace ROOT {
23namespace Internal {
24namespace SHA256 {
25
26#ifdef _MSC_VER
27
28#define ROTL32(v, n) _rotl((v), (n))
29#define ROTL64(v, n) _rotl64((v), (n))
30
31#define ROTR32(v, n) _rotr((v), (n))
32#define ROTR64(v, n) _rotr64((v), (n))
33
34#else
35
36#define U8V(v) ((uint8_t)(v)&0xFFU)
37#define U16V(v) ((uint16_t)(v)&0xFFFFU)
38#define U32V(v) ((uint32_t)(v)&0xFFFFFFFFU)
39#define U64V(v) ((uint64_t)(v)&0xFFFFFFFFFFFFFFFFU)
40
41#define ROTL32(v, n) (U32V((uint32_t)(v) << (n)) | ((uint32_t)(v) >> (32 - (n))))
42
43// tests fail if we don't have this cast...
44#define ROTL64(v, n) (U64V((uint64_t)(v) << (n)) | ((uint64_t)(v) >> (64 - (n))))
45
46#define ROTR32(v, n) ROTL32(v, 32 - (n))
47#define ROTR64(v, n) ROTL64(v, 64 - (n))
48
49#endif
50
51#define ROTL8(v, n) (U8V((uint8_t)(v) << (n)) | ((uint8_t)(v) >> (8 - (n))))
52
53#define ROTL16(v, n) (U16V((uint16_t)(v) << (n)) | ((uint16_t)(v) >> (16 - (n))))
54
55#define ROTR8(v, n) ROTL8(v, 8 - (n))
56#define ROTR16(v, n) ROTL16(v, 16 - (n))
57
58#define SHA256_DIGEST_SIZE 32
59
60typedef struct sha256_t {
61 uint32_t state[8];
62 uint64_t count;
63 unsigned char buffer[64];
65
66void sha256_init(sha256_t *p);
67void sha256_update(sha256_t *p, const unsigned char *data, size_t size);
68void sha256_final(sha256_t *p, unsigned char *digest);
69void sha256_hash(unsigned char *buf, const unsigned char *data, size_t size);
70
71/* define it for speed optimization */
72#define _SHA256_UNROLL
73#define _SHA256_UNROLL2
74
76{
77 p->state[0] = 0x6a09e667;
78 p->state[1] = 0xbb67ae85;
79 p->state[2] = 0x3c6ef372;
80 p->state[3] = 0xa54ff53a;
81 p->state[4] = 0x510e527f;
82 p->state[5] = 0x9b05688c;
83 p->state[6] = 0x1f83d9ab;
84 p->state[7] = 0x5be0cd19;
85 p->count = 0;
86}
87
88#define S0(x) (ROTR32(x, 2) ^ ROTR32(x, 13) ^ ROTR32(x, 22))
89#define S1(x) (ROTR32(x, 6) ^ ROTR32(x, 11) ^ ROTR32(x, 25))
90#define s0(x) (ROTR32(x, 7) ^ ROTR32(x, 18) ^ (x >> 3))
91#define s1(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ (x >> 10))
92
93#define blk0(i) (W[i] = data[i])
94#define blk2(i) (W[i & 15] += s1(W[(i - 2) & 15]) + W[(i - 7) & 15] + s0(W[(i - 15) & 15]))
95
96#define Ch(x, y, z) (z ^ (x & (y ^ z)))
97#define Maj(x, y, z) ((x & y) | (z & (x | y)))
98
99#define a(i) T[(0 - (i)) & 7]
100#define b(i) T[(1 - (i)) & 7]
101#define c(i) T[(2 - (i)) & 7]
102#define d(i) T[(3 - (i)) & 7]
103#define e(i) T[(4 - (i)) & 7]
104#define f(i) T[(5 - (i)) & 7]
105#define g(i) T[(6 - (i)) & 7]
106#define h(i) T[(7 - (i)) & 7]
107
108#ifdef _SHA256_UNROLL2
109
110#define R(a, b, c, d, e, f, g, h, i) \
111 h += S1(e) + Ch(e, f, g) + K[i + j] + (j ? blk2(i) : blk0(i)); \
112 d += h; \
113 h += S0(a) + Maj(a, b, c)
114
115#define RX_8(i) \
116 R(a, b, c, d, e, f, g, h, i); \
117 R(h, a, b, c, d, e, f, g, (i + 1)); \
118 R(g, h, a, b, c, d, e, f, (i + 2)); \
119 R(f, g, h, a, b, c, d, e, (i + 3)); \
120 R(e, f, g, h, a, b, c, d, (i + 4)); \
121 R(d, e, f, g, h, a, b, c, (i + 5)); \
122 R(c, d, e, f, g, h, a, b, (i + 6)); \
123 R(b, c, d, e, f, g, h, a, (i + 7))
124
125#else
126
127#define R(i) \
128 h(i) += S1(e(i)) + Ch(e(i), f(i), g(i)) + K[i + j] + (j ? blk2(i) : blk0(i)); \
129 d(i) += h(i); \
130 h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
131
132#ifdef _SHA256_UNROLL
133
134#define RX_8(i) \
135 R(i + 0); \
136 R(i + 1); \
137 R(i + 2); \
138 R(i + 3); \
139 R(i + 4); \
140 R(i + 5); \
141 R(i + 6); \
142 R(i + 7);
143
144#endif
145
146#endif
147
148static const uint32_t K[64] = {
149 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
150 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
151 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
152 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
153 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
154 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
155 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
156 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
157
158static void sha256_transform(uint32_t *state, const uint32_t *data)
159{
160 uint32_t W[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U};
161 unsigned j;
162#ifdef _SHA256_UNROLL2
163 uint32_t a, b, c, d, e, f, g, h;
164 a = state[0];
165 b = state[1];
166 c = state[2];
167 d = state[3];
168 e = state[4];
169 f = state[5];
170 g = state[6];
171 h = state[7];
172#else
173 uint32_t T[8];
174 for (j = 0; j < 8; j++)
175 T[j] = state[j];
176#endif
177
178 for (j = 0; j < 64; j += 16) {
179#if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2)
180 RX_8(0);
181 RX_8(8);
182#else
183 unsigned i;
184 for (i = 0; i < 16; i++) {
185 R(i);
186 }
187#endif
188 }
189
190#ifdef _SHA256_UNROLL2
191 state[0] += a;
192 state[1] += b;
193 state[2] += c;
194 state[3] += d;
195 state[4] += e;
196 state[5] += f;
197 state[6] += g;
198 state[7] += h;
199#else
200 for (j = 0; j < 8; j++)
201 state[j] += T[j];
202#endif
203
204 /* Wipe variables */
205 /* memset(W, 0, sizeof(W)); */
206 /* memset(T, 0, sizeof(T)); */
207}
208
209#undef S0
210#undef S1
211#undef s0
212#undef s1
213
215{
216 uint32_t data32[16];
217 unsigned i;
218 for (i = 0; i < 16; i++)
219 data32[i] = ((uint32_t)(p->buffer[i * 4]) << 24) + ((uint32_t)(p->buffer[i * 4 + 1]) << 16) +
220 ((uint32_t)(p->buffer[i * 4 + 2]) << 8) + ((uint32_t)(p->buffer[i * 4 + 3]));
221 sha256_transform(p->state, data32);
222}
223
224void sha256_update(sha256_t *p, const unsigned char *data, size_t size)
225{
226 uint32_t curBufferPos = (uint32_t)p->count & 0x3F;
227 while (size > 0) {
228 p->buffer[curBufferPos++] = *data++;
229 p->count++;
230 size--;
231 if (curBufferPos == 64) {
232 curBufferPos = 0;
234 }
235 }
236}
237
238void sha256_final(sha256_t *p, unsigned char *digest)
239{
240 uint64_t lenInBits = (p->count << 3);
241 uint32_t curBufferPos = (uint32_t)p->count & 0x3F;
242 unsigned i;
243 p->buffer[curBufferPos++] = 0x80;
244 while (curBufferPos != (64 - 8)) {
245 curBufferPos &= 0x3F;
246 if (curBufferPos == 0)
248 p->buffer[curBufferPos++] = 0;
249 }
250 for (i = 0; i < 8; i++) {
251 p->buffer[curBufferPos++] = (unsigned char)(lenInBits >> 56);
252 lenInBits <<= 8;
253 }
255
256 for (i = 0; i < 8; i++) {
257 *digest++ = (unsigned char)(p->state[i] >> 24);
258 *digest++ = (unsigned char)(p->state[i] >> 16);
259 *digest++ = (unsigned char)(p->state[i] >> 8);
260 *digest++ = (unsigned char)(p->state[i]);
261 }
262 sha256_init(p);
263}
264
265} // End NS SHA256
266
267void Sha256(const unsigned char *data, int len, ULong64_t *fDigest)
268{
269 // Here the final cast is to match the interface of the C code and
270 // the data member. The lenght is the same!
271 SHA256::sha256_t hash;
272 SHA256::sha256_init(&hash);
273 SHA256::sha256_update(&hash, data, len);
274 SHA256::sha256_final(&hash, reinterpret_cast<unsigned char *>(fDigest));
275}
276
277} // End NS Internal
278} // End NS ROOT
279
280#endif
#define d(i)
Definition: RSha256.hxx:102
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
#define c(i)
Definition: RSha256.hxx:101
#define RX_8(i)
Definition: RSha256.hxx:115
#define g(i)
Definition: RSha256.hxx:105
#define a(i)
Definition: RSha256.hxx:99
#define h(i)
Definition: RSha256.hxx:106
#define R(a, b, c, d, e, f, g, h, i)
Definition: RSha256.hxx:110
#define e(i)
Definition: RSha256.hxx:103
unsigned long long ULong64_t
Definition: RtypesCore.h:70
void sha256_update(sha256_t *p, const unsigned char *data, size_t size)
Definition: RSha256.hxx:224
static void sha256_transform(uint32_t *state, const uint32_t *data)
Definition: RSha256.hxx:158
static void sha256_write_byte_block(sha256_t *p)
Definition: RSha256.hxx:214
static const uint32_t K[64]
Definition: RSha256.hxx:148
void sha256_final(sha256_t *p, unsigned char *digest)
Definition: RSha256.hxx:238
void sha256_init(sha256_t *p)
Definition: RSha256.hxx:75
struct ROOT::Internal::SHA256::sha256_t sha256_t
void sha256_hash(unsigned char *buf, const unsigned char *data, size_t size)
void Sha256(const unsigned char *data, int len, ULong64_t *fDigest)
Definition: RSha256.hxx:267
double T(double x)
Definition: ChebyshevPol.h:34
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
unsigned char buffer[64]
Definition: RSha256.hxx:63