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