diff options
Diffstat (limited to 'core/ripemd160.js')
-rw-r--r-- | core/ripemd160.js | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/core/ripemd160.js b/core/ripemd160.js new file mode 100644 index 0000000..4ee7b92 --- /dev/null +++ b/core/ripemd160.js @@ -0,0 +1,207 @@ +/** @fileOverview Javascript RIPEMD-160 implementation. + * + * @author Artem S Vybornov <vybornov@gmail.com> + */ +(function() { + +/** + * Context for a RIPEMD-160 operation in progress. + * @constructor + * @class RIPEMD, 160 bits. + */ +sjcl.hash.ripemd160 = function (hash) { + if (hash) { + this._h = hash._h.slice(0); + this._buffer = hash._buffer.slice(0); + this._length = hash._length; + } else { + this.reset(); + } +}; + +/** + * Hash a string or an array of words. + * @static + * @param {bitArray|String} data the data to hash. + * @return {bitArray} The hash value, an array of 5 big-endian words. + */ +sjcl.hash.ripemd160.hash = function (data) { + return (new sjcl.hash.ripemd160()).update(data).finalize(); +}; + +sjcl.hash.ripemd160.prototype = { + /** + * Reset the hash state. + * @return this + */ + reset: function () { + this._h = _h0.slice(0); + this._buffer = []; + this._length = 0; + return this; + }, + + /** + * Reset the hash state. + * @param {bitArray|String} data the data to hash. + * @return this + */ + update: function (data) { + if ( typeof data === "string" ) + data = sjcl.codec.utf8String.toBits(data); + + var i, b = this._buffer = sjcl.bitArray.concat(this._buffer, data), + ol = this._length, + nl = this._length = ol + sjcl.bitArray.bitLength(data); + for (i = 512+ol & -512; i <= nl; i+= 512) { + var words = b.splice(0,16); + for ( var w = 0; w < 16; ++w ) + words[w] = _cvt(words[w]); + + _block.call( this, words ); + } + + return this; + }, + + /** + * Complete hashing and output the hash value. + * @return {bitArray} The hash value, an array of 5 big-endian words. + */ + finalize: function () { + var b = sjcl.bitArray.concat( this._buffer, [ sjcl.bitArray.partial(1,1) ] ), + l = ( this._length + 1 ) % 512, + z = ( l > 448 ? 512 : 448 ) - l % 448, + zp = z % 32; + + if ( zp > 0 ) + b = sjcl.bitArray.concat( b, [ sjcl.bitArray.partial(zp,0) ] ) + for ( ; z >= 32; z -= 32 ) + b.push(0); + + b.push( _cvt( this._length | 0 ) ); + b.push( _cvt( Math.floor(this._length / 0x100000000) ) ); + + while ( b.length ) { + var words = b.splice(0,16); + for ( var w = 0; w < 16; ++w ) + words[w] = _cvt(words[w]); + + _block.call( this, words ); + } + + var h = this._h; + this.reset(); + + for ( var w = 0; w < 5; ++w ) + h[w] = _cvt(h[w]); + + return h; + } +}; + +var _h0 = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ]; + +var _k1 = [ 0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e ]; +var _k2 = [ 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000 ]; +for ( var i = 4; i >= 0; --i ) { + for ( var j = 1; j < 16; ++j ) { + _k1.splice(i,0,_k1[i]); + _k2.splice(i,0,_k2[i]); + } +} + +var _r1 = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 ]; +var _r2 = [ 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 ]; + +var _s1 = [ 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 ]; +var _s2 = [ 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 ]; + +function _f0(x,y,z) { + return x ^ y ^ z; +}; + +function _f1(x,y,z) { + return (x & y) | (~x & z); +}; + +function _f2(x,y,z) { + return (x | ~y) ^ z; +}; + +function _f3(x,y,z) { + return (x & z) | (y & ~z); +}; + +function _f4(x,y,z) { + return x ^ (y | ~z); +}; + +function _rol(n,l) { + return (n << l) | (n >>> (32-l)); +} + +function _cvt(n) { + return ( (n & 0xff << 0) << 24 ) + | ( (n & 0xff << 8) << 8 ) + | ( (n & 0xff << 16) >>> 8 ) + | ( (n & 0xff << 24) >>> 24 ); +} + +function _block(X) { + var A1 = this._h[0], B1 = this._h[1], C1 = this._h[2], D1 = this._h[3], E1 = this._h[4], + A2 = this._h[0], B2 = this._h[1], C2 = this._h[2], D2 = this._h[3], E2 = this._h[4]; + + var j = 0, T; + + for ( ; j < 16; ++j ) { + T = _rol( A1 + _f0(B1,C1,D1) + X[_r1[j]] + _k1[j], _s1[j] ) + E1; + A1 = E1; E1 = D1; D1 = _rol(C1,10); C1 = B1; B1 = T; + T = _rol( A2 + _f4(B2,C2,D2) + X[_r2[j]] + _k2[j], _s2[j] ) + E2; + A2 = E2; E2 = D2; D2 = _rol(C2,10); C2 = B2; B2 = T; } + for ( ; j < 32; ++j ) { + T = _rol( A1 + _f1(B1,C1,D1) + X[_r1[j]] + _k1[j], _s1[j] ) + E1; + A1 = E1; E1 = D1; D1 = _rol(C1,10); C1 = B1; B1 = T; + T = _rol( A2 + _f3(B2,C2,D2) + X[_r2[j]] + _k2[j], _s2[j] ) + E2; + A2 = E2; E2 = D2; D2 = _rol(C2,10); C2 = B2; B2 = T; } + for ( ; j < 48; ++j ) { + T = _rol( A1 + _f2(B1,C1,D1) + X[_r1[j]] + _k1[j], _s1[j] ) + E1; + A1 = E1; E1 = D1; D1 = _rol(C1,10); C1 = B1; B1 = T; + T = _rol( A2 + _f2(B2,C2,D2) + X[_r2[j]] + _k2[j], _s2[j] ) + E2; + A2 = E2; E2 = D2; D2 = _rol(C2,10); C2 = B2; B2 = T; } + for ( ; j < 64; ++j ) { + T = _rol( A1 + _f3(B1,C1,D1) + X[_r1[j]] + _k1[j], _s1[j] ) + E1; + A1 = E1; E1 = D1; D1 = _rol(C1,10); C1 = B1; B1 = T; + T = _rol( A2 + _f1(B2,C2,D2) + X[_r2[j]] + _k2[j], _s2[j] ) + E2; + A2 = E2; E2 = D2; D2 = _rol(C2,10); C2 = B2; B2 = T; } + for ( ; j < 80; ++j ) { + T = _rol( A1 + _f4(B1,C1,D1) + X[_r1[j]] + _k1[j], _s1[j] ) + E1; + A1 = E1; E1 = D1; D1 = _rol(C1,10); C1 = B1; B1 = T; + T = _rol( A2 + _f0(B2,C2,D2) + X[_r2[j]] + _k2[j], _s2[j] ) + E2; + A2 = E2; E2 = D2; D2 = _rol(C2,10); C2 = B2; B2 = T; } + + T = this._h[1] + C1 + D2; + this._h[1] = this._h[2] + D1 + E2; + this._h[2] = this._h[3] + E1 + A2; + this._h[3] = this._h[4] + A1 + B2; + this._h[4] = this._h[0] + B1 + C2; + this._h[0] = T; +} + +})(); |