Back to index

courier  0.68.2
sha256.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 2005 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #define       SHA1_INTERNAL
00007 #include      "sha1.h"
00008 
00009 #include      <string.h>
00010 #include      <stdlib.h>
00011 
00012 
00013 #define ROTR(x,n) ((SHA256_WORD)(((SHA256_WORD)(x) >> (n))|((x) << (32-(n)))))
00014 
00015 #define ROTL(x,n) ((SHA256_WORD)(((SHA256_WORD)(x) << (n))|((x) >> (32-(n)))))
00016 
00017 
00018 #define CH(x,y,z) ((SHA256_WORD)(((x) & (y)) ^ ((~(x))&(z))))
00019 #define MAJ(x,y,z) ((SHA256_WORD)(((x)&(y))^((x)&(z))^((y)&(z))))
00020 
00021 #define SUM0(x) ((SHA256_WORD)(ROTR((x),2)^ROTR((x),13)^ROTR((x),22)))
00022 #define SUM1(x) ((SHA256_WORD)(ROTR((x),6)^ROTR((x),11)^ROTR((x),25)))
00023 
00024 #define TH0(x) ((SHA256_WORD)(ROTR((x),7)^ROTR((x),18)^((SHA256_WORD)(x)>>3)))
00025 #define TH1(x) ((SHA256_WORD)(ROTR((x),17)^ROTR((x),19)^((SHA256_WORD)(x)>>10)))
00026 
00027 static const SHA256_WORD K[64]=
00028        {0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
00029         0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
00030         0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
00031         0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
00032         0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
00033         0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
00034         0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
00035         0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2};
00036 
00037 void sha256_context_init(struct SHA256_CONTEXT *c)
00038 {
00039        if (sizeof(SHA256_WORD) != 4)
00040               abort();
00041 
00042        c->H[0] = 0x6A09E667;
00043        c->H[1] = 0xBB67AE85;
00044        c->H[2] = 0x3C6EF372;
00045        c->H[3] = 0xA54FF53A;
00046        c->H[4] = 0x510E527F;
00047        c->H[5] = 0x9B05688C;
00048        c->H[6] = 0x1F83D9AB;
00049        c->H[7] = 0x5BE0CD19;
00050        c->blk_ptr=0;
00051 }
00052 
00053 void sha256_context_hash(struct SHA256_CONTEXT *cc,
00054                       const unsigned char blk[SHA256_BLOCK_SIZE])
00055 {
00056        SHA256_WORD W[64];
00057        unsigned i, t;
00058        SHA256_WORD a,b,c,d,e,f,g,h;
00059 
00060        for (i=t=0; t<16; t++)
00061        {
00062               SHA256_WORD x=blk[i]; i++;
00063 
00064               x=(x << 8) | blk[i]; i++;
00065               x=(x << 8) | blk[i]; i++;
00066               W[t]=(x << 8) | blk[i]; i++;
00067        }
00068 
00069        for (t=16; t<64; t++)
00070               W[t]= TH1(W[t-2]) + W[t-7] + TH0(W[t-15]) + W[t-16];
00071 
00072        a=cc->H[0];
00073        b=cc->H[1];
00074        c=cc->H[2];
00075        d=cc->H[3];
00076        e=cc->H[4];
00077        f=cc->H[5];
00078        g=cc->H[6];
00079        h=cc->H[7];
00080 
00081        for (t=0; t<64; t++)
00082        {
00083               SHA256_WORD T1=h + SUM1(e) + CH(e,f,g) + K[t] + W[t];
00084               SHA256_WORD T2=SUM0(a)+MAJ(a,b,c);
00085               h=g;
00086               g=f;
00087               f=e;
00088               e=d+T1;
00089               d=c;
00090               c=b;
00091               b=a;
00092               a=T1+T2;
00093        }
00094 
00095        cc->H[0] += a;
00096        cc->H[1] += b;
00097        cc->H[2] += c;
00098        cc->H[3] += d;
00099        cc->H[4] += e;
00100        cc->H[5] += f;
00101        cc->H[6] += g;
00102        cc->H[7] += h;
00103 }
00104 
00105 void sha256_context_hashstream(struct SHA256_CONTEXT *c, const void *p, unsigned l)
00106 {
00107 const unsigned char *cp=(const unsigned char *)p;
00108 unsigned ll;
00109 
00110        while (l)
00111        {
00112               if (c->blk_ptr == 0 && l >= SHA256_BLOCK_SIZE)
00113               {
00114                      sha256_context_hash(c, cp);
00115                      cp += SHA256_BLOCK_SIZE;
00116                      l -= SHA256_BLOCK_SIZE;
00117                      continue;
00118               }
00119 
00120               ll=l;
00121               if (ll > SHA256_BLOCK_SIZE - c->blk_ptr)
00122                      ll=SHA256_BLOCK_SIZE - c->blk_ptr;
00123               memcpy(c->blk + c->blk_ptr, cp, ll);
00124               c->blk_ptr += ll;
00125               cp += ll;
00126               l -= ll;
00127               if (c->blk_ptr >= SHA256_BLOCK_SIZE)
00128               {
00129                      sha256_context_hash(c, c->blk);
00130                      c->blk_ptr=0;
00131               }
00132        }
00133 }
00134 
00135 void sha256_context_endstream(struct SHA256_CONTEXT *c, unsigned long l)
00136 {
00137        unsigned char buf[8];
00138        static const unsigned char zero[SHA256_BLOCK_SIZE-8];
00139 
00140        buf[0]=0x80;
00141        sha256_context_hashstream(c, &buf, 1);
00142        while (c->blk_ptr != SHA256_BLOCK_SIZE-8)
00143        {
00144               if (c->blk_ptr > SHA256_BLOCK_SIZE-8)
00145               {
00146                      sha256_context_hashstream(c, zero,
00147                             SHA256_BLOCK_SIZE - c->blk_ptr);
00148                      continue;
00149               }
00150               sha256_context_hashstream(c, zero,
00151                      SHA256_BLOCK_SIZE-8-c->blk_ptr);
00152        }
00153 
00154        l *= 8;
00155        buf[7] = l;
00156        buf[6] = (l >>= 8);
00157        buf[5] = (l >>= 8);
00158        buf[4] = (l >> 8);
00159        buf[3]=buf[2]=buf[1]=buf[0]=0;
00160 
00161        sha256_context_hashstream(c, buf, 8);
00162 }
00163 
00164 void sha256_context_digest(struct SHA256_CONTEXT *c, SHA256_DIGEST d)
00165 {
00166        unsigned char *dp=d + SHA256_DIGEST_SIZE;
00167        unsigned i;
00168 
00169        for ( i=8; i; )
00170        {
00171               SHA256_WORD   w=c->H[--i];
00172 
00173               *--dp=w; w >>= 8;
00174               *--dp=w; w >>= 8;
00175               *--dp=w; w >>= 8;
00176               *--dp=w;
00177        }
00178 }
00179 
00180 void sha256_context_restore(struct SHA256_CONTEXT *c, const SHA256_DIGEST d)
00181 {
00182        const unsigned char *dp=d;
00183        unsigned i;
00184 
00185        for (i=0; i<8; i++)
00186        {
00187               SHA256_WORD   w= *dp++;
00188 
00189               w=(w << 8) | *dp++;
00190               w=(w << 8) | *dp++;
00191               w=(w << 8) | *dp++;
00192               c->H[i]=w;
00193        }
00194        c->blk_ptr=0;
00195 }
00196 
00197 void sha256_digest(const void *msg, unsigned len, SHA256_DIGEST d)
00198 {
00199        struct SHA256_CONTEXT c;
00200 
00201        sha256_context_init( &c );
00202        sha256_context_hashstream(&c, msg, len);
00203        sha256_context_endstream(&c, len);
00204        sha256_context_digest( &c, d );
00205 }