signature.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %        SSSSS  IIIII   GGGG  N   N   AAA   TTTTT  U   U  RRRR   EEEEE        %
00006 %        SS       I    G      NN  N  A   A    T    U   U  R   R  E            %
00007 %         SSS     I    G  GG  N N N  AAAAA    T    U   U  RRRR   EEE          %
00008 %           SS    I    G   G  N  NN  A   A    T    U   U  R R    E            %
00009 %        SSSSS  IIIII   GGG   N   N  A   A    T     UUU   R  R   EEEEE        %
00010 %                                                                             %
00011 %                                                                             %
00012 %         MagickCore Methods to Compute a Message Digest for an Image         %
00013 %                                                                             %
00014 %                             Software Design                                 %
00015 %                               John Cristy                                   %
00016 %                              December 1992                                  %
00017 %                                                                             %
00018 %                                                                             %
00019 %  Copyright 1999-2008 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.imagemagick.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 %
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
00041 */
00042 #include "magick/studio.h"
00043 #include "magick/cache.h"
00044 #include "magick/exception.h"
00045 #include "magick/exception-private.h"
00046 #include "magick/property.h"
00047 #include "magick/image.h"
00048 #include "magick/memory_.h"
00049 #include "magick/quantum.h"
00050 #include "magick/quantum-private.h"
00051 #include "magick/signature.h"
00052 #include "magick/signature-private.h"
00053 #include "magick/string_.h"
00054 /*
00055   Define declarations.
00056 */
00057 #define SignatureBlocksize  64
00058 #define SignatureDigestsize  32
00059 
00060 /*
00061   Typedef declarations.
00062 */
00063 struct _SignatureInfo
00064 {   
00065   unsigned int
00066     digestsize,
00067     blocksize;
00068 
00069   StringInfo
00070     *digest,
00071     *message;
00072 
00073   unsigned int
00074     *accumulator,
00075     low_order,
00076     high_order;
00077 
00078   size_t
00079     offset;
00080 
00081   MagickBooleanType
00082     lsb_first;
00083 
00084   long
00085     timestamp;
00086 
00087   unsigned long
00088     signature;
00089 };
00090 
00091 /*
00092   Forward declarations.
00093 */
00094 static void
00095   TransformSignature(SignatureInfo *);
00096 
00097 /*
00098 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00099 %                                                                             %
00100 %                                                                             %
00101 %                                                                             %
00102 +   A c q u i r e S i g n a t u r e I n f o                                   %
00103 %                                                                             %
00104 %                                                                             %
00105 %                                                                             %
00106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00107 %
00108 %  AcquireSignatureInfo() allocate the SignatureInfo structure.
00109 %
00110 %  The format of the AcquireSignatureInfo method is:
00111 %
00112 %      SignatureInfo *AcquireSignatureInfo(void)
00113 %
00114 */
00115 MagickExport SignatureInfo *AcquireSignatureInfo(void)
00116 {
00117   SignatureInfo
00118     *signature_info;
00119 
00120   unsigned int
00121     lsb_first;
00122 
00123   signature_info=(SignatureInfo *) AcquireMagickMemory(sizeof(*signature_info));
00124   if (signature_info == (SignatureInfo *) NULL)
00125     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00126   (void) ResetMagickMemory(signature_info,0,sizeof(*signature_info));
00127   signature_info->digestsize=SignatureDigestsize;
00128   signature_info->blocksize=SignatureBlocksize;
00129   signature_info->digest=AcquireStringInfo(SignatureDigestsize);
00130   signature_info->message=AcquireStringInfo(SignatureBlocksize);
00131   signature_info->accumulator=(unsigned int *) AcquireQuantumMemory(
00132     SignatureBlocksize,sizeof(*signature_info->accumulator));
00133   if (signature_info->accumulator == (unsigned int *) NULL)
00134     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00135   lsb_first=1;
00136   signature_info->lsb_first=(int) (*(char *) &lsb_first) == 1 ? MagickTrue :
00137     MagickFalse;
00138   signature_info->timestamp=(long) time(0);
00139   signature_info->signature=MagickSignature;
00140   InitializeSignature(signature_info);
00141   return(signature_info);
00142 }
00143 
00144 /*
00145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00146 %                                                                             %
00147 %                                                                             %
00148 %                                                                             %
00149 +   D e s t r o y S i g n a t u r e I n f o                                   %
00150 %                                                                             %
00151 %                                                                             %
00152 %                                                                             %
00153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00154 %
00155 %  DestroySignatureInfo() zeros memory associated with the SignatureInfo
00156 %  structure.
00157 %
00158 %  The format of the DestroySignatureInfo method is:
00159 %
00160 %      SignatureInfo *DestroySignatureInfo(SignatureInfo *signature_info)
00161 %
00162 %  A description of each parameter follows:
00163 %
00164 %    o signature_info: the cipher signature_info.
00165 %
00166 */
00167 MagickExport SignatureInfo *DestroySignatureInfo(SignatureInfo *signature_info)
00168 {
00169   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00170   assert(signature_info != (SignatureInfo *) NULL);
00171   assert(signature_info->signature == MagickSignature);
00172   if (signature_info->accumulator != (unsigned int *) NULL)
00173     signature_info->accumulator=(unsigned int *) RelinquishMagickMemory(
00174       signature_info->accumulator);
00175   if (signature_info->message != (StringInfo *) NULL)
00176     signature_info->message=DestroyStringInfo(signature_info->message);
00177   if (signature_info->digest != (StringInfo *) NULL)
00178     signature_info->digest=DestroyStringInfo(signature_info->digest);
00179   signature_info->signature=(~MagickSignature);
00180   signature_info=(SignatureInfo *) RelinquishMagickMemory(signature_info);
00181   return(signature_info);
00182 }
00183 
00184 /*
00185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00186 %                                                                             %
00187 %                                                                             %
00188 %                                                                             %
00189 +   F i n a l i z e S i g n a t u r e                                         %
00190 %                                                                             %
00191 %                                                                             %
00192 %                                                                             %
00193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00194 %
00195 %  FinalizeSignature() finalizes the Signature message accumulator computation.
00196 %
00197 %  The format of the FinalizeSignature method is:
00198 %
00199 %      FinalizeSignature(SignatureInfo *signature_info)
00200 %
00201 %  A description of each parameter follows:
00202 %
00203 %    o signature_info: the address of a structure of type SignatureInfo.
00204 %
00205 */
00206 MagickExport void FinalizeSignature(SignatureInfo *signature_info)
00207 {
00208   register long
00209     i;
00210 
00211   register unsigned char
00212     *q;
00213 
00214   register unsigned int
00215     *p;
00216 
00217   unsigned char
00218     *datum;
00219 
00220   unsigned int
00221     count,
00222     high_order,
00223     low_order;
00224 
00225   /*
00226     Add padding and return the message accumulator.
00227   */
00228   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00229   assert(signature_info != (SignatureInfo *) NULL);
00230   assert(signature_info->signature == MagickSignature);
00231   low_order=signature_info->low_order;
00232   high_order=signature_info->high_order;
00233   count=((low_order >> 3) & 0x3f);
00234   datum=GetStringInfoDatum(signature_info->message);
00235   datum[count++]=(unsigned char) 0x80;
00236   if (count <= (unsigned int) (GetStringInfoLength(signature_info->message)-8))
00237     (void) ResetMagickMemory(datum+count,0,GetStringInfoLength(
00238       signature_info->message)-8-count);
00239   else
00240     {
00241       (void) ResetMagickMemory(datum+count,0,GetStringInfoLength(
00242         signature_info->message)-count);
00243       TransformSignature(signature_info);
00244       (void) ResetMagickMemory(datum,0,GetStringInfoLength(
00245         signature_info->message)-8);
00246     }
00247   datum[56]=(unsigned char) (high_order >> 24);
00248   datum[57]=(unsigned char) (high_order >> 16);
00249   datum[58]=(unsigned char) (high_order >> 8);
00250   datum[59]=(unsigned char) high_order;
00251   datum[60]=(unsigned char) (low_order >> 24);
00252   datum[61]=(unsigned char) (low_order >> 16);
00253   datum[62]=(unsigned char) (low_order >> 8);
00254   datum[63]=(unsigned char) low_order;
00255   TransformSignature(signature_info);
00256   p=signature_info->accumulator;
00257   q=GetStringInfoDatum(signature_info->digest);
00258   for (i=0; i < (SignatureDigestsize/4); i++)
00259   {
00260     *q++=(unsigned char) ((*p >> 24) & 0xff);
00261     *q++=(unsigned char) ((*p >> 16) & 0xff);
00262     *q++=(unsigned char) ((*p >> 8) & 0xff);
00263     *q++=(unsigned char) (*p & 0xff);
00264     p++;
00265   }
00266   /*
00267     Reset working registers.
00268   */
00269   count=0;
00270   high_order=0;
00271   low_order=0;
00272 }
00273 
00274 /*
00275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00276 %                                                                             %
00277 %                                                                             %
00278 %                                                                             %
00279 +   G e t S i g n a t u r e B l o c k s i z e                                 %
00280 %                                                                             %
00281 %                                                                             %
00282 %                                                                             %
00283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00284 %
00285 %  GetSignatureBlocksize() returns the Signature blocksize.
00286 %
00287 %  The format of the GetSignatureBlocksize method is:
00288 %
00289 %      unsigned int *GetSignatureBlocksize(const SignatureInfo *signature_info)
00290 %
00291 %  A description of each parameter follows:
00292 %
00293 %    o signature_info: the signature info.
00294 %
00295 */
00296 MagickExport unsigned int GetSignatureBlocksize(
00297   const SignatureInfo *signature_info)
00298 {
00299   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00300   assert(signature_info != (SignatureInfo *) NULL);
00301   assert(signature_info->signature == MagickSignature);
00302   return(signature_info->blocksize);
00303 }
00304 
00305 /*
00306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00307 %                                                                             %
00308 %                                                                             %
00309 %                                                                             %
00310 +   G e t S i g n a t u r e D i g e s t                                       %
00311 %                                                                             %
00312 %                                                                             %
00313 %                                                                             %
00314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00315 %
00316 %  GetSignatureDigest() returns the signature digest.
00317 %
00318 %  The format of the GetSignatureDigest method is:
00319 %
00320 %      const StringInfo *GetSignatureDigest(const SignatureInfo *signature_info)
00321 %
00322 %  A description of each parameter follows:
00323 %
00324 %    o signature_info: the signature info.
00325 %
00326 */
00327 MagickExport const StringInfo *GetSignatureDigest(
00328   const SignatureInfo *signature_info)
00329 {
00330   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00331   assert(signature_info != (SignatureInfo *) NULL);
00332   assert(signature_info->signature == MagickSignature);
00333   return(signature_info->digest);
00334 }
00335 
00336 /*
00337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00338 %                                                                             %
00339 %                                                                             %
00340 %                                                                             %
00341 +   G e t S i g n a t u r e D i g e s t s i z e                               %
00342 %                                                                             %
00343 %                                                                             %
00344 %                                                                             %
00345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00346 %
00347 %  GetSignatureDigestsize() returns the Signature digest size.
00348 %
00349 %  The format of the GetSignatureDigestsize method is:
00350 %
00351 %      unsigned int *GetSignatureDigestsize(const SignatureInfo *signature_info)
00352 %
00353 %  A description of each parameter follows:
00354 %
00355 %    o signature_info: the signature info.
00356 %
00357 */
00358 MagickExport unsigned int GetSignatureDigestsize(
00359   const SignatureInfo *signature_info)
00360 {
00361   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00362   assert(signature_info != (SignatureInfo *) NULL);
00363   assert(signature_info->signature == MagickSignature);
00364   return(signature_info->digestsize);
00365 }
00366 
00367 /*
00368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00369 %                                                                             %
00370 %                                                                             %
00371 %                                                                             %
00372 +   I n i t i a l i z e S i g n a t u r e                                     %
00373 %                                                                             %
00374 %                                                                             %
00375 %                                                                             %
00376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00377 %
00378 %  IntializeSignature() intializes the Signature accumulator.
00379 %
00380 %  The format of the DestroySignatureInfo method is:
00381 %
00382 %      void InitializeSignatureInfo(SignatureInfo *signature_info)
00383 %
00384 %  A description of each parameter follows:
00385 %
00386 %    o signature_info: the cipher signature_info.
00387 %
00388 */
00389 MagickExport void InitializeSignature(SignatureInfo *signature_info)
00390 {
00391   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00392   assert(signature_info != (SignatureInfo *) NULL);
00393   assert(signature_info->signature == MagickSignature);
00394   signature_info->accumulator[0]=0x6a09e667U;
00395   signature_info->accumulator[1]=0xbb67ae85U;
00396   signature_info->accumulator[2]=0x3c6ef372U;
00397   signature_info->accumulator[3]=0xa54ff53aU;
00398   signature_info->accumulator[4]=0x510e527fU;
00399   signature_info->accumulator[5]=0x9b05688cU;
00400   signature_info->accumulator[6]=0x1f83d9abU;
00401   signature_info->accumulator[7]=0x5be0cd19U;
00402   signature_info->low_order=0;
00403   signature_info->high_order=0;
00404   signature_info->offset=0;
00405 }
00406 
00407 /*
00408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00409 %                                                                             %
00410 %                                                                             %
00411 %                                                                             %
00412 +   S e t S i g n a t u r e D i g e s t                                       %
00413 %                                                                             %
00414 %                                                                             %
00415 %                                                                             %
00416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00417 %
00418 %  SetSignatureDigest() set the signature digest.
00419 %
00420 %  The format of the SetSignatureDigest method is:
00421 %
00422 %      SetSignatureDigest(SignatureInfo *signature_info,
00423 %        const StringInfo *digest)
00424 %
00425 %  A description of each parameter follows:
00426 %
00427 %    o signature_info: the signature info.
00428 %
00429 %    o digest: the digest.
00430 %
00431 */
00432 MagickExport void SetSignatureDigest(SignatureInfo *signature_info,
00433   const StringInfo *digest)
00434 {
00435   /*
00436     Set the signature accumulator.
00437   */
00438   assert(signature_info != (SignatureInfo *) NULL);
00439   assert(signature_info->signature == MagickSignature);
00440   SetStringInfo(signature_info->digest,digest);
00441 }
00442 
00443 /*
00444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00445 %                                                                             %
00446 %                                                                             %
00447 %                                                                             %
00448 %   S i g n a t u r e I m a g e                                               %
00449 %                                                                             %
00450 %                                                                             %
00451 %                                                                             %
00452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00453 %
00454 %  SignatureImage() computes a message digest from an image pixel stream with
00455 %  an implementation of the NIST SHA-256 Message Digest algorithm.  This
00456 %  signature uniquely identifies the image and is convenient for determining
00457 %  if an image has been modified or whether two images are identical.
00458 %
00459 %  The format of the SignatureImage method is:
00460 %
00461 %      MagickBooleanType SignatureImage(Image *image)
00462 %
00463 %  A description of each parameter follows:
00464 %
00465 %    o image: the image.
00466 %
00467 */
00468 MagickExport MagickBooleanType SignatureImage(Image *image)
00469 {
00470   char
00471     *hex_signature;
00472 
00473   ExceptionInfo
00474     *exception;
00475 
00476   long
00477     y;
00478 
00479   QuantumInfo
00480     *quantum_info;
00481 
00482   QuantumType
00483     quantum_type;
00484 
00485   register const PixelPacket
00486     *p;
00487 
00488   SignatureInfo
00489     *signature_info;
00490 
00491   size_t
00492     length;
00493 
00494   StringInfo
00495     *signature;
00496 
00497   unsigned char
00498     *pixels;
00499 
00500   ViewInfo
00501     *image_view;
00502 
00503   /*
00504     Compute image digital signature.
00505   */
00506   assert(image != (Image *) NULL);
00507   assert(image->signature == MagickSignature);
00508   if (image->debug != MagickFalse)
00509     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00510   quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
00511   if (quantum_info == (QuantumInfo *) NULL)
00512     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00513       image->filename);
00514   quantum_type=RGBQuantum;
00515   if (image->matte != MagickFalse)
00516     quantum_type=RGBAQuantum;
00517   if (image->colorspace == CMYKColorspace)
00518     {
00519       quantum_type=CMYKQuantum;
00520       if (image->matte != MagickFalse)
00521         quantum_type=CMYKAQuantum;
00522     }
00523   signature_info=AcquireSignatureInfo();
00524   signature=AcquireStringInfo(quantum_info->extent);
00525   pixels=GetQuantumPixels(quantum_info);
00526   exception=(&image->exception);
00527   image_view=AcquireCacheView(image);
00528   for (y=0; y < (long) image->rows; y++)
00529   {
00530     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
00531     if (p == (const PixelPacket *) NULL)
00532       break;
00533     length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
00534       pixels,&image->exception);
00535     SetStringInfoLength(signature,length);
00536     SetStringInfoDatum(signature,pixels);
00537     UpdateSignature(signature_info,signature);
00538   }
00539   image_view=DestroyCacheView(image_view);
00540   FinalizeSignature(signature_info);
00541   hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info));
00542   (void) DeleteImageProperty(image,"signature");
00543   (void) SetImageProperty(image,"signature",hex_signature);
00544   /*
00545     Free resources.
00546   */
00547   hex_signature=DestroyString(hex_signature);
00548   signature=DestroyStringInfo(signature);
00549   signature_info=DestroySignatureInfo(signature_info);
00550   return(MagickTrue);
00551 }
00552 
00553 /*
00554 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00555 %                                                                             %
00556 %                                                                             %
00557 %                                                                             %
00558 +   T r a n s f o r m S i g n a t u r e                                       %
00559 %                                                                             %
00560 %                                                                             %
00561 %                                                                             %
00562 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00563 %
00564 %  TransformSignature() transforms the Signature message accumulator.
00565 %
00566 %  The format of the TransformSignature method is:
00567 %
00568 %      TransformSignature(SignatureInfo *signature_info)
00569 %
00570 %  A description of each parameter follows:
00571 %
00572 %    o signature_info: the address of a structure of type SignatureInfo.
00573 %
00574 */
00575 
00576 static inline unsigned int Ch(unsigned int x,unsigned int y,unsigned int z)
00577 {
00578   return((x & y) ^ (~x & z));
00579 }
00580 
00581 static inline unsigned int Maj(unsigned int x,unsigned int y,unsigned int z)
00582 {
00583   return((x & y) ^ (x & z) ^ (y & z));
00584 }
00585 
00586 static inline unsigned int Trunc32(unsigned int x)
00587 {
00588   return((unsigned int) (x & 0xffffffffU));
00589 }
00590 
00591 static unsigned int RotateRight(unsigned int x,unsigned int n)
00592 {
00593   return(Trunc32((x >> n) | (x << (32-n))));
00594 }
00595 
00596 static void TransformSignature(SignatureInfo *signature_info)
00597 {
00598 #define Sigma0(x)  (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
00599 #define Sigma1(x)  (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
00600 #define Suma0(x)  (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
00601 #define Suma1(x)  (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
00602 
00603   long
00604     j;
00605 
00606   register long
00607     i;
00608 
00609   register unsigned char
00610     *p;
00611 
00612   static unsigned int
00613     K[64] =
00614     {
00615       0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU,
00616       0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U,
00617       0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U,
00618       0xc19bf174U, 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU,
00619       0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U,
00620       0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U,
00621       0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU,
00622       0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U,
00623       0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,
00624       0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U,
00625       0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU,
00626       0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U,
00627       0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U
00628     };  /* 32-bit fractional part of the cube root of the first 64 primes */
00629 
00630   unsigned int
00631     A,
00632     B,
00633     C,
00634     D,
00635     E,
00636     F,
00637     G,
00638     H,
00639     shift,
00640     T,
00641     T1,
00642     T2,
00643     W[64];
00644 
00645   shift=32;
00646   p=GetStringInfoDatum(signature_info->message);
00647   if (signature_info->lsb_first == MagickFalse)
00648     {
00649       if (sizeof(unsigned int) <= 4)
00650         for (i=0; i < 16; i++)
00651         {
00652           T=(*((unsigned int *) p));
00653           p+=4;
00654           W[i]=Trunc32(T);
00655         }
00656       else
00657         for (i=0; i < 16; i+=2)
00658         {
00659           T=(*((unsigned int *) p));
00660           p+=8;
00661           W[i]=Trunc32(T >> shift);
00662           W[i+1]=Trunc32(T);
00663         }
00664     }
00665   else
00666     if (sizeof(unsigned int) <= 4)
00667       for (i=0; i < 16; i++)
00668       {
00669         T=(*((unsigned int *) p));
00670         p+=4;
00671         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00672           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00673       }
00674     else
00675       for (i=0; i < 16; i+=2)
00676       {
00677         T=(*((unsigned int *) p));
00678         p+=8;
00679         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00680           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00681         T>>=shift;
00682         W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00683           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00684       }
00685   /*
00686     Copy accumulator to registers.
00687   */
00688   A=signature_info->accumulator[0];
00689   B=signature_info->accumulator[1];
00690   C=signature_info->accumulator[2];
00691   D=signature_info->accumulator[3];
00692   E=signature_info->accumulator[4];
00693   F=signature_info->accumulator[5];
00694   G=signature_info->accumulator[6];
00695   H=signature_info->accumulator[7];
00696   for (i=16; i < 64; i++)
00697     W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
00698   for (j=0; j < 64; j++)
00699   {
00700     T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
00701     T2=Trunc32(Suma0(A)+Maj(A,B,C));
00702     H=G;
00703     G=F;
00704     F=E;
00705     E=Trunc32(D+T1);
00706     D=C;
00707     C=B;
00708     B=A;
00709     A=Trunc32(T1+T2);
00710   }
00711   /*
00712     Add registers back to accumulator.
00713   */
00714   signature_info->accumulator[0]=Trunc32(signature_info->accumulator[0]+A);
00715   signature_info->accumulator[1]=Trunc32(signature_info->accumulator[1]+B);
00716   signature_info->accumulator[2]=Trunc32(signature_info->accumulator[2]+C);
00717   signature_info->accumulator[3]=Trunc32(signature_info->accumulator[3]+D);
00718   signature_info->accumulator[4]=Trunc32(signature_info->accumulator[4]+E);
00719   signature_info->accumulator[5]=Trunc32(signature_info->accumulator[5]+F);
00720   signature_info->accumulator[6]=Trunc32(signature_info->accumulator[6]+G);
00721   signature_info->accumulator[7]=Trunc32(signature_info->accumulator[7]+H);
00722   /*
00723     Reset working registers.
00724   */
00725   A=0;
00726   B=0;
00727   C=0;
00728   D=0;
00729   E=0;
00730   F=0;
00731   G=0;
00732   H=0;
00733   T=0;
00734   T1=0;
00735   T2=0;
00736   (void) ResetMagickMemory(W,0,sizeof(W));
00737 }
00738 
00739 /*
00740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00741 %                                                                             %
00742 %                                                                             %
00743 %                                                                             %
00744 +   U p d a t e S i g n a t u r e                                             %
00745 %                                                                             %
00746 %                                                                             %
00747 %                                                                             %
00748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00749 %
00750 %  UpdateSignature() updates the Signature message accumulator.
00751 %
00752 %  The format of the UpdateSignature method is:
00753 %
00754 %      UpdateSignature(SignatureInfo *signature_info,const StringInfo *message)
00755 %
00756 %  A description of each parameter follows:
00757 %
00758 %    o signature_info: the address of a structure of type SignatureInfo.
00759 %
00760 %    o message: the message.
00761 %
00762 */
00763 MagickExport void UpdateSignature(SignatureInfo *signature_info,
00764   const StringInfo *message)
00765 {
00766   register size_t
00767     i;
00768 
00769   register unsigned char
00770     *p;
00771 
00772   size_t
00773     n;
00774 
00775   unsigned int
00776     length;
00777 
00778   /*
00779     Update the Signature accumulator.
00780   */
00781   assert(signature_info != (SignatureInfo *) NULL);
00782   assert(signature_info->signature == MagickSignature);
00783   n=GetStringInfoLength(message);
00784   length=Trunc32((unsigned int) (signature_info->low_order+(n << 3)));
00785   if (length < signature_info->low_order)
00786     signature_info->high_order++;
00787   signature_info->low_order=length;
00788   signature_info->high_order+=(unsigned int) (n >> 29);
00789   p=GetStringInfoDatum(message);
00790   if (signature_info->offset != 0)
00791     {
00792       i=GetStringInfoLength(signature_info->message)-signature_info->offset;
00793       if (i > n)
00794         i=n;
00795       (void) CopyMagickMemory(GetStringInfoDatum(signature_info->message)+
00796         signature_info->offset,p,i);
00797       n-=i;
00798       p+=i;
00799       signature_info->offset+=i;
00800       if (signature_info->offset !=
00801           GetStringInfoLength(signature_info->message))
00802         return;
00803       TransformSignature(signature_info);
00804     }
00805   while (n >= GetStringInfoLength(signature_info->message))
00806   {
00807     SetStringInfoDatum(signature_info->message,p);
00808     p+=GetStringInfoLength(signature_info->message);
00809     n-=GetStringInfoLength(signature_info->message);
00810     TransformSignature(signature_info);
00811   }
00812   (void) CopyMagickMemory(GetStringInfoDatum(signature_info->message),p,n);
00813   signature_info->offset=n;
00814   /*
00815     Reset working registers.
00816   */
00817   i=0;
00818   n=0;
00819   length=0;
00820 }

Generated on Sat Nov 22 23:45:18 2008 for MagickCore by  doxygen 1.5.7.1