Logo ROOT  
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
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);
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
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
unsigned long long ULong64_t
Definition: RtypesCore.h:81
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
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
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
unsigned char buffer[64]
Definition: RSha256.hxx:63