"Fossies" - the Fresh Open Source Software Archive 
Member "unrar/sha256.cpp" (4 May 2022, 4246 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "sha256.cpp" see the
Fossies "Dox" file reference documentation.
1 #include "rar.hpp"
2 #include "sha256.hpp"
3
4 static const uint32 K[64] =
5 {
6 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
7 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
8 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
9 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
10 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
11 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
12 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
13 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
14 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
15 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
16 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
17 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
18 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
19 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
20 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
21 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
22 };
23
24 // SHA-256 functions. We could optimize Ch and Maj a little,
25 // but with no visible speed benefit.
26 #define Ch(x, y, z) ((x & y) ^ (~x & z))
27 #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
28
29 // Sigma functions.
30 #define Sg0(x) (rotr32(x, 2) ^ rotr32(x,13) ^ rotr32(x, 22))
31 #define Sg1(x) (rotr32(x, 6) ^ rotr32(x,11) ^ rotr32(x, 25))
32 #define sg0(x) (rotr32(x, 7) ^ rotr32(x,18) ^ (x >> 3))
33 #define sg1(x) (rotr32(x,17) ^ rotr32(x,19) ^ (x >> 10))
34
35 void sha256_init(sha256_context *ctx)
36 {
37 ctx->H[0] = 0x6a09e667; // Set the initial hash value.
38 ctx->H[1] = 0xbb67ae85;
39 ctx->H[2] = 0x3c6ef372;
40 ctx->H[3] = 0xa54ff53a;
41 ctx->H[4] = 0x510e527f;
42 ctx->H[5] = 0x9b05688c;
43 ctx->H[6] = 0x1f83d9ab;
44 ctx->H[7] = 0x5be0cd19;
45 ctx->Count = 0; // Processed data counter.
46 }
47
48
49 static void sha256_transform(sha256_context *ctx)
50 {
51 uint32 W[64]; // Words of message schedule.
52 uint32 v[8]; // FIPS a, b, c, d, e, f, g, h working variables.
53
54 // Prepare message schedule.
55 for (uint I = 0; I < 16; I++)
56 W[I] = RawGetBE4(ctx->Buffer + I * 4);
57 for (uint I = 16; I < 64; I++)
58 W[I] = sg1(W[I-2]) + W[I-7] + sg0(W[I-15]) + W[I-16];
59
60 uint32 *H=ctx->H;
61 v[0]=H[0]; v[1]=H[1]; v[2]=H[2]; v[3]=H[3];
62 v[4]=H[4]; v[5]=H[5]; v[6]=H[6]; v[7]=H[7];
63
64 for (uint I = 0; I < 64; I++)
65 {
66 uint T1 = v[7] + Sg1(v[4]) + Ch(v[4], v[5], v[6]) + K[I] + W[I];
67
68 // It is possible to eliminate variable copying if we unroll loop
69 // and rename variables every time. But my test did not show any speed
70 // gain on i7 for such full or partial unrolling.
71 v[7] = v[6];
72 v[6] = v[5];
73 v[5] = v[4];
74 v[4] = v[3] + T1;
75
76 // It works a little faster when moved here from beginning of loop.
77 uint T2 = Sg0(v[0]) + Maj(v[0], v[1], v[2]);
78
79 v[3] = v[2];
80 v[2] = v[1];
81 v[1] = v[0];
82 v[0] = T1 + T2;
83 }
84
85 H[0]+=v[0]; H[1]+=v[1]; H[2]+=v[2]; H[3]+=v[3];
86 H[4]+=v[4]; H[5]+=v[5]; H[6]+=v[6]; H[7]+=v[7];
87 }
88
89
90 void sha256_process(sha256_context *ctx, const void *Data, size_t Size)
91 {
92 const byte *Src=(const byte *)Data;
93 size_t BufPos = (uint)ctx->Count & 0x3f;
94 ctx->Count+=Size;
95 while (Size > 0)
96 {
97 size_t BufSpace=sizeof(ctx->Buffer)-BufPos;
98 size_t CopySize=Size>BufSpace ? BufSpace:Size;
99
100 memcpy(ctx->Buffer+BufPos,Src,CopySize);
101
102 Src+=CopySize;
103 BufPos+=CopySize;
104 Size-=CopySize;
105 if (BufPos == 64)
106 {
107 BufPos = 0;
108 sha256_transform(ctx);
109 }
110 }
111 }
112
113
114 void sha256_done(sha256_context *ctx, byte *Digest)
115 {
116 uint64 BitLength = ctx->Count * 8;
117 uint BufPos = (uint)ctx->Count & 0x3f;
118 ctx->Buffer[BufPos++] = 0x80; // Padding the message with "1" bit.
119
120 if (BufPos!=56) // We need 56 bytes block followed by 8 byte length.
121 {
122 if (BufPos>56)
123 {
124 while (BufPos<64)
125 ctx->Buffer[BufPos++] = 0;
126 BufPos=0;
127 }
128 if (BufPos==0)
129 sha256_transform(ctx);
130 memset(ctx->Buffer+BufPos,0,56-BufPos);
131 }
132
133 RawPutBE4((uint32)(BitLength>>32), ctx->Buffer + 56);
134 RawPutBE4((uint32)(BitLength), ctx->Buffer + 60);
135
136 sha256_transform(ctx);
137
138 RawPutBE4(ctx->H[0], Digest + 0);
139 RawPutBE4(ctx->H[1], Digest + 4);
140 RawPutBE4(ctx->H[2], Digest + 8);
141 RawPutBE4(ctx->H[3], Digest + 12);
142 RawPutBE4(ctx->H[4], Digest + 16);
143 RawPutBE4(ctx->H[5], Digest + 20);
144 RawPutBE4(ctx->H[6], Digest + 24);
145 RawPutBE4(ctx->H[7], Digest + 28);
146
147 sha256_init(ctx);
148 }