]> granicus.if.org Git - imagemagick/blob - MagickCore/signature.c
Update web pages
[imagemagick] / MagickCore / signature.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %        SSSSS  IIIII   GGGG  N   N   AAA   TTTTT  U   U  RRRR   EEEEE        %
6 %        SS       I    G      NN  N  A   A    T    U   U  R   R  E            %
7 %         SSS     I    G  GG  N N N  AAAAA    T    U   U  RRRR   EEE          %
8 %           SS    I    G   G  N  NN  A   A    T    U   U  R R    E            %
9 %        SSSSS  IIIII   GGG   N   N  A   A    T     UUU   R  R   EEEEE        %
10 %                                                                             %
11 %                                                                             %
12 %         MagickCore Methods to Compute a Message Digest for an Image         %
13 %                                                                             %
14 %                             Software Design                                 %
15 %                                  Cristy                                     %
16 %                              December 1992                                  %
17 %                                                                             %
18 %                                                                             %
19 %  Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization      %
20 %  dedicated to making software imaging solutions freely available.           %
21 %                                                                             %
22 %  You may not use this file except in compliance with the License.  You may  %
23 %  obtain a copy of the License at                                            %
24 %                                                                             %
25 %    http://www.imagemagick.org/script/license.php                            %
26 %                                                                             %
27 %  Unless required by applicable law or agreed to in writing, software        %
28 %  distributed under the License is distributed on an "AS IS" BASIS,          %
29 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
30 %  See the License for the specific language governing permissions and        %
31 %  limitations under the License.                                             %
32 %                                                                             %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %
35 %
36 %
37 */
38 \f
39 /*
40   Include declarations.
41 */
42 #include "MagickCore/studio.h"
43 #include "MagickCore/cache.h"
44 #include "MagickCore/exception.h"
45 #include "MagickCore/exception-private.h"
46 #include "MagickCore/property.h"
47 #include "MagickCore/image.h"
48 #include "MagickCore/memory_.h"
49 #include "MagickCore/pixel-accessor.h"
50 #include "MagickCore/quantum.h"
51 #include "MagickCore/quantum-private.h"
52 #include "MagickCore/signature.h"
53 #include "MagickCore/signature-private.h"
54 #include "MagickCore/string_.h"
55 /*
56   Define declarations.
57 */
58 #define SignatureBlocksize  64
59 #define SignatureDigestsize  32
60 \f
61 /*
62   Typedef declarations.
63 */
64 struct _SignatureInfo
65 {
66   unsigned int
67     digestsize,
68     blocksize;
69
70   StringInfo
71     *digest,
72     *message;
73
74   unsigned int
75     *accumulator,
76     low_order,
77     high_order;
78
79   size_t
80     offset;
81
82   MagickBooleanType
83     lsb_first;
84
85   ssize_t
86     timestamp;
87
88   size_t
89     signature;
90 };
91 \f
92 /*
93   Forward declarations.
94 */
95 static void
96   TransformSignature(SignatureInfo *);
97 \f
98 /*
99 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100 %                                                                             %
101 %                                                                             %
102 %                                                                             %
103 +   A c q u i r e S i g n a t u r e I n f o                                   %
104 %                                                                             %
105 %                                                                             %
106 %                                                                             %
107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108 %
109 %  AcquireSignatureInfo() allocate the SignatureInfo structure.
110 %
111 %  The format of the AcquireSignatureInfo method is:
112 %
113 %      SignatureInfo *AcquireSignatureInfo(void)
114 %
115 */
116 MagickPrivate SignatureInfo *AcquireSignatureInfo(void)
117 {
118   SignatureInfo
119     *signature_info;
120
121   unsigned int
122     lsb_first;
123
124   signature_info=(SignatureInfo *) AcquireMagickMemory(sizeof(*signature_info));
125   if (signature_info == (SignatureInfo *) NULL)
126     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
127   (void) ResetMagickMemory(signature_info,0,sizeof(*signature_info));
128   signature_info->digestsize=SignatureDigestsize;
129   signature_info->blocksize=SignatureBlocksize;
130   signature_info->digest=AcquireStringInfo(SignatureDigestsize);
131   signature_info->message=AcquireStringInfo(SignatureBlocksize);
132   signature_info->accumulator=(unsigned int *) AcquireQuantumMemory(
133     SignatureBlocksize,sizeof(*signature_info->accumulator));
134   if (signature_info->accumulator == (unsigned int *) NULL)
135     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
136   lsb_first=1;
137   signature_info->lsb_first=(int) (*(char *) &lsb_first) == 1 ? MagickTrue :
138     MagickFalse;
139   signature_info->timestamp=(ssize_t) time(0);
140   signature_info->signature=MagickCoreSignature;
141   InitializeSignature(signature_info);
142   return(signature_info);
143 }
144 \f
145 /*
146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
147 %                                                                             %
148 %                                                                             %
149 %                                                                             %
150 +   D e s t r o y S i g n a t u r e I n f o                                   %
151 %                                                                             %
152 %                                                                             %
153 %                                                                             %
154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
155 %
156 %  DestroySignatureInfo() zeros memory associated with the SignatureInfo
157 %  structure.
158 %
159 %  The format of the DestroySignatureInfo method is:
160 %
161 %      SignatureInfo *DestroySignatureInfo(SignatureInfo *signature_info)
162 %
163 %  A description of each parameter follows:
164 %
165 %    o signature_info: the cipher signature_info.
166 %
167 */
168 MagickPrivate SignatureInfo *DestroySignatureInfo(SignatureInfo *signature_info)
169 {
170   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
171   assert(signature_info != (SignatureInfo *) NULL);
172   assert(signature_info->signature == MagickCoreSignature);
173   if (signature_info->accumulator != (unsigned int *) NULL)
174     signature_info->accumulator=(unsigned int *) RelinquishMagickMemory(
175       signature_info->accumulator);
176   if (signature_info->message != (StringInfo *) NULL)
177     signature_info->message=DestroyStringInfo(signature_info->message);
178   if (signature_info->digest != (StringInfo *) NULL)
179     signature_info->digest=DestroyStringInfo(signature_info->digest);
180   signature_info->signature=(~MagickCoreSignature);
181   signature_info=(SignatureInfo *) RelinquishMagickMemory(signature_info);
182   return(signature_info);
183 }
184 \f
185 /*
186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
187 %                                                                             %
188 %                                                                             %
189 %                                                                             %
190 +   F i n a l i z e S i g n a t u r e                                         %
191 %                                                                             %
192 %                                                                             %
193 %                                                                             %
194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
195 %
196 %  FinalizeSignature() finalizes the Signature message accumulator computation.
197 %
198 %  The format of the FinalizeSignature method is:
199 %
200 %      FinalizeSignature(SignatureInfo *signature_info)
201 %
202 %  A description of each parameter follows:
203 %
204 %    o signature_info: the address of a structure of type SignatureInfo.
205 %
206 */
207 MagickPrivate void FinalizeSignature(SignatureInfo *signature_info)
208 {
209   register ssize_t
210     i;
211
212   register unsigned char
213     *q;
214
215   register unsigned int
216     *p;
217
218   unsigned char
219     *datum;
220
221   unsigned int
222     count,
223     high_order,
224     low_order;
225
226   /*
227     Add padding and return the message accumulator.
228   */
229   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
230   assert(signature_info != (SignatureInfo *) NULL);
231   assert(signature_info->signature == MagickCoreSignature);
232   low_order=signature_info->low_order;
233   high_order=signature_info->high_order;
234   count=((low_order >> 3) & 0x3f);
235   datum=GetStringInfoDatum(signature_info->message);
236   datum[count++]=(unsigned char) 0x80;
237   if (count <= (unsigned int) (GetStringInfoLength(signature_info->message)-8))
238     (void) ResetMagickMemory(datum+count,0,GetStringInfoLength(
239       signature_info->message)-8-count);
240   else
241     {
242       (void) ResetMagickMemory(datum+count,0,GetStringInfoLength(
243         signature_info->message)-count);
244       TransformSignature(signature_info);
245       (void) ResetMagickMemory(datum,0,GetStringInfoLength(
246         signature_info->message)-8);
247     }
248   datum[56]=(unsigned char) (high_order >> 24);
249   datum[57]=(unsigned char) (high_order >> 16);
250   datum[58]=(unsigned char) (high_order >> 8);
251   datum[59]=(unsigned char) high_order;
252   datum[60]=(unsigned char) (low_order >> 24);
253   datum[61]=(unsigned char) (low_order >> 16);
254   datum[62]=(unsigned char) (low_order >> 8);
255   datum[63]=(unsigned char) low_order;
256   TransformSignature(signature_info);
257   p=signature_info->accumulator;
258   q=GetStringInfoDatum(signature_info->digest);
259   for (i=0; i < (SignatureDigestsize/4); i++)
260   {
261     *q++=(unsigned char) ((*p >> 24) & 0xff);
262     *q++=(unsigned char) ((*p >> 16) & 0xff);
263     *q++=(unsigned char) ((*p >> 8) & 0xff);
264     *q++=(unsigned char) (*p & 0xff);
265     p++;
266   }
267 }
268 \f
269 /*
270 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271 %                                                                             %
272 %                                                                             %
273 %                                                                             %
274 +   G e t S i g n a t u r e B l o c k s i z e                                 %
275 %                                                                             %
276 %                                                                             %
277 %                                                                             %
278 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279 %
280 %  GetSignatureBlocksize() returns the Signature blocksize.
281 %
282 %  The format of the GetSignatureBlocksize method is:
283 %
284 %      unsigned int *GetSignatureBlocksize(const SignatureInfo *signature_info)
285 %
286 %  A description of each parameter follows:
287 %
288 %    o signature_info: the signature info.
289 %
290 */
291 MagickPrivate unsigned int GetSignatureBlocksize(
292   const SignatureInfo *signature_info)
293 {
294   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
295   assert(signature_info != (SignatureInfo *) NULL);
296   assert(signature_info->signature == MagickCoreSignature);
297   return(signature_info->blocksize);
298 }
299 \f
300 /*
301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
302 %                                                                             %
303 %                                                                             %
304 %                                                                             %
305 +   G e t S i g n a t u r e D i g e s t                                       %
306 %                                                                             %
307 %                                                                             %
308 %                                                                             %
309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
310 %
311 %  GetSignatureDigest() returns the signature digest.
312 %
313 %  The format of the GetSignatureDigest method is:
314 %
315 %      const StringInfo *GetSignatureDigest(const SignatureInfo *signature_info)
316 %
317 %  A description of each parameter follows:
318 %
319 %    o signature_info: the signature info.
320 %
321 */
322 MagickPrivate const StringInfo *GetSignatureDigest(
323   const SignatureInfo *signature_info)
324 {
325   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
326   assert(signature_info != (SignatureInfo *) NULL);
327   assert(signature_info->signature == MagickCoreSignature);
328   return(signature_info->digest);
329 }
330 \f
331 /*
332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
333 %                                                                             %
334 %                                                                             %
335 %                                                                             %
336 +   G e t S i g n a t u r e D i g e s t s i z e                               %
337 %                                                                             %
338 %                                                                             %
339 %                                                                             %
340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
341 %
342 %  GetSignatureDigestsize() returns the Signature digest size.
343 %
344 %  The format of the GetSignatureDigestsize method is:
345 %
346 %      unsigned int *GetSignatureDigestsize(const SignatureInfo *signature_info)
347 %
348 %  A description of each parameter follows:
349 %
350 %    o signature_info: the signature info.
351 %
352 */
353 MagickPrivate unsigned int GetSignatureDigestsize(
354   const SignatureInfo *signature_info)
355 {
356   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
357   assert(signature_info != (SignatureInfo *) NULL);
358   assert(signature_info->signature == MagickCoreSignature);
359   return(signature_info->digestsize);
360 }
361 \f
362 /*
363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
364 %                                                                             %
365 %                                                                             %
366 %                                                                             %
367 +   I n i t i a l i z e S i g n a t u r e                                     %
368 %                                                                             %
369 %                                                                             %
370 %                                                                             %
371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372 %
373 %  InitializeSignature() initializes the Signature accumulator.
374 %
375 %  The format of the DestroySignatureInfo method is:
376 %
377 %      void InitializeSignatureInfo(SignatureInfo *signature_info)
378 %
379 %  A description of each parameter follows:
380 %
381 %    o signature_info: the cipher signature_info.
382 %
383 */
384 MagickPrivate void InitializeSignature(SignatureInfo *signature_info)
385 {
386   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
387   assert(signature_info != (SignatureInfo *) NULL);
388   assert(signature_info->signature == MagickCoreSignature);
389   signature_info->accumulator[0]=0x6a09e667U;
390   signature_info->accumulator[1]=0xbb67ae85U;
391   signature_info->accumulator[2]=0x3c6ef372U;
392   signature_info->accumulator[3]=0xa54ff53aU;
393   signature_info->accumulator[4]=0x510e527fU;
394   signature_info->accumulator[5]=0x9b05688cU;
395   signature_info->accumulator[6]=0x1f83d9abU;
396   signature_info->accumulator[7]=0x5be0cd19U;
397   signature_info->low_order=0;
398   signature_info->high_order=0;
399   signature_info->offset=0;
400 }
401 \f
402 /*
403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
404 %                                                                             %
405 %                                                                             %
406 %                                                                             %
407 +   S e t S i g n a t u r e D i g e s t                                       %
408 %                                                                             %
409 %                                                                             %
410 %                                                                             %
411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
412 %
413 %  SetSignatureDigest() set the signature digest.
414 %
415 %  The format of the SetSignatureDigest method is:
416 %
417 %      SetSignatureDigest(SignatureInfo *signature_info,
418 %        const StringInfo *digest)
419 %
420 %  A description of each parameter follows:
421 %
422 %    o signature_info: the signature info.
423 %
424 %    o digest: the digest.
425 %
426 */
427 MagickPrivate void SetSignatureDigest(SignatureInfo *signature_info,
428   const StringInfo *digest)
429 {
430   /*
431     Set the signature accumulator.
432   */
433   assert(signature_info != (SignatureInfo *) NULL);
434   assert(signature_info->signature == MagickCoreSignature);
435   SetStringInfo(signature_info->digest,digest);
436 }
437 \f
438 /*
439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
440 %                                                                             %
441 %                                                                             %
442 %                                                                             %
443 %   S i g n a t u r e I m a g e                                               %
444 %                                                                             %
445 %                                                                             %
446 %                                                                             %
447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
448 %
449 %  SignatureImage() computes a message digest from an image pixel stream with
450 %  an implementation of the NIST SHA-256 Message Digest algorithm.  This
451 %  signature uniquely identifies the image and is convenient for determining
452 %  if an image has been modified or whether two images are identical.
453 %
454 %  The format of the SignatureImage method is:
455 %
456 %      MagickBooleanType SignatureImage(Image *image,ExceptionInfo *exception)
457 %
458 %  A description of each parameter follows:
459 %
460 %    o image: the image.
461 %
462 %    o exception: return any errors or warnings in this structure.
463 %
464 */
465 MagickExport MagickBooleanType SignatureImage(Image *image,
466   ExceptionInfo *exception)
467 {
468   CacheView
469     *image_view;
470
471   char
472     *hex_signature;
473
474   double
475     pixel;
476
477   register const Quantum
478     *p;
479
480   SignatureInfo
481     *signature_info;
482
483   ssize_t
484     y;
485
486   StringInfo
487     *signature;
488
489   unsigned char
490     *pixels;
491
492   /*
493     Compute image digital signature.
494   */
495   assert(image != (Image *) NULL);
496   assert(image->signature == MagickCoreSignature);
497   if (image->debug != MagickFalse)
498     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
499   signature_info=AcquireSignatureInfo();
500   signature=AcquireStringInfo(GetPixelChannels(image)*image->columns*
501     sizeof(pixel));
502   image_view=AcquireVirtualCacheView(image,exception);
503   for (y=0; y < (ssize_t) image->rows; y++)
504   {
505     register ssize_t
506       x;
507
508     register unsigned char
509       *q;
510
511     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
512     if (p == (const Quantum *) NULL)
513       break;
514     SetStringInfoLength(signature,GetPixelChannels(image)*image->columns*
515       sizeof(pixel));
516     pixels=GetStringInfoDatum(signature);
517     q=pixels;
518     for (x=0; x < (ssize_t) image->columns; x++)
519     {
520       register ssize_t
521         i;
522
523       if (GetPixelReadMask(image,p) == 0)
524         {
525           p+=GetPixelChannels(image);
526           continue;
527         }
528       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
529       {
530         register ssize_t
531           j;
532
533         PixelChannel channel=GetPixelChannelChannel(image,i);
534         PixelTrait traits=GetPixelChannelTraits(image,channel);
535         if (traits == UndefinedPixelTrait)
536           continue;
537         pixel=QuantumScale*p[i];
538         for (j=0; j < (ssize_t) sizeof(pixel); j++)
539           *q++=(unsigned char) ((unsigned char *) &pixel)[j];
540       }
541       p+=GetPixelChannels(image);
542     }
543     SetStringInfoLength(signature,(size_t) (q-pixels));
544     UpdateSignature(signature_info,signature);
545   }
546   image_view=DestroyCacheView(image_view);
547   FinalizeSignature(signature_info);
548   hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info));
549   (void) DeleteImageProperty(image,"signature");
550   (void) SetImageProperty(image,"signature",hex_signature,exception);
551   /*
552     Free resources.
553   */
554   hex_signature=DestroyString(hex_signature);
555   signature=DestroyStringInfo(signature);
556   signature_info=DestroySignatureInfo(signature_info);
557   return(MagickTrue);
558 }
559 \f
560 /*
561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
562 %                                                                             %
563 %                                                                             %
564 %                                                                             %
565 +   T r a n s f o r m S i g n a t u r e                                       %
566 %                                                                             %
567 %                                                                             %
568 %                                                                             %
569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
570 %
571 %  TransformSignature() transforms the Signature message accumulator.
572 %
573 %  The format of the TransformSignature method is:
574 %
575 %      TransformSignature(SignatureInfo *signature_info)
576 %
577 %  A description of each parameter follows:
578 %
579 %    o signature_info: the address of a structure of type SignatureInfo.
580 %
581 */
582
583 static inline unsigned int Ch(unsigned int x,unsigned int y,unsigned int z)
584 {
585   return((x & y) ^ (~x & z));
586 }
587
588 static inline unsigned int Maj(unsigned int x,unsigned int y,unsigned int z)
589 {
590   return((x & y) ^ (x & z) ^ (y & z));
591 }
592
593 static inline unsigned int Trunc32(unsigned int x)
594 {
595   return((unsigned int) (x & 0xffffffffU));
596 }
597
598 static unsigned int RotateRight(unsigned int x,unsigned int n)
599 {
600   return(Trunc32((x >> n) | (x << (32-n))));
601 }
602
603 static void TransformSignature(SignatureInfo *signature_info)
604 {
605 #define Sigma0(x)  (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
606 #define Sigma1(x)  (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
607 #define Suma0(x)  (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
608 #define Suma1(x)  (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
609
610   register ssize_t
611     i;
612
613   register unsigned char
614     *p;
615
616   ssize_t
617     j;
618
619   static unsigned int
620     K[64] =
621     {
622       0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU,
623       0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U,
624       0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U,
625       0xc19bf174U, 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU,
626       0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U,
627       0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U,
628       0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU,
629       0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U,
630       0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,
631       0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U,
632       0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU,
633       0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U,
634       0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U
635     };  /* 32-bit fractional part of the cube root of the first 64 primes */
636
637   unsigned int
638     A,
639     B,
640     C,
641     D,
642     E,
643     F,
644     G,
645     H,
646     shift,
647     T,
648     T1,
649     T2,
650     W[64];
651
652   shift=32;
653   p=GetStringInfoDatum(signature_info->message);
654   if (signature_info->lsb_first == MagickFalse)
655     {
656 DisableMSCWarning(4127)
657       if (sizeof(unsigned int) <= 4)
658 RestoreMSCWarning
659         for (i=0; i < 16; i++)
660         {
661           T=(*((unsigned int *) p));
662           p+=4;
663           W[i]=Trunc32(T);
664         }
665       else
666         for (i=0; i < 16; i+=2)
667         {
668           T=(*((unsigned int *) p));
669           p+=8;
670           W[i]=Trunc32(T >> shift);
671           W[i+1]=Trunc32(T);
672         }
673     }
674   else
675 DisableMSCWarning(4127)
676     if (sizeof(unsigned int) <= 4)
677 RestoreMSCWarning
678       for (i=0; i < 16; i++)
679       {
680         T=(*((unsigned int *) p));
681         p+=4;
682         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
683           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
684       }
685     else
686       for (i=0; i < 16; i+=2)
687       {
688         T=(*((unsigned int *) p));
689         p+=8;
690         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
691           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
692         T>>=shift;
693         W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
694           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
695       }
696   /*
697     Copy accumulator to registers.
698   */
699   A=signature_info->accumulator[0];
700   B=signature_info->accumulator[1];
701   C=signature_info->accumulator[2];
702   D=signature_info->accumulator[3];
703   E=signature_info->accumulator[4];
704   F=signature_info->accumulator[5];
705   G=signature_info->accumulator[6];
706   H=signature_info->accumulator[7];
707   for (i=16; i < 64; i++)
708     W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
709   for (j=0; j < 64; j++)
710   {
711     T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
712     T2=Trunc32(Suma0(A)+Maj(A,B,C));
713     H=G;
714     G=F;
715     F=E;
716     E=Trunc32(D+T1);
717     D=C;
718     C=B;
719     B=A;
720     A=Trunc32(T1+T2);
721   }
722   /*
723     Add registers back to accumulator.
724   */
725   signature_info->accumulator[0]=Trunc32(signature_info->accumulator[0]+A);
726   signature_info->accumulator[1]=Trunc32(signature_info->accumulator[1]+B);
727   signature_info->accumulator[2]=Trunc32(signature_info->accumulator[2]+C);
728   signature_info->accumulator[3]=Trunc32(signature_info->accumulator[3]+D);
729   signature_info->accumulator[4]=Trunc32(signature_info->accumulator[4]+E);
730   signature_info->accumulator[5]=Trunc32(signature_info->accumulator[5]+F);
731   signature_info->accumulator[6]=Trunc32(signature_info->accumulator[6]+G);
732   signature_info->accumulator[7]=Trunc32(signature_info->accumulator[7]+H);
733   /*
734     Reset working registers.
735   */
736   A=0;
737   B=0;
738   C=0;
739   D=0;
740   E=0;
741   F=0;
742   G=0;
743   H=0;
744   T=0;
745   T1=0;
746   T2=0;
747   (void) ResetMagickMemory(W,0,sizeof(W));
748 }
749 \f
750 /*
751 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
752 %                                                                             %
753 %                                                                             %
754 %                                                                             %
755 +   U p d a t e S i g n a t u r e                                             %
756 %                                                                             %
757 %                                                                             %
758 %                                                                             %
759 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
760 %
761 %  UpdateSignature() updates the Signature message accumulator.
762 %
763 %  The format of the UpdateSignature method is:
764 %
765 %      UpdateSignature(SignatureInfo *signature_info,const StringInfo *message)
766 %
767 %  A description of each parameter follows:
768 %
769 %    o signature_info: the address of a structure of type SignatureInfo.
770 %
771 %    o message: the message.
772 %
773 */
774 MagickPrivate void UpdateSignature(SignatureInfo *signature_info,
775   const StringInfo *message)
776 {
777   register size_t
778     i;
779
780   register unsigned char
781     *p;
782
783   size_t
784     n;
785
786   unsigned int
787     length;
788
789   /*
790     Update the Signature accumulator.
791   */
792   assert(signature_info != (SignatureInfo *) NULL);
793   assert(signature_info->signature == MagickCoreSignature);
794   n=GetStringInfoLength(message);
795   length=Trunc32((unsigned int) (signature_info->low_order+(n << 3)));
796   if (length < signature_info->low_order)
797     signature_info->high_order++;
798   signature_info->low_order=length;
799   signature_info->high_order+=(unsigned int) (n >> 29);
800   p=GetStringInfoDatum(message);
801   if (signature_info->offset != 0)
802     {
803       i=GetStringInfoLength(signature_info->message)-signature_info->offset;
804       if (i > n)
805         i=n;
806       (void) CopyMagickMemory(GetStringInfoDatum(signature_info->message)+
807         signature_info->offset,p,i);
808       n-=i;
809       p+=i;
810       signature_info->offset+=i;
811       if (signature_info->offset !=
812           GetStringInfoLength(signature_info->message))
813         return;
814       TransformSignature(signature_info);
815     }
816   while (n >= GetStringInfoLength(signature_info->message))
817   {
818     SetStringInfoDatum(signature_info->message,p);
819     p+=GetStringInfoLength(signature_info->message);
820     n-=GetStringInfoLength(signature_info->message);
821     TransformSignature(signature_info);
822   }
823   (void) CopyMagickMemory(GetStringInfoDatum(signature_info->message),p,n);
824   signature_info->offset=n;
825 }