/*
* 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);
}