package org.ripple.power.utils; import java.math.BigDecimal; import org.ripple.power.collection.LongArray; public class SHA1 { public SHA1() { if (_key == null || _key.length == 0) { _precompute(); reset(); } } public static LongArray hash(LongArray data) { SHA1 sha = new SHA1(); if (sha._key == null || sha._key.length == 0) { sha._precompute(); sha.reset(); } return sha.update(data)._finalize(); } int blockSize = 512; LongArray _init = new LongArray(); LongArray _key = new LongArray(); LongArray _h; LongArray _buffer = new LongArray(); int _length = 0; public SHA1 reset() { this._h = this._init.slice(0); this._buffer = new LongArray(); this._length = 0; return this; } public SHA1 update(Object d) { LongArray data = null; if (d instanceof String) { data = BigNumber.utf8_toBits((String) d); } else { data = (LongArray) d; } int i; if (_buffer == null) { _buffer = new LongArray(); } LongArray b = this._buffer = BitArray.concat(this._buffer, data); int ol = this._length, nl = this._length = ol + (int) BitArray.bitLength(data); for (i = this.blockSize + ol & -this.blockSize; i <= nl; i += this.blockSize) { this._block(b.splice(0, 16)); } return this; } public LongArray _finalize() { int i; LongArray b = this._buffer, h = this._h; long[] a = new long[] { BitArray.partial(1, 1) }; b = BitArray.concat(b, new LongArray(a)); for (i = b.length + 2; (i & 15) > 0; i++) { b.push(0); } b.push((long) Math.floor(this._length / 0x100000000l)); b.push(this._length | 0); while (b.length > 0) { this._block(b.splice(0, 16)); } return h; } public long frac(double x) { double math_floor = Math.floor(x); BigDecimal intx = new BigDecimal(x - math_floor); intx = intx.multiply(BigDecimal.valueOf(0x100000000l)); return intx.longValue() | 0; } public void _precompute() { _init = new LongArray(new long[] { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }); _key = new LongArray(new long[] { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 }); } public long _f(long t, long b, long c, long d) { if (t <= 19) { return (int) ((b & c) | (~b & d)); } else if (t <= 39) { return (int) (b ^ c ^ d); } else if (t <= 59) { return (int) ((b & c) | (b & d) | (c & d)); } else if (t <= 79) { return (int) (b ^ c ^ d); } return 0; } public long _S(long n, long x) { return (int) ((x << n) | (JS.MOVE_RightUShift(x, 32 - (int) n))); } public void _block(LongArray words) { int t; long tmp, a, b, c, d, e; LongArray w = words.slice(0); LongArray h = this._h; a = h.items[0]; b = h.items[1]; c = h.items[2]; d = h.items[3]; e = h.items[4]; for (t = 0; t <= 79; t++) { if (t >= 16) { w.items[t] = (int) (this._S(1, w.items[t - 3] ^ w.items[t - 8] ^ w.items[t - 14] ^ w.items[t - 16])); } tmp = (this._S(5, a) + this._f(t, b, c, d) + e + w.items[t] + (int) (this._key.items[(int) Math.floor((double) t / 20d)]) | 0); e = d; d = c; c = this._S(30, b); b = a; a = tmp; } h.items[0] = (int) ((h.items[0] + a) | 0); h.items[1] = (int) ((h.items[1] + b) | 0); h.items[2] = (int) ((h.items[2] + c) | 0); h.items[3] = (int) ((h.items[3] + d) | 0); h.items[4] = (int) ((h.items[4] + e) | 0); } }