Mercurial > hg > xemacs-beta
comparison lisp/gnus/md5.el @ 114:8619ce7e4c50 r20-1b9
Import from CVS: tag r20-1b9
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:21:54 +0200 |
parents | 1a767b41a199 |
children |
comparison
equal
deleted
inserted
replaced
113:2ec2fe4a4c89 | 114:8619ce7e4c50 |
---|---|
9 ;;; Details: ------------------------------------------------------------------ | 9 ;;; Details: ------------------------------------------------------------------ |
10 | 10 |
11 ;; This is a direct translation into Emacs LISP of the reference C | 11 ;; This is a direct translation into Emacs LISP of the reference C |
12 ;; implementation of the MD5 Message-Digest Algorithm written by RSA | 12 ;; implementation of the MD5 Message-Digest Algorithm written by RSA |
13 ;; Data Security, Inc. | 13 ;; Data Security, Inc. |
14 ;; | 14 ;; |
15 ;; The algorithm takes a message (that is, a string of bytes) and | 15 ;; The algorithm takes a message (that is, a string of bytes) and |
16 ;; computes a 16-byte checksum or "digest" for the message. This digest | 16 ;; computes a 16-byte checksum or "digest" for the message. This digest |
17 ;; is supposed to be cryptographically strong in the sense that if you | 17 ;; is supposed to be cryptographically strong in the sense that if you |
18 ;; are given a 16-byte digest D, then there is no easier way to | 18 ;; are given a 16-byte digest D, then there is no easier way to |
19 ;; construct a message whose digest is D than to exhaustively search the | 19 ;; construct a message whose digest is D than to exhaustively search the |
20 ;; space of messages. However, the robustness of the algorithm has not | 20 ;; space of messages. However, the robustness of the algorithm has not |
21 ;; been proven, and a similar algorithm (MD4) was shown to be unsound, | 21 ;; been proven, and a similar algorithm (MD4) was shown to be unsound, |
22 ;; so treat with caution! | 22 ;; so treat with caution! |
23 ;; | 23 ;; |
24 ;; The C algorithm uses 32-bit integers; because GNU Emacs | 24 ;; The C algorithm uses 32-bit integers; because GNU Emacs |
25 ;; implementations provide 28-bit integers (with 24-bit integers on | 25 ;; implementations provide 28-bit integers (with 24-bit integers on |
26 ;; versions prior to 19.29), the code represents a 32-bit integer as the | 26 ;; versions prior to 19.29), the code represents a 32-bit integer as the |
27 ;; cons of two 16-bit integers. The most significant word is stored in | 27 ;; cons of two 16-bit integers. The most significant word is stored in |
28 ;; the car and the least significant in the cdr. The algorithm requires | 28 ;; the car and the least significant in the cdr. The algorithm requires |
31 | 31 |
32 ;;; Usage: -------------------------------------------------------------------- | 32 ;;; Usage: -------------------------------------------------------------------- |
33 | 33 |
34 ;; To compute the MD5 Message Digest for a message M (represented as a | 34 ;; To compute the MD5 Message Digest for a message M (represented as a |
35 ;; string or as a vector of bytes), call | 35 ;; string or as a vector of bytes), call |
36 ;; | 36 ;; |
37 ;; (md5-encode M) | 37 ;; (md5-encode M) |
38 ;; | 38 ;; |
39 ;; which returns the message digest as a vector of 16 bytes. If you | 39 ;; which returns the message digest as a vector of 16 bytes. If you |
40 ;; need to supply the message in pieces M1, M2, ... Mn, then call | 40 ;; need to supply the message in pieces M1, M2, ... Mn, then call |
41 ;; | 41 ;; |
42 ;; (md5-init) | 42 ;; (md5-init) |
43 ;; (md5-update M1) | 43 ;; (md5-update M1) |
44 ;; (md5-update M2) | 44 ;; (md5-update M2) |
45 ;; ... | 45 ;; ... |
46 ;; (md5-update Mn) | 46 ;; (md5-update Mn) |
48 | 48 |
49 ;;; Copyright and licence: ---------------------------------------------------- | 49 ;;; Copyright and licence: ---------------------------------------------------- |
50 | 50 |
51 ;; Copyright (C) 1995 by Gareth Rees | 51 ;; Copyright (C) 1995 by Gareth Rees |
52 ;; Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm | 52 ;; Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm |
53 ;; | 53 ;; |
54 ;; md5.el is free software; you can redistribute it and/or modify it | 54 ;; md5.el is free software; you can redistribute it and/or modify it |
55 ;; under the terms of the GNU General Public License as published by the | 55 ;; under the terms of the GNU General Public License as published by the |
56 ;; Free Software Foundation; either version 2, or (at your option) any | 56 ;; Free Software Foundation; either version 2, or (at your option) any |
57 ;; later version. | 57 ;; later version. |
58 ;; | 58 ;; |
59 ;; md5.el is distributed in the hope that it will be useful, but WITHOUT | 59 ;; md5.el is distributed in the hope that it will be useful, but WITHOUT |
60 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 60 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
61 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 61 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
62 ;; for more details. | 62 ;; for more details. |
63 ;; | 63 ;; |
64 ;; The original copyright notice is given below, as required by the | 64 ;; The original copyright notice is given below, as required by the |
65 ;; licence for the original code. This code is distributed under *both* | 65 ;; licence for the original code. This code is distributed under *both* |
66 ;; RSA's original licence and the GNU General Public Licence. (There | 66 ;; RSA's original licence and the GNU General Public Licence. (There |
67 ;; should be no problems, as the former is more liberal than the | 67 ;; should be no problems, as the former is more liberal than the |
68 ;; latter). | 68 ;; latter). |
153 | 153 |
154 ;; FF, GG, HH and II are basic MD5 functions, providing transformations | 154 ;; FF, GG, HH and II are basic MD5 functions, providing transformations |
155 ;; for rounds 1, 2, 3 and 4 respectively. Each function follows this | 155 ;; for rounds 1, 2, 3 and 4 respectively. Each function follows this |
156 ;; pattern of computation (where ROTATE(x,y) means rotate 32-bit value x | 156 ;; pattern of computation (where ROTATE(x,y) means rotate 32-bit value x |
157 ;; by y bits to the left): | 157 ;; by y bits to the left): |
158 ;; | 158 ;; |
159 ;; FF(a,b,c,d,x,s,ac) = ROTATE(a + F(b,c,d) + x + ac,s) + b | 159 ;; FF(a,b,c,d,x,s,ac) = ROTATE(a + F(b,c,d) + x + ac,s) + b |
160 ;; | 160 ;; |
161 ;; so we use the macro `md5-make-step' to construct each one. The | 161 ;; so we use the macro `md5-make-step' to construct each one. The |
162 ;; helper functions F, G, H and I operate on 16-bit numbers; the full | 162 ;; helper functions F, G, H and I operate on 16-bit numbers; the full |
163 ;; operation splits its inputs, operates on the halves separately and | 163 ;; operation splits its inputs, operates on the halves separately and |
164 ;; then puts the results together. | 164 ;; then puts the results together. |
165 | 165 |
188 (md5-make-step md5-GG md5-G) | 188 (md5-make-step md5-GG md5-G) |
189 (md5-make-step md5-HH md5-H) | 189 (md5-make-step md5-HH md5-H) |
190 (md5-make-step md5-II md5-I) | 190 (md5-make-step md5-II md5-I) |
191 | 191 |
192 (defun md5-init () | 192 (defun md5-init () |
193 "Initialize the state of the message-digest routines." | 193 "Initialise the state of the message-digest routines." |
194 (aset md5-bits 0 0) | 194 (aset md5-bits 0 0) |
195 (aset md5-bits 1 0) | 195 (aset md5-bits 1 0) |
196 (aset md5-bits 2 0) | 196 (aset md5-bits 2 0) |
197 (aset md5-bits 3 0) | 197 (aset md5-bits 3 0) |
198 (aset md5-buffer 0 '(26437 . 8961)) | 198 (aset md5-buffer 0 '(26437 . 8961)) |
358 a (md5-II a b c d (aref in 4) 6 '(63315 . 32386)) | 358 a (md5-II a b c d (aref in 4) 6 '(63315 . 32386)) |
359 d (md5-II d a b c (aref in 11) 10 '(48442 . 62005)) | 359 d (md5-II d a b c (aref in 11) 10 '(48442 . 62005)) |
360 c (md5-II c d a b (aref in 2) 15 '(10967 . 53947)) | 360 c (md5-II c d a b (aref in 2) 15 '(10967 . 53947)) |
361 b (md5-II b c d a (aref in 9) 21 '(60294 . 54161))) | 361 b (md5-II b c d a (aref in 9) 21 '(60294 . 54161))) |
362 | 362 |
363 (aset md5-buffer 0 (md5-add (aref md5-buffer 0) a)) | 363 (aset md5-buffer 0 (md5-add (aref md5-buffer 0) a)) |
364 (aset md5-buffer 1 (md5-add (aref md5-buffer 1) b)) | 364 (aset md5-buffer 1 (md5-add (aref md5-buffer 1) b)) |
365 (aset md5-buffer 2 (md5-add (aref md5-buffer 2) c)) | 365 (aset md5-buffer 2 (md5-add (aref md5-buffer 2) c)) |
366 (aset md5-buffer 3 (md5-add (aref md5-buffer 3) d)))) | 366 (aset md5-buffer 3 (md5-add (aref md5-buffer 3) d)))) |
367 | 367 |
368 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 368 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
369 ;;; Here begins the merger with the XEmacs API and the md5.el from the URL | 369 ;;; Here begins the merger with the XEmacs API and the md5.el from the URL |
370 ;;; package. Courtesy wmperry@spry.com | 370 ;;; package. Courtesy wmperry@spry.com |
371 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 371 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
372 (eval-and-compile | 372 (defun md5 (object &optional start end) |
373 (unless (fboundp 'md5) | 373 "Return the MD5 (a secure message digest algorithm) of an object. |
374 (defun md5 (object &optional start end) | |
375 "Return the MD5 (a secure message digest algorithm) of an object. | |
376 OBJECT is either a string or a buffer. | 374 OBJECT is either a string or a buffer. |
377 Optional arguments START and END denote buffer positions for computing the | 375 Optional arguments START and END denote buffer positions for computing the |
378 hash of a portion of OBJECT." | 376 hash of a portion of OBJECT." |
379 (let ((buffer nil)) | 377 (let ((buffer nil)) |
380 (unwind-protect | 378 (unwind-protect |
381 (save-excursion | 379 (save-excursion |
382 (setq buffer (generate-new-buffer " *md5-work*")) | 380 (setq buffer (generate-new-buffer " *md5-work*")) |
383 (set-buffer buffer) | 381 (set-buffer buffer) |
384 (cond | 382 (cond |
385 ((bufferp object) | 383 ((bufferp object) |
386 (insert-buffer-substring object start end)) | 384 (insert-buffer-substring object start end)) |
387 ((stringp object) | 385 ((stringp object) |
388 (insert (if (or start end) | 386 (insert (if (or start end) |
389 (substring object start end) | 387 (substring object start end) |
390 object))) | 388 object))) |
391 (t nil)) | 389 (t nil)) |
392 (prog1 | 390 (prog1 |
393 (if (<= (point-max) md5-maximum-internal-length) | 391 (if (<= (point-max) md5-maximum-internal-length) |
394 (mapconcat | 392 (mapconcat |
395 (function (lambda (node) (format "%02x" node))) | 393 (function (lambda (node) (format "%02x" node))) |
396 (md5-encode (buffer-string)) | 394 (md5-encode (buffer-string)) |
397 "") | 395 "") |
398 (call-process-region (point-min) (point-max) | 396 (call-process-region (point-min) (point-max) |
399 (or shell-file-name "/bin/sh") | 397 (or shell-file-name "/bin/sh") |
400 t buffer nil | 398 t buffer nil |
401 "-c" md5-program) | 399 "-c" md5-program) |
402 ;; MD5 digest is 32 chars long | 400 ;; MD5 digest is 32 chars long |
403 ;; mddriver adds a newline to make neaten output for tty | 401 ;; mddriver adds a newline to make neaten output for tty |
404 ;; viewing, make sure we leave it behind. | 402 ;; viewing, make sure we leave it behind. |
405 (buffer-substring (point-min) (+ (point-min) 32))) | 403 (buffer-substring (point-min) (+ (point-min) 32))) |
406 (kill-buffer buffer))) | 404 (kill-buffer buffer))) |
407 (and buffer (kill-buffer buffer) nil)))))) | 405 (and buffer (kill-buffer buffer) nil)))) |
408 | 406 |
409 (provide 'md5) | 407 (provide 'md5) |
410 | 408 |
411 ;;; md5.el ends here ---------------------------------------------------------- | 409 ;;; md5.el ends here ---------------------------------------------------------- |