		TTL	> MD5 Assembler bits

;Assembler bits for MD5

		GET	hdr.Regs
		GET	hdr.CMacros

		PREAMBLE

;F, G, H and I are basic MD5 functions

;#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
		MACRO
$label		F	$x, $y, $z, $r, $t
$label		MVN	$t,$x				;t <- ~x
		AND	$t,$t,$z			;t <- ~x & z
		AND	$r,$x,$y			;r <- x & y
		ORR	$r,$r,$t			;r <- (x & y) | (~x & z)
		MEND

;#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
		MACRO
$label		G	$x, $y, $z, $r, $t
$label		MVN	$t,$z				;t <- ~z
		AND	$t,$y,$t			;t <- y & ~z
		AND	$r,$x,$z			;r <- x & z
		ORR	$r,$r,$t			;r <- (x & z) | (y & ~z)
		MEND

;#define H(x, y, z) ((x) ^ (y) ^ (z))
		MACRO
$label		H	$x, $y, $z, $r, $t
$label		EOR	$r,$x,$y			;r <- x ^ y
		EOR	$r,$r,$z			;r <- x ^ y ^ z
		MEND

;#define I(x, y, z) ((y) ^ ((x) | (~z)))
		MACRO
$label		I	$x, $y, $z, $r, $t
$label		MVN	$r,$z				;r <- ~z
		ORR	$r,$x,$r			;r <- x | ~z
		EOR	$r,$r,$y			;r <- y ^ (x | ~z)
		MEND


;/* ROTATE_LEFT rotates x left n bits */
;#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
;
;/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
;/* Rotation is separate from addition to prevent recomputation */

;result is in a
;b,c,d are registers - preserved
;t0,t1 are registers - not preserved
;in points to the input - preserved
;p is an offset from in to get the word to be worked upon
;s is a shift
;ac is a 32 bit constant

		MACRO
$label		XX	$fn, $a, $b, $c, $d, $p, $s, $ac
$label		ADD	$a,$a,#$ac :AND: &000000FF	;a+=ac
		ADD	$a,$a,#$ac :AND: &0000FF00	;a+=ac
		ADD	$a,$a,#$ac :AND: &00FF0000	;a+=ac
		ADD	$a,$a,#$ac :AND: &FF000000	;a+=ac
		LDR	t0,[in,#$p<<2]
		ADD	$a,$a,t0			;a+=x
		$fn	$b,$c,$d,t0,t1
		ADD	$a,$a,t0			;a+=F(b,c,d)
		MOV	$a,$a,ROR #32-$s		;a <- a ROL s
		ADD	$a,$a,$b			;a+=b
		MEND

;#define FF(a, b, c, d, x, s, ac) \-
;  {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \-
;   (a) = ROTATE_LEFT ((a), (s)); \-
;   (a) += (b); \-
;  }
		MACRO
$label		FF	$a, $b, $c, $d, $p, $s, $ac
$label		XX	F, $a, $b, $c, $d, $p, $s, $ac
		MEND

;#define GG(a, b, c, d, x, s, ac) \-
;  {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \-
;   (a) = ROTATE_LEFT ((a), (s)); \-
;   (a) += (b); \-
;  }
		MACRO
$label		GG	$a, $b, $c, $d, $p, $s, $ac
$label		XX	G, $a, $b, $c, $d, $p, $s, $ac
		MEND

;#define HH(a, b, c, d, x, s, ac) \-
;  {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \-
;   (a) = ROTATE_LEFT ((a), (s)); \-
;   (a) += (b); \-
;  }
		MACRO
$label		HH	$a, $b, $c, $d, $p, $s, $ac
$label		XX	H, $a, $b, $c, $d, $p, $s, $ac
		MEND

;#define II(a, b, c, d, x, s, ac) \-
;  {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \-
;   (a) = ROTATE_LEFT ((a), (s)); \-
;   (a) += (b); \-
;  }
		MACRO
$label		II	$a, $b, $c, $d, $p, $s, $ac
$label		XX	I, $a, $b, $c, $d, $p, $s, $ac
		MEND


;Basic MD5 step. Transforms buf based on in.  Note that if the Mysterious
;Constants are arranged backwards in little-endian order & decrypted with
;the DES they produce OCCULT MESSAGES!
;
;void Transform(register UINT4 *buf,register UINT4 *in)

buf		RN	a1
in		RN	a2
a		RN	a3
b		RN	a4
c		RN	v1
d		RN	v2
t0		RN	v3
t1		RN	v4
t2		RN	v5
t3		RN	v6

		STARTCODE	Transform
		STMFD		sp!,{v1-v6,lr}

;{
;  register UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
;
		LDMIA		buf,{a,b,c,d}		;get initial registers

; changed S11-S31 to add Z prefix to avoid multiple declarations  v0.08
ZS11		EQU	7
ZS12		EQU	12
ZS13		EQU	17
ZS14		EQU	22
ZS21		EQU	5
ZS22		EQU	9
ZS23		EQU	14
ZS24		EQU	20
ZS31		EQU	4
S32		EQU	11
S33		EQU	16
S34		EQU	23
S41		EQU	6
S42		EQU	10
S43		EQU	15
S44		EQU	21

;Round 1
		FF	a, b, c, d,  0, ZS11, &D76AA478	;1
		FF	d, a, b, c,  1, ZS12, &E8C7B756	;2
		FF	c, d, a, b,  2, ZS13, &242070DB	;3
		FF	b, c, d, a,  3, ZS14, &C1BDCEEE	;4
		FF	a, b, c, d,  4, ZS11, &F57C0FAF	;5
		FF	d, a, b, c,  5, ZS12, &4787C62A	;6
		FF	c, d, a, b,  6, ZS13, &A8304613	;7
		FF	b, c, d, a,  7, ZS14, &FD469501	;8
		FF	a, b, c, d,  8, ZS11, &698098D8	;9
		FF	d, a, b, c,  9, ZS12, &8B44F7AF	;10
		FF	c, d, a, b, 10, ZS13, &FFFF5BB1	;11
		FF	b, c, d, a, 11, ZS14, &895CD7BE	;12
		FF	a, b, c, d, 12, ZS11, &6B901122	;13
		FF	d, a, b, c, 13, ZS12, &FD987193	;14
		FF	c, d, a, b, 14, ZS13, &A679438E	;15
		FF	b, c, d, a, 15, ZS14, &49B40821	;16

;Round 2
		GG	a, b, c, d,  1, ZS21, &F61E2562	;17
		GG	d, a, b, c,  6, ZS22, &C040B340	;18
		GG	c, d, a, b, 11, ZS23, &265E5A51	;19
		GG	b, c, d, a,  0, ZS24, &E9B6C7AA	;20
		GG	a, b, c, d,  5, ZS21, &D62F105D	;21
		GG	d, a, b, c, 10, ZS22, &02441453	;22
		GG	c, d, a, b, 15, ZS23, &D8A1E681	;23
		GG	b, c, d, a,  4, ZS24, &E7D3FBC8	;24
		GG	a, b, c, d,  9, ZS21, &21E1CDE6	;25
		GG	d, a, b, c, 14, ZS22, &C33707D6	;26
		GG	c, d, a, b,  3, ZS23, &F4D50D87	;27
		GG	b, c, d, a,  8, ZS24, &455A14ED	;28
		GG	a, b, c, d, 13, ZS21, &A9E3E905	;29
		GG	d, a, b, c,  2, ZS22, &FCEFA3F8	;30
		GG	c, d, a, b,  7, ZS23, &676F02D9	;31
		GG	b, c, d, a, 12, ZS24, &8D2A4C8A	;32

;Round 3
		HH	a, b, c, d,  5, ZS31, &FFFA3942	;33
		HH	d, a, b, c,  8, S32, &8771F681	;34
		HH	c, d, a, b, 11, S33, &6D9D6122	;35
		HH	b, c, d, a, 14, S34, &FDE5380C	;36
		HH	a, b, c, d,  1, ZS31, &A4BEEA44	;37
		HH	d, a, b, c,  4, S32, &4BDECFA9	;38
		HH	c, d, a, b,  7, S33, &F6BB4B60	;39
		HH	b, c, d, a, 10, S34, &BEBFBC70	;40
		HH	a, b, c, d, 13, ZS31, &289B7EC6	;41
		HH	d, a, b, c,  0, S32, &EAA127FA	;42
		HH	c, d, a, b,  3, S33, &D4EF3085	;43
		HH	b, c, d, a,  6, S34, &04881D05	;44
		HH	a, b, c, d,  9, ZS31, &D9D4D039	;45
		HH	d, a, b, c, 12, S32, &E6DB99E5	;46
		HH	c, d, a, b, 15, S33, &1FA27CF8	;47
		HH	b, c, d, a,  2, S34, &C4AC5665	;48

;Round 4
		II	a, b, c, d,  0, S41, &F4292244	;49
		II	d, a, b, c,  7, S42, &432AFF97	;50
		II	c, d, a, b, 14, S43, &AB9423A7	;51
		II	b, c, d, a,  5, S44, &FC93A039	;52
		II	a, b, c, d, 12, S41, &655B59C3	;53
		II	d, a, b, c,  3, S42, &8F0CCC92	;54
		II	c, d, a, b, 10, S43, &FFEFF47D	;55
		II	b, c, d, a,  1, S44, &85845DD1	;56
		II	a, b, c, d,  8, S41, &6FA87E4F	;57
		II	d, a, b, c, 15, S42, &FE2CE6E0	;58
		II	c, d, a, b,  6, S43, &A3014314	;59
		II	b, c, d, a, 13, S44, &4E0811A1	;60
		II	a, b, c, d,  4, S41, &F7537E82	;61
		II	d, a, b, c, 11, S42, &BD3AF235	;62
		II	c, d, a, b,  2, S43, &2AD7D2BB	;63
		II	b, c, d, a,  9, S44, &EB86D391	;64

;  buf[0] += a;
;  buf[1] += b;
;  buf[2] += c;
;  buf[3] += d;

		LDMIA	buf,{t0,t1,t2,t3}
		ADD	t0,t0,a
		ADD	t1,t1,b
		ADD	t2,t2,c
		ADD	t3,t3,d
		STMIA	buf,{t0,t1,t2,t3}		;increment the buffer

;}
		LDMFD		sp!,{v1-v6,pc}	; removed ^  v0.08

		END
