"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 }