SHA1Implpublic class SHA1Impl extends Object implements SHA1_DataThis class contains methods providing SHA-1 functionality to use in classes.
The methods support the algorithm described in "SECURE HASH STANDARD", FIPS PUB 180-2,
"http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf"
The class contains two package level access methods, -
"void updateHash(int[], byte[], int, int)" and "void computeHash(int[])", -
performing the following operations.
The "updateHash(..)" method appends new bytes to existing ones
within limit of a frame of 64 bytes (16 words).
Once a length of accumulated bytes reaches the limit
the "computeHash(int[])" method is invoked on the frame to compute updated hash,
and the number of bytes in the frame is set to 0.
Thus, after appending all bytes, the frame contain only those bytes
that were not used in computing final hash value yet.
The "computeHash(..)" method generates a 160 bit hash value using
a 512 bit message stored in first 16 words of int[] array argument and
current hash value stored in five words, beginning HASH_OFFSET, of the array argument.
Computation is done according to SHA-1 algorithm.
The resulting hash value replaces the previous hash value in the array;
original bits of the message are not preserved. |
Methods Summary |
---|
static void | computeHash(int[] arrW)The method generates a 160 bit hash value using
a 512 bit message stored in first 16 words of int[] array argument and
current hash value stored in five words, beginning OFFSET+1, of the array argument.
Computation is done according to SHA-1 algorithm.
The resulting hash value replaces the previous hash value in the array;
original bits of the message are not preserved.
No checks on argument supplied, that is,
a calling method is responsible for such checks.
In case of incorrect array passed to the method
either NPE or IndexOutOfBoundException gets thrown by JVM.
int a = arrW[HASH_OFFSET ];
int b = arrW[HASH_OFFSET +1];
int c = arrW[HASH_OFFSET +2];
int d = arrW[HASH_OFFSET +3];
int e = arrW[HASH_OFFSET +4];
int temp;
// In this implementation the "d. For t = 0 to 79 do" loop
// is split into four loops. The following constants:
// K = 5A827999 0 <= t <= 19
// K = 6ED9EBA1 20 <= t <= 39
// K = 8F1BBCDC 40 <= t <= 59
// K = CA62C1D6 60 <= t <= 79
// are hex literals in the loops.
for ( int t = 16; t < 80 ; t++ ) {
temp = arrW[t-3] ^ arrW[t-8] ^ arrW[t-14] ^ arrW[t-16];
arrW[t] = ( temp<<1 ) | ( temp>>>31 );
}
for ( int t = 0 ; t < 20 ; t++ ) {
temp = ( ( a<<5 ) | ( a>>>27 ) ) +
( ( b & c) | ((~b) & d) ) +
( e + arrW[t] + 0x5A827999 ) ;
e = d;
d = c;
c = ( b<<30 ) | ( b>>>2 ) ;
b = a;
a = temp;
}
for ( int t = 20 ; t < 40 ; t++ ) {
temp = ((( a<<5 ) | ( a>>>27 ))) + (b ^ c ^ d) + (e + arrW[t] + 0x6ED9EBA1) ;
e = d;
d = c;
c = ( b<<30 ) | ( b>>>2 ) ;
b = a;
a = temp;
}
for ( int t = 40 ; t < 60 ; t++ ) {
temp = (( a<<5 ) | ( a>>>27 )) + ((b & c) | (b & d) | (c & d)) +
(e + arrW[t] + 0x8F1BBCDC) ;
e = d;
d = c;
c = ( b<<30 ) | ( b>>>2 ) ;
b = a;
a = temp;
}
for ( int t = 60 ; t < 80 ; t++ ) {
temp = ((( a<<5 ) | ( a>>>27 ))) + (b ^ c ^ d) + (e + arrW[t] + 0xCA62C1D6) ;
e = d;
d = c;
c = ( b<<30 ) | ( b>>>2 ) ;
b = a;
a = temp;
}
arrW[HASH_OFFSET ] += a;
arrW[HASH_OFFSET +1] += b;
arrW[HASH_OFFSET +2] += c;
arrW[HASH_OFFSET +3] += d;
arrW[HASH_OFFSET +4] += e;
| static void | updateHash(int[] intArray, byte[] byteInput, int fromByte, int toByte)The method appends new bytes to existing ones
within limit of a frame of 64 bytes (16 words).
Once a length of accumulated bytes reaches the limit
the "computeHash(int[])" method is invoked on the array to compute updated hash,
and the number of bytes in the frame is set to 0.
Thus, after appending all bytes, the array contain only those bytes
that were not used in computing final hash value yet.
No checks on arguments passed to the method, that is,
a calling method is responsible for such checks.
// As intArray contains a packed bytes
// the buffer's index is in the intArray[BYTES_OFFSET] element
int index = intArray[BYTES_OFFSET];
int i = fromByte;
int maxWord;
int nBytes;
int wordIndex = index >>2;
int byteIndex = index & 0x03;
intArray[BYTES_OFFSET] = ( index + toByte - fromByte + 1 ) & 077 ;
// In general case there are 3 stages :
// - appending bytes to non-full word,
// - writing 4 bytes into empty words,
// - writing less than 4 bytes in last word
if ( byteIndex != 0 ) { // appending bytes in non-full word (as if)
for ( ; ( i <= toByte ) && ( byteIndex < 4 ) ; i++ ) {
intArray[wordIndex] |= ( byteInput[i] & 0xFF ) << ((3 - byteIndex)<<3) ;
byteIndex++;
}
if ( byteIndex == 4 ) {
wordIndex++;
if ( wordIndex == 16 ) { // intArray is full, computing hash
computeHash(intArray);
wordIndex = 0;
}
}
if ( i > toByte ) { // all input bytes appended
return ;
}
}
// writing full words
maxWord = (toByte - i + 1) >> 2; // # of remaining full words, may be "0"
for ( int k = 0; k < maxWord ; k++ ) {
intArray[wordIndex] = ( ((int) byteInput[i ] & 0xFF) <<24 ) |
( ((int) byteInput[i +1] & 0xFF) <<16 ) |
( ((int) byteInput[i +2] & 0xFF) <<8 ) |
( ((int) byteInput[i +3] & 0xFF) ) ;
i += 4;
wordIndex++;
if ( wordIndex < 16 ) { // buffer is not full yet
continue;
}
computeHash(intArray); // buffer is full, computing hash
wordIndex = 0;
}
// writing last incomplete word
// after writing free byte positions are set to "0"s
nBytes = toByte - i +1;
if ( nBytes != 0 ) {
int w = ((int) byteInput[i] & 0xFF) <<24 ;
if ( nBytes != 1 ) {
w |= ((int) byteInput[i +1] & 0xFF) <<16 ;
if ( nBytes != 2) {
w |= ((int) byteInput[i +2] & 0xFF) <<8 ;
}
}
intArray[wordIndex] = w;
}
return ;
|
|