WizardsToolkit  1.0.7
sha1.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.html
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/sha1.h"
00047 
00048 /*
00049   Define declarations.
00050 */
00051 #define SHA1Blocksize  64
00052 #define SHA1Digestsize  20
00053 
00054 /*
00055   Typedef declarations.
00056 */
00057 struct _SHA1Info
00058 {   
00059   unsigned int
00060     digestsize,
00061     blocksize;
00062 
00063   StringInfo
00064     *digest,
00065     *message;
00066 
00067   unsigned int
00068     *accumulator,
00069     low_order,
00070     high_order;
00071 
00072   size_t
00073     offset;
00074 
00075   WizardBooleanType
00076     lsb_first;
00077 
00078   time_t
00079     timestamp;
00080 
00081   size_t
00082     signature;
00083 };
00084 
00085 /*
00086   Forward declarations.
00087 */
00088 static void
00089   TransformSHA1(SHA1Info *);
00090 
00091 /*
00092 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00093 %                                                                             %
00094 %                                                                             %
00095 %                                                                             %
00096 %   A c q u i r e S H A I n f o                                               %
00097 %                                                                             %
00098 %                                                                             %
00099 %                                                                             %
00100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00101 %
00102 %  AcquireSHA1Info() allocate the SHA1Info structure.
00103 %
00104 %  The format of the AcquireSHA1Info method is:
00105 %
00106 %      SHA1Info *AcquireSHA1Info(void)
00107 %
00108 */
00109 WizardExport SHA1Info *AcquireSHA1Info(void)
00110 {
00111   SHA1Info
00112     *sha_info;
00113 
00114   unsigned int
00115     lsb_first;
00116 
00117   sha_info=(SHA1Info *) AcquireWizardMemory(sizeof(*sha_info));
00118   if (sha_info == (SHA1Info *) NULL)
00119     ThrowWizardFatalError(HashDomain,MemoryError);
00120   (void) ResetWizardMemory(sha_info,0,sizeof(*sha_info));
00121   sha_info->digestsize=SHA1Digestsize;
00122   sha_info->blocksize=SHA1Blocksize;
00123   sha_info->digest=AcquireStringInfo(SHA1Digestsize);
00124   sha_info->message=AcquireStringInfo(SHA1Blocksize);
00125   sha_info->accumulator=(unsigned int *) AcquireQuantumMemory(SHA1Blocksize,
00126     sizeof(*sha_info->accumulator));
00127   if (sha_info->accumulator == (unsigned int *) NULL)
00128     ThrowWizardFatalError(HashDomain,MemoryError);
00129   lsb_first=1;
00130   sha_info->lsb_first=(int)
00131     (*(char *) &lsb_first) == 1 ? WizardTrue : WizardFalse;
00132   sha_info->timestamp=time((time_t *) NULL);
00133   sha_info->signature=WizardSignature;
00134   InitializeSHA1(sha_info);
00135   return(sha_info);
00136 }
00137 
00138 /*
00139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00140 %                                                                             %
00141 %                                                                             %
00142 %                                                                             %
00143 %   D e s t r o y S H A I n f o                                               %
00144 %                                                                             %
00145 %                                                                             %
00146 %                                                                             %
00147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00148 %
00149 %  DestroySHA1Info() zeros memory associated with the SHA1Info structure.
00150 %
00151 %  The format of the DestroySHA1Info method is:
00152 %
00153 %      SHA1Info *DestroySHA1Info(SHA1Info *sha_info)
00154 %
00155 %  A description of each parameter follows:
00156 %
00157 %    o sha_info: The cipher sha_info.
00158 %
00159 */
00160 WizardExport SHA1Info *DestroySHA1Info(SHA1Info *sha_info)
00161 {
00162   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00163   assert(sha_info != (SHA1Info *) NULL);
00164   assert(sha_info->signature == WizardSignature);
00165   if (sha_info->accumulator != (unsigned int *) NULL)
00166     sha_info->accumulator=(unsigned int *)
00167       RelinquishWizardMemory(sha_info->accumulator);
00168   if (sha_info->message != (StringInfo *) NULL)
00169     sha_info->message=DestroyStringInfo(sha_info->message);
00170   if (sha_info->digest != (StringInfo *) NULL)
00171     sha_info->digest=DestroyStringInfo(sha_info->digest);
00172   sha_info->signature=(~WizardSignature);
00173   sha_info=(SHA1Info *) RelinquishWizardMemory(sha_info);
00174   return(sha_info);
00175 }
00176 
00177 /*
00178 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00179 %                                                                             %
00180 %                                                                             %
00181 %                                                                             %
00182 %   F i n a l i z e S H A                                                     %
00183 %                                                                             %
00184 %                                                                             %
00185 %                                                                             %
00186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00187 %
00188 %  FinalizeSHA1() finalizes the SHA1 message accumulator computation.
00189 %
00190 %  The format of the FinalizeSHA1 method is:
00191 %
00192 %      FinalizeSHA1(SHA1Info *sha_info)
00193 %
00194 %  A description of each parameter follows:
00195 %
00196 %    o sha_info: The address of a structure of type SHA1Info.
00197 %
00198 %
00199 */
00200 WizardExport void FinalizeSHA1(SHA1Info *sha_info)
00201 {
00202   register size_t
00203     i;
00204 
00205   register unsigned char
00206     *q;
00207 
00208   register unsigned int
00209     *p;
00210 
00211   size_t
00212     count;
00213 
00214   unsigned char
00215     *datum;
00216 
00217   unsigned int
00218     high_order,
00219     low_order;
00220 
00221   /*
00222     Add padding and return the message accumulator.
00223   */
00224   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00225   assert(sha_info != (SHA1Info *) NULL);
00226   assert(sha_info->signature == WizardSignature);
00227   low_order=sha_info->low_order;
00228   high_order=sha_info->high_order;
00229   count=(size_t) ((low_order >> 3) & 0x3f);
00230   datum=GetStringInfoDatum(sha_info->message);
00231   datum[count++]=(unsigned char) 0x80;
00232   if (count <= (GetStringInfoLength(sha_info->message)-8))
00233     (void) ResetWizardMemory(datum+count,0,GetStringInfoLength(
00234       sha_info->message)-8-count);
00235   else
00236     {
00237       (void) ResetWizardMemory(datum+count,0,GetStringInfoLength(
00238         sha_info->message)-count);
00239       TransformSHA1(sha_info);
00240       (void) ResetWizardMemory(datum,0,GetStringInfoLength(sha_info->message)-
00241         8);
00242     }
00243   datum[56]=(unsigned char) (high_order >> 24);
00244   datum[57]=(unsigned char) (high_order >> 16);
00245   datum[58]=(unsigned char) (high_order >> 8);
00246   datum[59]=(unsigned char) high_order;
00247   datum[60]=(unsigned char) (low_order >> 24);
00248   datum[61]=(unsigned char) (low_order >> 16);
00249   datum[62]=(unsigned char) (low_order >> 8);
00250   datum[63]=(unsigned char) low_order;
00251   TransformSHA1(sha_info);
00252   p=sha_info->accumulator;
00253   q=GetStringInfoDatum(sha_info->digest);
00254   for (i=0; i < (SHA1Digestsize/4); i++)
00255   {
00256     *q++=(unsigned char) ((*p >> 24) & 0xff);
00257     *q++=(unsigned char) ((*p >> 16) & 0xff);
00258     *q++=(unsigned char) ((*p >> 8) & 0xff);
00259     *q++=(unsigned char) (*p & 0xff);
00260     p++;
00261   }
00262   /*
00263     Reset working registers.
00264   */
00265   count=0;
00266   high_order=0;
00267   low_order=0;
00268 }
00269 
00270 /*
00271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00272 %                                                                             %
00273 %                                                                             %
00274 %                                                                             %
00275 %   G e t S H A 1 B l o c k s i z e                                           %
00276 %                                                                             %
00277 %                                                                             %
00278 %                                                                             %
00279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00280 %
00281 %  GetSHA1Blocksize() returns the SHA1 blocksize.
00282 %
00283 %  The format of the GetSHA1Blocksize method is:
00284 %
00285 %      unsigned int *GetSHA1Blocksize(const SHA1Info *sha1_info)
00286 %
00287 %  A description of each parameter follows:
00288 %
00289 %    o sha1_info: The sha1 info.
00290 %
00291 */
00292 WizardExport unsigned int GetSHA1Blocksize(const SHA1Info *sha1_info)
00293 {
00294   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00295   WizardAssert(CipherDomain,sha1_info != (SHA1Info *) NULL);
00296   WizardAssert(CipherDomain,sha1_info->signature == WizardSignature);
00297   return(sha1_info->blocksize);
00298 }
00299 
00300 /*
00301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00302 %                                                                             %
00303 %                                                                             %
00304 %                                                                             %
00305 %   G e t S H A 1 D i g e s t                                                 %
00306 %                                                                             %
00307 %                                                                             %
00308 %                                                                             %
00309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00310 %
00311 %  GetSHA1Digest() returns the SHA1 digest.
00312 %
00313 %  The format of the GetSHA1Digest method is:
00314 %
00315 %      const StringInfo *GetSHA1Digest(const SHA1Info *sha1_info)
00316 %
00317 %  A description of each parameter follows:
00318 %
00319 %    o sha1_info: The sha1 info.
00320 %
00321 */
00322 WizardExport const StringInfo *GetSHA1Digest(const SHA1Info *sha1_info)
00323 {
00324   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00325   WizardAssert(HashDomain,sha1_info != (SHA1Info *) NULL);
00326   WizardAssert(HashDomain,sha1_info->signature == WizardSignature);
00327   return(sha1_info->digest);
00328 }
00329 
00330 /*
00331 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00332 %                                                                             %
00333 %                                                                             %
00334 %                                                                             %
00335 %   G e t S H A 1 D i g e s t s i z e                                         %
00336 %                                                                             %
00337 %                                                                             %
00338 %                                                                             %
00339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00340 %
00341 %  GetSHA1Digestsize() returns the SHA1 digest size.
00342 %
00343 %  The format of the GetSHA1Digestsize method is:
00344 %
00345 %      unsigned int *GetSHA1Digestsize(const SHA1Info *sha1_info)
00346 %
00347 %  A description of each parameter follows:
00348 %
00349 %    o sha1_info: The sha1 info.
00350 %
00351 */
00352 WizardExport unsigned int GetSHA1Digestsize(const SHA1Info *sha1_info)
00353 {
00354   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00355   WizardAssert(CipherDomain,sha1_info != (SHA1Info *) NULL);
00356   WizardAssert(CipherDomain,sha1_info->signature == WizardSignature);
00357   return(sha1_info->digestsize);
00358 }
00359 
00360 /*
00361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00362 %                                                                             %
00363 %                                                                             %
00364 %                                                                             %
00365 %   I n i t i a l i z e S H A                                                 %
00366 %                                                                             %
00367 %                                                                             %
00368 %                                                                             %
00369 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00370 %
00371 %  IntializeSHA1() intializes the SHA1 accumulator.
00372 %
00373 %  The format of the DestroySHA1Info method is:
00374 %
00375 %      void InitializeSHA1Info(SHA1Info *sha_info)
00376 %
00377 %  A description of each parameter follows:
00378 %
00379 %    o sha_info: The cipher sha_info.
00380 %
00381 */
00382 WizardExport void InitializeSHA1(SHA1Info *sha_info)
00383 {
00384   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00385   assert(sha_info != (SHA1Info *) NULL);
00386   assert(sha_info->signature == WizardSignature);
00387   sha_info->accumulator[0]=0x67452301U;
00388   sha_info->accumulator[1]=0xefcdab89U;
00389   sha_info->accumulator[2]=0x98badcfeU;
00390   sha_info->accumulator[3]=0x10325476U;
00391   sha_info->accumulator[4]=0xc3d2e1f0U;
00392   sha_info->low_order=0;
00393   sha_info->high_order=0;
00394   sha_info->offset=0;
00395 }
00396 
00397 /*
00398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00399 %                                                                             %
00400 %                                                                             %
00401 %                                                                             %
00402 %   T r a n s f o r m S H A                                                   %
00403 %                                                                             %
00404 %                                                                             %
00405 %                                                                             %
00406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00407 %
00408 %  TransformSHA1() transforms the SHA1 message accumulator.
00409 %
00410 %  The format of the TransformSHA1 method is:
00411 %
00412 %      TransformSHA1(SHA1Info *sha_info)
00413 %
00414 %  A description of each parameter follows:
00415 %
00416 %    o sha_info: The address of a structure of type SHA1Info.
00417 %
00418 %
00419 */
00420 
00421 static inline unsigned int Trunc32(unsigned int x)
00422 {
00423   return(x & 0xffffffffU);
00424 }
00425 
00426 static unsigned int RotateLeft(unsigned int x,unsigned int n)
00427 {
00428   return(Trunc32((x << n) | (x >> (32-n))));
00429 }
00430 
00431 static void TransformSHA1(SHA1Info *sha_info)
00432 {
00433   register ssize_t
00434     i;
00435 
00436   register unsigned char
00437     *p;
00438 
00439   register unsigned int
00440     *q;
00441 
00442   unsigned int
00443     A,
00444     B,
00445     C,
00446     D,
00447     E,
00448     shift,
00449     T,
00450     W[80];
00451 
00452   shift=32;
00453   p=GetStringInfoDatum(sha_info->message);
00454   if (sha_info->lsb_first == WizardFalse)
00455     {
00456       if (sizeof(unsigned int) <= 4)
00457         for (i=0; i < 16; i++)
00458         {
00459           T=(*((unsigned int *) p));
00460           p+=4;
00461           W[i]=Trunc32(T);
00462         }
00463       else
00464         for (i=0; i < 16; i+=2)
00465         {
00466           T=(*((unsigned int *) p));
00467           p+=8;
00468           W[i]=Trunc32(T >> shift);
00469           W[i+1]=Trunc32(T);
00470         }
00471     }
00472   else
00473     if (sizeof(unsigned int) <= 4)
00474       for (i=0; i < 16; i++)
00475       {
00476         T=(*((unsigned int *) p));
00477         p+=4;
00478         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00479           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00480       }
00481     else
00482       for (i=0; i < 16; i+=2)
00483       {
00484         T=(*((unsigned int *) p));
00485         p+=8;
00486         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00487           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00488         T>>=shift;
00489         W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00490           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00491       }
00492   /*
00493     Copy accumulator to registers.
00494   */
00495   A=sha_info->accumulator[0];
00496   B=sha_info->accumulator[1];
00497   C=sha_info->accumulator[2];
00498   D=sha_info->accumulator[3];
00499   E=sha_info->accumulator[4];
00500   for (i=16; i < 80; i++)
00501   {
00502     W[i]=W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
00503     W[i]=RotateLeft(W[i],1);
00504   }
00505   q=W;
00506   for (i=0; i < 20; i++)
00507   {
00508     T=Trunc32(RotateLeft(A,5)+((B & C) | (~B & D))+E+(*q)+0x5a827999U);
00509     E=D;
00510     D=C;
00511     C=RotateLeft(B,30);
00512     B=A;
00513     A=T;
00514     q++;
00515   }
00516   for ( ; i < 40; i++)
00517   {
00518     T=Trunc32(RotateLeft(A,5)+(B ^ C ^ D)+E+(*q)+0x6ed9eba1U);
00519     E=D;
00520     D=C;
00521     C=RotateLeft(B,30);
00522     B=A;
00523     A=T;
00524     q++;
00525   }
00526   for ( ; i < 60; i++)
00527   {
00528     T=Trunc32(RotateLeft(A,5)+((B & C) | (B & D) | (C & D))+E+(*q)+
00529       0x8F1bbcdcU);
00530     E=D;
00531     D=C;
00532     C=RotateLeft(B,30);
00533     B=A;
00534     A=T;
00535     q++;
00536   }
00537   for ( ; i < 80; i++)
00538   {
00539     T=Trunc32(RotateLeft(A,5)+(B ^ C ^ D)+E+(*q)+0xca62c1d6U);
00540     E=D;
00541     D=C;
00542     C=RotateLeft(B,30);
00543     B=A;
00544     A=T;
00545     q++;
00546   }
00547   /*
00548     Add registers back to accumulator.
00549   */
00550   sha_info->accumulator[0]=Trunc32(sha_info->accumulator[0]+A);
00551   sha_info->accumulator[1]=Trunc32(sha_info->accumulator[1]+B);
00552   sha_info->accumulator[2]=Trunc32(sha_info->accumulator[2]+C);
00553   sha_info->accumulator[3]=Trunc32(sha_info->accumulator[3]+D);
00554   sha_info->accumulator[4]=Trunc32(sha_info->accumulator[4]+E);
00555   /*
00556     Reset working registers.
00557   */
00558   A=0;
00559   B=0;
00560   C=0;
00561   D=0;
00562   E=0;
00563   T=0;
00564   (void) ResetWizardMemory(W,0,sizeof(W));
00565 }
00566 
00567 /*
00568 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00569 %                                                                             %
00570 %                                                                             %
00571 %                                                                             %
00572 %   U p d a t e S H A                                                         %
00573 %                                                                             %
00574 %                                                                             %
00575 %                                                                             %
00576 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00577 %
00578 %  UpdateSHA1() updates the SHA1 message accumulator.
00579 %
00580 %  The format of the UpdateSHA1 method is:
00581 %
00582 %      UpdateSHA1(SHA1Info *sha_info,const StringInfo *message)
00583 %
00584 %  A description of each parameter follows:
00585 %
00586 %    o sha_info: The address of a structure of type SHA1Info.
00587 %
00588 %    o message: The message
00589 %
00590 */
00591 WizardExport void UpdateSHA1(SHA1Info *sha_info,const StringInfo *message)
00592 {
00593   register size_t
00594     i;
00595 
00596   register unsigned char
00597     *p;
00598 
00599   size_t
00600     n;
00601 
00602   unsigned int
00603     length;
00604 
00605   /*
00606     Update the SHA1 accumulator.
00607   */
00608   assert(sha_info != (SHA1Info *) NULL);
00609   assert(sha_info->signature == WizardSignature);
00610   n=GetStringInfoLength(message);
00611   length=Trunc32((unsigned int) (sha_info->low_order+(n << 3)));
00612   if (length < sha_info->low_order)
00613     sha_info->high_order++;
00614   sha_info->low_order=length;
00615   sha_info->high_order+=(unsigned int) (n >> 29);
00616   p=GetStringInfoDatum(message);
00617   if (sha_info->offset != 0)
00618     {
00619       i=GetStringInfoLength(sha_info->message)-sha_info->offset;
00620       if (i > n)
00621         i=n;
00622       (void) CopyWizardMemory(GetStringInfoDatum(sha_info->message)+
00623         sha_info->offset,p,i);
00624       n-=i;
00625       p+=i;
00626       sha_info->offset+=i;
00627       if (sha_info->offset != GetStringInfoLength(sha_info->message))
00628         return;
00629       TransformSHA1(sha_info);
00630     }
00631   while (n >= GetStringInfoLength(sha_info->message))
00632   {
00633     SetStringInfoDatum(sha_info->message,p);
00634     p+=GetStringInfoLength(sha_info->message);
00635     n-=GetStringInfoLength(sha_info->message);
00636     TransformSHA1(sha_info);
00637   }
00638   (void) CopyWizardMemory(GetStringInfoDatum(sha_info->message),p,n);
00639   sha_info->offset=n;
00640   /*
00641     Reset working registers.
00642   */
00643   i=0;
00644   n=0;
00645   length=0;
00646 }