xref: /trunk/main/bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_bridges.hxx"
30 
31 
32 #ifndef TEST
33 #ifndef _SAL_TYPES_H_
34 #include <sal/types.h>
35 #endif
36 #else
37 typedef unsigned int sal_uInt32;
38 #endif
39 
40 #include <string.h>
41 
42 /*
43  *  build a hash for a character buffer using the NIST algorithm
44  */
45 
46 class NIST_Hash
47 {
48 
49     // helper functions
50     sal_uInt32 f1( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
51     {
52         return z ^ ( x & ( y ^ z ) );
53     }
54 
55     sal_uInt32 f2( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
56     {
57         return x ^ y ^ z;
58     }
59 
60     sal_uInt32 f3( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
61     {
62         return ( x & y ) + ( z & ( x ^ y ) );
63     }
64 
65     sal_uInt32 rotl( sal_uInt32 nValue, sal_uInt32 nBits )
66     {
67         return ( nValue << nBits ) | ( nValue >> (32-nBits) );
68     }
69 
70     sal_uInt32 expand_nostore( sal_uInt32 index )
71     {
72         return data[index&15] ^ data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
73     }
74 
75     sal_uInt32 expand_store( sal_uInt32 index )
76     {
77         return data[index&15] ^= data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
78     }
79 
80     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 )
81     {
82         e += rotl(a,5);
83         switch( nFunction )
84         {
85             case 1: e += f1( b, c, d );break;
86             case 2:
87             case 4: e += f2( b, c, d );break;
88             case 3: e += f3( b, c, d );break;
89         }
90         e += constant + datum;
91         b = rotl( b, 30 );
92     }
93 
94     void transform();
95     void final();
96 
97     // data members
98     sal_uInt32 data[16];
99     sal_uInt32 hashdata[5];
100 public:
101     NIST_Hash( const char* pString, sal_uInt32 nLen );
102 
103     sal_uInt32 *getHash() { return hashdata; }
104 };
105 
106 void NIST_Hash::transform()
107 {
108     // constants
109     const sal_uInt32 K2     = 0x5A827999;
110     const sal_uInt32 K3     = 0x6ED9EBA1;
111     const sal_uInt32 K5     = 0x8F1BBCDC;
112     const sal_uInt32 K10    = 0xCA62C1D6;
113 
114     sal_uInt32 a, b, c, d, e;
115     a = hashdata[0];
116     b = hashdata[1];
117     c = hashdata[2];
118     d = hashdata[3];
119     e = hashdata[4];
120 
121     subRound( a, b, c, d, e, K2, data[ 0], 1 );
122     subRound( e, a, b, c, d, K2, data[ 1], 1 );
123     subRound( d, e, a, b, c, K2, data[ 2], 1 );
124     subRound( c, d, e, a, b, K2, data[ 3], 1 );
125     subRound( b, c, d, e, a, K2, data[ 4], 1 );
126     subRound( a, b, c, d, e, K2, data[ 5], 1 );
127     subRound( e, a, b, c, d, K2, data[ 6], 1 );
128     subRound( d, e, a, b, c, K2, data[ 7], 1 );
129     subRound( c, d, e, a, b, K2, data[ 8], 1 );
130     subRound( b, c, d, e, a, K2, data[ 9], 1 );
131     subRound( a, b, c, d, e, K2, data[10], 1 );
132     subRound( e, a, b, c, d, K2, data[11], 1 );
133     subRound( d, e, a, b, c, K2, data[12], 1 );
134     subRound( c, d, e, a, b, K2, data[13], 1 );
135     subRound( b, c, d, e, a, K2, data[14], 1 );
136     subRound( a, b, c, d, e, K2, data[15], 1 );
137     subRound( e, a, b, c, d, K2, expand_store( 16 ), 1 );
138     subRound( d, e, a, b, c, K2, expand_store( 17 ), 1 );
139     subRound( c, d, e, a, b, K2, expand_store( 18 ), 1 );
140     subRound( b, c, d, e, a, K2, expand_store( 19 ), 1 );
141 
142     subRound( a, b, c, d, e, K3, expand_store( 20 ), 2 );
143     subRound( e, a, b, c, d, K3, expand_store( 21 ), 2 );
144     subRound( d, e, a, b, c, K3, expand_store( 22 ), 2 );
145     subRound( c, d, e, a, b, K3, expand_store( 23 ), 2 );
146     subRound( b, c, d, e, a, K3, expand_store( 24 ), 2 );
147     subRound( a, b, c, d, e, K3, expand_store( 25 ), 2 );
148     subRound( e, a, b, c, d, K3, expand_store( 26 ), 2 );
149     subRound( d, e, a, b, c, K3, expand_store( 27 ), 2 );
150     subRound( c, d, e, a, b, K3, expand_store( 28 ), 2 );
151     subRound( b, c, d, e, a, K3, expand_store( 29 ), 2 );
152     subRound( a, b, c, d, e, K3, expand_store( 30 ), 2 );
153     subRound( e, a, b, c, d, K3, expand_store( 31 ), 2 );
154     subRound( d, e, a, b, c, K3, expand_store( 32 ), 2 );
155     subRound( c, d, e, a, b, K3, expand_store( 33 ), 2 );
156     subRound( b, c, d, e, a, K3, expand_store( 34 ), 2 );
157     subRound( a, b, c, d, e, K3, expand_store( 35 ), 2 );
158     subRound( e, a, b, c, d, K3, expand_store( 36 ), 2 );
159     subRound( d, e, a, b, c, K3, expand_store( 37 ), 2 );
160     subRound( c, d, e, a, b, K3, expand_store( 38 ), 2 );
161     subRound( b, c, d, e, a, K3, expand_store( 39 ), 2 );
162 
163     subRound( a, b, c, d, e, K5, expand_store( 40 ), 3 );
164     subRound( e, a, b, c, d, K5, expand_store( 41 ), 3 );
165     subRound( d, e, a, b, c, K5, expand_store( 42 ), 3 );
166     subRound( c, d, e, a, b, K5, expand_store( 43 ), 3 );
167     subRound( b, c, d, e, a, K5, expand_store( 44 ), 3 );
168     subRound( a, b, c, d, e, K5, expand_store( 45 ), 3 );
169     subRound( e, a, b, c, d, K5, expand_store( 46 ), 3 );
170     subRound( d, e, a, b, c, K5, expand_store( 47 ), 3 );
171     subRound( c, d, e, a, b, K5, expand_store( 48 ), 3 );
172     subRound( b, c, d, e, a, K5, expand_store( 49 ), 3 );
173     subRound( a, b, c, d, e, K5, expand_store( 50 ), 3 );
174     subRound( e, a, b, c, d, K5, expand_store( 51 ), 3 );
175     subRound( d, e, a, b, c, K5, expand_store( 52 ), 3 );
176     subRound( c, d, e, a, b, K5, expand_store( 53 ), 3 );
177     subRound( b, c, d, e, a, K5, expand_store( 54 ), 3 );
178     subRound( a, b, c, d, e, K5, expand_store( 55 ), 3 );
179     subRound( e, a, b, c, d, K5, expand_store( 56 ), 3 );
180     subRound( d, e, a, b, c, K5, expand_store( 57 ), 3 );
181     subRound( c, d, e, a, b, K5, expand_store( 58 ), 3 );
182     subRound( b, c, d, e, a, K5, expand_store( 59 ), 3 );
183 
184     subRound( a, b, c, d, e, K10, expand_store( 60 ), 4 );
185     subRound( e, a, b, c, d, K10, expand_store( 61 ), 4 );
186     subRound( d, e, a, b, c, K10, expand_store( 62 ), 4 );
187     subRound( c, d, e, a, b, K10, expand_store( 63 ), 4 );
188     subRound( b, c, d, e, a, K10, expand_store( 64 ), 4 );
189     subRound( a, b, c, d, e, K10, expand_store( 65 ), 4 );
190     subRound( e, a, b, c, d, K10, expand_store( 66 ), 4 );
191     subRound( d, e, a, b, c, K10, expand_store( 67 ), 4 );
192     subRound( c, d, e, a, b, K10, expand_store( 68 ), 4 );
193     subRound( b, c, d, e, a, K10, expand_store( 69 ), 4 );
194     subRound( a, b, c, d, e, K10, expand_store( 70 ), 4 );
195     subRound( e, a, b, c, d, K10, expand_store( 71 ), 4 );
196     subRound( d, e, a, b, c, K10, expand_store( 72 ), 4 );
197     subRound( c, d, e, a, b, K10, expand_store( 73 ), 4 );
198     subRound( b, c, d, e, a, K10, expand_store( 74 ), 4 );
199     subRound( a, b, c, d, e, K10, expand_store( 75 ), 4 );
200     subRound( e, a, b, c, d, K10, expand_store( 76 ), 4 );
201     subRound( d, e, a, b, c, K10, expand_nostore( 77 ), 4 );
202     subRound( c, d, e, a, b, K10, expand_nostore( 78 ), 4 );
203     subRound( b, c, d, e, a, K10, expand_nostore( 79 ), 4 );
204 
205     hashdata[0] += a;
206     hashdata[1] += b;
207     hashdata[2] += c;
208     hashdata[3] += d;
209     hashdata[4] += e;
210 }
211 
212 #define BLOCKSIZE sizeof( data )
213 
214 NIST_Hash::NIST_Hash( const char* pString, sal_uInt32 nLen )
215 {
216     hashdata[0] = 0x67452301;
217     hashdata[1] = 0xefcdab89;
218     hashdata[2] = 0x98badcfe;
219     hashdata[3] = 0x10325476;
220     hashdata[4] = 0xc3d2e1f0;
221 
222     sal_uInt32 nBytes = nLen;
223 
224     while( nLen >= sizeof( data ) )
225     {
226         memcpy( data, pString, sizeof( data ) );
227         pString += sizeof( data );
228         nLen -= sizeof( data );
229         transform();
230     }
231     memcpy( data, pString, nLen );
232     ((char*)data)[nLen++] = 0x80;
233     if( nLen > sizeof( data ) - 8 )
234     {
235         memset( ((char*)data)+nLen, 0, sizeof( data ) - nLen );
236         transform();
237         memset( data, 0, sizeof( data ) - 8 );
238     }
239     else
240         memset( ((char*)data)+nLen, 0, sizeof( data ) - 8 - nLen );
241     data[14] = 0;
242     data[15] = nBytes << 3;
243     transform();
244 }
245 
246 #ifdef TEST
247 #include <stdio.h>
248 int main( int argc, const char** argv )
249 {
250     const char* pHash = argc < 2 ? argv[0] : argv[1];
251 
252     NIST_Hash aHash( pHash, strlen( pHash ) );
253     sal_uInt32* pBits = aHash.getHash();
254 
255     printf( "text : %s\n"
256             "bits : 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
257             pHash,
258             pBits[0], pBits[1], pBits[2],pBits[3],pBits[4]
259             );
260     return 0;
261 }
262 
263 #endif
264