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-2009 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   CacheView
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   quantum_info=DestroyQuantumInfo(quantum_info);
00541   FinalizeSignature(signature_info);
00542   hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info));
00543   (void) DeleteImageProperty(image,"signature");
00544   (void) SetImageProperty(image,"signature",hex_signature);
00545   /*
00546     Free resources.
00547   */
00548   hex_signature=DestroyString(hex_signature);
00549   signature=DestroyStringInfo(signature);
00550   signature_info=DestroySignatureInfo(signature_info);
00551   return(MagickTrue);
00552 }
00553 
00554 /*
00555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00556 %                                                                             %
00557 %                                                                             %
00558 %                                                                             %
00559 +   T r a n s f o r m S i g n a t u r e                                       %
00560 %                                                                             %
00561 %                                                                             %
00562 %                                                                             %
00563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00564 %
00565 %  TransformSignature() transforms the Signature message accumulator.
00566 %
00567 %  The format of the TransformSignature method is:
00568 %
00569 %      TransformSignature(SignatureInfo *signature_info)
00570 %
00571 %  A description of each parameter follows:
00572 %
00573 %    o signature_info: the address of a structure of type SignatureInfo.
00574 %
00575 */
00576 
00577 static inline unsigned int Ch(unsigned int x,unsigned int y,unsigned int z)
00578 {
00579   return((x & y) ^ (~x & z));
00580 }
00581 
00582 static inline unsigned int Maj(unsigned int x,unsigned int y,unsigned int z)
00583 {
00584   return((x & y) ^ (x & z) ^ (y & z));
00585 }
00586 
00587 static inline unsigned int Trunc32(unsigned int x)
00588 {
00589   return((unsigned int) (x & 0xffffffffU));
00590 }
00591 
00592 static unsigned int RotateRight(unsigned int x,unsigned int n)
00593 {
00594   return(Trunc32((x >> n) | (x << (32-n))));
00595 }
00596 
00597 static void TransformSignature(SignatureInfo *signature_info)
00598 {
00599 #define Sigma0(x)  (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
00600 #define Sigma1(x)  (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
00601 #define Suma0(x)  (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
00602 #define Suma1(x)  (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
00603 
00604   long
00605     j;
00606 
00607   register long
00608     i;
00609 
00610   register unsigned char
00611     *p;
00612 
00613   static unsigned int
00614     K[64] =
00615     {
00616       0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU,
00617       0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U,
00618       0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U,
00619       0xc19bf174U, 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU,
00620       0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U,
00621       0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U,
00622       0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU,
00623       0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U,
00624       0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,
00625       0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U,
00626       0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU,
00627       0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U,
00628       0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U
00629     };  /* 32-bit fractional part of the cube root of the first 64 primes */
00630 
00631   unsigned int
00632     A,
00633     B,
00634     C,
00635     D,
00636     E,
00637     F,
00638     G,
00639     H,
00640     shift,
00641     T,
00642     T1,
00643     T2,
00644     W[64];
00645 
00646   shift=32;
00647   p=GetStringInfoDatum(signature_info->message);
00648   if (signature_info->lsb_first == MagickFalse)
00649     {
00650       if (sizeof(unsigned int) <= 4)
00651         for (i=0; i < 16; i++)
00652         {
00653           T=(*((unsigned int *) p));
00654           p+=4;
00655           W[i]=Trunc32(T);
00656         }
00657       else
00658         for (i=0; i < 16; i+=2)
00659         {
00660           T=(*((unsigned int *) p));
00661           p+=8;
00662           W[i]=Trunc32(T >> shift);
00663           W[i+1]=Trunc32(T);
00664         }
00665     }
00666   else
00667     if (sizeof(unsigned int) <= 4)
00668       for (i=0; i < 16; i++)
00669       {
00670         T=(*((unsigned int *) p));
00671         p+=4;
00672         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00673           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00674       }
00675     else
00676       for (i=0; i < 16; i+=2)
00677       {
00678         T=(*((unsigned int *) p));
00679         p+=8;
00680         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00681           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00682         T>>=shift;
00683         W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00684           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00685       }
00686   /*
00687     Copy accumulator to registers.
00688   */
00689   A=signature_info->accumulator[0];
00690   B=signature_info->accumulator[1];
00691   C=signature_info->accumulator[2];
00692   D=signature_info->accumulator[3];
00693   E=signature_info->accumulator[4];
00694   F=signature_info->accumulator[5];
00695   G=signature_info->accumulator[6];
00696   H=signature_info->accumulator[7];
00697   for (i=16; i < 64; i++)
00698     W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
00699   for (j=0; j < 64; j++)
00700   {
00701     T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
00702     T2=Trunc32(Suma0(A)+Maj(A,B,C));
00703     H=G;
00704     G=F;
00705     F=E;
00706     E=Trunc32(D+T1);
00707     D=C;
00708     C=B;
00709     B=A;
00710     A=Trunc32(T1+T2);
00711   }
00712   /*
00713     Add registers back to accumulator.
00714   */
00715   signature_info->accumulator[0]=Trunc32(signature_info->accumulator[0]+A);
00716   signature_info->accumulator[1]=Trunc32(signature_info->accumulator[1]+B);
00717   signature_info->accumulator[2]=Trunc32(signature_info->accumulator[2]+C);
00718   signature_info->accumulator[3]=Trunc32(signature_info->accumulator[3]+D);
00719   signature_info->accumulator[4]=Trunc32(signature_info->accumulator[4]+E);
00720   signature_info->accumulator[5]=Trunc32(signature_info->accumulator[5]+F);
00721   signature_info->accumulator[6]=Trunc32(signature_info->accumulator[6]+G);
00722   signature_info->accumulator[7]=Trunc32(signature_info->accumulator[7]+H);
00723   /*
00724     Reset working registers.
00725   */
00726   A=0;
00727   B=0;
00728   C=0;
00729   D=0;
00730   E=0;
00731   F=0;
00732   G=0;
00733   H=0;
00734   T=0;
00735   T1=0;
00736   T2=0;
00737   (void) ResetMagickMemory(W,0,sizeof(W));
00738 }
00739 
00740 /*
00741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00742 %                                                                             %
00743 %                                                                             %
00744 %                                                                             %
00745 +   U p d a t e S i g n a t u r e                                             %
00746 %                                                                             %
00747 %                                                                             %
00748 %                                                                             %
00749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00750 %
00751 %  UpdateSignature() updates the Signature message accumulator.
00752 %
00753 %  The format of the UpdateSignature method is:
00754 %
00755 %      UpdateSignature(SignatureInfo *signature_info,const StringInfo *message)
00756 %
00757 %  A description of each parameter follows:
00758 %
00759 %    o signature_info: the address of a structure of type SignatureInfo.
00760 %
00761 %    o message: the message.
00762 %
00763 */
00764 MagickExport void UpdateSignature(SignatureInfo *signature_info,
00765   const StringInfo *message)
00766 {
00767   register size_t
00768     i;
00769 
00770   register unsigned char
00771     *p;
00772 
00773   size_t
00774     n;
00775 
00776   unsigned int
00777     length;
00778 
00779   /*
00780     Update the Signature accumulator.
00781   */
00782   assert(signature_info != (SignatureInfo *) NULL);
00783   assert(signature_info->signature == MagickSignature);
00784   n=GetStringInfoLength(message);
00785   length=Trunc32((unsigned int) (signature_info->low_order+(n << 3)));
00786   if (length < signature_info->low_order)
00787     signature_info->high_order++;
00788   signature_info->low_order=length;
00789   signature_info->high_order+=(unsigned int) (n >> 29);
00790   p=GetStringInfoDatum(message);
00791   if (signature_info->offset != 0)
00792     {
00793       i=GetStringInfoLength(signature_info->message)-signature_info->offset;
00794       if (i > n)
00795         i=n;
00796       (void) CopyMagickMemory(GetStringInfoDatum(signature_info->message)+
00797         signature_info->offset,p,i);
00798       n-=i;
00799       p+=i;
00800       signature_info->offset+=i;
00801       if (signature_info->offset !=
00802           GetStringInfoLength(signature_info->message))
00803         return;
00804       TransformSignature(signature_info);
00805     }
00806   while (n >= GetStringInfoLength(signature_info->message))
00807   {
00808     SetStringInfoDatum(signature_info->message,p);
00809     p+=GetStringInfoLength(signature_info->message);
00810     n-=GetStringInfoLength(signature_info->message);
00811     TransformSignature(signature_info);
00812   }
00813   (void) CopyMagickMemory(GetStringInfoDatum(signature_info->message),p,n);
00814   signature_info->offset=n;
00815   /*
00816     Reset working registers.
00817   */
00818   i=0;
00819   n=0;
00820   length=0;
00821 }

Generated on 19 Nov 2009 for MagickCore by  doxygen 1.6.1