|
ocssw
1.0
|
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % SSSSS IIIII GGGG N N AAA TTTTT U U RRRR EEEEE % 00006 % SS I G NN N A A T U U R R E % 00007 % SSS I G GG N N N AAAAA T U U RRRR EEE % 00008 % SS I G G N NN A A T U U R R E % 00009 % SSSSS IIIII GGG N N A A T UUU R R EEEEE % 00010 % % 00011 % % 00012 % Compute a Digital Signature for a Image Colormap % 00013 % % 00014 % % 00015 % % 00016 % Software Design % 00017 % John Cristy % 00018 % December 1992 % 00019 % % 00020 % Copyright 1994 E. I. du Pont de Nemours and Company % 00021 % % 00022 % Permission to use, copy, modify, distribute, and sell this software and % 00023 % its documentation for any purpose is hereby granted without fee, % 00024 % provided that the above Copyright notice appear in all copies and that % 00025 % both that Copyright notice and this permission notice appear in % 00026 % supporting documentation, and that the name of E. I. du Pont de Nemours % 00027 % and Company not be used in advertising or publicity pertaining to % 00028 % distribution of the software without specific, written prior % 00029 % permission. E. I. du Pont de Nemours and Company makes no representations % 00030 % about the suitability of this software for any purpose. It is provided % 00031 % "as is" without express or implied warranty. % 00032 % % 00033 % E. I. du Pont de Nemours and Company disclaims all warranties with regard % 00034 % to this software, including all implied warranties of merchantability % 00035 % and fitness, in no event shall E. I. du Pont de Nemours and Company be % 00036 % liable for any special, indirect or consequential damages or any % 00037 % damages whatsoever resulting from loss of use, data or profits, whether % 00038 % in an action of contract, negligence or other tortuous action, arising % 00039 % out of or in connection with the use or performance of this software. % 00040 % % 00041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00042 % 00043 % Routine ColormapSignature computes a digital signature from the image 00044 % colormap. This signature uniquely identifies the colormap and is convenient 00045 % for determining if the colormap of a sequence of images is identical when 00046 % animating. The digital signature is from RSA Data Security MD5 Digest 00047 % Algorithm described in Internet draft [MD5], July 1992. 00048 % 00049 % 00050 */ 00051 00052 /* 00053 Include declarations. 00054 */ 00055 #include "magick.h" 00056 #include "image.h" 00057 00058 /* 00059 Typedef declarations. 00060 */ 00061 typedef struct _MessageDigest 00062 { 00063 uint32_t 00064 number_bits[2], 00065 accumulator[4]; 00066 00067 unsigned char 00068 message[64], 00069 digest[16]; 00070 } MessageDigest; 00071 00072 /* 00073 Forward declarations. 00074 */ 00075 static void 00076 TransformMessageDigest _Declare((MessageDigest *,uint32_t *)), 00077 UpdateMessageDigest _Declare((MessageDigest *,unsigned char *,uint32_t)); 00078 00079 /* 00080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00081 % % 00082 % % 00083 % % 00084 % C o m p u t e M e s s a g e D i g e s t % 00085 % % 00086 % % 00087 % % 00088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00089 % 00090 % Function ComputeMessageDigest computes the message digest. 00091 % 00092 % The format of the ComputeMessageDigest routine is: 00093 % 00094 % ComputeMessageDigest(message_digest,input_message,message_length) 00095 % 00096 % A description of each parameter follows: 00097 % 00098 % o message_digest: The address of a structure of type MessageDigest. 00099 % 00100 % 00101 */ 00102 static void ComputeMessageDigest(message_digest) 00103 MessageDigest 00104 *message_digest; 00105 { 00106 int 00107 number_bytes; 00108 00109 register unsigned char 00110 *p; 00111 00112 register unsigned int 00113 i; 00114 00115 unsigned char 00116 padding[64]; 00117 00118 uint32_t 00119 message[16], 00120 padding_length; 00121 00122 /* 00123 Save number of bits. 00124 */ 00125 message[14]=message_digest->number_bits[0]; 00126 message[15]=message_digest->number_bits[1]; 00127 /* 00128 Compute number of bytes mod 64. 00129 */ 00130 number_bytes=(int) ((message_digest->number_bits[0] >> 3) & 0x3F); 00131 /* 00132 Pad message to 56 mod 64. 00133 */ 00134 padding_length=(number_bytes < 56) ? (56-number_bytes) : (120-number_bytes); 00135 padding[0]=0x80; 00136 for (i=1; i < padding_length; i++) 00137 padding[i]=(char) 0; 00138 UpdateMessageDigest(message_digest,padding,padding_length); 00139 /* 00140 Append length in bits and transform. 00141 */ 00142 p=message_digest->message; 00143 for (i=0; i < 14; i++) 00144 { 00145 message[i]=(uint32_t) (*p++); 00146 message[i]|=((uint32_t) (*p++)) << 8; 00147 message[i]|=((uint32_t) (*p++)) << 16; 00148 message[i]|=((uint32_t) (*p++)) << 24; 00149 } 00150 TransformMessageDigest(message_digest,message); 00151 /* 00152 Store message in digest. 00153 */ 00154 p=message_digest->digest; 00155 for (i=0; i < 4; i++) 00156 { 00157 *p++=(unsigned char) (message_digest->accumulator[i] & 0xff); 00158 *p++=(unsigned char) ((message_digest->accumulator[i] >> 8) & 0xff); 00159 *p++=(unsigned char) ((message_digest->accumulator[i] >> 16) & 0xff); 00160 *p++=(unsigned char) ((message_digest->accumulator[i] >> 24) & 0xff); 00161 } 00162 } 00163 00164 /* 00165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00166 % % 00167 % % 00168 % % 00169 % I n i t i a l i z e M e s s a g e D i g e s t % 00170 % % 00171 % % 00172 % % 00173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00174 % 00175 % Function InitializeMessageDigest initializes the message digest structure. 00176 % 00177 % The format of the InitializeMessageDigest routine is: 00178 % 00179 % InitializeMessageDigest(message_digest) 00180 % 00181 % A description of each parameter follows: 00182 % 00183 % o message_digest: The address of a structure of type MessageDigest. 00184 % 00185 % 00186 */ 00187 static void InitializeMessageDigest(message_digest) 00188 MessageDigest 00189 *message_digest; 00190 { 00191 message_digest->number_bits[0]=(uint32_t) 0; 00192 message_digest->number_bits[1]=(uint32_t) 0; 00193 /* 00194 Load magic initialization constants. 00195 */ 00196 message_digest->accumulator[0]=(uint32_t) 0x67452301; 00197 message_digest->accumulator[1]=(uint32_t) 0xefcdab89; 00198 message_digest->accumulator[2]=(uint32_t) 0x98badcfe; 00199 message_digest->accumulator[3]=(uint32_t) 0x10325476; 00200 } 00201 00202 /* 00203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00204 % % 00205 % % 00206 % % 00207 % T r a n s f o r m M e s s a g e D i g e s t % 00208 % % 00209 % % 00210 % % 00211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00212 % 00213 % Function TransformMessageDigest updates the message digest. 00214 % 00215 % The format of the TransformMessageDigest routine is: 00216 % 00217 % TransformMessageDigest(message_digest,message) 00218 % 00219 % A description of each parameter follows: 00220 % 00221 % o message_digest: The address of a structure of type MessageDigest. 00222 % 00223 % 00224 */ 00225 static void TransformMessageDigest(message_digest,message) 00226 MessageDigest 00227 *message_digest; 00228 00229 uint32_t 00230 *message; 00231 { 00232 #define F(x,y,z) (((x) & (y)) | ((~x) & (z))) 00233 #define G(x,y,z) (((x) & (z)) | ((y) & (~z))) 00234 #define H(x,y,z) ((x) ^ (y) ^ (z)) 00235 #define I(x,y,z) ((y) ^ ((x) | (~z))) 00236 #define RotateLeft(x,n) (((x) << (n)) | (((x) & 0xffffffff) >> (32-(n)))) 00237 00238 static uint32_t 00239 additive_constant[64]= /* 4294967296*abs(sin(i)), i in radians */ 00240 { 00241 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 00242 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 00243 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 00244 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 00245 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 00246 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 00247 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 00248 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 00249 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, 0xd9d4d039, 00250 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 00251 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 00252 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 00253 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, 00254 }; 00255 00256 register int 00257 i; 00258 00259 register unsigned int 00260 j; 00261 00262 register uint32_t 00263 a, 00264 b, 00265 c, 00266 d, 00267 *p; 00268 00269 /* 00270 Save accumulator. 00271 */ 00272 a=message_digest->accumulator[0]; 00273 b=message_digest->accumulator[1]; 00274 c=message_digest->accumulator[2]; 00275 d=message_digest->accumulator[3]; 00276 /* 00277 a=b+((a+F(b,c,d)+X[k]+t) <<< s). 00278 */ 00279 p=additive_constant; 00280 j=0; 00281 for (i=0; i < 4; i++) 00282 { 00283 a+=F(b,c,d)+message[j & 0x0f]+(*p++); 00284 a=RotateLeft(a,7)+b; 00285 j++; 00286 d+=F(a,b,c)+message[j & 0x0f]+(*p++); 00287 d=RotateLeft(d,12)+a; 00288 j++; 00289 c+=F(d,a,b)+message[j & 0x0f]+(*p++); 00290 c=RotateLeft(c,17)+d; 00291 j++; 00292 b+=F(c,d,a)+message[j & 0x0f]+(*p++); 00293 b=RotateLeft(b,22)+c; 00294 j++; 00295 } 00296 /* 00297 a=b+((a+G(b,c,d)+X[k]+t) <<< s). 00298 */ 00299 j=1; 00300 for (i=0; i < 4; i++) 00301 { 00302 a+=G(b,c,d)+message[j & 0x0f]+(*p++); 00303 a=RotateLeft(a,5)+b; 00304 j+=5; 00305 d+=G(a,b,c)+message[j & 0x0f]+(*p++); 00306 d=RotateLeft(d,9)+a; 00307 j+=5; 00308 c+=G(d,a,b)+message[j & 0x0f]+(*p++); 00309 c=RotateLeft(c,14)+d; 00310 j+=5; 00311 b+=G(c,d,a)+message[j & 0x0f]+(*p++); 00312 b=RotateLeft(b,20)+c; 00313 j+=5; 00314 } 00315 /* 00316 a=b+((a+H(b,c,d)+X[k]+t) <<< s). 00317 */ 00318 j=5; 00319 for (i=0; i < 4; i++) 00320 { 00321 a+=H(b,c,d)+message[j & 0x0f]+(*p++); 00322 a=RotateLeft(a,4)+b; 00323 j+=3; 00324 d+=H(a,b,c)+message[j & 0x0f]+(*p++); 00325 d=RotateLeft(d,11)+a; 00326 j+=3; 00327 c+=H(d,a,b)+message[j & 0x0f]+(*p++); 00328 c=RotateLeft(c,16)+d; 00329 j+=3; 00330 b+=H(c,d,a)+message[j & 0x0f]+(*p++); 00331 b=RotateLeft(b,23)+c; 00332 j+=3; 00333 } 00334 /* 00335 a=b+((a+I(b,c,d)+X[k]+t) <<< s). 00336 */ 00337 j=0; 00338 for (i=0; i < 4; i++) 00339 { 00340 a+=I(b,c,d)+message[j & 0x0f]+(*p++); 00341 a=RotateLeft(a,6)+b; 00342 j+=7; 00343 d+=I(a,b,c)+message[j & 0x0f]+(*p++); 00344 d=RotateLeft(d,10)+a; 00345 j+=7; 00346 c+=I(d,a,b)+message[j & 0x0f]+(*p++); 00347 c=RotateLeft(c,15)+d; 00348 j+=7; 00349 b+=I(c,d,a)+message[j & 0x0f]+(*p++); 00350 b=RotateLeft(b,21)+c; 00351 j+=7; 00352 } 00353 /* 00354 Increment accumulator. 00355 */ 00356 message_digest->accumulator[0]+=a; 00357 message_digest->accumulator[1]+=b; 00358 message_digest->accumulator[2]+=c; 00359 message_digest->accumulator[3]+=d; 00360 } 00361 00362 /* 00363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00364 % % 00365 % % 00366 % % 00367 % U p d a t e M e s s a g e D i g e s t % 00368 % % 00369 % % 00370 % % 00371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00372 % 00373 % Function UpdateMessageDigest updates the message digest. 00374 % 00375 % The format of the UpdateMessageDigest routine is: 00376 % 00377 % UpdateMessageDigest(message_digest,input_message,message_length) 00378 % 00379 % A description of each parameter follows: 00380 % 00381 % o message_digest: The address of a structure of type MessageDigest. 00382 % 00383 % 00384 */ 00385 static void UpdateMessageDigest(message_digest,input_message,message_length) 00386 MessageDigest 00387 *message_digest; 00388 00389 unsigned char 00390 *input_message; 00391 00392 uint32_t 00393 message_length; 00394 { 00395 int 00396 number_bytes; 00397 00398 register unsigned char 00399 *p; 00400 00401 register unsigned int 00402 i; 00403 00404 uint32_t 00405 message[16]; 00406 00407 /* 00408 Compute number of bytes mod 64. 00409 */ 00410 number_bytes=(int) ((message_digest->number_bits[0] >> 3) & 0x3F); 00411 /* 00412 Update number of bits. 00413 */ 00414 if (((message_digest->number_bits[0]+(message_length << 3)) & 0xffffffff) < 00415 message_digest->number_bits[0]) 00416 message_digest->number_bits[1]++; 00417 message_digest->number_bits[0]+=message_length << 3; 00418 message_digest->number_bits[1]+=message_length >> 29; 00419 while (message_length--) 00420 { 00421 /* 00422 Add new character to message. 00423 */ 00424 message_digest->message[number_bytes++]=(*input_message++); 00425 if (number_bytes == 0x40) 00426 { 00427 /* 00428 Transform message digest 64 bytes at a time. 00429 */ 00430 p=message_digest->message; 00431 for (i=0; i < 16; i++) 00432 { 00433 message[i]=(uint32_t) (*p++); 00434 message[i]|=((uint32_t) (*p++)) << 8; 00435 message[i]|=((uint32_t) (*p++)) << 16; 00436 message[i]|=((uint32_t) (*p++)) << 24; 00437 } 00438 TransformMessageDigest(message_digest,message); 00439 number_bytes=0; 00440 } 00441 } 00442 } 00443 00444 /* 00445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00446 % % 00447 % % 00448 % % 00449 % C o l o r m a p S i g n a t u r e % 00450 % % 00451 % % 00452 % % 00453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00454 % 00455 % Fucntion ColormapSignature computes a digital signature from the image 00456 % colormap. This signature uniquely identifies the colormap and is convenient 00457 % for determining if the colormap of a sequence of images is identical when 00458 % animating. The digital signature is from RSA Data Security MD5 Digest 00459 % Algorithm described in Internet draft [MD5], July 1992. 00460 % 00461 % The format of the ColormapSignature routine is: 00462 % 00463 % ColormapSignature(image) 00464 % 00465 % A description of each parameter follows: 00466 % 00467 % o image: The address of a structure of type Image. 00468 % 00469 % 00470 % 00471 */ 00472 void ColormapSignature(image) 00473 Image 00474 *image; 00475 { 00476 char 00477 *hex; 00478 00479 MessageDigest 00480 message_digest; 00481 00482 register int 00483 i; 00484 00485 register unsigned char 00486 *p; 00487 00488 unsigned char 00489 *colormap; 00490 00491 if (image->class != PseudoClass) 00492 return; 00493 /* 00494 Allocate colormap. 00495 */ 00496 colormap=(unsigned char *) malloc(3*image->colors*sizeof(unsigned char)); 00497 if (colormap == (unsigned char *) NULL) 00498 { 00499 Warning("Unable to compute colormap signature", 00500 "Memory allocation failed"); 00501 return; 00502 } 00503 p=colormap; 00504 for (i=0; i < image->colors; i++) 00505 { 00506 *p++=image->colormap[i].red; 00507 *p++=image->colormap[i].green; 00508 *p++=image->colormap[i].blue; 00509 } 00510 /* 00511 Compute program colormap signature. 00512 */ 00513 InitializeMessageDigest(&message_digest); 00514 UpdateMessageDigest(&message_digest,colormap, 00515 (uint32_t) (image->colors*3)); 00516 ComputeMessageDigest(&message_digest); 00517 (void) free((char *) colormap); 00518 /* 00519 Allocate memory for signature. 00520 */ 00521 if (image->signature != (char *) NULL) 00522 (void) free((char *) image->signature); 00523 image->signature=(char *) malloc(33*sizeof(char)); 00524 if (image->signature == (char *) NULL) 00525 { 00526 Warning("Unable to compute colormap signature", 00527 "Memory allocation failed"); 00528 return; 00529 } 00530 /* 00531 Convert digital signature to a 32 character hex string. 00532 */ 00533 p=(unsigned char *) image->signature; 00534 hex="0123456789abcdef"; 00535 for (i=0; i < 16; i++) 00536 { 00537 *p++=hex[(message_digest.digest[i] >> 4) & 0xf]; 00538 *p++=hex[message_digest.digest[i] & 0xf]; 00539 } 00540 *p='\0'; 00541 }
1.7.6.1