/* * A WML Script implementation of the RSA Data Security, Inc. MD5 Message * Digest Algorithm, as defined in RFC 1321. * Copyright (C) Simon Wistow, 2001 * * Auxillary functions - split into seperate files to keep each compiled * script down below the size of one UDP packet so all phones can use it */ use url ordlib "ord.wmlsc"; /* * Extract a value from one of our arrays. These are strings separated by the '|' character. */ extern function elt(str, index) { return String.elementAt (str, index, '|'); } /* * Extract a value from an array at offset: * base + ((group + offset) & 0xF) */ extern function elt2(str, base, group, offset) { return elt(str, base + ((group + offset) & 0xF)); } /* * Reduce size by turning this into a function. */ extern function combine (a, b, c, d) { return a + "|" + b + "|" + c + "|" + d; } /* * Take a string and return the hex representation of its MD5. */ extern function rhex(num) { var hex_chr = "0123456789abcdef"; var str = ""; for(var j = 0; j <= 3; j++) str += String.charAt(hex_chr, (num >> (j * 8 + 4)) & 0x0F) + String.charAt(hex_chr, (num >> (j * 8)) & 0x0F); return str; } /* * Convert a string to a sequence of 16-word blocks, stored as an array. * Append padding bits and the length, as described in the MD5 standard. */ extern function str2blks_MD5(str) { var nblk = ((String.length(str) + 8) >> 6) + 1; var blks = "0"; for(var i = 1; i < (nblk * 16); i++) blks += '|0'; for(i = 0; i <= String.length(str); i++) { var temp = String.elementAt(blks, i>>2, '|'); var ord_str = ordlib#ord_string(str); if (i != String.length(str)) temp |= String.elementAt(ord_str,i, '|') << ((i % 4) * 8); else temp |= 0x80 << ((i % 4) * 8); blks = String.replaceAt(blks, temp, i>>2, '|'); } blks = String.replaceAt(blks, String.length(str) * 8, nblk * 16 - 2, '|'); return blks; } /* * Add integers, wrapping at 2^32 */ extern function add(x, y) { return ((x&0x7FFFFFFF) + (y&0x7FFFFFFF)) ^ (x&0x80000000) ^ (y&0x80000000); } /* * Bitwise rotate a 32-bit number to the left */ extern function rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); } /* * These functions implement the basic operation for each round of the * algorithm. */ extern function cmn(q, a, b, x, s, t) { return add(rol(add(add(a, q), add(x, t)), s), b); } extern function ff(a, b, c, d, x, s, t) { return cmn((b & c) | ((~b) & d), a, b, x, s, t); } extern function gg(a, b, c, d, x, s, t) { return cmn((b & d) | (c & (~d)), a, b, x, s, t); } extern function hh(a, b, c, d, x, s, t) { return cmn(b ^ c ^ d, a, b, x, s, t); } extern function ii(a, b, c, d, x, s, t) { return cmn(c ^ (b | (~d)), a, b, x, s, t); } extern function ff_four (abcd, x, i, offset, t1, t2, t3, t4) { var a = String.elementAt(abcd, 0, '|'); var b = String.elementAt(abcd, 1, '|'); var c = String.elementAt(abcd, 2, '|'); var d = String.elementAt(abcd, 3, '|'); i+=offset; a = ff(a, b, c, d, String.elementAt(x, i+ 0, '|'), 7, t1); d = ff(d, a, b, c, String.elementAt(x, i+ 1, '|'),12, t2); c = ff(c, d, a, b, String.elementAt(x, i+ 2, '|'),17, t3); b = ff(b, c, d, a, String.elementAt(x, i+ 3, '|'),22, t4); return a + '|' + b + '|' + c + '|' + d; } extern function gg_four (abcd, x, i, offset, t1, t2, t3, t4) { var a = elt(abcd, 0); var b = elt(abcd, 1); var c = elt(abcd, 2); var d = elt(abcd, 3); a = gg(a, b, c, d, elt2(x, i, offset, 0), 5, t1); d = gg(d, a, b, c, elt2(x, i, offset, 5), 9, t2); c = gg(c, d, a, b, elt2(x, i, offset, 10), 14, t3); b = gg(b, c, d, a, elt2(x, i, offset, 15), 20, t4); return combine (a, b, c, d); } /* * Do four hh calculations at once. */ extern function hh_four (abcd, x, i, offset, t1, t2, t3, t4) { var a = elt(abcd, 0); var b = elt(abcd, 1); var c = elt(abcd, 2); var d = elt(abcd, 3); a = hh(a, b, c, d, elt2(x, i, offset, 0), 4, t1); d = hh(d, a, b, c, elt2(x, i, offset, 3), 11, t2); c = hh(c, d, a, b, elt2(x, i, offset, 6), 16, t3); b = hh(b, c, d, a, elt2(x, i, offset, 9), 23, t4); return combine (a, b, c, d); } /* * Do four ii calculations at once. */ extern function ii_four (abcd, x, i, offset, t1, t2, t3, t4) { var a = elt(abcd, 0); var b = elt(abcd, 1); var c = elt(abcd, 2); var d = elt(abcd, 3); a = ii(a, b, c, d, elt2(x, i, offset, 0), 6, t1); d = ii(d, a, b, c, elt2(x, i, offset, 7), 10, t2); c = ii(c, d, a, b, elt2(x, i, offset, 14), 15, t3); b = ii(b, c, d, a, elt2(x, i, offset, 21), 21, t4); return combine (a, b, c, d); }