/ * * A JavaScript implementation of the RSA Data Security, Inc. MD4 Message * Digest Algorithm, as defined in RFC 1320. * Version 2.1 Copyright (C) Jerrad Pierce, Paul Johnston 1999 - 2002. * Other contributors: Greg Holt, Andrew Kepert, YDNAR, LOSTINET * Distributed Under the BSD license * See http://pajhome.org.uk/crypt/md5 for more info. * /
. / * * Configurable variables You may need to tweak these to be compatible with * the server-side, but the defaults work in most cases * / var hexcase = 0; / * hex output format 0 - lowercase;.. 1 - uppercase * / var b64pad = ""; / * base-64 pad character. "=" = "for strict RFC Compliance * / var chrsz = 8; / * bits per input character. 8 - ascii; 16 - unicode * /
/ * SESE ARE THE FUNCTIONS You'll Usually Want To Call * / Function HEX_MD4 (S) {Return BINL2HEX (Core_MD4 (STR2BINL (S), S.LENGTH * ChRSZ);} Function B64_MD4 (S) {Return BINL2B64 ( CORE_MD4 (Str2binl (s), S.Length * Chrs);} Function STR_MD4 (S) {RETURN BINL2STR (Core_md4 (S.Length * Chrsz));} Function HEX_HMAC_MD4 (KEY, DATA) {Return binl2hex (core_hmac_md4 (key, data));} function b64_hmac_md4 (key, data) {return binl2b64 (core_hmac_md4 (key, data));} function str_hmac_md4 (key, data) {return binl2str (core_hmac_md4 (key, data)); }
/ * Perform A Simple Self-test to see if the vm is working * / function MD4_VM_TEST () {RETURN HEX_MD4 ("ABC") == "A448017AAF21D8525FC10AE87AA6729D";}
/ * * Calculate the md4 of an array of little-endian words, and a bit length * / function core_md4 (x, len) {/ * append padding * / x [len >> 5] | = 0x80 << (len% 32); ((LEN 64) >>> 9) << 4) 14] = LEN; var A = 1732584193; var c = -271733879; var C = -1732584194; var d = 271733878; for (VAR i = 0; i A = MD4_FF (A, B, C, D, X [i 0], 3); D = MD4_FF (D, A, B, C, X [i 1], 7); C = MD4_FF (C, D, A, B, X [i 2], 11); B = MD4_FF (B, C, D, A, X [i 3], 19); A = MD4_FF (A, B, C, D, X [i 4 ], 3); D = MD4_FF (D, A, B, C, X [i 5], 7); C = MD4_FF (C, D, A, B, X [i 6], 11); B = MD4_FF (B, C, D, A, X [i 7], 19); A = MD4_FF (A, B, C, D, X [i 8], 3); D = MD4_FF (D, A, B, C , x [i 9], 7); C = MD4_FF (C, D, A, B, X [i 10], 11); B = MD4_FF (B, C, D, A, X [i 11] , 19); A = MD4_FF (A, B, C, D, X [i 12], 3); D = MD4_FF (D, A, B, C, X [i 13], 7); c = MD4_FF (C, D, A, B, X [i 14], 11); B = MD4_FF (B, C, D, A, X [i 15], 19); A = MD4_GG (A, B, C, D, X [i 0], 3); D = MD4_GG (D, A, B, C, X [i 4], 5); C = MD4_GG (C, D, A, B, X [i 8], 9); B = MD4_GG (B, C, D, A, X [i 12], 13); A = MD4_GG (A, B, C, D, X [i 1], 3); D = MD4_GG (D, A, B, C, X [i 5], 5); C = MD4_GG (C, D, A, B, X [i 9], 9); b = MD4_GG (B, C, D, A, X [i 13], 13); A = MD4_GG (A, B, C, D, X [i 2], 3); D = MD4_GG (D, A, B , C, X [i 6], 5); C = MD4_GG (C, D, A, B, X [i 10], 9); B = MD4_GG (B, C, D, A, X [i 14], 13); A = MD4_GG (A, B, C, D, X [i 3], 3); D = MD4_GG (D, A, B, C, X [i 7], 5); c = MD4_GG (C, D, A, B, X [i 11], 9); B = MD4_GG (B, C, D, A, X [i 15], 13); A = MD4_HH (A, B, C, D, X [i 0], 3); D = MD4_HH (D, A, B, C, X [i 8], 9); C = MD4_HH (C, D, A, B, X [i 4 ], 11); B = MD4_HH (B, C, D, A, X [i 12], 15); A = MD4_HH (A, B, C, D, X [i 2], 3); D = MD4_HH (D, A, B, C, X [i 10], 9); C = MD4_HH (C, D, A, B, X [i 6], 11); B = MD4_HH (B, C, D , A, X [i 14], 15); A = MD4_HH (A, B, C, D, X [i 1], 3); D = MD4_HH (D, A, B, C, X [i 9], 9); C = MD4_HH (C, D, A, B, X [i 5], 11); B = MD4_HH (B, C, D, A, X [i 13], 15); A = MD4_HH (A, B, C, D, X [i 3], 3); D = MD4_HH (D, A, B, C, X [i 11 ], 9); C = MD4_HH (C, D, A, B, X [i 7], 11); B = MD4_HH (B, C, D, A, X [i 15], 15); A = SAFE_ADD (A, OLDA); B = SAFE_ADD (B, OLDB); C = SAFE_ADD (C, OLDC); D = SAFE_ADD (D, OLDD); } RETURN Array (A, B, C, D); } / * * * Sests for Each Round of the * algorithm. * / Function MD4_CMN (Q, A, B, X, S, T) {RETURN SAFE_ADD (ROL (SAFE_ADD (SAFE_ADD (A, Q), SAFE_ADD (x, t)), s), b);} function MD4_FF (A, B, C, D, X, S) {RETURN MD4_CMN ((B & C) | ((~ b) & d), A, 0, x, s, 0);} Function MD4_GG (A, B, C, D, X, S) {RETURN MD4_CMN ((B & C) | (B & D) | (C & D), A, 0 , X, S, 1518500249);} Function MD4_HH (A, B, C, D, X, S) {RETURN MD4_CMN (B ^ C ^ D, A, 0, X, S, 1859775393);} / * * Calculate THE HMAC-MD4, OF A Key and Some Data * / Function Core_HMAC_MD4 (Key, DATA) {var Bkey = Str2binl (key); if (bkey.length> 16) bkey = core_md4 (bKey, key.length * chrs; VAR iPad = array (16), opAd = array (16); for (var i = 0; i <16; i ) {ipad [i] = bkey [i] ^ 0x36363636; opad [i] = bkey [i] ^ 0x5c5c5c5c;} Var hash = core_md4 (iPad.Concat), 512 Data.Length * Chrsz); Return Core_md4 (Opad.Concat (Hash), 512 128); / * Add Integers, Wrapping AT 2 ^ 32. This Uses 16-bit Operations Internally * To Work Around Bugs in Some JS Interpreters. * / Function Safe_Add (x, y) {var Lsw = (x & 0xfff) (Y & 0xfff); VAR MSW = (x >> 16) (Y >> 16) (LSW >> 16); Return (MSW << 16) | (Lsw & 0xfff);} / * * Bitwise Rotate a 32-bit number to the left. * / Function rol (num, cnt) {Return (Num << CNT) | (NUM >>> (32 - CNT));} / * * Convert a string to an array of little-endian Words * if Chrs> 255 Have Their Hi-byte Silently Ignored. * / Function Str2binl (STR) {var bin = array (); var Mask = 1 << chrsz) - 1; for (var i = 0; i / * * Convert An Array of Little-Endian Words to a hex string. * / Function BINL2HEX (BINARRAY) {var hex_tab = hexcase? "0123456789abcdef": "0123456789abcdef"; var str = ""; for (var i = 0; I