source: ImageMagick/trunk/magick/signature.c @ 4683

Revision 4683, 28.5 KB checked in by glennrp, 23 months ago (diff)

spelling (initialize)

Line 
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
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
60/*
61  Typedef declarations.
62*/
63struct _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
91/*
92  Forward declarations.
93*/
94static void
95  TransformSignature(SignatureInfo *);
96
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*/
115MagickExport 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
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*/
167MagickExport 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
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*/
206MagickExport 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
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*/
296MagickExport 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
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*/
327MagickExport 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
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*/
358MagickExport 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
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%  InitializeSignature() initializes 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*/
389MagickExport 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
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*/
432MagickExport 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
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*/
468MagickExport 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
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
577static inline unsigned int Ch(unsigned int x,unsigned int y,unsigned int z)
578{
579  return((x & y) ^ (~x & z));
580}
581
582static inline unsigned int Maj(unsigned int x,unsigned int y,unsigned int z)
583{
584  return((x & y) ^ (x & z) ^ (y & z));
585}
586
587static inline unsigned int Trunc32(unsigned int x)
588{
589  return((unsigned int) (x & 0xffffffffU));
590}
591
592static unsigned int RotateRight(unsigned int x,unsigned int n)
593{
594  return(Trunc32((x >> n) | (x << (32-n))));
595}
596
597static 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
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*/
764MagickExport 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}
Note: See TracBrowser for help on using the repository browser.