Logo ROOT   6.14/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 
22 namespace ROOT {
23 namespace Internal {
24 namespace 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 
60 typedef struct sha256_t {
61  uint32_t state[8];
62  uint64_t count;
63  unsigned char buffer[64];
64 } sha256_t;
65 
66 void sha256_init(sha256_t *p);
67 void sha256_update(sha256_t *p, const unsigned char *data, size_t size);
68 void sha256_final(sha256_t *p, unsigned char *digest);
69 void 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 
148 static 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 
158 static 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 
224 void 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 
238 void 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 
267 void 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
static void sha256_write_byte_block(sha256_t *p)
Definition: RSha256.hxx:214
void sha256_hash(unsigned char *buf, const unsigned char *data, size_t size)
static void sha256_transform(uint32_t *state, const uint32_t *data)
Definition: RSha256.hxx:158
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
void sha256_update(sha256_t *p, const unsigned char *data, size_t size)
Definition: RSha256.hxx:224
void sha256_final(sha256_t *p, unsigned char *digest)
Definition: RSha256.hxx:238
double T(double x)
Definition: ChebyshevPol.h:34
#define g(i)
Definition: RSha256.hxx:105
#define e(i)
Definition: RSha256.hxx:103
#define RX_8(i)
Definition: RSha256.hxx:115
#define f(i)
Definition: RSha256.hxx:104
#define R(a, b, c, d, e, f, g, h, i)
Definition: RSha256.hxx:110
#define b(i)
Definition: RSha256.hxx:100
static const uint32_t K[64]
Definition: RSha256.hxx:148
void Sha256(const unsigned char *data, int len, ULong64_t *fDigest)
Definition: RSha256.hxx:267
#define h(i)
Definition: RSha256.hxx:106
#define d(i)
Definition: RSha256.hxx:102
unsigned long long ULong64_t
Definition: RtypesCore.h:70
#define a(i)
Definition: RSha256.hxx:99
unsigned char buffer[64]
Definition: RSha256.hxx:63
void sha256_init(sha256_t *p)
Definition: RSha256.hxx:75
#define c(i)
Definition: RSha256.hxx:101
struct ROOT::Internal::SHA256::sha256_t sha256_t