/* * Created on Apr 12, 2004 * Created by Olivier Chalouhi * Modified Apr 13, 2004 by Alon Rohter * Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * AELITIS, SAS au capital de 46,603.30 euros * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. * */ package org.gudy.azureus2.core3.util; import java.nio.ByteBuffer; /** * SHA-1 message digest class. */ public final class SHA1 { private int h0,h1,h2,h3,h4; private ByteBuffer finalBuffer; private ByteBuffer saveBuffer; private int s0,s1,s2,s3,s4; private long length; private long saveLength; /** * Create a new SHA-1 message digest hasher. */ public SHA1() { finalBuffer = ByteBuffer.allocate(64); finalBuffer.position(0); finalBuffer.limit(64); saveBuffer = ByteBuffer.allocate(64); saveBuffer.position(0); saveBuffer.limit(64); reset(); } final private void transform(final byte[] ar, int offset) { int w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; int a,b,c,d,e; /* * we're using direct array access instead of buffer.getInt() since it is significantly faster * combined with the chunk-fetching on direct byte buffers this is 30(direct) to 100%(heap) faster * than the previous implementation */ w0 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w1 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w2 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w3 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w4 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w5 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w6 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w7 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w8 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w9 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w10 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w11 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w12 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w13 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w14 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset++]&0xff); w15 = (ar[offset++]&0xff) << 24 | (ar[offset++]&0xff) << 16 | (ar[offset++]&0xff) << 8 | (ar[offset]&0xff); a = h0 ; b = h1 ; c = h2 ; d = h3 ; e = h4; e += ((a << 5) | ( a >>> 27)) + w0 + ((b & c) | ((~b ) & d)) + 0x5A827999 ; b = (b << 30) | (b >>> 2) ; d += ((e << 5) | ( e >>> 27)) + w1 + ((a & b) | ((~a ) & c)) + 0x5A827999 ; a = (a << 30) | (a >>> 2) ; c += ((d << 5) | ( d >>> 27)) + w2 + ((e & a) | ((~e ) & b)) + 0x5A827999 ; e = (e << 30) | (e >>> 2) ; b += ((c << 5) | ( c >>> 27)) + w3 + ((d & e) | ((~d ) & a)) + 0x5A827999 ; d = (d << 30) | (d >>> 2) ; a += ((b << 5) | ( b >>> 27)) + w4 + ((c & d) | ((~c ) & e)) + 0x5A827999 ; c = (c << 30) | (c >>> 2) ; e += ((a << 5) | ( a >>> 27)) + w5 + ((b & c) | ((~b ) & d)) + 0x5A827999 ; b = (b << 30) | (b >>> 2) ; d += ((e << 5) | ( e >>> 27)) + w6 + ((a & b) | ((~a ) & c)) + 0x5A827999 ; a = (a << 30) | (a >>> 2) ; c += ((d << 5) | ( d >>> 27)) + w7 + ((e & a) | ((~e ) & b)) + 0x5A827999 ; e = (e << 30) | (e >>> 2) ; b += ((c << 5) | ( c >>> 27)) + w8 + ((d & e) | ((~d ) & a)) + 0x5A827999 ; d = (d << 30) | (d >>> 2) ; a += ((b << 5) | ( b >>> 27)) + w9 + ((c & d) | ((~c ) & e)) + 0x5A827999 ; c = (c << 30) | (c >>> 2) ; e += ((a << 5) | ( a >>> 27)) + w10 + ((b & c) | ((~b ) & d)) + 0x5A827999 ; b = (b << 30) | (b >>> 2) ; d += ((e << 5) | ( e >>> 27)) + w11 + ((a & b) | ((~a ) & c)) + 0x5A827999 ; a = (a << 30) | (a >>> 2) ; c += ((d << 5) | ( d >>> 27)) + w12 + ((e & a) | ((~e ) & b)) + 0x5A827999 ; e = (e << 30) | (e >>> 2) ; b += ((c << 5) | ( c >>> 27)) + w13 + ((d & e) | ((~d ) & a)) + 0x5A827999 ; d = (d << 30) | (d >>> 2) ; a += ((b << 5) | ( b >>> 27)) + w14 + ((c & d) | ((~c ) & e)) + 0x5A827999 ; c = (c << 30) | (c >>> 2) ; e += ((a << 5) | ( a >>> 27)) + w15 + ((b & c) | ((~b ) & d)) + 0x5A827999 ; b = (b << 30) | (b >>> 2) ; w0 = w13 ^ w8 ^ w2 ^ w0; w0 = (w0 << 1) | (w0 >>> 31) ; d += ((e << 5) | ( e >>> 27)) + w0 + ((a & b) | ((~a ) & c)) + 0x5A827999 ; a = (a << 30) | (a >>> 2) ; w1 = w14 ^ w9 ^ w3 ^ w1; w1 = (w1 << 1) | (w1 >>> 31) ; c += ((d << 5) | ( d >>> 27)) + w1 + ((e & a) | ((~e ) & b)) + 0x5A827999 ; e = (e << 30) | (e >>> 2) ; w2 = w15 ^ w10 ^ w4 ^ w2; w2 = (w2 << 1) | (w2 >>> 31) ; b += ((c << 5) | ( c >>> 27)) + w2 + ((d & e) | ((~d ) & a)) + 0x5A827999 ; d = (d << 30) | (d >>> 2) ; w3 = w0 ^ w11 ^ w5 ^ w3; w3 = (w3 << 1) | (w3 >>> 31) ; a += ((b << 5) | ( b >>> 27)) + w3 + ((c & d) | ((~c ) & e)) + 0x5A827999 ; c = (c << 30) | (c >>> 2) ; w4 = w1 ^ w12 ^ w6 ^ w4; w4 = (w4 << 1) | (w4 >>> 31) ; e += ((a << 5) | ( a >>> 27)) + w4 + (b ^ c ^ d) + 0x6ED9EBA1 ; b = (b << 30) | (b >>> 2) ; w5 = w2 ^ w13 ^ w7 ^ w5; w5 = (w5 << 1) | (w5 >>> 31) ; d += ((e << 5) | ( e >>> 27)) + w5 + (a ^ b ^ c) + 0x6ED9EBA1 ; a = (a << 30) | (a >>> 2) ; w6 = w3 ^ w14 ^ w8 ^ w6; w6 = (w6 << 1) | (w6 >>> 31) ; c += ((d << 5) | ( d >>> 27)) + w6 + (e ^ a ^ b) + 0x6ED9EBA1 ; e = (e << 30) | (e >>> 2) ; w7 = w4 ^ w15 ^ w9 ^ w7; w7 = (w7 << 1) | (w7 >>> 31) ; b += ((c << 5) | ( c >>> 27)) + w7 + (d ^ e ^ a) + 0x6ED9EBA1 ; d = (d << 30) | (d >>> 2) ; w8 = w5 ^ w0 ^ w10 ^ w8; w8 = (w8 << 1) | (w8 >>> 31) ; a += ((b << 5) | ( b >>> 27)) + w8 + (c ^ d ^ e) + 0x6ED9EBA1 ; c = (c << 30) | (c >>> 2) ; w9 = w6 ^ w1 ^ w11 ^ w9; w9 = (w9 << 1) | (w9 >>> 31) ; e += ((a << 5) | ( a >>> 27)) + w9 + (b ^ c ^ d) + 0x6ED9EBA1 ; b = (b << 30) | (b >>> 2) ; w10 = w7 ^ w2 ^ w12 ^ w10; w10 = (w10 << 1) | (w10 >>> 31) ; d += ((e << 5) | ( e >>> 27)) + w10 + (a ^ b ^ c) + 0x6ED9EBA1 ; a = (a << 30) | (a >>> 2) ; w11 = w8 ^ w3 ^ w13 ^ w11; w11 = (w11 << 1) | (w11 >>> 31) ; c += ((d << 5) | ( d >>> 27)) + w11 + (e ^ a ^ b) + 0x6ED9EBA1 ; e = (e << 30) | (e >>> 2) ; w12 = w9 ^ w4 ^ w14 ^ w12; w12 = (w12 << 1) | (w12 >>> 31) ; b += ((c << 5) | ( c >>> 27)) + w12 + (d ^ e ^ a) + 0x6ED9EBA1 ; d = (d << 30) | (d >>> 2) ; w13 = w10 ^ w5 ^ w15 ^ w13; w13 = (w13 << 1) | (w13 >>> 31) ; a += ((b << 5) | ( b >>> 27)) + w13 + (c ^ d ^ e) + 0x6ED9EBA1 ; c = (c << 30) | (c >>> 2) ; w14 = w11 ^ w6 ^ w0 ^ w14; w14 = (w14 << 1) | (w14 >>> 31) ; e += ((a << 5) | ( a >>> 27)) + w14 + (b ^ c ^ d) + 0x6ED9EBA1 ; b = (b << 30) | (b >>> 2) ; w15 = w12 ^ w7 ^ w1 ^ w15; w15 = (w15 << 1) | (w15 >>> 31) ; d += ((e << 5) | ( e >>> 27)) + w15 + (a ^ b ^ c) + 0x6ED9EBA1 ; a = (a << 30) | (a >>> 2) ; w0 = w13 ^ w8 ^ w2 ^ w0; w0 = (w0 << 1) | (w0 >>> 31) ; c += ((d << 5) | ( d >>> 27)) + w0 + (e ^ a ^ b) + 0x6ED9EBA1 ; e = (e << 30) | (e >>> 2) ; w1 = w14 ^ w9 ^ w3 ^ w1; w1 = (w1 << 1) | (w1 >>> 31) ; b += ((c << 5) | ( c >>> 27)) + w1 + (d ^ e ^ a) + 0x6ED9EBA1 ; d = (d << 30) | (d >>> 2) ; w2 = w15 ^ w10 ^ w4 ^ w2; w2 = (w2 << 1) | (w2 >>> 31) ; a += ((b << 5) | ( b >>> 27)) + w2 + (c ^ d ^ e) + 0x6ED9EBA1 ; c = (c << 30) | (c >>> 2) ; w3 = w0 ^ w11 ^ w5 ^ w3; w3 = (w3 << 1) | (w3 >>> 31) ; e += ((a << 5) | ( a >>> 27)) + w3 + (b ^ c ^ d) + 0x6ED9EBA1 ; b = (b << 30) | (b >>> 2) ; w4 = w1 ^ w12 ^ w6 ^ w4; w4 = (w4 << 1) | (w4 >>> 31) ; d += ((e << 5) | ( e >>> 27)) + w4 + (a ^ b ^ c) + 0x6ED9EBA1 ; a = (a << 30) | (a >>> 2) ; w5 = w2 ^ w13 ^ w7 ^ w5; w5 = (w5 << 1) | (w5 >>> 31) ; c += ((d << 5) | ( d >>> 27)) + w5 + (e ^ a ^ b) + 0x6ED9EBA1 ; e = (e << 30) | (e >>> 2) ; w6 = w3 ^ w14 ^ w8 ^ w6; w6 = (w6 << 1) | (w6 >>> 31) ; b += ((c << 5) | ( c >>> 27)) + w6 + (d ^ e ^ a) + 0x6ED9EBA1 ; d = (d << 30) | (d >>> 2) ; w7 = w4 ^ w15 ^ w9 ^ w7; w7 = (w7 << 1) | (w7 >>> 31) ; a += ((b << 5) | ( b >>> 27)) + w7 + (c ^ d ^ e) + 0x6ED9EBA1 ; c = (c << 30) | (c >>> 2) ; w8 = w5 ^ w0 ^ w10 ^ w8; w8 = (w8 << 1) | (w8 >>> 31) ; e += ((a << 5) | ( a >>> 27)) + w8 + ((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC ; b = (b << 30) | (b >>> 2) ; w9 = w6 ^ w1 ^ w11 ^ w9; w9 = (w9 << 1) | (w9 >>> 31) ; d += ((e << 5) | ( e >>> 27)) + w9 + ((a & b) | (a & c) | (b & c)) + 0x8F1BBCDC ; a = (a << 30) | (a >>> 2) ; w10 = w7 ^ w2 ^ w12 ^ w10; w10 = (w10 << 1) | (w10 >>> 31) ; c += ((d << 5) | ( d >>> 27)) + w10 + ((e & a) | (e & b) | (a & b)) + 0x8F1BBCDC ; e = (e << 30) | (e >>> 2) ; w11 = w8 ^ w3 ^ w13 ^ w11; w11 = (w11 << 1) | (w11 >>> 31) ; b += ((c << 5) | ( c >>> 27)) + w11 + ((d & e) | (d & a) | (e & a)) + 0x8F1BBCDC ; d = (d << 30) | (d >>> 2) ; w12 = w9 ^ w4 ^ w14 ^ w12; w12 = (w12 << 1) | (w12 >>> 31) ; a += ((b << 5) | ( b >>> 27)) + w12 + ((c & d) | (c & e) | (d & e)) + 0x8F1BBCDC ; c = (c << 30) | (c >>> 2) ; w13 = w10 ^ w5 ^ w15 ^ w13; w13 = (w13 << 1) | (w13 >>> 31) ; e += ((a << 5) | ( a >>> 27)) + w13 + ((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC ; b = (b << 30) | (b >>> 2) ; w14 = w11 ^ w6 ^ w0 ^ w14; w14 = (w14 << 1) | (w14 >>> 31) ; d += ((e << 5) | ( e >>> 27)) + w14 + ((a & b) | (a & c) | (b & c)) + 0x8F1BBCDC ; a = (a << 30) | (a >>> 2) ; w15 = w12 ^ w7 ^ w1 ^ w15; w15 = (w15 << 1) | (w15 >>> 31) ; c += ((d << 5) | ( d >>> 27)) + w15 + ((e & a) | (e & b) | (a & b)) + 0x8F1BBCDC ; e = (e << 30) | (e >>> 2) ; w0 = w13 ^ w8 ^ w2 ^ w0; w0 = (w0 << 1) | (w0 >>> 31) ; b += ((c << 5) | ( c >>> 27)) + w0 + ((d & e) | (d & a) | (e & a)) + 0x8F1BBCDC ; d = (d << 30) | (d >>> 2) ; w1 = w14 ^ w9 ^ w3 ^ w1; w1 = (w1 << 1) | (w1 >>> 31) ; a += ((b << 5) | ( b >>> 27)) + w1 + ((c & d) | (c & e) | (d & e)) + 0x8F1BBCDC ; c = (c << 30) | (c >>> 2) ; w2 = w15 ^ w10 ^ w4 ^ w2; w2 = (w2 << 1) | (w2 >>> 31) ; e += ((a << 5) | ( a >>> 27)) + w2 + ((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC ; b = (b << 30) | (b >>> 2) ; w3 = w0 ^ w11 ^ w5 ^ w3; w3 = (w3 << 1) | (w3 >>> 31) ; d += ((e << 5) | ( e >>> 27)) + w3 + ((a & b) | (a & c) | (b & c)) + 0x8F1BBCDC ; a = (a << 30) | (a >>> 2) ; w4 = w1 ^ w12 ^ w6 ^ w4; w4 = (w4 << 1) | (w4 >>> 31) ; c += ((d << 5) | ( d >>> 27)) + w4 + ((e & a) | (e & b) | (a & b)) + 0x8F1BBCDC ; e = (e << 30) | (e >>> 2) ; w5 = w2 ^ w13 ^ w7 ^ w5; w5 = (w5 << 1) | (w5 >>> 31) ; b += ((c << 5) | ( c >>> 27)) + w5 + ((d & e) | (d & a) | (e & a)) + 0x8F1BBCDC ; d = (d << 30) | (d >>> 2) ; w6 = w3 ^ w14 ^ w8 ^ w6; w6 = (w6 << 1) | (w6 >>> 31) ; a += ((b << 5) | ( b >>> 27)) + w6 + ((c & d) | (c & e) | (d & e)) + 0x8F1BBCDC ; c = (c << 30) | (c >>> 2) ; w7 = w4 ^ w15 ^ w9 ^ w7; w7 = (w7 << 1) | (w7 >>> 31) ; e += ((a << 5) | ( a >>> 27)) + w7 + ((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC ; b = (b << 30) | (b >>> 2) ; w8 = w5 ^ w0 ^ w10 ^ w8; w8 = (w8 << 1) | (w8 >>> 31) ; d += ((e << 5) | ( e >>> 27)) + w8 + ((a & b) | (a & c) | (b & c)) + 0x8F1BBCDC ; a = (a << 30) | (a >>> 2) ; w9 = w6 ^ w1 ^ w11 ^ w9; w9 = (w9 << 1) | (w9 >>> 31) ; c += ((d << 5) | ( d >>> 27)) + w9 + ((e & a) | (e & b) | (a & b)) + 0x8F1BBCDC ; e = (e << 30) | (e >>> 2) ; w10 = w7 ^ w2 ^ w12 ^ w10; w10 = (w10 << 1) | (w10 >>> 31) ; b += ((c << 5) | ( c >>> 27)) + w10 + ((d & e) | (d & a) | (e & a)) + 0x8F1BBCDC ; d = (d << 30) | (d >>> 2) ; w11 = w8 ^ w3 ^ w13 ^ w11; w11 = (w11 << 1) | (w11 >>> 31) ; a += ((b << 5) | ( b >>> 27)) + w11 + ((c & d) | (c & e) | (d & e)) + 0x8F1BBCDC ; c = (c << 30) | (c >>> 2) ; w12 = w9 ^ w4 ^ w14 ^ w12; w12 = (w12 << 1) | (w12 >>> 31) ; e += ((a << 5) | ( a >>> 27)) + w12 + (b ^ c ^ d) + 0xCA62C1D6 ; b = (b << 30) | (b >>> 2) ; w13 = w10 ^ w5 ^ w15 ^ w13; w13 = (w13 << 1) | (w13 >>> 31) ; d += ((e << 5) | ( e >>> 27)) + w13 + (a ^ b ^ c) + 0xCA62C1D6 ; a = (a << 30) | (a >>> 2) ; w14 = w11 ^ w6 ^ w0 ^ w14; w14 = (w14 << 1) | (w14 >>> 31) ; c += ((d << 5) | ( d >>> 27)) + w14 + (e ^ a ^ b) + 0xCA62C1D6 ; e = (e << 30) | (e >>> 2) ; w15 = w12 ^ w7 ^ w1 ^ w15; w15 = (w15 << 1) | (w15 >>> 31) ; b += ((c << 5) | ( c >>> 27)) + w15 + (d ^ e ^ a) + 0xCA62C1D6 ; d = (d << 30) | (d >>> 2) ; w0 = w13 ^ w8 ^ w2 ^ w0; w0 = (w0 << 1) | (w0 >>> 31) ; a += ((b << 5) | ( b >>> 27)) + w0 + (c ^ d ^ e) + 0xCA62C1D6 ; c = (c << 30) | (c >>> 2) ; w1 = w14 ^ w9 ^ w3 ^ w1; w1 = (w1 << 1) | (w1 >>> 31) ; e += ((a << 5) | ( a >>> 27)) + w1 + (b ^ c ^ d) + 0xCA62C1D6 ; b = (b << 30) | (b >>> 2) ; w2 = w15 ^ w10 ^ w4 ^ w2; w2 = (w2 << 1) | (w2 >>> 31) ; d += ((e << 5) | ( e >>> 27)) + w2 + (a ^ b ^ c) + 0xCA62C1D6 ; a = (a << 30) | (a >>> 2) ; w3 = w0 ^ w11 ^ w5 ^ w3; w3 = (w3 << 1) | (w3 >>> 31) ; c += ((d << 5) | ( d >>> 27)) + w3 + (e ^ a ^ b) + 0xCA62C1D6 ; e = (e << 30) | (e >>> 2) ; w4 = w1 ^ w12 ^ w6 ^ w4; w4 = (w4 << 1) | (w4 >>> 31) ; b += ((c << 5) | ( c >>> 27)) + w4 + (d ^ e ^ a) + 0xCA62C1D6 ; d = (d << 30) | (d >>> 2) ; w5 = w2 ^ w13 ^ w7 ^ w5; w5 = (w5 << 1) | (w5 >>> 31) ; a += ((b << 5) | ( b >>> 27)) + w5 + (c ^ d ^ e) + 0xCA62C1D6 ; c = (c << 30) | (c >>> 2) ; w6 = w3 ^ w14 ^ w8 ^ w6; w6 = (w6 << 1) | (w6 >>> 31) ; e += ((a << 5) | ( a >>> 27)) + w6 + (b ^ c ^ d) + 0xCA62C1D6 ; b = (b << 30) | (b >>> 2) ; w7 = w4 ^ w15 ^ w9 ^ w7; w7 = (w7 << 1) | (w7 >>> 31) ; d += ((e << 5) | ( e >>> 27)) + w7 + (a ^ b ^ c) + 0xCA62C1D6 ; a = (a << 30) | (a >>> 2) ; w8 = w5 ^ w0 ^ w10 ^ w8; w8 = (w8 << 1) | (w8 >>> 31) ; c += ((d << 5) | ( d >>> 27)) + w8 + (e ^ a ^ b) + 0xCA62C1D6 ; e = (e << 30) | (e >>> 2) ; w9 = w6 ^ w1 ^ w11 ^ w9; w9 = (w9 << 1) | (w9 >>> 31) ; b += ((c << 5) | ( c >>> 27)) + w9 + (d ^ e ^ a) + 0xCA62C1D6 ; d = (d << 30) | (d >>> 2) ; w10 = w7 ^ w2 ^ w12 ^ w10; w10 = (w10 << 1) | (w10 >>> 31) ; a += ((b << 5) | ( b >>> 27)) + w10 + (c ^ d ^ e) + 0xCA62C1D6 ; c = (c << 30) | (c >>> 2) ; w11 = w8 ^ w3 ^ w13 ^ w11; w11 = (w11 << 1) | (w11 >>> 31) ; e += ((a << 5) | ( a >>> 27)) + w11 + (b ^ c ^ d) + 0xCA62C1D6 ; b = (b << 30) | (b >>> 2) ; w12 = w9 ^ w4 ^ w14 ^ w12; w12 = (w12 << 1) | (w12 >>> 31) ; d += ((e << 5) | ( e >>> 27)) + w12 + (a ^ b ^ c) + 0xCA62C1D6 ; a = (a << 30) | (a >>> 2) ; w13 = w10 ^ w5 ^ w15 ^ w13; w13 = (w13 << 1) | (w13 >>> 31) ; c += ((d << 5) | ( d >>> 27)) + w13 + (e ^ a ^ b) + 0xCA62C1D6 ; e = (e << 30) | (e >>> 2) ; w14 = w11 ^ w6 ^ w0 ^ w14; w14 = (w14 << 1) | (w14 >>> 31) ; b += ((c << 5) | ( c >>> 27)) + w14 + (d ^ e ^ a) + 0xCA62C1D6 ; d = (d << 30) | (d >>> 2) ; w15 = w12 ^ w7 ^ w1 ^ w15; w15 = (w15 << 1) | (w15 >>> 31) ; a += ((b << 5) | ( b >>> 27)) + w15 + (c ^ d ^ e) + 0xCA62C1D6 ; c = (c << 30) | (c >>> 2) ; h0 += a; h1 += b; h2 += c; h3 += d; h4 += e; } private void completeFinalBuffer(ByteBuffer buffer) { if(finalBuffer.position() == 0) return; while(buffer.remaining() > 0 && finalBuffer.remaining() > 0) { finalBuffer.put(buffer.get()); } if(finalBuffer.remaining() == 0) { transform(finalBuffer.array(),0); finalBuffer.rewind(); } } /** * Resets the SHA-1 to initial state for a new message digest calculation. * Must be called before starting a new hash calculation. */ public void reset() { h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476; h4 = 0xC3D2E1F0; length = 0; finalBuffer.clear(); } // must be a multiple of 64 private static final int cacheSize = 4*1024; // cache block to reduce expensive native access for direct byte buffers private byte[] cacheBlock; /** * Starts or continues a SHA-1 message digest calculation. * Only the remaining bytes of the given ByteBuffer are used. * @param buffer input data */ public void update(ByteBuffer buffer) { length += buffer.remaining(); //Save current position to leave given buffer unchanged int position = buffer.position(); //Complete the final buffer if needed completeFinalBuffer(buffer); if(!buffer.hasArray() || buffer.isDirect()) { if(cacheBlock == null) // only allocate if we process direct byte buffers cacheBlock = new byte[cacheSize]; while(buffer.remaining() >= 64) { int toProcess = Math.min(buffer.remaining()-buffer.remaining()%64,cacheSize); buffer.get(cacheBlock, 0, toProcess); for(int i = 0;i < toProcess; i+=64) transform(cacheBlock,i); } } else // use direct array access for heap buffers { final int endPos = buffer.position()+buffer.remaining()-buffer.remaining()%64; final int internalEndPos = endPos+buffer.arrayOffset(); for(int i = buffer.arrayOffset()+buffer.position();i < internalEndPos;i+=64) transform(buffer.array(),i); buffer.position(endPos); } if(buffer.remaining() != 0) { finalBuffer.put(buffer); } buffer.position(position); } /** * Finishes the SHA-1 message digest calculation. * @return 20-byte hash result */ public byte[] digest() { byte[] result = new byte[20]; finalBuffer.put((byte)0x80); if(finalBuffer.remaining() < 8) { while(finalBuffer.remaining() > 0) { finalBuffer.put((byte)0); } finalBuffer.position(0); transform(finalBuffer.array(),0); finalBuffer.position(0); } while(finalBuffer.remaining() > 8) { finalBuffer.put((byte)0); } finalBuffer.putLong(length << 3); finalBuffer.position(0); transform(finalBuffer.array(),0); finalBuffer.position(0); finalBuffer.putInt(h0); finalBuffer.putInt(h1); finalBuffer.putInt(h2); finalBuffer.putInt(h3); finalBuffer.putInt(h4); finalBuffer.rewind(); finalBuffer.get(result, 0, 20); return result; } /** * Finishes the SHA-1 message digest calculation, by first performing a final update * from the given input buffer, then completing the calculation as with digest(). * @param buffer input data * @return 20-byte hash result */ public byte[] digest(ByteBuffer buffer) { update( buffer ); return digest(); } /** * Save the current digest state. * This allows the resuming of a SHA-1 calculation, even after a digest calculation * is finished with digest(). */ public void saveState() { s0=h0; s1=h1; s2=h2; s3=h3; s4=h4; saveLength = length; int position = finalBuffer.position(); finalBuffer.rewind(); finalBuffer.limit(position); saveBuffer.clear(); saveBuffer.put(finalBuffer); saveBuffer.flip(); finalBuffer.limit(64); finalBuffer.position( position ); } /** * Restore the digest to its previously-saved state. */ public void restoreState() { h0=s0; h1=s1; h2=s2; h3=s3; h4=s4; length = saveLength; finalBuffer.clear(); finalBuffer.put(saveBuffer); } }