1 ;;; md4.el --- MD4 Message Digest Algorithm.
3 ;; Copyright (C) 2001, 2004, 2007, 2008 Free Software Foundation, Inc.
5 ;; Author: Taro Kawagishi <tarok@transpulse.org>
8 ;; Created: February 2001
10 ;; This file is part of GNU Emacs.
12 ;; GNU Emacs is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 3, or (at your option)
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
30 ;;; MD4 hash calculation
32 (defvar md4-buffer
(make-vector 4 '(0 .
0))
33 "work buffer of four 32-bit integers")
36 "Returns the MD4 hash string of 16 bytes long for a string IN of N
37 bytes long. N is required to handle strings containing character 0."
41 (buf (make-string 128 0)) c4
)
43 (aset md4-buffer
0 '(26437 .
8961)) ;0x67452301
44 (aset md4-buffer
1 '(61389 .
43913)) ;0xefcdab89
45 (aset md4-buffer
2 '(39098 .
56574)) ;0x98badcfe
46 (aset md4-buffer
3 '(4146 .
21622)) ;0x10325476
48 ;; process the string in 64 bits chunks
50 (setq m
(md4-copy64 (substring in
0 64)))
52 (setq in
(substring in
64))
55 ;; process the rest of the string (length is now n <= 64)
58 (aset buf i
(aref in i
))
60 (aset buf n
128) ;0x80
63 (setq c4
(md4-pack-int32 b
))
64 (aset buf
56 (aref c4
0))
65 (aset buf
57 (aref c4
1))
66 (aset buf
58 (aref c4
2))
67 (aset buf
59 (aref c4
3))
68 (setq m
(md4-copy64 buf
))
71 (setq c4
(md4-pack-int32 b
))
72 (aset buf
120 (aref c4
0))
73 (aset buf
121 (aref c4
1))
74 (aset buf
122 (aref c4
2))
75 (aset buf
123 (aref c4
3))
76 (setq m
(md4-copy64 buf
))
78 (setq m
(md4-copy64 (substring buf
64)))
81 (concat (md4-pack-int32 (aref md4-buffer
0))
82 (md4-pack-int32 (aref md4-buffer
1))
83 (md4-pack-int32 (aref md4-buffer
2))
84 (md4-pack-int32 (aref md4-buffer
3))))
86 (defsubst md4-F
(x y z
) (logior (logand x y
) (logand (lognot x
) z
)))
87 (defsubst md4-G
(x y z
) (logior (logand x y
) (logand x z
) (logand y z
)))
88 (defsubst md4-H
(x y z
) (logxor x y z
))
90 (defmacro md4-make-step
(name func
)
91 `(defun ,name
(a b c d xk s ac
)
93 ((h1 (+ (car a
) (,func
(car b
) (car c
) (car d
)) (car xk
) (car ac
)))
94 (l1 (+ (cdr a
) (,func
(cdr b
) (cdr c
) (cdr d
)) (cdr xk
) (cdr ac
)))
95 (h2 (logand 65535 (+ h1
(lsh l1 -
16))))
96 (l2 (logand 65535 l1
))
97 ;; cyclic shift of 32 bits integer
98 (h3 (logand 65535 (if (> s
15)
99 (+ (lsh h2
(- s
32)) (lsh l2
(- s
16)))
100 (+ (lsh h2 s
) (lsh l2
(- s
16))))))
101 (l3 (logand 65535 (if (> s
15)
102 (+ (lsh l2
(- s
32)) (lsh h2
(- s
16)))
103 (+ (lsh l2 s
) (lsh h2
(- s
16)))))))
106 (md4-make-step md4-round1 md4-F
)
107 (md4-make-step md4-round2 md4-G
)
108 (md4-make-step md4-round3 md4-H
)
110 (defsubst md4-add
(x y
)
111 "Return 32-bit sum of 32-bit integers X and Y."
112 (let ((h (+ (car x
) (car y
)))
113 (l (+ (cdr x
) (cdr y
))))
114 (cons (logand 65535 (+ h
(lsh l -
16))) (logand 65535 l
))))
116 (defsubst md4-and
(x y
)
117 (cons (logand (car x
) (car y
)) (logand (cdr x
) (cdr y
))))
120 "Calculate md4 of 64 bytes chunk M which is represented as 16 pairs of
121 32 bits integers. The resulting md4 value is placed in md4-buffer."
122 (let ((a (aref md4-buffer
0))
123 (b (aref md4-buffer
1))
124 (c (aref md4-buffer
2))
125 (d (aref md4-buffer
3)))
126 (setq a
(md4-round1 a b c d
(aref m
0) 3 '(0 .
0))
127 d
(md4-round1 d a b c
(aref m
1) 7 '(0 .
0))
128 c
(md4-round1 c d a b
(aref m
2) 11 '(0 .
0))
129 b
(md4-round1 b c d a
(aref m
3) 19 '(0 .
0))
130 a
(md4-round1 a b c d
(aref m
4) 3 '(0 .
0))
131 d
(md4-round1 d a b c
(aref m
5) 7 '(0 .
0))
132 c
(md4-round1 c d a b
(aref m
6) 11 '(0 .
0))
133 b
(md4-round1 b c d a
(aref m
7) 19 '(0 .
0))
134 a
(md4-round1 a b c d
(aref m
8) 3 '(0 .
0))
135 d
(md4-round1 d a b c
(aref m
9) 7 '(0 .
0))
136 c
(md4-round1 c d a b
(aref m
10) 11 '(0 .
0))
137 b
(md4-round1 b c d a
(aref m
11) 19 '(0 .
0))
138 a
(md4-round1 a b c d
(aref m
12) 3 '(0 .
0))
139 d
(md4-round1 d a b c
(aref m
13) 7 '(0 .
0))
140 c
(md4-round1 c d a b
(aref m
14) 11 '(0 .
0))
141 b
(md4-round1 b c d a
(aref m
15) 19 '(0 .
0))
143 a
(md4-round2 a b c d
(aref m
0) 3 '(23170 .
31129)) ;0x5A827999
144 d
(md4-round2 d a b c
(aref m
4) 5 '(23170 .
31129))
145 c
(md4-round2 c d a b
(aref m
8) 9 '(23170 .
31129))
146 b
(md4-round2 b c d a
(aref m
12) 13 '(23170 .
31129))
147 a
(md4-round2 a b c d
(aref m
1) 3 '(23170 .
31129))
148 d
(md4-round2 d a b c
(aref m
5) 5 '(23170 .
31129))
149 c
(md4-round2 c d a b
(aref m
9) 9 '(23170 .
31129))
150 b
(md4-round2 b c d a
(aref m
13) 13 '(23170 .
31129))
151 a
(md4-round2 a b c d
(aref m
2) 3 '(23170 .
31129))
152 d
(md4-round2 d a b c
(aref m
6) 5 '(23170 .
31129))
153 c
(md4-round2 c d a b
(aref m
10) 9 '(23170 .
31129))
154 b
(md4-round2 b c d a
(aref m
14) 13 '(23170 .
31129))
155 a
(md4-round2 a b c d
(aref m
3) 3 '(23170 .
31129))
156 d
(md4-round2 d a b c
(aref m
7) 5 '(23170 .
31129))
157 c
(md4-round2 c d a b
(aref m
11) 9 '(23170 .
31129))
158 b
(md4-round2 b c d a
(aref m
15) 13 '(23170 .
31129))
160 a
(md4-round3 a b c d
(aref m
0) 3 '(28377 .
60321)) ;0x6ED9EBA1
161 d
(md4-round3 d a b c
(aref m
8) 9 '(28377 .
60321))
162 c
(md4-round3 c d a b
(aref m
4) 11 '(28377 .
60321))
163 b
(md4-round3 b c d a
(aref m
12) 15 '(28377 .
60321))
164 a
(md4-round3 a b c d
(aref m
2) 3 '(28377 .
60321))
165 d
(md4-round3 d a b c
(aref m
10) 9 '(28377 .
60321))
166 c
(md4-round3 c d a b
(aref m
6) 11 '(28377 .
60321))
167 b
(md4-round3 b c d a
(aref m
14) 15 '(28377 .
60321))
168 a
(md4-round3 a b c d
(aref m
1) 3 '(28377 .
60321))
169 d
(md4-round3 d a b c
(aref m
9) 9 '(28377 .
60321))
170 c
(md4-round3 c d a b
(aref m
5) 11 '(28377 .
60321))
171 b
(md4-round3 b c d a
(aref m
13) 15 '(28377 .
60321))
172 a
(md4-round3 a b c d
(aref m
3) 3 '(28377 .
60321))
173 d
(md4-round3 d a b c
(aref m
11) 9 '(28377 .
60321))
174 c
(md4-round3 c d a b
(aref m
7) 11 '(28377 .
60321))
175 b
(md4-round3 b c d a
(aref m
15) 15 '(28377 .
60321)))
177 (aset md4-buffer
0 (md4-add a
(aref md4-buffer
0)))
178 (aset md4-buffer
1 (md4-add b
(aref md4-buffer
1)))
179 (aset md4-buffer
2 (md4-add c
(aref md4-buffer
2)))
180 (aset md4-buffer
3 (md4-add d
(aref md4-buffer
3)))
183 (defun md4-copy64 (seq)
184 "Unpack a 64 bytes string into 16 pairs of 32 bits integers."
185 (let ((int32s (make-vector 16 0)) (i 0) j
)
188 (aset int32s i
(cons (+ (aref seq
(+ j
2)) (lsh (aref seq
(+ j
3)) 8))
189 (+ (aref seq j
) (lsh (aref seq
(1+ j
)) 8))))
196 (defun md4-pack-int16 (int16)
197 "Pack 16 bits integer in 2 bytes string as little endian."
198 (let ((str (make-string 2 0)))
199 (aset str
0 (logand int16
255))
200 (aset str
1 (lsh int16 -
8))
203 (defun md4-pack-int32 (int32)
204 "Pack 32 bits integer in a 4 bytes string as little endian. A 32 bits
205 integer is represented as a pair of two 16 bits integers (cons high low)."
206 (let ((str (make-string 4 0))
207 (h (car int32
)) (l (cdr int32
)))
208 (aset str
0 (logand l
255))
209 (aset str
1 (lsh l -
8))
210 (aset str
2 (logand h
255))
211 (aset str
3 (lsh h -
8))
214 (defun md4-unpack-int16 (str)
215 (if (eq 2 (length str
))
216 (+ (lsh (aref str
1) 8) (aref str
0))
217 (error "%s is not 2 bytes long" str
)))
219 (defun md4-unpack-int32 (str)
220 (if (eq 4 (length str
))
221 (cons (+ (lsh (aref str
3) 8) (aref str
2))
222 (+ (lsh (aref str
1) 8) (aref str
0)))
223 (error "%s is not 4 bytes long" str
)))
227 ;;; arch-tag: 99d706fe-089b-42ea-9507-67ae41091e6e