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