Commits

Anonymous committed 5aaadec Merge

Use md5 from ecrypto.

  • Participants
  • Parent commits 4a30e0c, 0beec39

Comments (0)

Files changed (5)

+2002-09-17  Ville Skyttä  <ville.skytta@xemacs.org>
+
+	* Makefile (REQUIRES): Add ecrypto, we'll use md5 from there.
+	(EXTRA_SOURCES): Add lisp/md5.el.upstream.
+
+	* package-info.in (provides): Remove md5.
+
+	* lisp/md5.el: Renamed to lisp/md5.el.upstream.
+
 2002-06-27  Steve Youngs  <youngs@xemacs.org>
 
 	* Makefile (VERSION): XEmacs package 1.25 released.
 MAINTAINER = XEmacs Development Team <xemacs-beta@xemacs.org>
 PACKAGE = w3
 PKG_TYPE = regular
-REQUIRES = w3 mail-lib xemacs-base
+REQUIRES = w3 mail-lib xemacs-base ecrypto
 CATEGORY = standard
 
 ELCS =  lisp/css.elc lisp/dsssl-flow.elc \
 	lisp/w3-sysdp.elc \
 	lisp/w3-toolbar.elc lisp/w3-vars.elc lisp/w3-widget.elc \
 	lisp/w3-xemac.elc lisp/w3.elc lisp/w3-cfg.elc
-EXTRA_SOURCES = BUGS HOWTO INSTALL README README.NT README.VMS TODO
+
+EXTRA_SOURCES = BUGS HOWTO INSTALL README README.NT README.VMS TODO \
+	lisp/md5.el.upstream
 
 DATA_FILES = stylesheet $(wildcard images/*.x?m)
 DATA_DEST = $(PACKAGE)

lisp/md5.el

-;;; md5.el -- MD5 Message Digest Algorithm
-;;; Gareth Rees <gdr11@cl.cam.ac.uk>
-
-;; LCD Archive Entry:
-;; md5|Gareth Rees|gdr11@cl.cam.ac.uk|
-;; MD5 cryptographic message digest algorithm|
-;; 13-Nov-95|1.0|~/misc/md5.el.Z|
-
-;;; Details: ------------------------------------------------------------------
-
-;; This is a direct translation into Emacs LISP of the reference C
-;; implementation of the MD5 Message-Digest Algorithm written by RSA
-;; Data Security, Inc.
-;; 
-;; The algorithm takes a message (that is, a string of bytes) and
-;; computes a 16-byte checksum or "digest" for the message.  This digest
-;; is supposed to be cryptographically strong in the sense that if you
-;; are given a 16-byte digest D, then there is no easier way to
-;; construct a message whose digest is D than to exhaustively search the
-;; space of messages.  However, the robustness of the algorithm has not
-;; been proven, and a similar algorithm (MD4) was shown to be unsound,
-;; so treat with caution!
-;; 
-;; The C algorithm uses 32-bit integers; because GNU Emacs
-;; implementations provide 28-bit integers (with 24-bit integers on
-;; versions prior to 19.29), the code represents a 32-bit integer as the
-;; cons of two 16-bit integers.  The most significant word is stored in
-;; the car and the least significant in the cdr.  The algorithm requires
-;; at least 17 bits of integer representation in order to represent the
-;; carry from a 16-bit addition.
-
-;;; Usage: --------------------------------------------------------------------
-
-;; To compute the MD5 Message Digest for a message M (represented as a
-;; string or as a vector of bytes), call
-;; 
-;;   (md5-encode M)
-;; 
-;; which returns the message digest as a vector of 16 bytes.  If you
-;; need to supply the message in pieces M1, M2, ... Mn, then call
-;; 
-;;   (md5-init)
-;;   (md5-update M1)
-;;   (md5-update M2)
-;;   ...
-;;   (md5-update Mn)
-;;   (md5-final)
-
-;;; Copyright and licence: ----------------------------------------------------
-
-;; Copyright (C) 1995, 1996, 1997 by Gareth Rees
-;; Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm
-;; 
-;; md5.el is free software; you can redistribute it and/or modify it
-;; under the terms of the GNU General Public License as published by the
-;; Free Software Foundation; either version 2, or (at your option) any
-;; later version.
-;; 
-;; md5.el is distributed in the hope that it will be useful, but WITHOUT
-;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-;; for more details.
-;; 
-;; The original copyright notice is given below, as required by the
-;; licence for the original code.  This code is distributed under *both*
-;; RSA's original licence and the GNU General Public Licence.  (There
-;; should be no problems, as the former is more liberal than the
-;; latter).
-
-;;; Original copyright notice: ------------------------------------------------
-
-;; Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.
-;;
-;; License to copy and use this software is granted provided that it is
-;; identified as the "RSA Data Security, Inc. MD5 Message- Digest
-;; Algorithm" in all material mentioning or referencing this software or
-;; this function.
-;;
-;; License is also granted to make and use derivative works provided
-;; that such works are identified as "derived from the RSA Data
-;; Security, Inc. MD5 Message-Digest Algorithm" in all material
-;; mentioning or referencing the derived work.
-;;
-;; RSA Data Security, Inc. makes no representations concerning either
-;; the merchantability of this software or the suitability of this
-;; software for any particular purpose.  It is provided "as is" without
-;; express or implied warranty of any kind.
-;;
-;; These notices must be retained in any copies of any part of this
-;; documentation and/or software.
-
-;;; Code: ---------------------------------------------------------------------
-
-(defvar md5-program "md5"
-  "*Program that reads a message on its standard input and writes an
-MD5 digest on its output.")
-
-(defvar md5-maximum-internal-length 4096
-  "*The maximum size of a piece of data that should use the MD5 routines
-written in lisp.  If a message exceeds this, it will be run through an
-external filter for processing.  Also see the `md5-program' variable.
-This variable has no effect if you call the md5-init|update|final
-functions - only used by the `md5' function's simpler interface.")
-
-(defvar md5-bits (make-vector 4 0)
-  "Number of bits handled, modulo 2^64.
-Represented as four 16-bit numbers, least significant first.")
-(defvar md5-buffer (make-vector 4 '(0 . 0))
-  "Scratch buffer (four 32-bit integers).")
-(defvar md5-input (make-vector 64 0)
-  "Input buffer (64 bytes).")
-
-(defun md5-unhex (x)
-  (if (> x ?9)
-      (if (>= x ?a)
-	  (+ 10 (- x ?a))
-	(+ 10 (- x ?A)))
-    (- x ?0)))
-
-(defun md5-encode (message)
-  "Encodes MESSAGE using the MD5 message digest algorithm.
-MESSAGE must be a string or an array of bytes.
-Returns a vector of 16 bytes containing the message digest."
-  (if (<= (length message) md5-maximum-internal-length)
-      (progn
-	(md5-init)
-	(md5-update message)
-	(md5-final))
-    (save-excursion
-      (set-buffer (get-buffer-create " *md5-work*"))
-      (erase-buffer)
-      (insert message)
-      (call-process-region (point-min) (point-max)
-			   md5-program
-			   t (current-buffer))
-      ;; MD5 digest is 32 chars long
-      ;; mddriver adds a newline to make neaten output for tty
-      ;; viewing, make sure we leave it behind.
-      (let ((data (buffer-substring (point-min) (+ (point-min) 32)))
-	    (vec (make-vector 16 0))
-	    (ctr 0))
-	(while (< ctr 16)
-	  (aset vec ctr (+ (* 16 (md5-unhex (aref data (* ctr 2))))
-			   (md5-unhex (aref data (1+ (* ctr 2))))))
-	  (setq ctr (1+ ctr)))))))
-
-(defsubst md5-add (x y)
-  "Return 32-bit sum of 32-bit integers X and Y."
-  (let ((m (+ (car x) (car y)))
-        (l (+ (cdr x) (cdr y))))
-    (cons (logand 65535 (+ m (lsh l -16))) (logand l 65535))))
-
-;; FF, GG, HH and II are basic MD5 functions, providing transformations
-;; for rounds 1, 2, 3 and 4 respectively.  Each function follows this
-;; pattern of computation (where ROTATE(x,y) means rotate 32-bit value x
-;; by y bits to the left):
-;; 
-;;   FF(a,b,c,d,x,s,ac) = ROTATE(a + F(b,c,d) + x + ac,s) + b
-;; 
-;; so we use the macro `md5-make-step' to construct each one.  The
-;; helper functions F, G, H and I operate on 16-bit numbers; the full
-;; operation splits its inputs, operates on the halves separately and
-;; then puts the results together.
-
-(defsubst md5-F (x y z) (logior (logand x y) (logand (lognot x) z)))
-(defsubst md5-G (x y z) (logior (logand x z) (logand y (lognot z))))
-(defsubst md5-H (x y z) (logxor x y z))
-(defsubst md5-I (x y z) (logxor y (logior x (logand 65535 (lognot z)))))
-
-(defmacro md5-make-step (name func)
-  (`
-   (defun (, name) (a b c d x s ac)
-     (let*
-         ((m1 (+ (car a) ((, func) (car b) (car c) (car d)) (car x) (car ac)))
-          (l1 (+ (cdr a) ((, func) (cdr b) (cdr c) (cdr d)) (cdr x) (cdr ac)))
-          (m2 (logand 65535 (+ m1 (lsh l1 -16))))
-          (l2 (logand 65535 l1))
-          (m3 (logand 65535 (if (> s 15)
-                                (+ (lsh m2 (- s 32)) (lsh l2 (- s 16)))
-                              (+ (lsh m2 s) (lsh l2 (- s 16))))))
-          (l3 (logand 65535 (if (> s 15)
-                                (+ (lsh l2 (- s 32)) (lsh m2 (- s 16)))
-                              (+ (lsh l2 s) (lsh m2 (- s 16)))))))
-       (md5-add (cons m3 l3) b)))))
-
-(md5-make-step md5-FF md5-F)
-(md5-make-step md5-GG md5-G)
-(md5-make-step md5-HH md5-H)
-(md5-make-step md5-II md5-I)
-
-(defun md5-init ()
-  "Initialise the state of the message-digest routines."
-  (aset md5-bits 0 0)
-  (aset md5-bits 1 0)
-  (aset md5-bits 2 0)
-  (aset md5-bits 3 0)
-  (aset md5-buffer 0 '(26437 .  8961))
-  (aset md5-buffer 1 '(61389 . 43913))
-  (aset md5-buffer 2 '(39098 . 56574))
-  (aset md5-buffer 3 '( 4146 . 21622)))
-
-(defun md5-update (string)
-  "Update the current MD5 state with STRING (an array of bytes)."
-  (let ((len (length string))
-        (i 0)
-        (j 0))
-    (while (< i len)
-      ;; Compute number of bytes modulo 64
-      (setq j (% (/ (aref md5-bits 0) 8) 64))
-
-      ;; Store this byte (truncating to 8 bits to be sure)
-      (aset md5-input j (logand 255 (aref string i)))
-
-      ;; Update number of bits by 8 (modulo 2^64)
-      (let ((c 8) (k 0))
-        (while (and (> c 0) (< k 4))
-          (let ((b (aref md5-bits k)))
-            (aset md5-bits k (logand 65535 (+ b c)))
-            (setq c (if (> b (- 65535 c)) 1 0)
-                  k (1+ k)))))
-
-      ;; Increment number of bytes processed
-      (setq i (1+ i))
-
-      ;; When 64 bytes accumulated, pack them into sixteen 32-bit
-      ;; integers in the array `in' and then transform them.
-      (if (= j 63)
-          (let ((in (make-vector 16 (cons 0 0)))
-                (k 0)
-                (kk 0))
-            (while (< k 16)
-              (aset in k (md5-pack md5-input kk))
-              (setq k (+ k 1) kk (+ kk 4)))
-            (md5-transform in))))))
-
-(defun md5-pack (array i)
-  "Pack the four bytes at ARRAY reference I to I+3 into a 32-bit integer."
-  (cons (+ (lsh (aref array (+ i 3)) 8) (aref array (+ i 2)))
-        (+ (lsh (aref array (+ i 1)) 8) (aref array (+ i 0)))))
-
-(defun md5-byte (array n b)
-  "Unpack byte B (0 to 3) from Nth member of ARRAY of 32-bit integers."
-  (let ((e (aref array n)))
-    (cond ((eq b 0) (logand 255 (cdr e)))
-          ((eq b 1) (lsh (cdr e) -8))
-          ((eq b 2) (logand 255 (car e)))
-          ((eq b 3) (lsh (car e) -8)))))
-
-(defun md5-final ()
-  (let ((in (make-vector 16 (cons 0 0)))
-        (j 0)
-        (digest (make-vector 16 0))
-        (padding))
-
-    ;; Save the number of bits in the message
-    (aset in 14 (cons (aref md5-bits 1) (aref md5-bits 0)))
-    (aset in 15 (cons (aref md5-bits 3) (aref md5-bits 2)))
-
-    ;; Compute number of bytes modulo 64
-    (setq j (% (/ (aref md5-bits 0) 8) 64))
-
-    ;; Pad out computation to 56 bytes modulo 64
-    (setq padding (make-vector (if (< j 56) (- 56 j) (- 120 j)) 0))
-    (aset padding 0 128)
-    (md5-update padding)
-
-    ;; Append length in bits and transform
-    (let ((k 0) (kk 0))
-      (while (< k 14)
-        (aset in k (md5-pack md5-input kk))
-        (setq k (+ k 1) kk (+ kk 4))))
-    (md5-transform in)
-
-    ;; Store the results in the digest
-    (let ((k 0) (kk 0))
-      (while (< k 4)
-        (aset digest (+ kk 0) (md5-byte md5-buffer k 0))
-        (aset digest (+ kk 1) (md5-byte md5-buffer k 1))
-        (aset digest (+ kk 2) (md5-byte md5-buffer k 2))
-        (aset digest (+ kk 3) (md5-byte md5-buffer k 3))
-        (setq k (+ k 1) kk (+ kk 4))))
-
-    ;; Return digest
-    digest))
-
-;; It says in the RSA source, "Note that if the Mysterious Constants are
-;; arranged backwards in little-endian order and decrypted with the DES
-;; they produce OCCULT MESSAGES!"  Security through obscurity?
-
-(defun md5-transform (in)
-  "Basic MD5 step. Transform md5-buffer based on array IN."
-  (let ((a (aref md5-buffer 0))
-        (b (aref md5-buffer 1))
-        (c (aref md5-buffer 2))
-        (d (aref md5-buffer 3)))
-    (setq
-     a (md5-FF a b c d (aref in  0)  7 '(55146 . 42104))
-     d (md5-FF d a b c (aref in  1) 12 '(59591 . 46934))
-     c (md5-FF c d a b (aref in  2) 17 '( 9248 . 28891))
-     b (md5-FF b c d a (aref in  3) 22 '(49597 . 52974))
-     a (md5-FF a b c d (aref in  4)  7 '(62844 .  4015))
-     d (md5-FF d a b c (aref in  5) 12 '(18311 . 50730))
-     c (md5-FF c d a b (aref in  6) 17 '(43056 . 17939))
-     b (md5-FF b c d a (aref in  7) 22 '(64838 . 38145))
-     a (md5-FF a b c d (aref in  8)  7 '(27008 . 39128))
-     d (md5-FF d a b c (aref in  9) 12 '(35652 . 63407))
-     c (md5-FF c d a b (aref in 10) 17 '(65535 . 23473))
-     b (md5-FF b c d a (aref in 11) 22 '(35164 . 55230))
-     a (md5-FF a b c d (aref in 12)  7 '(27536 .  4386))
-     d (md5-FF d a b c (aref in 13) 12 '(64920 . 29075))
-     c (md5-FF c d a b (aref in 14) 17 '(42617 . 17294))
-     b (md5-FF b c d a (aref in 15) 22 '(18868 .  2081))
-     a (md5-GG a b c d (aref in  1)  5 '(63006 .  9570))
-     d (md5-GG d a b c (aref in  6)  9 '(49216 . 45888))
-     c (md5-GG c d a b (aref in 11) 14 '( 9822 . 23121))
-     b (md5-GG b c d a (aref in  0) 20 '(59830 . 51114))
-     a (md5-GG a b c d (aref in  5)  5 '(54831 .  4189))
-     d (md5-GG d a b c (aref in 10)  9 '(  580 .  5203))
-     c (md5-GG c d a b (aref in 15) 14 '(55457 . 59009))
-     b (md5-GG b c d a (aref in  4) 20 '(59347 . 64456))
-     a (md5-GG a b c d (aref in  9)  5 '( 8673 . 52710))
-     d (md5-GG d a b c (aref in 14)  9 '(49975 .  2006))
-     c (md5-GG c d a b (aref in  3) 14 '(62677 .  3463))
-     b (md5-GG b c d a (aref in  8) 20 '(17754 .  5357))
-     a (md5-GG a b c d (aref in 13)  5 '(43491 . 59653))
-     d (md5-GG d a b c (aref in  2)  9 '(64751 . 41976))
-     c (md5-GG c d a b (aref in  7) 14 '(26479 .   729))
-     b (md5-GG b c d a (aref in 12) 20 '(36138 . 19594))
-     a (md5-HH a b c d (aref in  5)  4 '(65530 . 14658))
-     d (md5-HH d a b c (aref in  8) 11 '(34673 . 63105))
-     c (md5-HH c d a b (aref in 11) 16 '(28061 . 24866))
-     b (md5-HH b c d a (aref in 14) 23 '(64997 . 14348))
-     a (md5-HH a b c d (aref in  1)  4 '(42174 . 59972))
-     d (md5-HH d a b c (aref in  4) 11 '(19422 . 53161))
-     c (md5-HH c d a b (aref in  7) 16 '(63163 . 19296))
-     b (md5-HH b c d a (aref in 10) 23 '(48831 . 48240))
-     a (md5-HH a b c d (aref in 13)  4 '(10395 . 32454))
-     d (md5-HH d a b c (aref in  0) 11 '(60065 . 10234))
-     c (md5-HH c d a b (aref in  3) 16 '(54511 . 12421))
-     b (md5-HH b c d a (aref in  6) 23 '( 1160 .  7429))
-     a (md5-HH a b c d (aref in  9)  4 '(55764 . 53305))
-     d (md5-HH d a b c (aref in 12) 11 '(59099 . 39397))
-     c (md5-HH c d a b (aref in 15) 16 '( 8098 . 31992))
-     b (md5-HH b c d a (aref in  2) 23 '(50348 . 22117))
-     a (md5-II a b c d (aref in  0)  6 '(62505 .  8772))
-     d (md5-II d a b c (aref in  7) 10 '(17194 . 65431))
-     c (md5-II c d a b (aref in 14) 15 '(43924 .  9127))
-     b (md5-II b c d a (aref in  5) 21 '(64659 . 41017))
-     a (md5-II a b c d (aref in 12)  6 '(25947 . 22979))
-     d (md5-II d a b c (aref in  3) 10 '(36620 . 52370))
-     c (md5-II c d a b (aref in 10) 15 '(65519 . 62589))
-     b (md5-II b c d a (aref in  1) 21 '(34180 . 24017))
-     a (md5-II a b c d (aref in  8)  6 '(28584 . 32335))
-     d (md5-II d a b c (aref in 15) 10 '(65068 . 59104))
-     c (md5-II c d a b (aref in  6) 15 '(41729 . 17172))
-     b (md5-II b c d a (aref in 13) 21 '(19976 .  4513))
-     a (md5-II a b c d (aref in  4)  6 '(63315 . 32386))
-     d (md5-II d a b c (aref in 11) 10 '(48442 . 62005))
-     c (md5-II c d a b (aref in  2) 15 '(10967 . 53947))
-     b (md5-II b c d a (aref in  9) 21 '(60294 . 54161)))
-
-     (aset md5-buffer 0 (md5-add (aref md5-buffer 0) a))
-     (aset md5-buffer 1 (md5-add (aref md5-buffer 1) b))
-     (aset md5-buffer 2 (md5-add (aref md5-buffer 2) c))
-     (aset md5-buffer 3 (md5-add (aref md5-buffer 3) d))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Here begins the merger with the XEmacs API and the md5.el from the URL
-;;; package.  Courtesy wmperry@cs.indiana.edu
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun md5 (object &optional start end)
-  "Return the MD5 (a secure message digest algorithm) of an object.
-OBJECT is either a string or a buffer.
-Optional arguments START and END denote buffer positions for computing the
-hash of a portion of OBJECT."
- (let ((buffer nil))
-    (unwind-protect
-	(save-excursion
-	  (setq buffer (generate-new-buffer " *md5-work*"))
-	  (set-buffer buffer)
-	  (cond
-	   ((bufferp object)
-	    (insert-buffer-substring object start end))
-	   ((stringp object)
-	    (insert (if (or start end)
-			(substring object start end)
-		      object)))
-	   (t nil))
-	  (prog1
-	      (if (<= (point-max) md5-maximum-internal-length)
-		  (mapconcat
-		   (function (lambda (node) (format "%02x" node)))
-		   (md5-encode (buffer-string))
-		   "")
-		(call-process-region (point-min) (point-max)
-				     shell-file-name
-				     t buffer nil
-				     shell-command-switch md5-program)
-		;; MD5 digest is 32 chars long
-		;; mddriver adds a newline to make neaten output for tty
-		;; viewing, make sure we leave it behind.
-		(buffer-substring (point-min) (+ (point-min) 32)))
-	    (kill-buffer buffer)))
-      (and buffer (buffer-name buffer) (kill-buffer buffer) nil))))
-
-(provide 'md5)

lisp/md5.el.upstream

+;;; md5.el -- MD5 Message Digest Algorithm
+;;; Gareth Rees <gdr11@cl.cam.ac.uk>
+
+;; LCD Archive Entry:
+;; md5|Gareth Rees|gdr11@cl.cam.ac.uk|
+;; MD5 cryptographic message digest algorithm|
+;; 13-Nov-95|1.0|~/misc/md5.el.Z|
+
+;;; Details: ------------------------------------------------------------------
+
+;; This is a direct translation into Emacs LISP of the reference C
+;; implementation of the MD5 Message-Digest Algorithm written by RSA
+;; Data Security, Inc.
+;; 
+;; The algorithm takes a message (that is, a string of bytes) and
+;; computes a 16-byte checksum or "digest" for the message.  This digest
+;; is supposed to be cryptographically strong in the sense that if you
+;; are given a 16-byte digest D, then there is no easier way to
+;; construct a message whose digest is D than to exhaustively search the
+;; space of messages.  However, the robustness of the algorithm has not
+;; been proven, and a similar algorithm (MD4) was shown to be unsound,
+;; so treat with caution!
+;; 
+;; The C algorithm uses 32-bit integers; because GNU Emacs
+;; implementations provide 28-bit integers (with 24-bit integers on
+;; versions prior to 19.29), the code represents a 32-bit integer as the
+;; cons of two 16-bit integers.  The most significant word is stored in
+;; the car and the least significant in the cdr.  The algorithm requires
+;; at least 17 bits of integer representation in order to represent the
+;; carry from a 16-bit addition.
+
+;;; Usage: --------------------------------------------------------------------
+
+;; To compute the MD5 Message Digest for a message M (represented as a
+;; string or as a vector of bytes), call
+;; 
+;;   (md5-encode M)
+;; 
+;; which returns the message digest as a vector of 16 bytes.  If you
+;; need to supply the message in pieces M1, M2, ... Mn, then call
+;; 
+;;   (md5-init)
+;;   (md5-update M1)
+;;   (md5-update M2)
+;;   ...
+;;   (md5-update Mn)
+;;   (md5-final)
+
+;;; Copyright and licence: ----------------------------------------------------
+
+;; Copyright (C) 1995, 1996, 1997 by Gareth Rees
+;; Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm
+;; 
+;; md5.el is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by the
+;; Free Software Foundation; either version 2, or (at your option) any
+;; later version.
+;; 
+;; md5.el is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+;; for more details.
+;; 
+;; The original copyright notice is given below, as required by the
+;; licence for the original code.  This code is distributed under *both*
+;; RSA's original licence and the GNU General Public Licence.  (There
+;; should be no problems, as the former is more liberal than the
+;; latter).
+
+;;; Original copyright notice: ------------------------------------------------
+
+;; Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.
+;;
+;; License to copy and use this software is granted provided that it is
+;; identified as the "RSA Data Security, Inc. MD5 Message- Digest
+;; Algorithm" in all material mentioning or referencing this software or
+;; this function.
+;;
+;; License is also granted to make and use derivative works provided
+;; that such works are identified as "derived from the RSA Data
+;; Security, Inc. MD5 Message-Digest Algorithm" in all material
+;; mentioning or referencing the derived work.
+;;
+;; RSA Data Security, Inc. makes no representations concerning either
+;; the merchantability of this software or the suitability of this
+;; software for any particular purpose.  It is provided "as is" without
+;; express or implied warranty of any kind.
+;;
+;; These notices must be retained in any copies of any part of this
+;; documentation and/or software.
+
+;;; Code: ---------------------------------------------------------------------
+
+(defvar md5-program "md5"
+  "*Program that reads a message on its standard input and writes an
+MD5 digest on its output.")
+
+(defvar md5-maximum-internal-length 4096
+  "*The maximum size of a piece of data that should use the MD5 routines
+written in lisp.  If a message exceeds this, it will be run through an
+external filter for processing.  Also see the `md5-program' variable.
+This variable has no effect if you call the md5-init|update|final
+functions - only used by the `md5' function's simpler interface.")
+
+(defvar md5-bits (make-vector 4 0)
+  "Number of bits handled, modulo 2^64.
+Represented as four 16-bit numbers, least significant first.")
+(defvar md5-buffer (make-vector 4 '(0 . 0))
+  "Scratch buffer (four 32-bit integers).")
+(defvar md5-input (make-vector 64 0)
+  "Input buffer (64 bytes).")
+
+(defun md5-unhex (x)
+  (if (> x ?9)
+      (if (>= x ?a)
+	  (+ 10 (- x ?a))
+	(+ 10 (- x ?A)))
+    (- x ?0)))
+
+(defun md5-encode (message)
+  "Encodes MESSAGE using the MD5 message digest algorithm.
+MESSAGE must be a string or an array of bytes.
+Returns a vector of 16 bytes containing the message digest."
+  (if (<= (length message) md5-maximum-internal-length)
+      (progn
+	(md5-init)
+	(md5-update message)
+	(md5-final))
+    (save-excursion
+      (set-buffer (get-buffer-create " *md5-work*"))
+      (erase-buffer)
+      (insert message)
+      (call-process-region (point-min) (point-max)
+			   md5-program
+			   t (current-buffer))
+      ;; MD5 digest is 32 chars long
+      ;; mddriver adds a newline to make neaten output for tty
+      ;; viewing, make sure we leave it behind.
+      (let ((data (buffer-substring (point-min) (+ (point-min) 32)))
+	    (vec (make-vector 16 0))
+	    (ctr 0))
+	(while (< ctr 16)
+	  (aset vec ctr (+ (* 16 (md5-unhex (aref data (* ctr 2))))
+			   (md5-unhex (aref data (1+ (* ctr 2))))))
+	  (setq ctr (1+ ctr)))))))
+
+(defsubst md5-add (x y)
+  "Return 32-bit sum of 32-bit integers X and Y."
+  (let ((m (+ (car x) (car y)))
+        (l (+ (cdr x) (cdr y))))
+    (cons (logand 65535 (+ m (lsh l -16))) (logand l 65535))))
+
+;; FF, GG, HH and II are basic MD5 functions, providing transformations
+;; for rounds 1, 2, 3 and 4 respectively.  Each function follows this
+;; pattern of computation (where ROTATE(x,y) means rotate 32-bit value x
+;; by y bits to the left):
+;; 
+;;   FF(a,b,c,d,x,s,ac) = ROTATE(a + F(b,c,d) + x + ac,s) + b
+;; 
+;; so we use the macro `md5-make-step' to construct each one.  The
+;; helper functions F, G, H and I operate on 16-bit numbers; the full
+;; operation splits its inputs, operates on the halves separately and
+;; then puts the results together.
+
+(defsubst md5-F (x y z) (logior (logand x y) (logand (lognot x) z)))
+(defsubst md5-G (x y z) (logior (logand x z) (logand y (lognot z))))
+(defsubst md5-H (x y z) (logxor x y z))
+(defsubst md5-I (x y z) (logxor y (logior x (logand 65535 (lognot z)))))
+
+(defmacro md5-make-step (name func)
+  (`
+   (defun (, name) (a b c d x s ac)
+     (let*
+         ((m1 (+ (car a) ((, func) (car b) (car c) (car d)) (car x) (car ac)))
+          (l1 (+ (cdr a) ((, func) (cdr b) (cdr c) (cdr d)) (cdr x) (cdr ac)))
+          (m2 (logand 65535 (+ m1 (lsh l1 -16))))
+          (l2 (logand 65535 l1))
+          (m3 (logand 65535 (if (> s 15)
+                                (+ (lsh m2 (- s 32)) (lsh l2 (- s 16)))
+                              (+ (lsh m2 s) (lsh l2 (- s 16))))))
+          (l3 (logand 65535 (if (> s 15)
+                                (+ (lsh l2 (- s 32)) (lsh m2 (- s 16)))
+                              (+ (lsh l2 s) (lsh m2 (- s 16)))))))
+       (md5-add (cons m3 l3) b)))))
+
+(md5-make-step md5-FF md5-F)
+(md5-make-step md5-GG md5-G)
+(md5-make-step md5-HH md5-H)
+(md5-make-step md5-II md5-I)
+
+(defun md5-init ()
+  "Initialise the state of the message-digest routines."
+  (aset md5-bits 0 0)
+  (aset md5-bits 1 0)
+  (aset md5-bits 2 0)
+  (aset md5-bits 3 0)
+  (aset md5-buffer 0 '(26437 .  8961))
+  (aset md5-buffer 1 '(61389 . 43913))
+  (aset md5-buffer 2 '(39098 . 56574))
+  (aset md5-buffer 3 '( 4146 . 21622)))
+
+(defun md5-update (string)
+  "Update the current MD5 state with STRING (an array of bytes)."
+  (let ((len (length string))
+        (i 0)
+        (j 0))
+    (while (< i len)
+      ;; Compute number of bytes modulo 64
+      (setq j (% (/ (aref md5-bits 0) 8) 64))
+
+      ;; Store this byte (truncating to 8 bits to be sure)
+      (aset md5-input j (logand 255 (aref string i)))
+
+      ;; Update number of bits by 8 (modulo 2^64)
+      (let ((c 8) (k 0))
+        (while (and (> c 0) (< k 4))
+          (let ((b (aref md5-bits k)))
+            (aset md5-bits k (logand 65535 (+ b c)))
+            (setq c (if (> b (- 65535 c)) 1 0)
+                  k (1+ k)))))
+
+      ;; Increment number of bytes processed
+      (setq i (1+ i))
+
+      ;; When 64 bytes accumulated, pack them into sixteen 32-bit
+      ;; integers in the array `in' and then transform them.
+      (if (= j 63)
+          (let ((in (make-vector 16 (cons 0 0)))
+                (k 0)
+                (kk 0))
+            (while (< k 16)
+              (aset in k (md5-pack md5-input kk))
+              (setq k (+ k 1) kk (+ kk 4)))
+            (md5-transform in))))))
+
+(defun md5-pack (array i)
+  "Pack the four bytes at ARRAY reference I to I+3 into a 32-bit integer."
+  (cons (+ (lsh (aref array (+ i 3)) 8) (aref array (+ i 2)))
+        (+ (lsh (aref array (+ i 1)) 8) (aref array (+ i 0)))))
+
+(defun md5-byte (array n b)
+  "Unpack byte B (0 to 3) from Nth member of ARRAY of 32-bit integers."
+  (let ((e (aref array n)))
+    (cond ((eq b 0) (logand 255 (cdr e)))
+          ((eq b 1) (lsh (cdr e) -8))
+          ((eq b 2) (logand 255 (car e)))
+          ((eq b 3) (lsh (car e) -8)))))
+
+(defun md5-final ()
+  (let ((in (make-vector 16 (cons 0 0)))
+        (j 0)
+        (digest (make-vector 16 0))
+        (padding))
+
+    ;; Save the number of bits in the message
+    (aset in 14 (cons (aref md5-bits 1) (aref md5-bits 0)))
+    (aset in 15 (cons (aref md5-bits 3) (aref md5-bits 2)))
+
+    ;; Compute number of bytes modulo 64
+    (setq j (% (/ (aref md5-bits 0) 8) 64))
+
+    ;; Pad out computation to 56 bytes modulo 64
+    (setq padding (make-vector (if (< j 56) (- 56 j) (- 120 j)) 0))
+    (aset padding 0 128)
+    (md5-update padding)
+
+    ;; Append length in bits and transform
+    (let ((k 0) (kk 0))
+      (while (< k 14)
+        (aset in k (md5-pack md5-input kk))
+        (setq k (+ k 1) kk (+ kk 4))))
+    (md5-transform in)
+
+    ;; Store the results in the digest
+    (let ((k 0) (kk 0))
+      (while (< k 4)
+        (aset digest (+ kk 0) (md5-byte md5-buffer k 0))
+        (aset digest (+ kk 1) (md5-byte md5-buffer k 1))
+        (aset digest (+ kk 2) (md5-byte md5-buffer k 2))
+        (aset digest (+ kk 3) (md5-byte md5-buffer k 3))
+        (setq k (+ k 1) kk (+ kk 4))))
+
+    ;; Return digest
+    digest))
+
+;; It says in the RSA source, "Note that if the Mysterious Constants are
+;; arranged backwards in little-endian order and decrypted with the DES
+;; they produce OCCULT MESSAGES!"  Security through obscurity?
+
+(defun md5-transform (in)
+  "Basic MD5 step. Transform md5-buffer based on array IN."
+  (let ((a (aref md5-buffer 0))
+        (b (aref md5-buffer 1))
+        (c (aref md5-buffer 2))
+        (d (aref md5-buffer 3)))
+    (setq
+     a (md5-FF a b c d (aref in  0)  7 '(55146 . 42104))
+     d (md5-FF d a b c (aref in  1) 12 '(59591 . 46934))
+     c (md5-FF c d a b (aref in  2) 17 '( 9248 . 28891))
+     b (md5-FF b c d a (aref in  3) 22 '(49597 . 52974))
+     a (md5-FF a b c d (aref in  4)  7 '(62844 .  4015))
+     d (md5-FF d a b c (aref in  5) 12 '(18311 . 50730))
+     c (md5-FF c d a b (aref in  6) 17 '(43056 . 17939))
+     b (md5-FF b c d a (aref in  7) 22 '(64838 . 38145))
+     a (md5-FF a b c d (aref in  8)  7 '(27008 . 39128))
+     d (md5-FF d a b c (aref in  9) 12 '(35652 . 63407))
+     c (md5-FF c d a b (aref in 10) 17 '(65535 . 23473))
+     b (md5-FF b c d a (aref in 11) 22 '(35164 . 55230))
+     a (md5-FF a b c d (aref in 12)  7 '(27536 .  4386))
+     d (md5-FF d a b c (aref in 13) 12 '(64920 . 29075))
+     c (md5-FF c d a b (aref in 14) 17 '(42617 . 17294))
+     b (md5-FF b c d a (aref in 15) 22 '(18868 .  2081))
+     a (md5-GG a b c d (aref in  1)  5 '(63006 .  9570))
+     d (md5-GG d a b c (aref in  6)  9 '(49216 . 45888))
+     c (md5-GG c d a b (aref in 11) 14 '( 9822 . 23121))
+     b (md5-GG b c d a (aref in  0) 20 '(59830 . 51114))
+     a (md5-GG a b c d (aref in  5)  5 '(54831 .  4189))
+     d (md5-GG d a b c (aref in 10)  9 '(  580 .  5203))
+     c (md5-GG c d a b (aref in 15) 14 '(55457 . 59009))
+     b (md5-GG b c d a (aref in  4) 20 '(59347 . 64456))
+     a (md5-GG a b c d (aref in  9)  5 '( 8673 . 52710))
+     d (md5-GG d a b c (aref in 14)  9 '(49975 .  2006))
+     c (md5-GG c d a b (aref in  3) 14 '(62677 .  3463))
+     b (md5-GG b c d a (aref in  8) 20 '(17754 .  5357))
+     a (md5-GG a b c d (aref in 13)  5 '(43491 . 59653))
+     d (md5-GG d a b c (aref in  2)  9 '(64751 . 41976))
+     c (md5-GG c d a b (aref in  7) 14 '(26479 .   729))
+     b (md5-GG b c d a (aref in 12) 20 '(36138 . 19594))
+     a (md5-HH a b c d (aref in  5)  4 '(65530 . 14658))
+     d (md5-HH d a b c (aref in  8) 11 '(34673 . 63105))
+     c (md5-HH c d a b (aref in 11) 16 '(28061 . 24866))
+     b (md5-HH b c d a (aref in 14) 23 '(64997 . 14348))
+     a (md5-HH a b c d (aref in  1)  4 '(42174 . 59972))
+     d (md5-HH d a b c (aref in  4) 11 '(19422 . 53161))
+     c (md5-HH c d a b (aref in  7) 16 '(63163 . 19296))
+     b (md5-HH b c d a (aref in 10) 23 '(48831 . 48240))
+     a (md5-HH a b c d (aref in 13)  4 '(10395 . 32454))
+     d (md5-HH d a b c (aref in  0) 11 '(60065 . 10234))
+     c (md5-HH c d a b (aref in  3) 16 '(54511 . 12421))
+     b (md5-HH b c d a (aref in  6) 23 '( 1160 .  7429))
+     a (md5-HH a b c d (aref in  9)  4 '(55764 . 53305))
+     d (md5-HH d a b c (aref in 12) 11 '(59099 . 39397))
+     c (md5-HH c d a b (aref in 15) 16 '( 8098 . 31992))
+     b (md5-HH b c d a (aref in  2) 23 '(50348 . 22117))
+     a (md5-II a b c d (aref in  0)  6 '(62505 .  8772))
+     d (md5-II d a b c (aref in  7) 10 '(17194 . 65431))
+     c (md5-II c d a b (aref in 14) 15 '(43924 .  9127))
+     b (md5-II b c d a (aref in  5) 21 '(64659 . 41017))
+     a (md5-II a b c d (aref in 12)  6 '(25947 . 22979))
+     d (md5-II d a b c (aref in  3) 10 '(36620 . 52370))
+     c (md5-II c d a b (aref in 10) 15 '(65519 . 62589))
+     b (md5-II b c d a (aref in  1) 21 '(34180 . 24017))
+     a (md5-II a b c d (aref in  8)  6 '(28584 . 32335))
+     d (md5-II d a b c (aref in 15) 10 '(65068 . 59104))
+     c (md5-II c d a b (aref in  6) 15 '(41729 . 17172))
+     b (md5-II b c d a (aref in 13) 21 '(19976 .  4513))
+     a (md5-II a b c d (aref in  4)  6 '(63315 . 32386))
+     d (md5-II d a b c (aref in 11) 10 '(48442 . 62005))
+     c (md5-II c d a b (aref in  2) 15 '(10967 . 53947))
+     b (md5-II b c d a (aref in  9) 21 '(60294 . 54161)))
+
+     (aset md5-buffer 0 (md5-add (aref md5-buffer 0) a))
+     (aset md5-buffer 1 (md5-add (aref md5-buffer 1) b))
+     (aset md5-buffer 2 (md5-add (aref md5-buffer 2) c))
+     (aset md5-buffer 3 (md5-add (aref md5-buffer 3) d))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Here begins the merger with the XEmacs API and the md5.el from the URL
+;;; package.  Courtesy wmperry@cs.indiana.edu
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defun md5 (object &optional start end)
+  "Return the MD5 (a secure message digest algorithm) of an object.
+OBJECT is either a string or a buffer.
+Optional arguments START and END denote buffer positions for computing the
+hash of a portion of OBJECT."
+ (let ((buffer nil))
+    (unwind-protect
+	(save-excursion
+	  (setq buffer (generate-new-buffer " *md5-work*"))
+	  (set-buffer buffer)
+	  (cond
+	   ((bufferp object)
+	    (insert-buffer-substring object start end))
+	   ((stringp object)
+	    (insert (if (or start end)
+			(substring object start end)
+		      object)))
+	   (t nil))
+	  (prog1
+	      (if (<= (point-max) md5-maximum-internal-length)
+		  (mapconcat
+		   (function (lambda (node) (format "%02x" node)))
+		   (md5-encode (buffer-string))
+		   "")
+		(call-process-region (point-min) (point-max)
+				     shell-file-name
+				     t buffer nil
+				     shell-command-switch md5-program)
+		;; MD5 digest is 32 chars long
+		;; mddriver adds a newline to make neaten output for tty
+		;; viewing, make sure we leave it behind.
+		(buffer-substring (point-min) (+ (point-min) 32)))
+	    (kill-buffer buffer)))
+      (and buffer (buffer-name buffer) (kill-buffer buffer) nil))))
+
+(provide 'md5)
    filename FILENAME
    md5sum MD5SUM
    size SIZE
-   provides (css devices w3-auto dsssl-flow dsssl font images md5 mm mule-sysdp socks ssl urlauth url-cache url-cookie url-file url-gopher url-gw url-http url-ldap url-mail url-misc url-news url-ns url-parse url-vars url w3-about w3-auto w3-cfg w3-cus w3-display w3-emacs19 w3-e19 w3-e20 w3-elisp w3-emulate w3-forms w3-hot w3-hotindex w3-imap w3-java w3-jscript w3-keyword w3-latex w3-menu w3-mouse w3-parse w3-print w3-props w3-script w3-structure w3-speak w3-style w3-sysdp w3-toolbar w3-vars w3-widget w3-xemacs w3-xemac w3)
+   provides (css devices w3-auto dsssl-flow dsssl font images mm mule-sysdp socks ssl urlauth url-cache url-cookie url-file url-gopher url-gw url-http url-ldap url-mail url-misc url-news url-ns url-parse url-vars url w3-about w3-auto w3-cfg w3-cus w3-display w3-emacs19 w3-e19 w3-e20 w3-elisp w3-emulate w3-forms w3-hot w3-hotindex w3-imap w3-java w3-jscript w3-keyword w3-latex w3-menu w3-mouse w3-parse w3-print w3-props w3-script w3-structure w3-speak w3-style w3-sysdp w3-toolbar w3-vars w3-widget w3-xemacs w3-xemac w3)
    requires (REQUIRES)
    type regular
 ))