WizardsToolkit  1.0.7
sha384.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-384 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/sha384.h"
00047 /*
00048   Define declarations.
00049 */
00050 #define SHA384Blocksize  128
00051 #define SHA384Digestsize  48
00052 
00053 /*
00054   Typedef declarations.
00055 */
00056 struct _SHA384Info
00057 {   
00058   unsigned int
00059     digestsize,
00060     blocksize;
00061 
00062   StringInfo
00063     *digest,
00064     *message;
00065 
00066   WizardSizeType
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   TransformSHA384(SHA384Info *);
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 %  AcquireSHA384Info() allocate the SHA384Info structure.
00102 %
00103 %  The format of the AcquireSHA384Info method is:
00104 %
00105 %      SHA384Info *AcquireSHA384Info(void)
00106 %
00107 */
00108 WizardExport SHA384Info *AcquireSHA384Info(void)
00109 {
00110   SHA384Info
00111     *sha_info;
00112 
00113   unsigned int
00114     lsb_first;
00115 
00116   sha_info=(SHA384Info *) AcquireWizardMemory(sizeof(*sha_info));
00117   if (sha_info == (SHA384Info *) NULL)
00118     ThrowWizardFatalError(HashError,MemoryError);
00119   (void) ResetWizardMemory(sha_info,0,sizeof(*sha_info));
00120   sha_info->digestsize=SHA384Digestsize;
00121   sha_info->blocksize=SHA384Blocksize;
00122   sha_info->digest=AcquireStringInfo(SHA384Digestsize);
00123   sha_info->message=AcquireStringInfo(SHA384Blocksize);
00124   sha_info->accumulator=(WizardSizeType *) AcquireQuantumMemory(SHA384Blocksize,
00125     sizeof(*sha_info->accumulator));
00126   if (sha_info->accumulator == (WizardSizeType *) NULL)
00127     ThrowWizardFatalError(HashError,MemoryError);
00128   lsb_first=1;
00129   sha_info->lsb_first=(int)
00130     (*(char *) &lsb_first) == 1 ? WizardTrue : WizardFalse;
00131   sha_info->timestamp=time((time_t *) NULL);
00132   sha_info->signature=WizardSignature;
00133   InitializeSHA384(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 %  DestroySHA384Info() zeros memory associated with the SHA384Info structure.
00149 %
00150 %  The format of the DestroySHA384Info method is:
00151 %
00152 %      SHA384Info *DestroySHA384Info(SHA384Info *sha_info)
00153 %
00154 %  A description of each parameter follows:
00155 %
00156 %    o sha_info: The cipher sha_info.
00157 %
00158 */
00159 WizardExport SHA384Info *DestroySHA384Info(SHA384Info *sha_info)
00160 {
00161   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00162   assert(sha_info != (SHA384Info *) NULL);
00163   assert(sha_info->signature == WizardSignature);
00164   if (sha_info->accumulator != (WizardSizeType *) NULL)
00165     sha_info->accumulator=(WizardSizeType *)
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=(SHA384Info *) 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 %  FinalizeSHA384() finalizes the SHA384 message accumulator computation.
00188 %
00189 %  The format of the FinalizeSHA384 method is:
00190 %
00191 %      FinalizeSHA384(SHA384Info *sha_info)
00192 %
00193 %  A description of each parameter follows:
00194 %
00195 %    o sha_info: The address of a structure of type SHA384Info.
00196 %
00197 %
00198 */
00199 WizardExport void FinalizeSHA384(SHA384Info *sha_info)
00200 {
00201   register size_t
00202     i;
00203 
00204   register unsigned char
00205     *q;
00206 
00207   register WizardSizeType
00208     *p;
00209 
00210   unsigned char
00211     *datum;
00212 
00213   WizardSizeType
00214     count,
00215     high_order,
00216     low_order;
00217 
00218   /*
00219     Add padding and return the message accumulator.
00220   */
00221   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00222   assert(sha_info != (SHA384Info *) NULL);
00223   assert(sha_info->signature == WizardSignature);
00224   low_order=sha_info->low_order;
00225   high_order=sha_info->high_order;
00226   count=(low_order >> 3) & 0x7f;
00227   datum=GetStringInfoDatum(sha_info->message);
00228   datum[count++]=(unsigned char) 0x80;
00229   if (count <= (WizardSizeType) (GetStringInfoLength(sha_info->message)-16))
00230     (void) ResetWizardMemory(datum+count,0,(size_t) (GetStringInfoLength(
00231       sha_info->message)-16-count));
00232   else
00233     {
00234       (void) ResetWizardMemory(datum+count,0,(size_t) (GetStringInfoLength(
00235         sha_info->message)-count));
00236       TransformSHA384(sha_info);
00237       (void) ResetWizardMemory(datum,0,
00238         (size_t) (GetStringInfoLength(sha_info->message)-16));
00239     }
00240   datum[112]=(unsigned char) (high_order >> 56);
00241   datum[113]=(unsigned char) (high_order >> 48);
00242   datum[114]=(unsigned char) (high_order >> 40);
00243   datum[115]=(unsigned char) (high_order >> 32);
00244   datum[116]=(unsigned char) (high_order >> 24);
00245   datum[117]=(unsigned char) (high_order >> 16);
00246   datum[118]=(unsigned char) (high_order >> 8);
00247   datum[119]=(unsigned char) high_order;
00248   datum[120]=(unsigned char) (low_order >> 56);
00249   datum[121]=(unsigned char) (low_order >> 48);
00250   datum[122]=(unsigned char) (low_order >> 40);
00251   datum[123]=(unsigned char) (low_order >> 32);
00252   datum[124]=(unsigned char) (low_order >> 24);
00253   datum[125]=(unsigned char) (low_order >> 16);
00254   datum[126]=(unsigned char) (low_order >> 8);
00255   datum[127]=(unsigned char) low_order;
00256   TransformSHA384(sha_info);
00257   p=sha_info->accumulator;
00258   q=GetStringInfoDatum(sha_info->digest);
00259   for (i=0; i < (SHA384Digestsize/8); i++)
00260   {
00261     *q++=(unsigned char) ((*p >> 56) & 0xff);
00262     *q++=(unsigned char) ((*p >> 48) & 0xff);
00263     *q++=(unsigned char) ((*p >> 40) & 0xff);
00264     *q++=(unsigned char) ((*p >> 32) & 0xff);
00265     *q++=(unsigned char) ((*p >> 24) & 0xff);
00266     *q++=(unsigned char) ((*p >> 16) & 0xff);
00267     *q++=(unsigned char) ((*p >> 8) & 0xff);
00268     *q++=(unsigned char) (*p & 0xff);
00269     p++;
00270   }
00271   /*
00272     Reset working registers.
00273   */
00274   count=0;
00275   high_order=0;
00276   low_order=0;
00277 }
00278 
00279 /*
00280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00281 %                                                                             %
00282 %                                                                             %
00283 %                                                                             %
00284 %   G e t S H A 3 8 4 B l o c k s i z e                                       %
00285 %                                                                             %
00286 %                                                                             %
00287 %                                                                             %
00288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00289 %
00290 %  GetSHA384Blocksize() returns the SHA384 blocksize.
00291 %
00292 %  The format of the GetSHA384Blocksize method is:
00293 %
00294 %      unsigned int *GetSHA384Blocksize(const SHA384Info *sha384_info)
00295 %
00296 %  A description of each parameter follows:
00297 %
00298 %    o sha384_info: The sha384 info.
00299 %
00300 */
00301 WizardExport unsigned int GetSHA384Blocksize(const SHA384Info *sha384_info)
00302 {
00303   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00304   WizardAssert(CipherDomain,sha384_info != (SHA384Info *) NULL);
00305   WizardAssert(CipherDomain,sha384_info->signature == WizardSignature);
00306   return(sha384_info->blocksize);
00307 }
00308 
00309 /*
00310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00311 %                                                                             %
00312 %                                                                             %
00313 %                                                                             %
00314 %   G e t S H A 3 8 4 D i g e s t                                             %
00315 %                                                                             %
00316 %                                                                             %
00317 %                                                                             %
00318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00319 %
00320 %  GetSHA384Digest() returns the SHA384 digest.
00321 %
00322 %  The format of the GetSHA384Digest method is:
00323 %
00324 %      const StringInfo *GetSHA384Digest(const SHA384Info *sha384_info)
00325 %
00326 %  A description of each parameter follows:
00327 %
00328 %    o sha384_info: The sha384 info.
00329 %
00330 */
00331 WizardExport const StringInfo *GetSHA384Digest(const SHA384Info *sha384_info)
00332 {
00333   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00334   WizardAssert(HashDomain,sha384_info != (SHA384Info *) NULL);
00335   WizardAssert(HashDomain,sha384_info->signature == WizardSignature);
00336   return(sha384_info->digest);
00337 }
00338 
00339 /*
00340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00341 %                                                                             %
00342 %                                                                             %
00343 %                                                                             %
00344 %   G e t S H A 3 8 4 D i g e s t s i z e                                     %
00345 %                                                                             %
00346 %                                                                             %
00347 %                                                                             %
00348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00349 %
00350 %  GetSHA384Digestsize() returns the SHA384 digest size.
00351 %
00352 %  The format of the GetSHA384Digestsize method is:
00353 %
00354 %      unsigned int *GetSHA384Digestsize(const SHA384Info *sha384_info)
00355 %
00356 %  A description of each parameter follows:
00357 %
00358 %    o sha384_info: The sha384 info.
00359 %
00360 */
00361 WizardExport unsigned int GetSHA384Digestsize(const SHA384Info *sha384_info)
00362 {
00363   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00364   WizardAssert(CipherDomain,sha384_info != (SHA384Info *) NULL);
00365   WizardAssert(CipherDomain,sha384_info->signature == WizardSignature);
00366   return(sha384_info->digestsize);
00367 }
00368 
00369 /*
00370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00371 %                                                                             %
00372 %                                                                             %
00373 %                                                                             %
00374 %   I n i t i a l i z e S H A                                                 %
00375 %                                                                             %
00376 %                                                                             %
00377 %                                                                             %
00378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00379 %
00380 %  IntializeSHA384() intializes the SHA384 accumulator.
00381 %
00382 %  The format of the DestroySHA384Info method is:
00383 %
00384 %      void InitializeSHA384Info(SHA384Info *sha_info)
00385 %
00386 %  A description of each parameter follows:
00387 %
00388 %    o sha_info: The cipher sha_info.
00389 %
00390 */
00391 WizardExport void InitializeSHA384(SHA384Info *sha_info)
00392 {
00393   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00394   assert(sha_info != (SHA384Info *) NULL);
00395   assert(sha_info->signature == WizardSignature);
00396   sha_info->accumulator[0]=WizardULLConstant(0xcbbb9d5dc1059ed8);
00397   sha_info->accumulator[1]=WizardULLConstant(0x629a292a367cd507);
00398   sha_info->accumulator[2]=WizardULLConstant(0x9159015a3070dd17);
00399   sha_info->accumulator[3]=WizardULLConstant(0x152fecd8f70e5939);
00400   sha_info->accumulator[4]=WizardULLConstant(0x67332667ffc00b31);
00401   sha_info->accumulator[5]=WizardULLConstant(0x8eb44a8768581511);
00402   sha_info->accumulator[6]=WizardULLConstant(0xdb0c2e0d64f98fa7);
00403   sha_info->accumulator[7]=WizardULLConstant(0x47b5481dbefa4fa4);
00404   sha_info->low_order=0;
00405   sha_info->high_order=0;
00406   sha_info->offset=0;
00407 }
00408 
00409 /*
00410 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00411 %                                                                             %
00412 %                                                                             %
00413 %                                                                             %
00414 %   T r a n s f o r m S H A                                                   %
00415 %                                                                             %
00416 %                                                                             %
00417 %                                                                             %
00418 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00419 %
00420 %  TransformSHA384() transforms the SHA384 message accumulator.
00421 %
00422 %  The format of the TransformSHA384 method is:
00423 %
00424 %      TransformSHA384(SHA384Info *sha_info)
00425 %
00426 %  A description of each parameter follows:
00427 %
00428 %    o sha_info: The address of a structure of type SHA384Info.
00429 %
00430 %
00431 */
00432 
00433 static inline WizardSizeType Ch(WizardSizeType x,WizardSizeType y,WizardSizeType z)
00434 {
00435   return((x & y) ^ (~x & z));
00436 }
00437 
00438 static inline WizardSizeType Maj(WizardSizeType x, WizardSizeType y,WizardSizeType z)
00439 {
00440   return((x & y) ^ (x & z) ^ (y & z));
00441 }
00442 
00443 static inline WizardSizeType Trunc64(WizardSizeType x)
00444 {
00445   return((WizardSizeType) (x & WizardULLConstant(0xffffffffffffffff)));
00446 }
00447 
00448 static WizardSizeType RotateRight(WizardSizeType x,WizardSizeType n)
00449 {
00450   return(Trunc64((x >> n) | (x << (64-n))));
00451 }
00452 
00453 static void TransformSHA384(SHA384Info *sha_info)
00454 {
00455 #define Sigma0(x)  (RotateRight(x,1) ^ RotateRight(x,8) ^ Trunc64((x) >> 7))
00456 #define Sigma1(x)  (RotateRight(x,19) ^ RotateRight(x,61) ^ Trunc64((x) >> 6))
00457 #define Suma0(x)  (RotateRight(x,28) ^ RotateRight(x,34) ^ RotateRight(x,39))
00458 #define Suma1(x)  (RotateRight(x,14) ^ RotateRight(x,18) ^ RotateRight(x,41))
00459 
00460   ssize_t
00461     j;
00462 
00463   register ssize_t
00464     i;
00465 
00466   register unsigned char
00467     *p;
00468 
00469   static WizardSizeType
00470     K[80] =
00471     {
00472       WizardULLConstant(0x428a2f98d728ae22),
00473       WizardULLConstant(0x7137449123ef65cd),
00474       WizardULLConstant(0xb5c0fbcfec4d3b2f),
00475       WizardULLConstant(0xe9b5dba58189dbbc),
00476       WizardULLConstant(0x3956c25bf348b538),
00477       WizardULLConstant(0x59f111f1b605d019),
00478       WizardULLConstant(0x923f82a4af194f9b),
00479       WizardULLConstant(0xab1c5ed5da6d8118),
00480       WizardULLConstant(0xd807aa98a3030242),
00481       WizardULLConstant(0x12835b0145706fbe),
00482       WizardULLConstant(0x243185be4ee4b28c),
00483       WizardULLConstant(0x550c7dc3d5ffb4e2),
00484       WizardULLConstant(0x72be5d74f27b896f),
00485       WizardULLConstant(0x80deb1fe3b1696b1),
00486       WizardULLConstant(0x9bdc06a725c71235),
00487       WizardULLConstant(0xc19bf174cf692694),
00488       WizardULLConstant(0xe49b69c19ef14ad2),
00489       WizardULLConstant(0xefbe4786384f25e3),
00490       WizardULLConstant(0x0fc19dc68b8cd5b5),
00491       WizardULLConstant(0x240ca1cc77ac9c65),
00492       WizardULLConstant(0x2de92c6f592b0275),
00493       WizardULLConstant(0x4a7484aa6ea6e483),
00494       WizardULLConstant(0x5cb0a9dcbd41fbd4),
00495       WizardULLConstant(0x76f988da831153b5),
00496       WizardULLConstant(0x983e5152ee66dfab),
00497       WizardULLConstant(0xa831c66d2db43210),
00498       WizardULLConstant(0xb00327c898fb213f),
00499       WizardULLConstant(0xbf597fc7beef0ee4),
00500       WizardULLConstant(0xc6e00bf33da88fc2),
00501       WizardULLConstant(0xd5a79147930aa725),
00502       WizardULLConstant(0x06ca6351e003826f),
00503       WizardULLConstant(0x142929670a0e6e70),
00504       WizardULLConstant(0x27b70a8546d22ffc),
00505       WizardULLConstant(0x2e1b21385c26c926),
00506       WizardULLConstant(0x4d2c6dfc5ac42aed),
00507       WizardULLConstant(0x53380d139d95b3df),
00508       WizardULLConstant(0x650a73548baf63de),
00509       WizardULLConstant(0x766a0abb3c77b2a8),
00510       WizardULLConstant(0x81c2c92e47edaee6),
00511       WizardULLConstant(0x92722c851482353b),
00512       WizardULLConstant(0xa2bfe8a14cf10364),
00513       WizardULLConstant(0xa81a664bbc423001),
00514       WizardULLConstant(0xc24b8b70d0f89791),
00515       WizardULLConstant(0xc76c51a30654be30),
00516       WizardULLConstant(0xd192e819d6ef5218),
00517       WizardULLConstant(0xd69906245565a910),
00518       WizardULLConstant(0xf40e35855771202a),
00519       WizardULLConstant(0x106aa07032bbd1b8),
00520       WizardULLConstant(0x19a4c116b8d2d0c8),
00521       WizardULLConstant(0x1e376c085141ab53),
00522       WizardULLConstant(0x2748774cdf8eeb99),
00523       WizardULLConstant(0x34b0bcb5e19b48a8),
00524       WizardULLConstant(0x391c0cb3c5c95a63),
00525       WizardULLConstant(0x4ed8aa4ae3418acb),
00526       WizardULLConstant(0x5b9cca4f7763e373),
00527       WizardULLConstant(0x682e6ff3d6b2b8a3),
00528       WizardULLConstant(0x748f82ee5defb2fc),
00529       WizardULLConstant(0x78a5636f43172f60),
00530       WizardULLConstant(0x84c87814a1f0ab72),
00531       WizardULLConstant(0x8cc702081a6439ec),
00532       WizardULLConstant(0x90befffa23631e28),
00533       WizardULLConstant(0xa4506cebde82bde9),
00534       WizardULLConstant(0xbef9a3f7b2c67915),
00535       WizardULLConstant(0xc67178f2e372532b),
00536       WizardULLConstant(0xca273eceea26619c),
00537       WizardULLConstant(0xd186b8c721c0c207),
00538       WizardULLConstant(0xeada7dd6cde0eb1e),
00539       WizardULLConstant(0xf57d4f7fee6ed178),
00540       WizardULLConstant(0x06f067aa72176fba),
00541       WizardULLConstant(0x0a637dc5a2c898a6),
00542       WizardULLConstant(0x113f9804bef90dae),
00543       WizardULLConstant(0x1b710b35131c471b),
00544       WizardULLConstant(0x28db77f523047d84),
00545       WizardULLConstant(0x32caab7b40c72493),
00546       WizardULLConstant(0x3c9ebe0a15c9bebc),
00547       WizardULLConstant(0x431d67c49c100d4c),
00548       WizardULLConstant(0x4cc5d4becb3e42b6),
00549       WizardULLConstant(0x597f299cfc657e2a),
00550       WizardULLConstant(0x5fcb6fab3ad6faec),
00551       WizardULLConstant(0x6c44198c4a475817)
00552     };  /* 64-bit fractional part of the cube root of the first 64 primes */
00553 
00554   WizardSizeType
00555     A,
00556     B,
00557     C,
00558     D,
00559     E,
00560     F,
00561     G,
00562     H,
00563     T,
00564     T1,
00565     T2,
00566     W[80];
00567 
00568   p=GetStringInfoDatum(sha_info->message);
00569   if (sha_info->lsb_first == WizardFalse)
00570     for (i=0; i < 16; i++)
00571     {
00572       T=(*((WizardSizeType *) p));
00573       p+=8;
00574       W[i]=(T);
00575     }
00576   else
00577     {
00578       for (i=0; i < 16; i++)
00579       {
00580         T=(*((WizardSizeType *) p));
00581         p+=8;
00582         W[i]=(WizardSizeType)
00583           (((T << 56) & WizardULLConstant(0xff00000000000000)) |
00584            ((T << 40) & WizardULLConstant(0x00ff000000000000)) |
00585            ((T << 24) & WizardULLConstant(0x0000ff0000000000)) |
00586            ((T <<  8) & WizardULLConstant(0x000000ff00000000)) |
00587            ((T >>  8) & WizardULLConstant(0x00000000ff000000)) |
00588            ((T >> 24) & WizardULLConstant(0x0000000000ff0000)) |
00589            ((T >> 40) & WizardULLConstant(0x000000000000ff00)) |
00590            ((T >> 56) & WizardULLConstant(0x00000000000000ff)));
00591       }
00592     }
00593   /*
00594     Copy accumulator to registers.
00595   */
00596   A=sha_info->accumulator[0];
00597   B=sha_info->accumulator[1];
00598   C=sha_info->accumulator[2];
00599   D=sha_info->accumulator[3];
00600   E=sha_info->accumulator[4];
00601   F=sha_info->accumulator[5];
00602   G=sha_info->accumulator[6];
00603   H=sha_info->accumulator[7];
00604   for (i=16; i < 80; i++)
00605     W[i]=Trunc64(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
00606   for (j=0; j < 80; j++)
00607   {
00608     T1=Trunc64(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
00609     T2=Trunc64(Suma0(A)+Maj(A,B,C));
00610     H=G;
00611     G=F;
00612     F=E;
00613     E=Trunc64(D+T1);
00614     D=C;
00615     C=B;
00616     B=A;
00617     A=Trunc64(T1+T2);
00618   }
00619   /*
00620     Add registers back to accumulator.
00621   */
00622   sha_info->accumulator[0]=Trunc64(sha_info->accumulator[0]+A);
00623   sha_info->accumulator[1]=Trunc64(sha_info->accumulator[1]+B);
00624   sha_info->accumulator[2]=Trunc64(sha_info->accumulator[2]+C);
00625   sha_info->accumulator[3]=Trunc64(sha_info->accumulator[3]+D);
00626   sha_info->accumulator[4]=Trunc64(sha_info->accumulator[4]+E);
00627   sha_info->accumulator[5]=Trunc64(sha_info->accumulator[5]+F);
00628   sha_info->accumulator[6]=Trunc64(sha_info->accumulator[6]+G);
00629   sha_info->accumulator[7]=Trunc64(sha_info->accumulator[7]+H);
00630   /*
00631     Reset working registers.
00632   */
00633   A=0;
00634   B=0;
00635   C=0;
00636   D=0;
00637   E=0;
00638   F=0;
00639   G=0;
00640   H=0;
00641   T=0;
00642   T1=0;
00643   T2=0;
00644   (void) ResetWizardMemory(W,0,sizeof(W));
00645 }
00646 
00647 /*
00648 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00649 %                                                                             %
00650 %                                                                             %
00651 %                                                                             %
00652 %   U p d a t e S H A                                                         %
00653 %                                                                             %
00654 %                                                                             %
00655 %                                                                             %
00656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00657 %
00658 %  UpdateSHA384() updates the SHA384 message accumulator.
00659 %
00660 %  The format of the UpdateSHA384 method is:
00661 %
00662 %      UpdateSHA384(SHA384Info *sha_info,const StringInfo *message)
00663 %
00664 %  A description of each parameter follows:
00665 %
00666 %    o sha_info: The address of a structure of type SHA384Info.
00667 %
00668 %    o message: The message.
00669 %
00670 */
00671 WizardExport void UpdateSHA384(SHA384Info *sha_info,const StringInfo *message)
00672 {
00673   register size_t
00674     i;
00675 
00676   register unsigned char
00677     *p;
00678 
00679   WizardSizeType
00680     length,
00681     n;
00682 
00683   /*
00684     Update the SHA384 accumulator.
00685   */
00686   assert(sha_info != (SHA384Info *) NULL);
00687   assert(sha_info->signature == WizardSignature);
00688   n=(WizardSizeType) GetStringInfoLength(message);
00689   length=Trunc64(sha_info->low_order+(n << 3));
00690   if (length < sha_info->low_order)
00691     sha_info->high_order++;
00692   sha_info->low_order=length;
00693   sha_info->high_order+=(n >> 61);
00694   p=GetStringInfoDatum(message);
00695   if (sha_info->offset != 0)
00696     {
00697       i=GetStringInfoLength(sha_info->message)-sha_info->offset;
00698       if ((WizardSizeType) i > n)
00699         i=(size_t) n;
00700       (void) CopyWizardMemory(GetStringInfoDatum(sha_info->message)+
00701         sha_info->offset,p,i);
00702       n-=i;
00703       p+=i;
00704       sha_info->offset+=i;
00705       if (sha_info->offset != GetStringInfoLength(sha_info->message))
00706         return;
00707       TransformSHA384(sha_info);
00708     }
00709   while (n >= (WizardSizeType) GetStringInfoLength(sha_info->message))
00710   {
00711     SetStringInfoDatum(sha_info->message,p);
00712     p+=GetStringInfoLength(sha_info->message);
00713     n-=GetStringInfoLength(sha_info->message);
00714     TransformSHA384(sha_info);
00715   }
00716   (void) CopyWizardMemory(GetStringInfoDatum(sha_info->message),p,(size_t) n);
00717   sha_info->offset=(size_t) n;
00718   /*
00719     Reset working registers.
00720   */
00721   i=0;
00722   n=0;
00723   length=0;
00724 }