]> granicus.if.org Git - imagemagick/blob - MagickCore/signature.c
(no commit message)
[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=MagickSignature;
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 == MagickSignature);
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=(~MagickSignature);
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 == MagickSignature);
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     Reset working registers.
269   */
270   count=0;
271   high_order=0;
272   low_order=0;
273 }
274 \f
275 /*
276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
277 %                                                                             %
278 %                                                                             %
279 %                                                                             %
280 +   G e t S i g n a t u r e B l o c k s i z e                                 %
281 %                                                                             %
282 %                                                                             %
283 %                                                                             %
284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285 %
286 %  GetSignatureBlocksize() returns the Signature blocksize.
287 %
288 %  The format of the GetSignatureBlocksize method is:
289 %
290 %      unsigned int *GetSignatureBlocksize(const SignatureInfo *signature_info)
291 %
292 %  A description of each parameter follows:
293 %
294 %    o signature_info: the signature info.
295 %
296 */
297 MagickPrivate unsigned int GetSignatureBlocksize(
298   const SignatureInfo *signature_info)
299 {
300   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
301   assert(signature_info != (SignatureInfo *) NULL);
302   assert(signature_info->signature == MagickSignature);
303   return(signature_info->blocksize);
304 }
305 \f
306 /*
307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
308 %                                                                             %
309 %                                                                             %
310 %                                                                             %
311 +   G e t S i g n a t u r e D i g e s t                                       %
312 %                                                                             %
313 %                                                                             %
314 %                                                                             %
315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
316 %
317 %  GetSignatureDigest() returns the signature digest.
318 %
319 %  The format of the GetSignatureDigest method is:
320 %
321 %      const StringInfo *GetSignatureDigest(const SignatureInfo *signature_info)
322 %
323 %  A description of each parameter follows:
324 %
325 %    o signature_info: the signature info.
326 %
327 */
328 MagickPrivate const StringInfo *GetSignatureDigest(
329   const SignatureInfo *signature_info)
330 {
331   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
332   assert(signature_info != (SignatureInfo *) NULL);
333   assert(signature_info->signature == MagickSignature);
334   return(signature_info->digest);
335 }
336 \f
337 /*
338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
339 %                                                                             %
340 %                                                                             %
341 %                                                                             %
342 +   G e t S i g n a t u r e D i g e s t s i z e                               %
343 %                                                                             %
344 %                                                                             %
345 %                                                                             %
346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347 %
348 %  GetSignatureDigestsize() returns the Signature digest size.
349 %
350 %  The format of the GetSignatureDigestsize method is:
351 %
352 %      unsigned int *GetSignatureDigestsize(const SignatureInfo *signature_info)
353 %
354 %  A description of each parameter follows:
355 %
356 %    o signature_info: the signature info.
357 %
358 */
359 MagickPrivate unsigned int GetSignatureDigestsize(
360   const SignatureInfo *signature_info)
361 {
362   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
363   assert(signature_info != (SignatureInfo *) NULL);
364   assert(signature_info->signature == MagickSignature);
365   return(signature_info->digestsize);
366 }
367 \f
368 /*
369 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
370 %                                                                             %
371 %                                                                             %
372 %                                                                             %
373 +   I n i t i a l i z e S i g n a t u r e                                     %
374 %                                                                             %
375 %                                                                             %
376 %                                                                             %
377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378 %
379 %  InitializeSignature() initializes the Signature accumulator.
380 %
381 %  The format of the DestroySignatureInfo method is:
382 %
383 %      void InitializeSignatureInfo(SignatureInfo *signature_info)
384 %
385 %  A description of each parameter follows:
386 %
387 %    o signature_info: the cipher signature_info.
388 %
389 */
390 MagickPrivate void InitializeSignature(SignatureInfo *signature_info)
391 {
392   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
393   assert(signature_info != (SignatureInfo *) NULL);
394   assert(signature_info->signature == MagickSignature);
395   signature_info->accumulator[0]=0x6a09e667U;
396   signature_info->accumulator[1]=0xbb67ae85U;
397   signature_info->accumulator[2]=0x3c6ef372U;
398   signature_info->accumulator[3]=0xa54ff53aU;
399   signature_info->accumulator[4]=0x510e527fU;
400   signature_info->accumulator[5]=0x9b05688cU;
401   signature_info->accumulator[6]=0x1f83d9abU;
402   signature_info->accumulator[7]=0x5be0cd19U;
403   signature_info->low_order=0;
404   signature_info->high_order=0;
405   signature_info->offset=0;
406 }
407 \f
408 /*
409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
410 %                                                                             %
411 %                                                                             %
412 %                                                                             %
413 +   S e t S i g n a t u r e D i g e s t                                       %
414 %                                                                             %
415 %                                                                             %
416 %                                                                             %
417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
418 %
419 %  SetSignatureDigest() set the signature digest.
420 %
421 %  The format of the SetSignatureDigest method is:
422 %
423 %      SetSignatureDigest(SignatureInfo *signature_info,
424 %        const StringInfo *digest)
425 %
426 %  A description of each parameter follows:
427 %
428 %    o signature_info: the signature info.
429 %
430 %    o digest: the digest.
431 %
432 */
433 MagickPrivate void SetSignatureDigest(SignatureInfo *signature_info,
434   const StringInfo *digest)
435 {
436   /*
437     Set the signature accumulator.
438   */
439   assert(signature_info != (SignatureInfo *) NULL);
440   assert(signature_info->signature == MagickSignature);
441   SetStringInfo(signature_info->digest,digest);
442 }
443 \f
444 /*
445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
446 %                                                                             %
447 %                                                                             %
448 %                                                                             %
449 %   S i g n a t u r e I m a g e                                               %
450 %                                                                             %
451 %                                                                             %
452 %                                                                             %
453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
454 %
455 %  SignatureImage() computes a message digest from an image pixel stream with
456 %  an implementation of the NIST SHA-256 Message Digest algorithm.  This
457 %  signature uniquely identifies the image and is convenient for determining
458 %  if an image has been modified or whether two images are identical.
459 %
460 %  The format of the SignatureImage method is:
461 %
462 %      MagickBooleanType SignatureImage(Image *image,ExceptionInfo *exception)
463 %
464 %  A description of each parameter follows:
465 %
466 %    o image: the image.
467 %
468 %    o exception: return any errors or warnings in this structure.
469 %
470 */
471 MagickExport MagickBooleanType SignatureImage(Image *image,
472   ExceptionInfo *exception)
473 {
474   CacheView
475     *image_view;
476
477   char
478     *hex_signature;
479
480   double
481     pixel;
482
483   register const Quantum
484     *p;
485
486   SignatureInfo
487     *signature_info;
488
489   ssize_t
490     y;
491
492   StringInfo
493     *signature;
494
495   unsigned char
496     *pixels;
497
498   /*
499     Compute image digital signature.
500   */
501   assert(image != (Image *) NULL);
502   assert(image->signature == MagickSignature);
503   if (image->debug != MagickFalse)
504     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
505   signature_info=AcquireSignatureInfo();
506   signature=AcquireStringInfo(image->columns*GetPixelChannels(image)*
507     sizeof(pixel));
508   image_view=AcquireVirtualCacheView(image,exception);
509   for (y=0; y < (ssize_t) image->rows; y++)
510   {
511     register ssize_t
512       x;
513
514     register unsigned char
515       *q;
516
517     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
518     if (p == (const Quantum *) NULL)
519       break;
520     SetStringInfoLength(signature,image->columns*GetPixelChannels(image)*
521       sizeof(pixel));
522     pixels=GetStringInfoDatum(signature);
523     q=pixels;
524     for (x=0; x < (ssize_t) image->columns; x++)
525     {
526       register ssize_t
527         i;
528
529       if (GetPixelReadMask(image,p) == 0)
530         {
531           p+=GetPixelChannels(image);
532           continue;
533         }
534       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
535       {
536         register ssize_t
537           j;
538
539         PixelChannel channel=GetPixelChannelChannel(image,i);
540         PixelTrait traits=GetPixelChannelTraits(image,channel);
541         if (traits == UndefinedPixelTrait)
542           continue;
543         pixel=QuantumScale*p[i];
544         for (j=0; j < (ssize_t) sizeof(pixel); j++)
545           *q++=(unsigned char) ((unsigned char *) &pixel)[j];
546       }
547       p+=GetPixelChannels(image);
548     }
549     SetStringInfoLength(signature,(size_t) (q-pixels));
550     UpdateSignature(signature_info,signature);
551   }
552   image_view=DestroyCacheView(image_view);
553   FinalizeSignature(signature_info);
554   hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info));
555   (void) DeleteImageProperty(image,"signature");
556   (void) SetImageProperty(image,"signature",hex_signature,exception);
557   /*
558     Free resources.
559   */
560   hex_signature=DestroyString(hex_signature);
561   signature=DestroyStringInfo(signature);
562   signature_info=DestroySignatureInfo(signature_info);
563   return(MagickTrue);
564 }
565 \f
566 /*
567 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
568 %                                                                             %
569 %                                                                             %
570 %                                                                             %
571 +   T r a n s f o r m S i g n a t u r e                                       %
572 %                                                                             %
573 %                                                                             %
574 %                                                                             %
575 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
576 %
577 %  TransformSignature() transforms the Signature message accumulator.
578 %
579 %  The format of the TransformSignature method is:
580 %
581 %      TransformSignature(SignatureInfo *signature_info)
582 %
583 %  A description of each parameter follows:
584 %
585 %    o signature_info: the address of a structure of type SignatureInfo.
586 %
587 */
588
589 static inline unsigned int Ch(unsigned int x,unsigned int y,unsigned int z)
590 {
591   return((x & y) ^ (~x & z));
592 }
593
594 static inline unsigned int Maj(unsigned int x,unsigned int y,unsigned int z)
595 {
596   return((x & y) ^ (x & z) ^ (y & z));
597 }
598
599 static inline unsigned int Trunc32(unsigned int x)
600 {
601   return((unsigned int) (x & 0xffffffffU));
602 }
603
604 static unsigned int RotateRight(unsigned int x,unsigned int n)
605 {
606   return(Trunc32((x >> n) | (x << (32-n))));
607 }
608
609 static void TransformSignature(SignatureInfo *signature_info)
610 {
611 #define Sigma0(x)  (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
612 #define Sigma1(x)  (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
613 #define Suma0(x)  (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
614 #define Suma1(x)  (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
615
616   register ssize_t
617     i;
618
619   register unsigned char
620     *p;
621
622   ssize_t
623     j;
624
625   static unsigned int
626     K[64] =
627     {
628       0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU,
629       0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U,
630       0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U,
631       0xc19bf174U, 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU,
632       0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U,
633       0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U,
634       0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU,
635       0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U,
636       0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,
637       0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U,
638       0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU,
639       0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U,
640       0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U
641     };  /* 32-bit fractional part of the cube root of the first 64 primes */
642
643   unsigned int
644     A,
645     B,
646     C,
647     D,
648     E,
649     F,
650     G,
651     H,
652     shift,
653     T,
654     T1,
655     T2,
656     W[64];
657
658   shift=32;
659   p=GetStringInfoDatum(signature_info->message);
660   if (signature_info->lsb_first == MagickFalse)
661     {
662 DisableMSCWarning(4127)
663       if (sizeof(unsigned int) <= 4)
664 RestoreMSCWarning
665         for (i=0; i < 16; i++)
666         {
667           T=(*((unsigned int *) p));
668           p+=4;
669           W[i]=Trunc32(T);
670         }
671       else
672         for (i=0; i < 16; i+=2)
673         {
674           T=(*((unsigned int *) p));
675           p+=8;
676           W[i]=Trunc32(T >> shift);
677           W[i+1]=Trunc32(T);
678         }
679     }
680   else
681 DisableMSCWarning(4127)
682     if (sizeof(unsigned int) <= 4)
683 RestoreMSCWarning
684       for (i=0; i < 16; i++)
685       {
686         T=(*((unsigned int *) p));
687         p+=4;
688         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
689           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
690       }
691     else
692       for (i=0; i < 16; i+=2)
693       {
694         T=(*((unsigned int *) p));
695         p+=8;
696         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
697           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
698         T>>=shift;
699         W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
700           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
701       }
702   /*
703     Copy accumulator to registers.
704   */
705   A=signature_info->accumulator[0];
706   B=signature_info->accumulator[1];
707   C=signature_info->accumulator[2];
708   D=signature_info->accumulator[3];
709   E=signature_info->accumulator[4];
710   F=signature_info->accumulator[5];
711   G=signature_info->accumulator[6];
712   H=signature_info->accumulator[7];
713   for (i=16; i < 64; i++)
714     W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
715   for (j=0; j < 64; j++)
716   {
717     T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
718     T2=Trunc32(Suma0(A)+Maj(A,B,C));
719     H=G;
720     G=F;
721     F=E;
722     E=Trunc32(D+T1);
723     D=C;
724     C=B;
725     B=A;
726     A=Trunc32(T1+T2);
727   }
728   /*
729     Add registers back to accumulator.
730   */
731   signature_info->accumulator[0]=Trunc32(signature_info->accumulator[0]+A);
732   signature_info->accumulator[1]=Trunc32(signature_info->accumulator[1]+B);
733   signature_info->accumulator[2]=Trunc32(signature_info->accumulator[2]+C);
734   signature_info->accumulator[3]=Trunc32(signature_info->accumulator[3]+D);
735   signature_info->accumulator[4]=Trunc32(signature_info->accumulator[4]+E);
736   signature_info->accumulator[5]=Trunc32(signature_info->accumulator[5]+F);
737   signature_info->accumulator[6]=Trunc32(signature_info->accumulator[6]+G);
738   signature_info->accumulator[7]=Trunc32(signature_info->accumulator[7]+H);
739   /*
740     Reset working registers.
741   */
742   A=0;
743   B=0;
744   C=0;
745   D=0;
746   E=0;
747   F=0;
748   G=0;
749   H=0;
750   T=0;
751   T1=0;
752   T2=0;
753   (void) ResetMagickMemory(W,0,sizeof(W));
754 }
755 \f
756 /*
757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
758 %                                                                             %
759 %                                                                             %
760 %                                                                             %
761 +   U p d a t e S i g n a t u r e                                             %
762 %                                                                             %
763 %                                                                             %
764 %                                                                             %
765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
766 %
767 %  UpdateSignature() updates the Signature message accumulator.
768 %
769 %  The format of the UpdateSignature method is:
770 %
771 %      UpdateSignature(SignatureInfo *signature_info,const StringInfo *message)
772 %
773 %  A description of each parameter follows:
774 %
775 %    o signature_info: the address of a structure of type SignatureInfo.
776 %
777 %    o message: the message.
778 %
779 */
780 MagickPrivate void UpdateSignature(SignatureInfo *signature_info,
781   const StringInfo *message)
782 {
783   register size_t
784     i;
785
786   register unsigned char
787     *p;
788
789   size_t
790     n;
791
792   unsigned int
793     length;
794
795   /*
796     Update the Signature accumulator.
797   */
798   assert(signature_info != (SignatureInfo *) NULL);
799   assert(signature_info->signature == MagickSignature);
800   n=GetStringInfoLength(message);
801   length=Trunc32((unsigned int) (signature_info->low_order+(n << 3)));
802   if (length < signature_info->low_order)
803     signature_info->high_order++;
804   signature_info->low_order=length;
805   signature_info->high_order+=(unsigned int) (n >> 29);
806   p=GetStringInfoDatum(message);
807   if (signature_info->offset != 0)
808     {
809       i=GetStringInfoLength(signature_info->message)-signature_info->offset;
810       if (i > n)
811         i=n;
812       (void) CopyMagickMemory(GetStringInfoDatum(signature_info->message)+
813         signature_info->offset,p,i);
814       n-=i;
815       p+=i;
816       signature_info->offset+=i;
817       if (signature_info->offset !=
818           GetStringInfoLength(signature_info->message))
819         return;
820       TransformSignature(signature_info);
821     }
822   while (n >= GetStringInfoLength(signature_info->message))
823   {
824     SetStringInfoDatum(signature_info->message,p);
825     p+=GetStringInfoLength(signature_info->message);
826     n-=GetStringInfoLength(signature_info->message);
827     TransformSignature(signature_info);
828   }
829   (void) CopyMagickMemory(GetStringInfoDatum(signature_info->message),p,n);
830   signature_info->offset=n;
831   /*
832     Reset working registers.
833   */
834   i=0;
835   n=0;
836   length=0;
837 }