WizardsToolkit  1.0.7
sha256.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                             SSSSS  H   H   AAA                              %
00006 %                             SS     H   H  A   A                             %
00007 %                              SSS   HHHHH  AAAAA                             %
00008 %                                SS  H   H  A   A                             %
00009 %                             SSSSS  H   H  A   A                             %
00010 %                                                                             %
00011 %                                                                             %
00012 %             Wizard's Toolkit Secure Hash Algorithm-256 Methods              %
00013 %                                                                             %
00014 %                             Software Design                                 %
00015 %                               John Cristy                                   %
00016 %                               March  2003                                   %
00017 %                                                                             %
00018 %                                                                             %
00019 %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
00020 %  dedicated to making software imaging solutions freely available.           %
00021 %                                                                             %
00022 %  You may not use this file except in compliance with the License.  You may  %
00023 %  obtain a copy of the License at                                            %
00024 %                                                                             %
00025 %    http://www.wizards-toolkit.org/script/license.php                        %
00026 %                                                                             %
00027 %  Unless required by applicable law or agreed to in writing, software        %
00028 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00029 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00030 %  See the License for the specific language governing permissions and        %
00031 %  limitations under the License.                                             %
00032 %                                                                             %
00033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00034 %
00035 % See http://csrc.nist.gov/cryptval/shs.htm.
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
00041 */
00042 #include "wizard/studio.h"
00043 #include "wizard/exception.h"
00044 #include "wizard/exception-private.h"
00045 #include "wizard/memory_.h"
00046 #include "wizard/sha256.h"
00047 /*
00048   Define declarations.
00049 */
00050 #define SHA256Blocksize  64
00051 #define SHA256Digestsize  32
00052 
00053 /*
00054   Typedef declarations.
00055 */
00056 struct _SHA256Info
00057 {   
00058   unsigned int
00059     digestsize,
00060     blocksize;
00061 
00062   StringInfo
00063     *digest,
00064     *message;
00065 
00066   unsigned int
00067     *accumulator,
00068     low_order,
00069     high_order;
00070 
00071   size_t
00072     offset;
00073 
00074   WizardBooleanType
00075     lsb_first;
00076 
00077   time_t
00078     timestamp;
00079 
00080   size_t
00081     signature;
00082 };
00083 
00084 /*
00085   Forward declarations.
00086 */
00087 static void
00088   TransformSHA256(SHA256Info *);
00089 
00090 /*
00091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00092 %                                                                             %
00093 %                                                                             %
00094 %                                                                             %
00095 %   A c q u i r e S H A I n f o                                               %
00096 %                                                                             %
00097 %                                                                             %
00098 %                                                                             %
00099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00100 %
00101 %  AcquireSHA256Info() allocate the SHA256Info structure.
00102 %
00103 %  The format of the AcquireSHA256Info method is:
00104 %
00105 %      SHA256Info *AcquireSHA256Info(void)
00106 %
00107 */
00108 WizardExport SHA256Info *AcquireSHA256Info(void)
00109 {
00110   SHA256Info
00111     *sha_info;
00112 
00113   unsigned int
00114     lsb_first;
00115 
00116   sha_info=(SHA256Info *) AcquireWizardMemory(sizeof(*sha_info));
00117   if (sha_info == (SHA256Info *) NULL)
00118     ThrowWizardFatalError(HashError,MemoryError);
00119   (void) ResetWizardMemory(sha_info,0,sizeof(*sha_info));
00120   sha_info->digestsize=SHA256Digestsize;
00121   sha_info->blocksize=SHA256Blocksize;
00122   sha_info->digest=AcquireStringInfo(SHA256Digestsize);
00123   sha_info->message=AcquireStringInfo(SHA256Blocksize);
00124   sha_info->accumulator=(unsigned int *) AcquireQuantumMemory(SHA256Blocksize,
00125     sizeof(*sha_info->accumulator));
00126   if (sha_info->accumulator == (unsigned int *) NULL)
00127     ThrowWizardFatalError(HashError,MemoryError);
00128   lsb_first=1;
00129   sha_info->lsb_first=(int) (*(char *) &lsb_first) == 1 ? WizardTrue :
00130      WizardFalse;
00131   sha_info->timestamp=time((time_t *) NULL);
00132   sha_info->signature=WizardSignature;
00133   InitializeSHA256(sha_info);
00134   return(sha_info);
00135 }
00136 
00137 /*
00138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00139 %                                                                             %
00140 %                                                                             %
00141 %                                                                             %
00142 %   D e s t r o y S H A I n f o                                               %
00143 %                                                                             %
00144 %                                                                             %
00145 %                                                                             %
00146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00147 %
00148 %  DestroySHA256Info() zeros memory associated with the SHA256Info structure.
00149 %
00150 %  The format of the DestroySHA256Info method is:
00151 %
00152 %      SHA256Info *DestroySHA256Info(SHA256Info *sha_info)
00153 %
00154 %  A description of each parameter follows:
00155 %
00156 %    o sha_info: The cipher sha_info.
00157 %
00158 */
00159 WizardExport SHA256Info *DestroySHA256Info(SHA256Info *sha_info)
00160 {
00161   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00162   assert(sha_info != (SHA256Info *) NULL);
00163   assert(sha_info->signature == WizardSignature);
00164   if (sha_info->accumulator != (unsigned int *) NULL)
00165     sha_info->accumulator=(unsigned int *)
00166       RelinquishWizardMemory(sha_info->accumulator);
00167   if (sha_info->message != (StringInfo *) NULL)
00168     sha_info->message=DestroyStringInfo(sha_info->message);
00169   if (sha_info->digest != (StringInfo *) NULL)
00170     sha_info->digest=DestroyStringInfo(sha_info->digest);
00171   sha_info->signature=(~WizardSignature);
00172   sha_info=(SHA256Info *) RelinquishWizardMemory(sha_info);
00173   return(sha_info);
00174 }
00175 
00176 /*
00177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00178 %                                                                             %
00179 %                                                                             %
00180 %                                                                             %
00181 %   F i n a l i z e S H A                                                     %
00182 %                                                                             %
00183 %                                                                             %
00184 %                                                                             %
00185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00186 %
00187 %  FinalizeSHA256() finalizes the SHA256 message accumulator computation.
00188 %
00189 %  The format of the FinalizeSHA256 method is:
00190 %
00191 %      FinalizeSHA256(SHA256Info *sha_info)
00192 %
00193 %  A description of each parameter follows:
00194 %
00195 %    o sha_info: The address of a structure of type SHA256Info.
00196 %
00197 */
00198 WizardExport void FinalizeSHA256(SHA256Info *sha_info)
00199 {
00200   register ssize_t
00201     i;
00202 
00203   register unsigned char
00204     *q;
00205 
00206   register unsigned int
00207     *p;
00208 
00209   unsigned char
00210     *datum;
00211 
00212   unsigned int
00213     count,
00214     high_order,
00215     low_order;
00216 
00217   /*
00218     Add padding and return the message accumulator.
00219   */
00220   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00221   assert(sha_info != (SHA256Info *) NULL);
00222   assert(sha_info->signature == WizardSignature);
00223   low_order=sha_info->low_order;
00224   high_order=sha_info->high_order;
00225   count=((low_order >> 3) & 0x3f);
00226   datum=GetStringInfoDatum(sha_info->message);
00227   datum[count++]=(unsigned char) 0x80;
00228   if (count <= (unsigned int) (GetStringInfoLength(sha_info->message)-8))
00229     (void) ResetWizardMemory(datum+count,0,GetStringInfoLength(
00230       sha_info->message)-8-count);
00231   else
00232     {
00233       (void) ResetWizardMemory(datum+count,0,
00234         GetStringInfoLength(sha_info->message)-count);
00235       TransformSHA256(sha_info);
00236       (void) ResetWizardMemory(datum,0,GetStringInfoLength(sha_info->message)-
00237         8);
00238     }
00239   datum[56]=(unsigned char) (high_order >> 24);
00240   datum[57]=(unsigned char) (high_order >> 16);
00241   datum[58]=(unsigned char) (high_order >> 8);
00242   datum[59]=(unsigned char) high_order;
00243   datum[60]=(unsigned char) (low_order >> 24);
00244   datum[61]=(unsigned char) (low_order >> 16);
00245   datum[62]=(unsigned char) (low_order >> 8);
00246   datum[63]=(unsigned char) low_order;
00247   TransformSHA256(sha_info);
00248   p=sha_info->accumulator;
00249   q=GetStringInfoDatum(sha_info->digest);
00250   for (i=0; i < (SHA256Digestsize/4); i++)
00251   {
00252     *q++=(unsigned char) ((*p >> 24) & 0xff);
00253     *q++=(unsigned char) ((*p >> 16) & 0xff);
00254     *q++=(unsigned char) ((*p >> 8) & 0xff);
00255     *q++=(unsigned char) (*p & 0xff);
00256     p++;
00257   }
00258   /*
00259     Reset working registers.
00260   */
00261   count=0;
00262   high_order=0;
00263   low_order=0;
00264 }
00265 
00266 /*
00267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00268 %                                                                             %
00269 %                                                                             %
00270 %                                                                             %
00271 %   G e t S H A 2 5 6 B l o c k s i z e                                       %
00272 %                                                                             %
00273 %                                                                             %
00274 %                                                                             %
00275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00276 %
00277 %  GetSHA256Blocksize() returns the SHA256 blocksize.
00278 %
00279 %  The format of the GetSHA256Blocksize method is:
00280 %
00281 %      unsigned int *GetSHA256Blocksize(const SHA256Info *sha256_info)
00282 %
00283 %  A description of each parameter follows:
00284 %
00285 %    o sha256_info: The sha256 info.
00286 %
00287 */
00288 WizardExport unsigned int GetSHA256Blocksize(const SHA256Info *sha256_info)
00289 {
00290   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00291   WizardAssert(CipherDomain,sha256_info != (SHA256Info *) NULL);
00292   WizardAssert(CipherDomain,sha256_info->signature == WizardSignature);
00293   return(sha256_info->blocksize);
00294 }
00295 
00296 /*
00297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00298 %                                                                             %
00299 %                                                                             %
00300 %                                                                             %
00301 %   G e t S H A 2 5 6 D i g e s t                                             %
00302 %                                                                             %
00303 %                                                                             %
00304 %                                                                             %
00305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00306 %
00307 %  GetSHA256Digest() returns the SHA256 digest.
00308 %
00309 %  The format of the GetSHA256Digest method is:
00310 %
00311 %      const StringInfo *GetSHA256Digest(const SHA256Info *sha256_info)
00312 %
00313 %  A description of each parameter follows:
00314 %
00315 %    o sha256_info: The sha256 info.
00316 %
00317 */
00318 WizardExport const StringInfo *GetSHA256Digest(const SHA256Info *sha256_info)
00319 {
00320   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00321   WizardAssert(HashDomain,sha256_info != (SHA256Info *) NULL);
00322   WizardAssert(HashDomain,sha256_info->signature == WizardSignature);
00323   return(sha256_info->digest);
00324 }
00325 
00326 /*
00327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00328 %                                                                             %
00329 %                                                                             %
00330 %                                                                             %
00331 %   G e t S H A 2 5 6 D i g e s t s i z e                                     %
00332 %                                                                             %
00333 %                                                                             %
00334 %                                                                             %
00335 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00336 %
00337 %  GetSHA256Digestsize() returns the SHA256 digest size.
00338 %
00339 %  The format of the GetSHA256Digestsize method is:
00340 %
00341 %      unsigned int *GetSHA256Digestsize(const SHA256Info *sha256_info)
00342 %
00343 %  A description of each parameter follows:
00344 %
00345 %    o sha256_info: The sha256 info.
00346 %
00347 */
00348 WizardExport unsigned int GetSHA256Digestsize(const SHA256Info *sha256_info)
00349 {
00350   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00351   WizardAssert(CipherDomain,sha256_info != (SHA256Info *) NULL);
00352   WizardAssert(CipherDomain,sha256_info->signature == WizardSignature);
00353   return(sha256_info->digestsize);
00354 }
00355 
00356 /*
00357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00358 %                                                                             %
00359 %                                                                             %
00360 %                                                                             %
00361 %   I n i t i a l i z e S H A                                                 %
00362 %                                                                             %
00363 %                                                                             %
00364 %                                                                             %
00365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00366 %
00367 %  IntializeSHA256() intializes the SHA256 accumulator.
00368 %
00369 %  The format of the DestroySHA256Info method is:
00370 %
00371 %      void InitializeSHA256Info(SHA256Info *sha_info)
00372 %
00373 %  A description of each parameter follows:
00374 %
00375 %    o sha_info: The cipher sha_info.
00376 %
00377 */
00378 WizardExport void InitializeSHA256(SHA256Info *sha_info)
00379 {
00380   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00381   assert(sha_info != (SHA256Info *) NULL);
00382   assert(sha_info->signature == WizardSignature);
00383   sha_info->accumulator[0]=0x6a09e667U;
00384   sha_info->accumulator[1]=0xbb67ae85U;
00385   sha_info->accumulator[2]=0x3c6ef372U;
00386   sha_info->accumulator[3]=0xa54ff53aU;
00387   sha_info->accumulator[4]=0x510e527fU;
00388   sha_info->accumulator[5]=0x9b05688cU;
00389   sha_info->accumulator[6]=0x1f83d9abU;
00390   sha_info->accumulator[7]=0x5be0cd19U;
00391   sha_info->low_order=0;
00392   sha_info->high_order=0;
00393   sha_info->offset=0;
00394 }
00395 
00396 /*
00397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00398 %                                                                             %
00399 %                                                                             %
00400 %                                                                             %
00401 %   T r a n s f o r m S H A                                                   %
00402 %                                                                             %
00403 %                                                                             %
00404 %                                                                             %
00405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00406 %
00407 %  TransformSHA256() transforms the SHA256 message accumulator.
00408 %
00409 %  The format of the TransformSHA256 method is:
00410 %
00411 %      TransformSHA256(SHA256Info *sha_info)
00412 %
00413 %  A description of each parameter follows:
00414 %
00415 %    o sha_info: The address of a structure of type SHA256Info.
00416 %
00417 */
00418 
00419 static inline unsigned int Ch(unsigned int x,unsigned int y,unsigned int z)
00420 {
00421   return((x & y) ^ (~x & z));
00422 }
00423 
00424 static inline unsigned int Maj(unsigned int x,unsigned int y,unsigned int z)
00425 {
00426   return((x & y) ^ (x & z) ^ (y & z));
00427 }
00428 
00429 static inline unsigned int Trunc32(unsigned int x)
00430 {
00431   return((unsigned int) (x & 0xffffffffU));
00432 }
00433 
00434 static unsigned int RotateRight(unsigned int x,unsigned int n)
00435 {
00436   return(Trunc32((x >> n) | (x << (32-n))));
00437 }
00438 
00439 static void TransformSHA256(SHA256Info *sha_info)
00440 {
00441 #define Sigma0(x)  (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
00442 #define Sigma1(x)  (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
00443 #define Suma0(x)  (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
00444 #define Suma1(x)  (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
00445 
00446   ssize_t
00447     j;
00448 
00449   register ssize_t
00450     i;
00451 
00452   register unsigned char
00453     *p;
00454 
00455   static unsigned int
00456     K[64] =
00457     {
00458       0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU,
00459       0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U,
00460       0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U,
00461       0xc19bf174U, 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU,
00462       0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U,
00463       0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U,
00464       0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU,
00465       0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U,
00466       0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,
00467       0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U,
00468       0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU,
00469       0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U,
00470       0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U
00471     };  /* 32-bit fractional part of the cube root of the first 64 primes */
00472 
00473   unsigned int
00474     A,
00475     B,
00476     C,
00477     D,
00478     E,
00479     F,
00480     G,
00481     H,
00482     shift,
00483     T,
00484     T1,
00485     T2,
00486     W[64];
00487 
00488   shift=32;
00489   p=GetStringInfoDatum(sha_info->message);
00490   if (sha_info->lsb_first == WizardFalse)
00491     {
00492       if (sizeof(unsigned int) <= 4)
00493         for (i=0; i < 16; i++)
00494         {
00495           T=(*((unsigned int *) p));
00496           p+=4;
00497           W[i]=Trunc32(T);
00498         }
00499       else
00500         for (i=0; i < 16; i+=2)
00501         {
00502           T=(*((unsigned int *) p));
00503           p+=8;
00504           W[i]=Trunc32(T >> shift);
00505           W[i+1]=Trunc32(T);
00506         }
00507     }
00508   else
00509     if (sizeof(unsigned int) <= 4)
00510       for (i=0; i < 16; i++)
00511       {
00512         T=(*((unsigned int *) p));
00513         p+=4;
00514         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00515           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00516       }
00517     else
00518       for (i=0; i < 16; i+=2)
00519       {
00520         T=(*((unsigned int *) p));
00521         p+=8;
00522         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00523           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00524         T>>=shift;
00525         W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00526           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00527       }
00528   /*
00529     Copy accumulator to registers.
00530   */
00531   A=sha_info->accumulator[0];
00532   B=sha_info->accumulator[1];
00533   C=sha_info->accumulator[2];
00534   D=sha_info->accumulator[3];
00535   E=sha_info->accumulator[4];
00536   F=sha_info->accumulator[5];
00537   G=sha_info->accumulator[6];
00538   H=sha_info->accumulator[7];
00539   for (i=16; i < 64; i++)
00540     W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
00541   for (j=0; j < 64; j++)
00542   {
00543     T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
00544     T2=Trunc32(Suma0(A)+Maj(A,B,C));
00545     H=G;
00546     G=F;
00547     F=E;
00548     E=Trunc32(D+T1);
00549     D=C;
00550     C=B;
00551     B=A;
00552     A=Trunc32(T1+T2);
00553   }
00554   /*
00555     Add registers back to accumulator.
00556   */
00557   sha_info->accumulator[0]=Trunc32(sha_info->accumulator[0]+A);
00558   sha_info->accumulator[1]=Trunc32(sha_info->accumulator[1]+B);
00559   sha_info->accumulator[2]=Trunc32(sha_info->accumulator[2]+C);
00560   sha_info->accumulator[3]=Trunc32(sha_info->accumulator[3]+D);
00561   sha_info->accumulator[4]=Trunc32(sha_info->accumulator[4]+E);
00562   sha_info->accumulator[5]=Trunc32(sha_info->accumulator[5]+F);
00563   sha_info->accumulator[6]=Trunc32(sha_info->accumulator[6]+G);
00564   sha_info->accumulator[7]=Trunc32(sha_info->accumulator[7]+H);
00565   /*
00566     Reset working registers.
00567   */
00568   A=0;
00569   B=0;
00570   C=0;
00571   D=0;
00572   E=0;
00573   F=0;
00574   G=0;
00575   H=0;
00576   T=0;
00577   T1=0;
00578   T2=0;
00579   (void) ResetWizardMemory(W,0,sizeof(W));
00580 }
00581 
00582 /*
00583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00584 %                                                                             %
00585 %                                                                             %
00586 %                                                                             %
00587 %   U p d a t e S H A                                                         %
00588 %                                                                             %
00589 %                                                                             %
00590 %                                                                             %
00591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00592 %
00593 %  UpdateSHA256() updates the SHA256 message accumulator.
00594 %
00595 %  The format of the UpdateSHA256 method is:
00596 %
00597 %      UpdateSHA256(SHA256Info *sha_info,const StringInfo *message)
00598 %
00599 %  A description of each parameter follows:
00600 %
00601 %    o sha_info: The address of a structure of type SHA256Info.
00602 %
00603 %    o message: The message.
00604 %
00605 */
00606 WizardExport void UpdateSHA256(SHA256Info *sha_info,const StringInfo *message)
00607 {
00608   register size_t
00609     i;
00610 
00611   register unsigned char
00612     *p;
00613 
00614   size_t
00615     n;
00616 
00617   unsigned int
00618     length;
00619 
00620   /*
00621     Update the SHA256 accumulator.
00622   */
00623   assert(sha_info != (SHA256Info *) NULL);
00624   assert(sha_info->signature == WizardSignature);
00625   n=GetStringInfoLength(message);
00626   length=Trunc32((unsigned int) (sha_info->low_order+(n << 3)));
00627   if (length < sha_info->low_order)
00628     sha_info->high_order++;
00629   sha_info->low_order=length;
00630   sha_info->high_order+=(unsigned int) (n >> 29);
00631   p=GetStringInfoDatum(message);
00632   if (sha_info->offset != 0)
00633     {
00634       i=GetStringInfoLength(sha_info->message)-sha_info->offset;
00635       if (i > n)
00636         i=n;
00637       (void) CopyWizardMemory(GetStringInfoDatum(sha_info->message)+
00638         sha_info->offset,p,i);
00639       n-=i;
00640       p+=i;
00641       sha_info->offset+=i;
00642       if (sha_info->offset != GetStringInfoLength(sha_info->message))
00643         return;
00644       TransformSHA256(sha_info);
00645     }
00646   while (n >= GetStringInfoLength(sha_info->message))
00647   {
00648     SetStringInfoDatum(sha_info->message,p);
00649     p+=GetStringInfoLength(sha_info->message);
00650     n-=GetStringInfoLength(sha_info->message);
00651     TransformSHA256(sha_info);
00652   }
00653   (void) CopyWizardMemory(GetStringInfoDatum(sha_info->message),p,n);
00654   sha_info->offset=n;
00655   /*
00656     Reset working registers.
00657   */
00658   i=0;
00659   n=0;
00660   length=0;
00661 }