| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_bridges.hxx" |
| |
| |
| #ifndef TEST |
| #ifndef _SAL_TYPES_H_ |
| #include <sal/types.h> |
| #endif |
| #else |
| typedef unsigned int sal_uInt32; |
| #endif |
| |
| #include <string.h> |
| |
| /* |
| * build a hash for a character buffer using the NIST algorithm |
| */ |
| |
| class NIST_Hash |
| { |
| |
| // helper functions |
| sal_uInt32 f1( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z ) |
| { |
| return z ^ ( x & ( y ^ z ) ); |
| } |
| |
| sal_uInt32 f2( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z ) |
| { |
| return x ^ y ^ z; |
| } |
| |
| sal_uInt32 f3( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z ) |
| { |
| return ( x & y ) + ( z & ( x ^ y ) ); |
| } |
| |
| sal_uInt32 rotl( sal_uInt32 nValue, sal_uInt32 nBits ) |
| { |
| return ( nValue << nBits ) | ( nValue >> (32-nBits) ); |
| } |
| |
| sal_uInt32 expand_nostore( sal_uInt32 index ) |
| { |
| return data[index&15] ^ data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15]; |
| } |
| |
| sal_uInt32 expand_store( sal_uInt32 index ) |
| { |
| return data[index&15] ^= data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15]; |
| } |
| |
| void subRound( sal_uInt32 a, sal_uInt32& b, sal_uInt32 c, sal_uInt32 d, sal_uInt32& e, sal_uInt32 constant, sal_uInt32 datum, sal_uInt32 nFunction ) |
| { |
| e += rotl(a,5); |
| switch( nFunction ) |
| { |
| case 1: e += f1( b, c, d );break; |
| case 2: |
| case 4: e += f2( b, c, d );break; |
| case 3: e += f3( b, c, d );break; |
| } |
| e += constant + datum; |
| b = rotl( b, 30 ); |
| } |
| |
| void transform(); |
| void final(); |
| |
| // data members |
| sal_uInt32 data[16]; |
| sal_uInt32 hashdata[5]; |
| public: |
| NIST_Hash( const char* pString, sal_uInt32 nLen ); |
| |
| sal_uInt32 *getHash() { return hashdata; } |
| }; |
| |
| void NIST_Hash::transform() |
| { |
| // constants |
| const sal_uInt32 K2 = 0x5A827999; |
| const sal_uInt32 K3 = 0x6ED9EBA1; |
| const sal_uInt32 K5 = 0x8F1BBCDC; |
| const sal_uInt32 K10 = 0xCA62C1D6; |
| |
| sal_uInt32 a, b, c, d, e; |
| a = hashdata[0]; |
| b = hashdata[1]; |
| c = hashdata[2]; |
| d = hashdata[3]; |
| e = hashdata[4]; |
| |
| subRound( a, b, c, d, e, K2, data[ 0], 1 ); |
| subRound( e, a, b, c, d, K2, data[ 1], 1 ); |
| subRound( d, e, a, b, c, K2, data[ 2], 1 ); |
| subRound( c, d, e, a, b, K2, data[ 3], 1 ); |
| subRound( b, c, d, e, a, K2, data[ 4], 1 ); |
| subRound( a, b, c, d, e, K2, data[ 5], 1 ); |
| subRound( e, a, b, c, d, K2, data[ 6], 1 ); |
| subRound( d, e, a, b, c, K2, data[ 7], 1 ); |
| subRound( c, d, e, a, b, K2, data[ 8], 1 ); |
| subRound( b, c, d, e, a, K2, data[ 9], 1 ); |
| subRound( a, b, c, d, e, K2, data[10], 1 ); |
| subRound( e, a, b, c, d, K2, data[11], 1 ); |
| subRound( d, e, a, b, c, K2, data[12], 1 ); |
| subRound( c, d, e, a, b, K2, data[13], 1 ); |
| subRound( b, c, d, e, a, K2, data[14], 1 ); |
| subRound( a, b, c, d, e, K2, data[15], 1 ); |
| subRound( e, a, b, c, d, K2, expand_store( 16 ), 1 ); |
| subRound( d, e, a, b, c, K2, expand_store( 17 ), 1 ); |
| subRound( c, d, e, a, b, K2, expand_store( 18 ), 1 ); |
| subRound( b, c, d, e, a, K2, expand_store( 19 ), 1 ); |
| |
| subRound( a, b, c, d, e, K3, expand_store( 20 ), 2 ); |
| subRound( e, a, b, c, d, K3, expand_store( 21 ), 2 ); |
| subRound( d, e, a, b, c, K3, expand_store( 22 ), 2 ); |
| subRound( c, d, e, a, b, K3, expand_store( 23 ), 2 ); |
| subRound( b, c, d, e, a, K3, expand_store( 24 ), 2 ); |
| subRound( a, b, c, d, e, K3, expand_store( 25 ), 2 ); |
| subRound( e, a, b, c, d, K3, expand_store( 26 ), 2 ); |
| subRound( d, e, a, b, c, K3, expand_store( 27 ), 2 ); |
| subRound( c, d, e, a, b, K3, expand_store( 28 ), 2 ); |
| subRound( b, c, d, e, a, K3, expand_store( 29 ), 2 ); |
| subRound( a, b, c, d, e, K3, expand_store( 30 ), 2 ); |
| subRound( e, a, b, c, d, K3, expand_store( 31 ), 2 ); |
| subRound( d, e, a, b, c, K3, expand_store( 32 ), 2 ); |
| subRound( c, d, e, a, b, K3, expand_store( 33 ), 2 ); |
| subRound( b, c, d, e, a, K3, expand_store( 34 ), 2 ); |
| subRound( a, b, c, d, e, K3, expand_store( 35 ), 2 ); |
| subRound( e, a, b, c, d, K3, expand_store( 36 ), 2 ); |
| subRound( d, e, a, b, c, K3, expand_store( 37 ), 2 ); |
| subRound( c, d, e, a, b, K3, expand_store( 38 ), 2 ); |
| subRound( b, c, d, e, a, K3, expand_store( 39 ), 2 ); |
| |
| subRound( a, b, c, d, e, K5, expand_store( 40 ), 3 ); |
| subRound( e, a, b, c, d, K5, expand_store( 41 ), 3 ); |
| subRound( d, e, a, b, c, K5, expand_store( 42 ), 3 ); |
| subRound( c, d, e, a, b, K5, expand_store( 43 ), 3 ); |
| subRound( b, c, d, e, a, K5, expand_store( 44 ), 3 ); |
| subRound( a, b, c, d, e, K5, expand_store( 45 ), 3 ); |
| subRound( e, a, b, c, d, K5, expand_store( 46 ), 3 ); |
| subRound( d, e, a, b, c, K5, expand_store( 47 ), 3 ); |
| subRound( c, d, e, a, b, K5, expand_store( 48 ), 3 ); |
| subRound( b, c, d, e, a, K5, expand_store( 49 ), 3 ); |
| subRound( a, b, c, d, e, K5, expand_store( 50 ), 3 ); |
| subRound( e, a, b, c, d, K5, expand_store( 51 ), 3 ); |
| subRound( d, e, a, b, c, K5, expand_store( 52 ), 3 ); |
| subRound( c, d, e, a, b, K5, expand_store( 53 ), 3 ); |
| subRound( b, c, d, e, a, K5, expand_store( 54 ), 3 ); |
| subRound( a, b, c, d, e, K5, expand_store( 55 ), 3 ); |
| subRound( e, a, b, c, d, K5, expand_store( 56 ), 3 ); |
| subRound( d, e, a, b, c, K5, expand_store( 57 ), 3 ); |
| subRound( c, d, e, a, b, K5, expand_store( 58 ), 3 ); |
| subRound( b, c, d, e, a, K5, expand_store( 59 ), 3 ); |
| |
| subRound( a, b, c, d, e, K10, expand_store( 60 ), 4 ); |
| subRound( e, a, b, c, d, K10, expand_store( 61 ), 4 ); |
| subRound( d, e, a, b, c, K10, expand_store( 62 ), 4 ); |
| subRound( c, d, e, a, b, K10, expand_store( 63 ), 4 ); |
| subRound( b, c, d, e, a, K10, expand_store( 64 ), 4 ); |
| subRound( a, b, c, d, e, K10, expand_store( 65 ), 4 ); |
| subRound( e, a, b, c, d, K10, expand_store( 66 ), 4 ); |
| subRound( d, e, a, b, c, K10, expand_store( 67 ), 4 ); |
| subRound( c, d, e, a, b, K10, expand_store( 68 ), 4 ); |
| subRound( b, c, d, e, a, K10, expand_store( 69 ), 4 ); |
| subRound( a, b, c, d, e, K10, expand_store( 70 ), 4 ); |
| subRound( e, a, b, c, d, K10, expand_store( 71 ), 4 ); |
| subRound( d, e, a, b, c, K10, expand_store( 72 ), 4 ); |
| subRound( c, d, e, a, b, K10, expand_store( 73 ), 4 ); |
| subRound( b, c, d, e, a, K10, expand_store( 74 ), 4 ); |
| subRound( a, b, c, d, e, K10, expand_store( 75 ), 4 ); |
| subRound( e, a, b, c, d, K10, expand_store( 76 ), 4 ); |
| subRound( d, e, a, b, c, K10, expand_nostore( 77 ), 4 ); |
| subRound( c, d, e, a, b, K10, expand_nostore( 78 ), 4 ); |
| subRound( b, c, d, e, a, K10, expand_nostore( 79 ), 4 ); |
| |
| hashdata[0] += a; |
| hashdata[1] += b; |
| hashdata[2] += c; |
| hashdata[3] += d; |
| hashdata[4] += e; |
| } |
| |
| #define BLOCKSIZE sizeof( data ) |
| |
| NIST_Hash::NIST_Hash( const char* pString, sal_uInt32 nLen ) |
| { |
| hashdata[0] = 0x67452301; |
| hashdata[1] = 0xefcdab89; |
| hashdata[2] = 0x98badcfe; |
| hashdata[3] = 0x10325476; |
| hashdata[4] = 0xc3d2e1f0; |
| |
| sal_uInt32 nBytes = nLen; |
| |
| while( nLen >= sizeof( data ) ) |
| { |
| memcpy( data, pString, sizeof( data ) ); |
| pString += sizeof( data ); |
| nLen -= sizeof( data ); |
| transform(); |
| } |
| memcpy( data, pString, nLen ); |
| ((char*)data)[nLen++] = 0x80; |
| if( nLen > sizeof( data ) - 8 ) |
| { |
| memset( ((char*)data)+nLen, 0, sizeof( data ) - nLen ); |
| transform(); |
| memset( data, 0, sizeof( data ) - 8 ); |
| } |
| else |
| memset( ((char*)data)+nLen, 0, sizeof( data ) - 8 - nLen ); |
| data[14] = 0; |
| data[15] = nBytes << 3; |
| transform(); |
| } |
| |
| #ifdef TEST |
| #include <stdio.h> |
| int main( int argc, const char** argv ) |
| { |
| const char* pHash = argc < 2 ? argv[0] : argv[1]; |
| |
| NIST_Hash aHash( pHash, strlen( pHash ) ); |
| sal_uInt32* pBits = aHash.getHash(); |
| |
| printf( "text : %s\n" |
| "bits : 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", |
| pHash, |
| pBits[0], pBits[1], pBits[2],pBits[3],pBits[4] |
| ); |
| return 0; |
| } |
| |
| #endif |